Solved

Help me solve this algorith problem

Posted on 2009-04-02
5
291 Views
Last Modified: 2013-11-23
So I'm working on creating a battleship game in Java.  I have already set up the board and all my classes.  My method for placing the ships is up and running.  

public void placeShip(Ship shipType, Coordinate coord, boolean isHorizontal)

basically I take a coordinate and based on the ship size and it's position I place it on the board, it also checks whether it's possible to place, i.e it doesn't go outside the grid or overlaps with another ship).

My problem is this, my Ocean board consists of a grid of 10X10 JButtons.  I have another JPanel with 5 JButtons each of them representing a ship.  When I click on one of these buttons(this means this is the ship I select to place),  then I must click on a button on the ocean grid. (that would be my coordinate.).  and this coordinate where the start of the ship is placed.

How would you about doing this? Since I have to be waiting on the user to pick a ship button and also pick an button in the ocean, would I need a thread?  I'm unsure how to do this. Can you guys help me out?

I posted the code for the class I'm using to test my program.  Let me know if you want to see the code for the other classes.

Thanks.
import java.awt.BorderLayout;

import java.awt.Color;

import java.awt.Dimension;

import java.awt.FlowLayout;

import java.awt.GridLayout;

 

import javax.swing.ImageIcon;

import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JPanel;

import javax.swing.JScrollPane;

import javax.swing.JTextArea;

import javax.swing.border.Border;

import javax.swing.border.LineBorder;

import javax.swing.border.TitledBorder;

 

import java.awt.Container;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

 

 

public class Debug extends JFrame{

 

	private static final long serialVersionUID = 1L;

	final ImageIcon logo = new ImageIcon("images/board_logo.png");

	JPanel ocean;

	JPanel enemy;

	JPanel logoPanel;

	JPanel statusPanel;

	JButton logoButton;

	JTextArea status;

	BattleField battlefield;

	Container contents;

	

	

	//final ImageIcon logo = new ImageIcon("images/board_logo.png");

	final ImageIcon carrierLogo = new ImageIcon("images/carrier/carrier_h.png");

	final ImageIcon battleshipLogo = new ImageIcon("images/battleship/battleship_h.png");

	final ImageIcon destroyerLogo = new ImageIcon("images/destroyer/destroyer_h.png");

	final ImageIcon submarineLogo = new ImageIcon("images/submarine/submarine_h.png");

	final ImageIcon patrolBoatLogo = new ImageIcon("images/patrol/patrol_h.png");

	JPanel shipsPanel, shipsTop, shipsBottom;

	

	Ship carrier, battleship, submarine, destroyer, patrolBoat;

	JButton carrierButton, battleshipButton, destroyerButton, submarineButton, patrolBoatButton;

	ShipButtonHandler shipBH;

	Ship activeShip;

	

	

	public Debug(){

	super("test");

	contents = getContentPane();

	setSize(750,415);

	setResizable(false);

 

	contents.setLayout(new BorderLayout());

	battlefield = new BattleField();

	contents.add(battlefield, BorderLayout.NORTH);

	status = new JTextArea("Welcome");

	statusPanel = new JPanel();

	statusPanel.setLayout(new BorderLayout());

	statusPanel.setBorder(new TitledBorder("Game Status"));

	statusPanel.add(new JScrollPane(status, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,

					JScrollPane.HORIZONTAL_SCROLLBAR_NEVER), BorderLayout.CENTER);

	contents.add(statusPanel, BorderLayout.SOUTH);

	

	

	

	carrierButton = new JButton("Carrier");

	battleshipButton = new JButton("Battleship");

	destroyerButton = new JButton("Destroyer");

	submarineButton = new JButton("Submarine");

	patrolBoatButton = new JButton("Patrol Boat");

	carrierButton.setIcon(carrierLogo);

	battleshipButton.setIcon(battleshipLogo);

	destroyerButton.setIcon(destroyerLogo);

	submarineButton.setIcon(submarineLogo);

	patrolBoatButton.setIcon(patrolBoatLogo);

	shipsPanel = new JPanel(new GridLayout(2,1));

	shipsTop = new JPanel(new GridLayout(1,2));

	shipsBottom = new JPanel(new GridLayout(1,3));

	shipsTop.add(carrierButton);

	shipsTop.add(battleshipButton);

	shipsBottom.add(destroyerButton);

	shipsBottom.add(submarineButton);

	shipsBottom.add(patrolBoatButton);

	shipsPanel.add(shipsTop);

	shipsPanel.add(shipsBottom);

	//shipsPanel.setPreferredSize(new Dimension(700,30));

	contents.add(shipsPanel, BorderLayout.CENTER);

	//carrierButton.setEnabled(false);

	shipBH = new ShipButtonHandler();

	

	carrier = new AircraftCarrier();

	battleship = new Battleship();

	submarine = new Submarine();

	destroyer = new Destroyer();

	patrolBoat = new PatrolBoat();

	

	

	carrierButton.addActionListener(shipBH);

	battleshipButton.addActionListener(shipBH);

	destroyerButton.addActionListener(shipBH);

	submarineButton.addActionListener(shipBH);

	patrolBoatButton.addActionListener(shipBH);

	activeShip = new Ship();

	

	//battlefield.enemy.disableOcean();

	//battlefield.ocean.disableOcean();

	}

	

 

