Introduction
You have worked with arrays in previous labs. Arrays can hold a variety of things, from primitives to objects.
Today, we will be working with two-dimensional arrays. These are essentially arrays of arrays, where each element in the outer array is actually another array.
Their declaration looks like this:
variableType [][] arrayName = new variableType[numberOfArrays][numberOfElementsInEachArray];
We can actually create multidimensional arrays beyond just two dimensions, by adding arrays as the inner elements repeatedly.
Let’s see an example of a two-dimensional array that stores ints.
int [][] arr = new int[4][4];
I could also initialize the above array with values instead of just initializing the size, like this:
int [][] arr = {{1,2,3,4}, {5,6,7,8}, {9,10,11,12}, {13,14,15,16}};
We’ve seen how to iterate through a single dimensional array using a for loop, like so:
int [] arr = {1,2,3,4,5}
for(int i = 0; i < arr.length; i++){
System.out.println(arr[i] + " ");
}
The above code would output: 1 2 3 4 5.
To iterate through a two dimensional array, you must use nested for loops, like so:
for(int i = 0; i < arr.length; i++){
for(int j = 0; j < arr[i].length; j++){
System.out.println(arr[i][j] + " ");
}
System.out.println();
}
The above code would output: **1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
Note a few things in the above code:
- To iterate through the outer array, we use the usual for loop indices and iterate until arr.length.
- To iterate through the inner array, we iterate through until arr[i].length which gives us the length of a specific element array.
- A newline print statement is included in the outer for loop.
Two dimensional arrays are very helpful to think about in terms of a table, but in can be tricky remembering which indices correspond to the “rows” and “columns”.
int[row][column]
Introduction to Lab: BattleShip
In today’s lab, we will be working with two classes, Player and Game that will resemble a game of Battleship between two classes.
However, this implementation simplifies the game down significantly, for our purposes in practicing with two dimensional arrays.
So let’s talk about what our version of Battleship will look like:
There are two classes:
- Player: an object that represents one of two players in the Game class
- has three class variables, map and guess which are two dimensional arrays of ints, and an int, score
- has a constructor, which initializes map, guess, and score, and calls the readPlayerSheet() method
- a method called readPlayerSheet that takes a String filename as a parameter and initializes the object’s variables with the relevant information
- Game: an object that represents a single game of Battleship between two players
- has two class variables, static Player objects player1 and player2
- has a constructor that initializes the two players with the appropriate filenames
- has four methods: gameResults, compareMapToGuess, mapToString, and tallyScores
A new game can be created based on two files created by each player. The files look like this:
0 0 0 0 0 0 1 1 1 1
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 1 0 0 1 0 0 0 0 0
0 1 0 0 1 0 0 0 0 0
0 1 0 0 1 0 0 0 0 0
0 1 0 0 1 0 0 0 0 1
0 0 0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0 0 1
0 0 0 1 1 1 1 0 0 1
1-2 9-5 4-5 3-6 5-9
The player can create their own 10 by 10 board containing five ships with a length of four each. Ships are represented by 1’s, and empty spots are represented by 0’s. The player also includes guesses for the coordinates of their opponent’s ship. These are in pairs with the format row-column, and they are allowed five guesses.
If the player correctly guesses a point on their opponent’s ship, they score a point. Whoever has the most points wins!
Main is the class provided for you to test your code. We have also provided text files map1 and map2 to download. Test your code with Main before submitting your lab to check for any compilation errors, and to ensure your methods for both Game and Player are working as expected.
Step 1: Player Variable Declaration and Initialization
Part A:
In the Player class, declare two class variables, map and guess that are two dimensional arrays of ints.
Part B:
In the constructor of the Player class, initialize the map and guess arrays with the appropriate size:
- map: 10 by 10 (10 outer arrays with 10 elements each)
- guess: 5 by 2 (5 outer arrays with 2 elements each)
Step 2: Player.readPlayerSheet() Part A
The readPlayerSheet method in the Player class is parsing through the player’s file sheet to initialize the map and guess arrays for that object.
In the readPlayerSheet method of the Player class, use two nested for loops to iterate through the size of the map array. Each element of the map array should be assigned the value of the next int from the scanner.
Step 3: Player.readPlayerSheet() Part B
After your code from Step 2, and after the scnr.nextLine(), read the next line from the player’s file.
Then, parse through that line to initialize the appropriate values in the guess array. The guess array is a two-dimensional array that contains 5 sub-arrays and 2 elements per sub-array.
The format of the string that represents a guess in the player’s file is characterized by:
- each guess represented by a number, then a dash, then a number, like 1-2
- each guess separated from the next by a space, excluding the first and last guesses
Think about how you can manipulate the String returned from scnr.nextLine(), and extract each pair of numbers in the format “1-2” as a single guess. Each pair of numbers will initialize one of the five sub-arrays of the guess array, and the two numbers within the guess initialize each element within the subarray.
Review the file format shown above to understand what line you’re working with, and think back to previous labs and methods like parseInt, substring, and indexOf to parse the guesses.
For example, if we were to include a line of guesses in a player file like this:
1-2 9-5 4-5 3-6 5-9
Our array would look like this after parsing through the values in the readPlayerSheet method: [[1,2],[9,5],[4,5],[3,6],[5,9]]
Step 4: Game.mapToString()
Complete the method mapToString() in the Game class. This method takes a two dimensional array of ints as a parameter, and returns that result as a string.
Each element in an inner array should be separated by a space, and each inner array should be separated by a new line. The last inner array should also be followed by a new line.
You will be using a StringBuilder to concatenate the array elements into a single string and return it at the end.
Step 5: Game.compareMapToGuess()
Write a method called compareMapToGuess in the Game class that has the following characteristics:
- takes two parameters, both two dimensional int arrays, with one that represents a map and one that represents a guess
- returns an int
- returns the number of guesses that successfully “hit” the opponent’s ship (the coordinates of the guess match a 1 in the same location on the map)
Hint: Consider iterating through the guesses, and extracting the row and column from the array to see if they are a “hit” in the map.