Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

This is a Java BattleShip Program contaning methods. I need the methods checkWat

ID: 3735684 • Letter: T

Question

This is a Java BattleShip Program contaning methods. I need the methods checkWater, addShip, printBoard, placeShip and placeRandomShip. Please check the ones given are correct and also that addShip is completed. Thanks.

Also I need 2 tests per test method for testCheckWater and testPlaceShip.

Here is the code for the file Battleship.java:

import java.util.Scanner;
import java.util.Random;

public class Battleship {

/**
* This method converts a String representing a base (or radix) 26 number into a decimal (or
* base 10) number. The String representation of the base 26 number uses the letters of the
* Latin alphabet to represent the 26 digits. That is, A represents 0, B represents 1, C
* represents 2, ..., Y represents 24, and Z represents 25.
*
* A couple of examples: BAAA = 1 * 26^3 + 0 * 26^2 + 0 * 26^1 + 0 * 26^0 = 17576 ZERTY = 25 *
* 26^4 + 4 * 26^3 + 17 * 26^2 + 19 * 26^1 + 24 * 26^0 = 11506714
*
* For this method: - use Math.pow to calculate the powers of 26. - don't assume that the input
* is in any particular case; use toUpperCase(). - don't check that the input is only 'A' to
* 'Z'. - calculate the value of each digit relative to 'A'. - start from either the first or
* last character, and calculate the exponent based on the index of each character.
*
* @param coord The coordinate value in base 26 as described above.
* @return The numeric representation of the coordinate.
*/
public static int coordAlphaToNum(String coord) {
int result = 0;
for (int i = 0; i < coord.length(); ++i) {
int num = Character.toUpperCase(coord.charAt(i)) - 'A';
result = result + (num * (int) Math.pow(26, coord.length() - i - 1));
}
return result;
}

/**
* This method converts an int value into a base (or radix) 26 number, where the digits are
* represented by the 26 letters of the Latin alphabet. That is, A represents 0, B represents 1,
* C represents 2, ..., Y represents 24, and Z represents 25. A couple of examples: 17576 is
* BAAA, 11506714 is ZERTY.
*
* The algorithm to convert an int to a String representing these base 26 numbers is as follows:
* - Initialize res to the input integer - The next digit is determined by calculating the
* remainder of res with respect to 26 - Convert this next digit to a letter based on 'A' - Set
* res to the integer division of res and 26 - Repeat until res is 0
*
* @param coord The integer value to convert into an alpha coordinate.
* @return The alpha coordinate in base 26 as described above. If coord is negative, an empty
* string is returned.
*/
public static String coordNumToAlpha(int coord) {
String result = "";
while (coord > 0) {
int res = coord % 26;
res += 'A';
char nextDigit = (char) res;
result = nextDigit + result;
coord = coord / 26;
}
return result;
}

/**
* Prompts the user for an integer value, displaying the following: "Enter the valName (min to
* max): " Note: There should not be a new line terminating the prompt. valName should contain
* the contents of the String referenced by the parameter valName. min and max should be the
* values passed in the respective parameters.
*
* After prompting the user, the method will read an int from the console and consume an entire
* line of input. If the value read is between min and max (inclusive), that value is returned.
* Otherwise, "Invalid value." terminated by a new line is output and the user is prompted
* again.
*
* @param sc The Scanner instance to read from System.in.
* @param valName The name of the value for which the user is prompted.
* @param min The minimum acceptable int value (inclusive).
* @param min The maximum acceptable int value (inclusive).
* @return Returns the value read from the user.
*/
public static int promptInt(Scanner sc, String valName, int min, int max) {
System.out.print("Enter the " + valName + " (" + min + " to " + max + "): ");
int num = sc.nextInt();
  
if (min <= num && max >= num) {
return num;
} else {
System.out.println("Invalid value.");
return promptInt(sc, valName, min, max);
}
}

/**
* Prompts the user for an String value, displaying the following: "Enter the valName (min to
* max): " Note: There should not be a new line terminating the prompt. valName should contain
* the contents of the String referenced by the parameter valName. min and max should be the
* values passed in the respective parameters.
*
* After prompting the user, the method will read an entire line of input, trimming any trailing
* or leading whitespace. If the value read is (lexicographically ignoring case) between min and
* max (inclusive), that value is returned. Otherwise, "Invalid value." terminated by a new line
* is output and the user is prompted again.
*
* @param sc The Scanner instance to read from System.in.
* @param valName The name of the value for which the user is prompted.
* @param min The minimum acceptable String value (inclusive).
* @param min The maximum acceptable String value (inclusive).
* @return Returns the value read from the user.
*/
public static String promptStr(Scanner sc, String valName, String min, String max) {
System.out.print("Enter the " + valName + " (" + min + " to " + max + "): ");
String str = sc.nextLine();
str = str.trim();
  
String min_ = min.toUpperCase();
String max_ = max.toUpperCase();
str = str.toUpperCase();
if (min_.compareTo(str) <= 0 && str.compareTo(max_) <= 0) {
return str;
} else {
System.out.println("Invalid value.");
return promptStr(sc, valName, min, max);
}
}

/**
* Prompts the user for an char value. The prompt displayed is the contents of the String
* referenced by the prompt parameter. Note: There should not be a new line terminating the
* prompt.
*
* After prompting the user, the method will read an entire line of input and return the first
* non-whitespace character in lower case.
*
* @param sc The Scanner instance to read from System.in
* @param prompt The user prompt.
* @return Returns the first non-whitespace character (in lower case) read from the user. If
* there are no non-whitespace characters read, the null character is returned.
*/
public static char promptChar(Scanner sc, String prompt) {
System.out.println(prompt);
String in = sc.next();
in = in.trim();
in = in.toLowerCase();
return in.charAt(0);
}

/**
* Initialises a game board so that all the entries are Config.WATER_CHAR.
*
* @param board The game board to initialise.
*/
public static void initBoard(char board[][]) {
for (int i = 0; i < board.length; ++i) {
for (int j = 0; j < board[i].length; ++j) {
board[i][j] = Config.WATER_CHAR;
}
}
}

/**
* Prints the game boards as viewed by the user. This method is used to print the game boards as
* the user is placing their ships and during the game play.
*
* Some notes on the display: - Each column printed will have a width of Config.MAX_COL_WIDTH. -
* Each row is followed by an empty line. - The values in the headers and cells are to be right
* justified.
*
* @param board The board to print.
* @param caption The board caption.
*/
public static void printBoard(char board[][], String caption) {
System.out.println(caption);
for(int i = 0; i < board.length; ++i) {
for(int j = 0;j < board[i].length; ++j) {
System.out.print(board[i][j] + " ");
}
System.out.println();
}
}

  
/**
* Determines if a sequence of cells of length len in a game board is clear or not. This is used
* to determine if a ship will fit on a given game board. The x and y coordinates passed in as
* parameters represent the top-left cell of the ship when considering the grid.
*
* @param board The game board to search.
* @param xcoord The x-coordinate of the top-left cell of the ship.
* @param ycoord The y-coordinate of the top-left cell of the ship.
* @param len The length of the ship.
* @param dir true if the ship will be vertical, otherwise horizontal
* @return 1 if the cells to be occupied by the ship are all Config.WATER_CHAR, -1 if the cells
* to be occupied are not Config.WATER_CHAR, and -2 if the ship would go out-of-bounds
* of the board.
*/
public static int checkWater(char board[][], int xcoord, int ycoord, int len, boolean dir) {
int result = -2;
if (dir) {
for (int i = 0; i < board.length; ++i) {
int counter1 = 0;
int counter2 = 0;
boolean water = true;
for (int j = 0; j < board.length; ++j) {
if (board[j][i] == Config.WATER_CHAR) {
++counter1;
}
if (board[j][i] != Config.WATER_CHAR) {
++counter2;
}
}
if (counter1 == board.length && counter1 >= len) {
result = 1;
} else if (counter2 == board.length && counter2 >= len) {
result = -1;
}
}
} else {
for(int i = 0; i < board.length; ++i) {
int counter1 = 0;
int counter2 = 0;
boolean water = true;
for(int j = 0; j < board[i].length; ++j) {
if (board[i][j] == Config.WATER_CHAR) {
++counter1;
} if (board[i][j] != Config.WATER_CHAR) {
++counter2;
}
}
if (counter1 == board[i].length && counter1 >= len) {
result = 1;
} else if (counter2 == board[i].length && counter2 >= len) {
result = -1;
}
}
}
return result;
}

/**
* Checks the cells of the game board to determine if all the ships have been sunk.
*
* @param board The game board to check.
* @return true if all the ships have been sunk, false otherwise.
*/
public static boolean checkLost(char board[][]) {
// FIXME
return false;
}

/**
* Places a ship into a game board. The coordinate passed in the parameters xcoord and ycoord
* represent the top-left coordinate of the ship. The ship is represented on the game board by
* the Character representation of the ship id. (For this method, you can assume that the id
* parameter will only be values 1 through 9.)
*
* @param board The game board to search.
* @param xcoord The x-coordinate of the top-left cell of the ship.
* @param ycoord The y-coordinate of the top-left cell of the ship.
* @param len The length of the ship.
* @param dir true if the ship will be vertical, otherwise horizontal.
* @param id The ship id, assumed to be 1 to 9.
* @return false if the ship goes out-of-bounds of the board, true otherwise.
*/
public static boolean placeShip(char board[][], int xcoord, int ycoord, int len, boolean dir,
int id) {
if (dir == true) {
if (ycoord + len >= Config.MAX_HEIGHT) {
return false;
}
for (int i = ycoord; i < ycoord + len; ++i) {
board[i][xcoord] = (char) ('0' + id);
}
return true;
} else {
if (xcoord + len >= Config.MAX_WIDTH) {
return false;
}
for (int i = xcoord; i < xcoord + len; ++i) {
board[ycoord][i] = (char) ('0' + id);
}
return true;
}
}

/**
* Randomly attempts to place a ship into a game board. The random process is as follows: 1 -
* Pick a random boolean, using rand. True represents vertical, false horizontal. 2 - Pick a
* random integer, using rand, for the x-coordinate of the top-left cell of the ship. The number
* of integers to choose from should be calculated based on the width of the board and length of
* the ship such that the placement of the ship won't be out-of-bounds. 3 - Pick a random
* integer, using rand, for the y-coordinate of the top-left cell of the ship. The number of
* integers to choose from should be calculated based on the height of the board and length of
* the ship such that the placement of the ship won't be out-of-bounds. 4 - Verify that this
* random location can fit the ship without intersecting another ship (checkWater method). If
* so, place the ship with the placeShip method.
*
* It is possible for the configuration of a board to be such that a ship of a given length may
* not fit. So, the random process will be attempted at most Config.RAND_SHIP_TRIES times.
*
* @param board The game board to search.
* @param len The length of the ship.
* @param id The ship id, assumed to be 1 to 9..
* @param rand The Random object.
* @return true if the ship is placed successfully, false otherwise.
*/
public static boolean placeRandomShip(char board[][], int len, int id, Random rand) {
boolean dir = rand.nextBoolean();
for (int i = 0; i < Config.RAND_SHIP_TRIES; ++i) {
int xcoord = rand.nextInt(Config.MAX_WIDTH - len);
int ycoord = rand.nextInt(Config.MAX_HEIGHT - len);
if (checkWater(board, xcoord, ycoord, len, dir) == 1) {
boolean canPlace = placeShip(board, xcoord, ycoord, len, dir, id);
if (canPlace == true) {
return true;
}
}
}
return false;
}

/**
* This method interacts with the user to place a ship on the game board of the human player and
* the computer opponent. The process is as follows: 1 - Print the user primary board, using the
* printBoard. 2 - Using the promptChar method, prompt the user with "Vertical or horizontal?
* (v/h) ". A response of v is interpreted as vertical. Anything else is assumed to be
* horizontal. 3 - Using the promptInt method, prompt the user for an integer representing the
* "ship length", where the minimum ship length is Config.MIN_SHIP_LEN and the maximum ship
* length is width or height of the game board, depending on the input of the user from step 1.
* 4 - Using the promptStr method, prompt the user for the "x-coord". The maximum value should
* be calculated based on the width of the board and the length of the ship. You will need to
* use the coordAlphaToNum and coordNumToAlpha methods to convert between int and String values
* of coordinates. 5 - Using the promptInt method, prompt the user for the "y-coord". The
* maximum value should be calculated based on the width of the board and the length of the
* ship. 6 - Check if there is space on the board to place the ship. 6a - If so: - Place the
* ship on the board using placeShip. - Then, call placeRandomShip to place the opponents ships
* of the same length. - If placeRandomShip fails, print out the error message (terminated by a
* new line): "Unable to place opponent ship: id", where id is the ship id, and return false. 6b
* - If not: - Using promptChar, prompt the user with "No room for ship. Try again? (y/n): " -
* If the user enters a 'y', restart the process at Step 1. - Otherwise, return false.
*
* @param sc The Scanner instance to read from System.in.
* @param boardPrime The human player board.
* @param boardOpp The opponent board.
* @param id The ship id, assumed to be 1 to 9.
* @param rand The Random object.
* @return true if ship placed successfully by player and computer opponent, false otherwise.
*/

public static boolean addShip(Scanner sc, char boardPrime[][], char boardOpp[][], int id,
Random rand) {
printBoard(boardPrime, "My Ships");
char ch = promptChar(sc, "Vertical or horizontal? (v/h) ");
boolean dir = ch == 'v' ? true : false;
if (dir == true) {
int len = promptInt(sc, "ship length", Config.MIN_SHIP_LEN, boardPrime.length);
} else {
int len = promptInt(sc, "ship length", Config.MIN_SHIP_LEN, boardPrime[0].length);
}
String xcoordStr = promptStr(sc, "x-coord", coordNumToAlpha(0), coordNumToAlpha(boardPrime[0].length - len));
return false;
}

Here is the code for Config.java:

/**
* This class contains the constants used in the Battleship program. These constants may be changed
* when testing. So, your program should use the constants, not the values.
*
* @author Marc Renault
*/
public class Config {

/**
* Minimum and maximum values used in the program
*/
public static final int MIN_WIDTH = 1; //Minimum number of columns
public static final int MAX_WIDTH = 675; //Maximum number of columns
public static final int MIN_HEIGHT = 1; //Minimum number of rows
public static final int MAX_HEIGHT = 99; //Maximum number of rows
public static final int MAX_COL_WIDTH = 3; //Maximum number of characters per column
public static final int MIN_SHIPS = 1; //Minimum number of ships
public static final int MAX_SHIPS = 9; //Maximum number of ships
public static final int MIN_SHIP_LEN = 1; //Minimum ship length

/**
* Character values for displaying the different statuses of the game board cells.
*/
public static final char WATER_CHAR = '~'; // Water character (not yet targeted)
public static final char HIT_CHAR = '*'; // Hit character
public static final char MISS_CHAR = '@'; // Miss character

/**
* Constants for the random processes.
*/
public static final long SEED = 1234; // The random seed
public static final int RAND_SHIP_TRIES = 20; // Maximum number of tries to place a ship
  
}

Here is the code for TestBattleship.java:

/**
* This file contains testing methods for the Battleship project. These methods are intended to
* provide an example of a way to incrementally test your code, and to provide example method calls
* for the Battleship methods
*
* Toward these objectives, the expectation is that part of the grade for the Battleship project is
* to write some tests and write header comments summarizing the tests that have been written.
* Specific places are noted with FIXME but add any other comments you feel would be useful.
*/

import java.util.Random;
import java.util.Scanner;

/**
* This class contains a few methods for testing methods in the Battleship
* class as they are developed. These methods are all private as they are only
* intended for use within this class.
*
* @author Marc Renault
* @author FIXME add your name here when you add test
*
*/
public class TestBattleship {

/**
* This is the main method that runs the various tests. Uncomment the tests when
* you are ready for them to run.
*
* @param args (unused)
*/
public static void main(String[] args) {
// Milestone 1
testCoordAlphaToNum();
testCoordNumToAlpha();
// Milestone 2
testCheckWater();
testPlaceShip();
// Milestone 3
testTakeShot();
testCheckLost();
}
  
private static void testCoordAlphaToNum() {
int numTests = 4;
int passed = numTests;
int res;
if((res = Battleship.coordAlphaToNum("BAAA")) != 17576) {
System.out.println("FAILED: Battleship.coordAlphaToNum("BAAA") != 17576, but " + res);
passed--;
}
if((res = Battleship.coordAlphaToNum("ZERTY")) != 11506714) {
System.out.println("FAILED: Battleship.coordAlphaToNum("ZERTY") != 11506714, but " + res);
passed--;
}
if((res = Battleship.coordAlphaToNum("zerty")) != 11506714) {
System.out.println("FAILED: Battleship.coordAlphaToNum("zerty") != 11506714, but " + res);
passed--;
}
if((res = Battleship.coordAlphaToNum("&é"")) != -14747) {
System.out.println("FAILED: Battleship.coordAlphaToNum("&é\"") != -14747, but " + res);
passed--;
}
if((res = Battleship.coordAlphaToNum("baaa")) != 17576) {
System.out.println("FAILED: Battleship.coordAlphaToNum("baaa") != 17576, but " + res);
passed--;
}
if ((res = Battleship.coordAlphaToNum("YeEt")) != 425354) {
System.out.println("FAILED: Battleship.coordAlphaToNum("YeEt") != 425354, but " + res);
}
System.out.println("testCoordAlphatoNum: Passed " + passed + " of " + numTests + " tests.");
}

private static void testCoordNumToAlpha() {
//FIXME
}
  
private static void testCheckWater() {
//FIXME
}
  
private static void testPlaceShip() {
//FIXME
}
  

Explanation / Answer

Here is the code for Battleship.java:

import java.util.Scanner;
import java.util.Random;
public class Battleship {
/**
* This method converts a String representing a base (or radix) 26 number into a decimal (or
* base 10) number. The String representation of the base 26 number uses the letters of the
* Latin alphabet to represent the 26 digits. That is, A represents 0, B represents 1, C
* represents 2, ..., Y represents 24, and Z represents 25.
*
* A couple of examples: BAAA = 1 * 26^3 + 0 * 26^2 + 0 * 26^1 + 0 * 26^0 = 17576 ZERTY = 25 *
* 26^4 + 4 * 26^3 + 17 * 26^2 + 19 * 26^1 + 24 * 26^0 = 11506714
*
* For this method: - use Math.pow to calculate the powers of 26. - don't assume that the input
* is in any particular case; use toUpperCase(). - don't check that the input is only 'A' to
* 'Z'. - calculate the value of each digit relative to 'A'. - start from either the first or
* last character, and calculate the exponent based on the index of each character.
*
* @param coord The coordinate value in base 26 as described above.
* @return The numeric representation of the coordinate.
*/
public static int coordAlphaToNum(String coord) {
int result = 0;
for (int i = 0; i < coord.length(); ++i) {
int num = Character.toUpperCase(coord.charAt(i)) - 'A';
result = result + (num * (int) Math.pow(26, coord.length() - i - 1));
}
return result;
}
/**
* This method converts an int value into a base (or radix) 26 number, where the digits are
* represented by the 26 letters of the Latin alphabet. That is, A represents 0, B represents 1,
* C represents 2, ..., Y represents 24, and Z represents 25. A couple of examples: 17576 is
* BAAA, 11506714 is ZERTY.
*
* The algorithm to convert an int to a String representing these base 26 numbers is as follows:
* - Initialize res to the input integer - The next digit is determined by calculating the
* remainder of res with respect to 26 - Convert this next digit to a letter based on 'A' - Set
* res to the integer division of res and 26 - Repeat until res is 0
*
* @param coord The integer value to convert into an alpha coordinate.
* @return The alpha coordinate in base 26 as described above. If coord is negative, an empty
* string is returned.
*/
public static String coordNumToAlpha(int coord) {
String result = "";
while (coord > 0) {
int res = coord % 26;
res += 'A';
char nextDigit = (char) res;
result = nextDigit + result;
coord = coord / 26;
}
return result;
}
/**
* Prompts the user for an integer value, displaying the following: "Enter the valName (min to
* max): " Note: There should not be a new line terminating the prompt. valName should contain
* the contents of the String referenced by the parameter valName. min and max should be the
* values passed in the respective parameters.
*
* After prompting the user, the method will read an int from the console and consume an entire
* line of input. If the value read is between min and max (inclusive), that value is returned.
* Otherwise, "Invalid value." terminated by a new line is output and the user is prompted
* again.
*
* @param sc The Scanner instance to read from System.in.
* @param valName The name of the value for which the user is prompted.
* @param min The minimum acceptable int value (inclusive).
* @param min The maximum acceptable int value (inclusive).
* @return Returns the value read from the user.
*/
public static int promptInt(Scanner sc, String valName, int min, int max) {
System.out.print("Enter the " + valName + " (" + min + " to " + max + "): ");
int num = sc.nextInt();
  
if (min <= num && max >= num) {
return num;
} else {
System.out.println("Invalid value.");
return promptInt(sc, valName, min, max);
}
}
/**
* Prompts the user for an String value, displaying the following: "Enter the valName (min to
* max): " Note: There should not be a new line terminating the prompt. valName should contain
* the contents of the String referenced by the parameter valName. min and max should be the
* values passed in the respective parameters.
*
* After prompting the user, the method will read an entire line of input, trimming any trailing
* or leading whitespace. If the value read is (lexicographically ignoring case) between min and
* max (inclusive), that value is returned. Otherwise, "Invalid value." terminated by a new line
* is output and the user is prompted again.
*
* @param sc The Scanner instance to read from System.in.
* @param valName The name of the value for which the user is prompted.
* @param min The minimum acceptable String value (inclusive).
* @param min The maximum acceptable String value (inclusive).
* @return Returns the value read from the user.
*/
public static String promptStr(Scanner sc, String valName, String min, String max) {
System.out.print("Enter the " + valName + " (" + min + " to " + max + "): ");
String str = sc.nextLine();
str = str.trim();
  
String min_ = min.toUpperCase();
String max_ = max.toUpperCase();
str = str.toUpperCase();
if (min_.compareTo(str) <= 0 && str.compareTo(max_) <= 0) {
return str;
} else {
System.out.println("Invalid value.");
return promptStr(sc, valName, min, max);
}
}
/**
* Prompts the user for an char value. The prompt displayed is the contents of the String
* referenced by the prompt parameter. Note: There should not be a new line terminating the
* prompt.
*
* After prompting the user, the method will read an entire line of input and return the first
* non-whitespace character in lower case.
*
* @param sc The Scanner instance to read from System.in
* @param prompt The user prompt.
* @return Returns the first non-whitespace character (in lower case) read from the user. If
* there are no non-whitespace characters read, the null character is returned.
*/
public static char promptChar(Scanner sc, String prompt) {
System.out.println(prompt);
String in = sc.next();
in = in.trim();
in = in.toLowerCase();
return in.charAt(0);
}
/**
* Initialises a game board so that all the entries are Config.WATER_CHAR.
*
* @param board The game board to initialise.
*/
public static void initBoard(char board[][]) {
for (int i = 0; i < board.length; ++i) {
for (int j = 0; j < board[i].length; ++j) {
board[i][j] = Config.WATER_CHAR;
}
}
}
/**
* Prints the game boards as viewed by the user. This method is used to print the game boards as
* the user is placing their ships and during the game play.
*
* Some notes on the display: - Each column printed will have a width of Config.MAX_COL_WIDTH. -
* Each row is followed by an empty line. - The values in the headers and cells are to be right
* justified.
*
* @param board The board to print.
* @param caption The board caption.
*/
public static void printBoard(char board[][], String caption) {
System.out.println(caption);
for(int i = 0; i < board.length; ++i) {
for(int j = 0;j < board[i].length; ++j) {
System.out.print(board[i][j] + " ");
}
System.out.println();
}
}
  
/**
* Determines if a sequence of cells of length len in a game board is clear or not. This is used
* to determine if a ship will fit on a given game board. The x and y coordinates passed in as
* parameters represent the top-left cell of the ship when considering the grid.
*
* @param board The game board to search.
* @param xcoord The x-coordinate of the top-left cell of the ship.
* @param ycoord The y-coordinate of the top-left cell of the ship.
* @param len The length of the ship.
* @param dir true if the ship will be vertical, otherwise horizontal
* @return 1 if the cells to be occupied by the ship are all Config.WATER_CHAR, -1 if the cells
* to be occupied are not Config.WATER_CHAR, and -2 if the ship would go out-of-bounds
* of the board.
*/
public static int checkWater(char board[][], int xcoord, int ycoord, int len, boolean dir) {
int result = -2;
if (dir) {
for (int i = 0; i < board.length; ++i) {
int counter1 = 0;
int counter2 = 0;
boolean water = true;
for (int j = 0; j < board.length; ++j) {
if (board[j][i] == Config.WATER_CHAR) {
++counter1;
}
if (board[j][i] != Config.WATER_CHAR) {
++counter2;
}
}
if (counter1 == board.length && counter1 >= len) {
result = 1;
} else if (counter2 == board.length && counter2 >= len) {
result = -1;
}
}
} else {
for(int i = 0; i < board.length; ++i) {
int counter1 = 0;
int counter2 = 0;
boolean water = true;
for(int j = 0; j < board[i].length; ++j) {
if (board[i][j] == Config.WATER_CHAR) {
++counter1;
} if (board[i][j] != Config.WATER_CHAR) {
++counter2;
}
}
if (counter1 == board[i].length && counter1 >= len) {
result = 1;
} else if (counter2 == board[i].length && counter2 >= len) {
result = -1;
}
}
}
return result;
}
/**
* Checks the cells of the game board to determine if all the ships have been sunk.
*
* @param board The game board to check.
* @return true if all the ships have been sunk, false otherwise.
*/
public static boolean checkLost(char board[][]) {
// FIXME
for(int i = 0; i < board.length; i++)
   for(int j = 0; j < board[i].length; j++)
       if(board[i][j] >= 1 && board[i][j] <= 9)   //If that marks a valid ship id.
           return false;
return true;   //No ships found, and hence return true.          
}
/**
* Places a ship into a game board. The coordinate passed in the parameters xcoord and ycoord
* represent the top-left coordinate of the ship. The ship is represented on the game board by
* the Character representation of the ship id. (For this method, you can assume that the id
* parameter will only be values 1 through 9.)
*
* @param board The game board to search.
* @param xcoord The x-coordinate of the top-left cell of the ship.
* @param ycoord The y-coordinate of the top-left cell of the ship.
* @param len The length of the ship.
* @param dir true if the ship will be vertical, otherwise horizontal.
* @param id The ship id, assumed to be 1 to 9.
* @return false if the ship goes out-of-bounds of the board, true otherwise.
*/
public static boolean placeShip(char board[][], int xcoord, int ycoord, int len, boolean dir,
int id) {
if (dir == true) {
if (ycoord + len >= Config.MAX_HEIGHT) {
return false;
}
for (int i = ycoord; i < ycoord + len; ++i) {
board[i][xcoord] = (char) ('0' + id);
}
return true;
} else {
if (xcoord + len >= Config.MAX_WIDTH) {
return false;
}
for (int i = xcoord; i < xcoord + len; ++i) {
board[ycoord][i] = (char) ('0' + id);
}
return true;
}
}
/**
* Randomly attempts to place a ship into a game board. The random process is as follows: 1 -
* Pick a random boolean, using rand. True represents vertical, false horizontal. 2 - Pick a
* random integer, using rand, for the x-coordinate of the top-left cell of the ship. The number
* of integers to choose from should be calculated based on the width of the board and length of
* the ship such that the placement of the ship won't be out-of-bounds. 3 - Pick a random
* integer, using rand, for the y-coordinate of the top-left cell of the ship. The number of
* integers to choose from should be calculated based on the height of the board and length of
* the ship such that the placement of the ship won't be out-of-bounds. 4 - Verify that this
* random location can fit the ship without intersecting another ship (checkWater method). If
* so, place the ship with the placeShip method.
*
* It is possible for the configuration of a board to be such that a ship of a given length may
* not fit. So, the random process will be attempted at most Config.RAND_SHIP_TRIES times.
*
* @param board The game board to search.
* @param len The length of the ship.
* @param id The ship id, assumed to be 1 to 9..
* @param rand The Random object.
* @return true if the ship is placed successfully, false otherwise.
*/
public static boolean placeRandomShip(char board[][], int len, int id, Random rand) {
boolean dir = rand.nextBoolean();
for (int i = 0; i < Config.RAND_SHIP_TRIES; ++i) {
int xcoord = rand.nextInt(Config.MAX_WIDTH - len);
int ycoord = rand.nextInt(Config.MAX_HEIGHT - len);
if (checkWater(board, xcoord, ycoord, len, dir) == 1) {
boolean canPlace = placeShip(board, xcoord, ycoord, len, dir, id);
if (canPlace == true) {
return true;
}
}
}
return false;
}
/**
* This method interacts with the user to place a ship on the game board of the human player and
* the computer opponent. The process is as follows: 1 - Print the user primary board, using the
* printBoard. 2 - Using the promptChar method, prompt the user with "Vertical or horizontal?
* (v/h) ". A response of v is interpreted as vertical. Anything else is assumed to be
* horizontal. 3 - Using the promptInt method, prompt the user for an integer representing the
* "ship length", where the minimum ship length is Config.MIN_SHIP_LEN and the maximum ship
* length is width or height of the game board, depending on the input of the user from step 1.
* 4 - Using the promptStr method, prompt the user for the "x-coord". The maximum value should
* be calculated based on the width of the board and the length of the ship. You will need to
* use the coordAlphaToNum and coordNumToAlpha methods to convert between int and String values
* of coordinates. 5 - Using the promptInt method, prompt the user for the "y-coord". The
* maximum value should be calculated based on the width of the board and the length of the
* ship. 6 - Check if there is space on the board to place the ship. 6a - If so: - Place the
* ship on the board using placeShip. - Then, call placeRandomShip to place the opponents ships
* of the same length. - If placeRandomShip fails, print out the error message (terminated by a
* new line): "Unable to place opponent ship: id", where id is the ship id, and return false. 6b
* - If not: - Using promptChar, prompt the user with "No room for ship. Try again? (y/n): " -
* If the user enters a 'y', restart the process at Step 1. - Otherwise, return false.
*
* @param sc The Scanner instance to read from System.in.
* @param boardPrime The human player board.
* @param boardOpp The opponent board.
* @param id The ship id, assumed to be 1 to 9.
* @param rand The Random object.
* @return true if ship placed successfully by player and computer opponent, false otherwise.
*/
public static boolean addShip(Scanner sc, char boardPrime[][], char boardOpp[][], int id,
Random rand) {
printBoard(boardPrime, "My Ships");
char ch = promptChar(sc, "Vertical or horizontal? (v/h) ");
int len;
boolean dir = ch == 'v' ? true : false;
if (dir == true) {
len = promptInt(sc, "ship length", Config.MIN_SHIP_LEN, boardPrime.length);
} else {
len = promptInt(sc, "ship length", Config.MIN_SHIP_LEN, boardPrime[0].length);
}
String xcoordStr = promptStr(sc, "x-coord", coordNumToAlpha(0), coordNumToAlpha(boardPrime[0].length - len));
return false;
}
}

And the code for TestBattleship.java is:

/**
* This file contains testing methods for the Battleship project. These methods are intended to
* provide an example of a way to incrementally test your code, and to provide example method calls
* for the Battleship methods
*
* Toward these objectives, the expectation is that part of the grade for the Battleship project is
* to write some tests and write header comments summarizing the tests that have been written.
* Specific places are noted with FIXME but add any other comments you feel would be useful.
*/
import java.util.Random;
import java.util.Scanner;
/**
* This class contains a few methods for testing methods in the Battleship
* class as they are developed. These methods are all private as they are only
* intended for use within this class.
*
* @author Marc Renault
* @author FIXME add your name here when you add test
*
*/
public class TestBattleship {
/**
* This is the main method that runs the various tests. Uncomment the tests when
* you are ready for them to run.
*
* @param args (unused)
*/
public static void main(String[] args) {
// Milestone 1
testCoordAlphaToNum();
testCoordNumToAlpha();
// Milestone 2
testCheckWater();
testPlaceShip();
// Milestone 3
//testTakeShot();
//testCheckLost();
}
  
private static void testCoordAlphaToNum() {
int numTests = 4;
int passed = numTests;
int res;
if((res = Battleship.coordAlphaToNum("BAAA")) != 17576) {
System.out.println("FAILED: Battleship.coordAlphaToNum("BAAA") != 17576, but " + res);
passed--;
}
if((res = Battleship.coordAlphaToNum("ZERTY")) != 11506714) {
System.out.println("FAILED: Battleship.coordAlphaToNum("ZERTY") != 11506714, but " + res);
passed--;
}
if((res = Battleship.coordAlphaToNum("zerty")) != 11506714) {
System.out.println("FAILED: Battleship.coordAlphaToNum("zerty") != 11506714, but " + res);
passed--;
}
if((res = Battleship.coordAlphaToNum("&é"")) != -14747) {
System.out.println("FAILED: Battleship.coordAlphaToNum("&é\"") != -14747, but " + res);
passed--;
}
if((res = Battleship.coordAlphaToNum("baaa")) != 17576) {
System.out.println("FAILED: Battleship.coordAlphaToNum("baaa") != 17576, but " + res);
passed--;
}
if ((res = Battleship.coordAlphaToNum("YeEt")) != 425354) {
System.out.println("FAILED: Battleship.coordAlphaToNum("YeEt") != 425354, but " + res);
}
System.out.println("testCoordAlphatoNum: Passed " + passed + " of " + numTests + " tests.");
}
private static void testCoordNumToAlpha() {
//FIXME
int numTests = 2;
int passed = numTests;
String res;
if(!(res = Battleship.coordNumToAlpha(17576)).equals("BAAA")) {
   System.out.println("FAILED: Battleship.coordNumToAlpha(17576) != "BAAA", but " + res);
   passed--;
}
if(!(res = Battleship.coordNumToAlpha(11506714)).equals("ZERTY")) {
   System.out.println("FAILED: Battleship.coordNumToAlpha(11506714) != "ZERTY", but " + res);
   passed--;
}
System.out.println("testCoordNumToAlpha: Passed " + passed + " of " + numTests + " tests.");
}
  
private static void testCheckWater() {
//FIXME
int numTests = 2;
int passed = numTests;
int res;
char[][] board = {{'~'}};
int xcoord = 1;
int ycoord = 1;
int len = 3;
boolean dir = true;
if((res = Battleship.checkWater(board, xcoord, ycoord, len, dir)) != -2) {
   System.out.println("FAILED: Battleship.checkWater() != -2, but " + res);
   passed--;
}
dir = false;
if((res = Battleship.checkWater(board, xcoord, ycoord, len, dir)) != -2) {
   System.out.println("FAILED: Battleship.checkWater() != -2, but " + res);
   passed--;
}
System.out.println("testCheckWater: Passed " + passed + " of " + numTests + " tests.");
}
  
private static void testPlaceShip() {
//FIXME
int numTests = 2;
int passed = numTests;
boolean res;
char[][] board1 = {{'~'}};
int xcoord = 1;
int ycoord = 1;
int len = 3;
boolean dir = true;
int id = 1;
if((res = Battleship.placeShip(board1, xcoord, ycoord, len, dir, id)) != false) {
   System.out.println("FAILED: Battleship.placeShip() != false, but " + res);
   passed--;
}
char[][] board2 = {{'~', '~', '~', '~'}, {'~', '~', '~', '~'}, {'~', '~', '~', '~'}, {'~', '~', '~', '~'}};
if((res = Battleship.placeShip(board2, xcoord, ycoord, len, dir, id)) != true) {
   System.out.println("FAILED: Battleship.placeShip() != false, but " + res);
   passed--;
}
System.out.println("testPlaceShip: Passed " + passed + " of " + numTests + " tests.");
}
}
  

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote