Reputation: 157
This is my attempt at recreating Battleship using Java. I decided to test the simpler version of the game with only one ship and giving the ship a concrete location on the game board. I found a problem with my code. No matter what coordinate I enter, I end up "hitting" the ship.
Here is all the code I have written so far:
import java.util.Scanner;
class GameBoard {
Scanner input = new Scanner(System.in); // scanner object
String[][] board = { // game board
{"_", " 1", " 2", " 3", " 4", " 5", " 6", " 7", " 8", " 9", "10"},
{"A", "[ ]", "[ ]", "[ ]", "[ ]", "[ ]", "[ ]", "[ ]", "[ ]", "[ ]", "[ ]"},
{"B", "[ ]", "[ ]", "[ ]", "[ ]", "[ ]", "[ ]", "[ ]", "[ ]", "[ ]", "[ ]"},
{"C", "[ ]", "[ ]", "[ ]", "[ ]", "[ ]", "[ ]", "[ ]", "[ ]", "[ ]", "[ ]"},
{"D", "[ ]", "[ ]", "[ ]", "[ ]", "[ ]", "[ ]", "[ ]", "[ ]", "[ ]", "[ ]"},
{"E", "[ ]", "[ ]", "[ ]", "[ ]", "[ ]", "[ ]", "[ ]", "[ ]", "[ ]", "[ ]"},
{"F", "[ ]", "[ ]", "[ ]", "[ ]", "[ ]", "[ ]", "[ ]", "[ ]", "[ ]", "[ ]"},
{"G", "[ ]", "[ ]", "[ ]", "[ ]", "[ ]", "[ ]", "[ ]", "[ ]", "[ ]", "[ ]"},
{"H", "[ ]", "[ ]", "[ ]", "[ ]", "[ ]", "[ ]", "[ ]", "[ ]", "[ ]", "[ ]"},
{"I", "[ ]", "[ ]", "[ ]", "[ ]", "[ ]", "[ ]", "[ ]", "[ ]", "[ ]", "[ ]"},
{"J", "[ ]", "[ ]", "[ ]", "[ ]", "[ ]", "[ ]", "[ ]", "[ ]", "[ ]", "[ ]"}
};
boolean frigateIsAlive = true; // the ship is still alive
int numOfHitsOnFrigate = 0; // number of hits the player made on the frigate
String [] frigate = {board[1][1], board[1][2]}; // ship
public void createBoard(){ // draws the battleship game board
for (int row = 0; row < board.length; row++) {
for (int col = 0; col < board[row].length; col++) {
System.out.print(board[row][col] + "\t");
} // inner loop
System.out.println();
System.out.println();
System.out.println();
} // outer loop
}
public String getUserGuess() { // takes the users guess
System.out.println("Choose a coordinate on the board to fire at");
int x = input.nextInt();
int y = input.nextInt();
String userGuess = board[x][y];
return userGuess;
}
public void checkResult(String userGuess) { // checks the user's guess
if(userGuess.equalsIgnoreCase(frigate[0])){
System.out.println("hit!");
numOfHitsOnFrigate++;
board[1][1] = " *";
createBoard();
}
else if(userGuess.equalsIgnoreCase(frigate[1])) {
System.out.println("hit!");
numOfHitsOnFrigate++;
board[1][2] = " *";
createBoard();
}
else {
System.out.println("miss!");
}
if (numOfHitsOnFrigate == 2) {
System.out.println("Enemy frigate has been sunk!");
frigateIsAlive = false;
}
}
} // end class
public class Game {
public static void run() {
GameBoard newGame = new GameBoard();
newGame.createBoard();
while(newGame.frigateIsAlive) {
newGame.checkResult(newGame.getUserGuess());
}
}
}
public class App {
public static void main(String[] args) {
Game.run();
}
}
Upvotes: 0
Views: 1213
Reputation: 1218
The boat is always being hit because the declaration of frigate
is:
frigate = {board[1][1], board[1][2]}
, which is ultimately assigning the string '[ ]'
to both values of the frigate. This is then being compared to more empty strings, when you are looking for the frigate and comparing the values.
This can be fixed by making a board of position x in [1,2,3,4, n]
and y in [A,B,C...,Letter_n]
. That is, the coordinates of the frigate would be Frigate.x = 1
and Frigate.y = A
.
I hope this helps!
I saw your further question of how to implement this. I would make Frigate a class that has a list of coordinates:
this.x
as one point either Letter or Number
this.y
as one point Not of type this.x as in your example
The tuple (this.x, this.y)
would work nice in your list Frigate
Do the same for any other points in the list Frigate.
After the list Frigate has been completed, then two more things have to be changed.
The first thing that has be changed is how to check if the user is calling things in the scope that you want.
The second thing that has to be changed is how to make sure the same point isn't being called over and over again to 'blow up' a ship. That is, when a point in Frigate gets called, then it should be removed from Frigate. The remaining tuples in Frigate are going to be the 'health' of 'hit points' left on Frigate. To recall the original size of Frigate, an addition of Frigate.initialSize()
would be very handy, but this could be later down the road.
Upvotes: 1