Help with battleship game, please!
Hello all! I have just joined the online community as well as the field of computer science! I am taking an intro course to programming and have done well so far but for our last program we are to revise and compile a Battleship program. I've done some research and it appears that this is a normal game for the intro level. I am having a hard time with it though because this whole course has been crammed into 4 weeks. Right now I'm working on the toughest part of the program-- placing the ships. I have made a method for the ships to be placed but now I need to create another method to determine the validity of the ship. The grid is 10 x 10 and the two conditions for a ship to be placed are for it to 1) not go out of bound and 2) not have another ship in the way. I am trying to write a do while loop to complete this method that will run while the boolean is false (that the ship is not valid) Below I have posted the code I have thus far (this is only a small portion of the overall code so there is much more to the program):
Code:
private void placeAllShips()
{
Random rnd = new Random();
int randRow = rnd.nextInt(NUM_ROWS);
int randCol = rnd.nextInt(NUM_COLS);
int randDirection = rnd.nextInt(2); // DIRECTION_RIGHT has a value of 0 and DIRECTION_DOWN has a value of 1
}
private void isShipValid(int randRow, int randCol, int randDirection,
int shipLength) // THIS IS WHERE I NEED HELP!
do
{
}
while (boolean = false);
/**
* placeShip assumes ship will fit under both conditions and it will place
* the ship in the grid
*
* @param randRow
* Random row to place ship on
* @param randCol
* Random column to place ship on
* @param randDirection
* Random direction for ship to go in (right or down)
* @param shipLength
* Length of ship (2-5)
*/
private void placeShip(int randRow, int randCol, int randDirection,
int shipLength)
{
if (randDirection == DIRECTION_RIGHT)
{
for (int i = 0; i < shipLength; i++)
{
grid[randRow][randCol + (i)] = SHIP;
}
}
else
{
for (int i = 0; i < shipLength; i++)
{
grid[randRow + (i)][randCol] = SHIP;
}
}
}
Thanks A TON in advance for any feedback. Not looking for anyone to do it for me just trying to get some input because I am lost and very new to Java and computer programming. Let me know if you need more info.
Re: Help with battleship game, please!
I forgot to add this bit a code to use in the loop. There is method inBounds to determine to determine if a particular row and column pair is inbounds and a getCell method that will get the value of the cell at the specified row and column.
Code:
/**
* Determine if the cell at the specified row and column is in the grid's
* bounds.
*
* @param row
* the cell's row
* @param col
* the cell's column
*
* @return true if the cell is in bounds, false otherwise
*/
private boolean inBounds(int row, int col)
{
return ((row >= 0) && (row < NUM_ROWS) && (col >= 0) && (col < NUM_COLS));
}
/**
* Returns the value of the cell at [row][col] if the cell is in bounds.
* Otherwise, returns OUT_OF_BOUNDS.
*
* @param row
* the cell's row
* @param col
* the cell's column
*
* @return if in bounds, the value of the cell at [row][col], otherwise
* OUT_OF_BOUNDS
*/
public int getCell(int row, int col)
{
if (inBounds(row, col))
return grid[row][col];
else
return OUT_OF_BOUNDS;
}
Re: Help with battleship game, please!
Re: Help with battleship game, please!
Uh, please apply the code tags to your code, and I guarantee you'll get more help. Otherwise its too painful to read your code :)
Without reading too much through your code (because of the above reasons :P) here is in my opinion a good way to place ships - i'm assuming a very random approach in the placement of ships, so no AI or other optimization strategies applied:
-keep a list of locations you've already placed ships (sort of like a Tabu list)
-when placing a "DIRECTION_RIGHT" oriented ship pick a random starting point on the grid for x coordinates 0 to 10-l (where l is the lenght of your ship) and of course check with the Tabu list for the chosen point, as well the l-1 points to the right, so you dont overlap ships. This will guarantee you're placing the ship in bounds and not over other ships
-analogically when placing a "DIRECTION_DOWN" ship pick the start point from grid for y coordinates 0 to 10-l, and check with the Tabu list. This way you can place the vertical ships safely.
This is by no means an optimal way of placing the ships, as your code will likely pick starting points that aren't valid sometimes, and simply have to redo it, till all the ships are placed. But its a start, and fairly quick and easy to implement.
Re: Help with battleship game, please!
Thanks for the tips @Otacon and @Darryl. I apologize for not putting in the code tags I was unaware of that rule but I have implemented them. So now I figured out that part but I am working on my overarching loop to call the two methods, isShipValid and placeShip. I was wrong about trying to do a do while loop there and the do while loop actually needs to go here. This is what I have so far and I have noted where I need help/am working on:
Code:
/**
* Places all of the game's ships onto the grid.
*/
private void placeAllShips()
{
for (int index = 0; index < SHIP_LENGTHS.length; index++) // THIS IS WHERE I NEED HELP
{
int length = SHIP_LENGTHS[index];
Random rnd = new Random();
int randRow = rnd.nextInt(NUM_ROWS);
int randCol = rnd.nextInt(NUM_COLS);
int randDirection = rnd.nextInt(2);
do
{
isShipValid(randRow, randCol, randDirection, length); // This is not complete
} while (isShipValid(randRow, randCol, randDirection, length) == false); // This is not complete
} // Need to call placeShips method
}
private boolean isShipValid(int randRow, int randCol, int randDirection,
int shipLength)
{
if (randDirection == DIRECTION_RIGHT)
{
for (int i = 0; i < shipLength; i++)
{
if (getCell(randRow, randCol + (i)) != EMPTY)
{
return false;
}
}
return true;
}
else
{
for (int i = 0; i < shipLength; i++)
{
if (getCell(randRow + (i), randCol) != EMPTY)
{
return false;
}
}
return true;
}
}
/**
* placeShip assumes ship will fit under both conditions and it will place
* the ship in the grid
*
* @param randRow
* Random row to place ship on
* @param randCol
* Random column to place ship on
* @param randDirection
* Random direction for ship to go in (right or down)
* @param shipLength
* Length of ship (2-5)
*/
private void placeShip(int randRow, int randCol, int randDirection,
int shipLength)
{
if (randDirection == DIRECTION_RIGHT)
{
for (int i = 0; i < shipLength; i++)
{
grid[randRow][randCol + (i)] = SHIP;
}
}
else
{
for (int i = 0; i < shipLength; i++)
{
grid[randRow + (i)][randCol] = SHIP;
}
}
}
Thanks again for all of those that can help. I am really struggling with this class!
Re: Help with battleship game, please!
You're on a decent track to get things at least working, even if not efficient :)
Quote:
int length = SHIP_LENGTHS[index];
Random rnd = new Random();
int randRow = rnd.nextInt(NUM_ROWS);
int randCol = rnd.nextInt(NUM_COLS);
int randDirection = rnd.nextInt(2);
Few things that might fix some issues:
1. Take out Random rnd = new Random(); from the for loop, you don't need to create it every time, just once before the loop starts
2. Decide on the direction first, and use that along with ship length information to only generate ship positions which will not go out of bounds (for example if length = 2 and direction_right, you only want the random number from 1-8, not 1-10 for the x-var; Something like this maybe:
Code:
int randRow;
int randCol;
int length = SHIP_LENGTHS[index];
int randDirection = rnd.nextInt(2); //generated first
//Random rnd = new Random(); -- this is now above the for loop
//Only generate a position that will fit the ship, and not go out of bounds based on direction and length
if (randDirection == DIRECTION_RIGHT){
randRow = rnd.nextInt(NUM_ROWS);
randCol = rnd.nextInt(NUM_COLS-length);
}
else{
randRow = rnd.nextInt(NUM_ROWS-length);
randCol = rnd.nextInt(NUM_COLS);
}
This should help you generate ship locations that are legal as far the the board is concerned (I didn't compile it, so sorry if there any any typos). It doesn't however handle if a ship has already been placed. You could try to handle it here as well, or use your validation method, and the getCell().
Let me know what problems you're still having :)