	private boolean areAllPlaced(){

		if(carrier.isPlaced && battleship.isPlaced && submarine.isPlaced

				&& destroyer.isPlaced && patrolBoat.isPlaced)

			return true;

			else

				return false;

		}

	

	public void place(){

		while(!this.areAllPlaced()){

		battlefield.ocean.placeShip(battlefield.ocean.selectedCoord, activeShip, battlefield.ocean.horizontal);

		}

	}

	

 

	

 

	

	public static void main(String[] args) {

 

		Debug d = new Debug();

		d.setVisible(true);

		d.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

 

		

		

	}

	

	private class ShipButtonHandler implements ActionListener{

 

		//Coordinate temp = new Coordinate();

		public void actionPerformed(ActionEvent e) {

			if(e.getSource() == carrierButton){

				activeShip = new AircraftCarrier();

				carrierButton.setEnabled(false);

				battlefield.ocean.selectedCoord = null;

			}

			else if(e.getSource() == battleshipButton){

				activeShip = new Battleship();

				battleshipButton.setEnabled(false);

				battlefield.ocean.selectedCoord = null;

			}

			else if(e.getSource() == destroyerButton){

				activeShip = new Destroyer();

				destroyerButton.setEnabled(false);

				battlefield.ocean.selectedCoord = null;

			}

			else if(e.getSource() == submarineButton){

				activeShip = new Submarine();

				

				submarineButton.setEnabled(false);

				battlefield.ocean.selectedCoord = null;

			}

			else if(e.getSource() == patrolBoatButton){

				activeShip = new PatrolBoat();

				

				patrolBoatButton.setEnabled(false);

				battlefield.ocean.selectedCoord = null;

			}

			else

				System.out.println("Error");

			

			}

		}

	

}

Open in new window

0
Comment
Question by:ubuntuguy
5 Comments
 
LVL 16

Assisted Solution

by:imladris
imladris earned 160 total points
ID: 24050912
I would be inclined to inspect (and create, if necessary) relevant variables to determine the legality of various actions. That is, a ship cannot be placed, if activeShip is null (that is, no ship has been selected). In that case, if place gets called and activeShip is null, and you have a suitable feedback line, you can abort the action and emit an error message explaining the problem instead.

Alternatively, buttons can be enabled and disabled. This works very well in lots of situations. However, in this case I think it is going to wind up being more messy and complicated. If, for instance, you start with the ocean grey and the ships enabled, then select a ship, grey the ships and enable the ocean you are perfectly shepherding the user in the expected sequence. However, what if they change their mind about what ship they want? You would need a "cancel selection button". What if they place it in the ocean and then change their mind? Again you would need some way of accomodating that. I think it makes for a more complicated, less natural interface in the situation.
0
 
LVL 3

Accepted Solution

by:
avdej earned 300 total points
ID: 24051539
No, you don't need any multithreading  here.
I think (considering your code) you have TWO possible principal solutions here:
1. "Immediately assign the selected ship to the first ocean field clicked"
2. "Allow to change ship and/or ocean selection before a final ship assignment"

1. According to your code you should always have exactly ONE ship selected, then you can AUTOMATICALLY handle the FIRST subsequent click on the ocean field as a ship placement.
OR
2. You can add "Place Ship" button and allow a user to place the selected ship on demand, i.e. after she is ready/satisfied with her choice of a final ship-field pair (i.e. activeShip and activeField in your terminology).
0
 
LVL 22

Assisted Solution

by:NovaDenizen
NovaDenizen earned 40 total points
ID: 24062078
Personally, I'd make a couple of subclasses of JComponent that implemented MouseListener and MouseMotionListener, and do it from scratch.  But you seem like you're most comfortable with the grid-of-buttons approach.

The JPanel with 5 buttons, 1 for each ship.  I'd make it have two buttons for each ship, one for horizontal placement and the other for vertical placement.  When the user picks one of these 10 buttons, you can iterate through your 10x10 grid, looking for all the places that it would be legal to place the ship.  Disable the buttons where it would be illegal to place the ship, and enable the buttons that represent a legal placement.  Then the user should be able to see which places he can put a ship.
0
 
LVL 1

Author Comment

by:ubuntuguy
ID: 24065966
OK I fixed it. I added a private class that implements actionListener for all the buttons on the ocean.  So when I click on it I added the active ship or did nothing if no active ship was selected.
0
 
LVL 16

Expert Comment

by:imladris
ID: 24068288
So now it is time to close the question.

Please select one or more answers that helped and provide a grade.
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
map related example 6 38
reverse digits of a number using for loop 5 36
table example 4 25
varialbe initialization 11 30
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
Introduction This article is the second of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article covers the basic installation and configuration of the test automation tools used by…
Viewers learn about the “for” loop and how it works in Java. By comparing it to the while loop learned before, viewers can make the transition easily. You will learn about the formatting of the for loop as we write a program that prints even numbers…
Viewers will learn about the different types of variables in Java and how to declare them. Decide the type of variable desired: Put the keyword corresponding to the type of variable in front of the variable name: Use the equal sign to assign a v…

863 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now