# Multidimensional Arrays

Multidimensional arrays are nothing more than arrays that contain other arrays.

Nice, succinct explanation of multidimensional arrays:

## Concept

Think of them as a matrix/grid of n-dimensions

```int[][] matrix; //declaration follows pattern, elementType[][] arrayRefVar;
```

## Creating a multidimensional array

### Declare, allocate, and assign values separately

```int[][] matrix; //declare

matrix = new int[3][3]; //allocate

//then assign values as separate statements
matrix[0][0] = 1;
matrix[0][1] = 2;
matrix[0][2] = 3;
matrix[1][0] = 4;
matrix[1][1] = 5;
matrix[1][2] = 6;
matrix[2][0] = 7;
matrix[2][1] = 8;
matrix[2][2] = 9;
```

### Declare and initialize in one statement

Both declare and allocation in one statement:

```int[][] matrix = new int[3][3]; //declare and allocate

//assign values
matrix[0][0] = 1;
matrix[0][1] = 2;
matrix[0][2] = 3;
matrix[1][0] = 4;
matrix[1][1] = 5;
matrix[1][2] = 6;
matrix[2][0] = 7;
matrix[2][1] = 8;
matrix[2][2] = 9;
```

### Declaration, initialization, and assignment in one statement

All steps in one statement

```//declare, allocate, and assign values all at once in shorthand notation
//note that allocation is implicit and not directly written in code
int[][] matrix = {
{1,2,3},
{4,5,6},
{7,8,9}
}
```

## Ragged arrays

Ragged arrays are simply multi-dim arrays with uneven length sub-arrays.

```int[][] triangleArray = new int[3][]; //if sub-array lengths are all different, leave them blank here
//int[][] triangleArray = new int[][]; //is an error!  you must supply the first dimension's length when allocating

//allocate different lengthed sub-arrays
triangleArray[0] = new int[3];
triangleArray[1] = new int[2];
triangleArray[0] = new int[1];
```

## Passing multidimensional arrays as function arguments

```//define function to accept multidimensional array as parameter
public static int doSomething(int[][] bar) { ...etc... }

//create multi-dimensional array
int[][] foo = new int[5][2];
...etc...

//call function and pass it the multidimensional array
doSomething(foo); //function call with arg
```

## Example programs

### Two-dimensional array

```/**
* Example of using a two-dimensional array to manipulate two-dimensional grid-like tabular data
* @author Foo Barstein
* @version 0.2
*
*/

public class MultiDimensionalArrayExample {

public static void main(String[] args) {

//INITIALIZE MULTI-DIMENSIONAL ARRAY
String[][] grades = new String[44][3]; //imagine a grade chart for 44 students taking 3 exams

//WRITE VALUES TO EVERY ELEMENT IN MULTI-DIMENSIONAL ARRAY
for (int i=0; i<grades.length; i++) { //loop through each row
for (int j=0; j<grades[i].length; j++) { //loop through all columns within the current row
grades[i][j] = "F"; //enter F for each element
}
}

//read each element of our multi-dim array and make it look nicely formatted
System.out.printf("%5s%10s%10s%10s", "", "Exam 1", "Exam 2", "Exam 3"); //print out column headings
System.out.println(); //print a line break
for (int i=0; i<grades.length; i++) { //loop through each row
System.out.printf("%5s", i); //print the row number
for (int j=0; j<grades[i].length; j++) { //loop through each column
}
System.out.println(); //print a line break
}
}

}
```

### Ragged multidimensional array

```/**
* Example of creating a ragged array: a multidimensional array with rows of varying lengths
* @author Foo Barstein
* @version 0.6
*
*/

public class RaggedArrayExample {

public static void main(String[] args) {

//create ragged array the easy way... using shorthand notation to allocate and assign all sub-arrays at once...
int[][] foo = {
{0,1,2,3},
{4,5,6,7},
{8,9}
};

// create a ragged array the hard way... allocate and assign each sub-array separately
int[][] bar = new int[3][];
bar[0] = new int[4];
bar[0][0] = 0;
bar[0][1] = 1;
bar[0][2] = 2;
bar[0][3] = 3;
bar[1] = new int[4];
bar[1][0] = 4;
bar[1][1] = 5;
bar[1][2] = 6;
bar[1][3] = 7;
bar[2] = new int[2];
bar[2][0] = 8;
bar[2][1] = 9;
*/

//loop through each sub-array the hard way and output every element
for (int i=0; i<foo.length; i++) {
for (int j=0; j<foo[i].length; j++) {
int val = foo[i][j];
System.out.println(val);
}
}

//loop through each sub-array the easy way and output every element
for (int[] subArray : bar) {
for (int val : subArray) {
System.out.println(val);
}
}

}

}
```

### Tic-tac-toe game

We use a two-dimensional array to hold the game board. Note that most of the code revolves around the game mechanics: taking turns, checking whether a move is allowed, etc. The multidimensional array simply serves as a useful data structure with which to model tabular data, like the game board.

Note also how we loop through the elements in the two-dimensional array when we show the board.

```package edu.nyu.cs.fb1258;

import java.util.Scanner;

public class TicTacToe {

//define constants representing each possible data value we will use in our tic tac toe board
final static int X = 1;
final static int O = 2;
final static int BLANK = 3;
static int currentPlayer = X;

//make a globalish variable that holds the board
static int[][] board = {
{BLANK, BLANK, BLANK},
{BLANK, BLANK, BLANK},
{BLANK, BLANK, BLANK}
};

public static void printBoard() {

//loop through each row, one at a time
for (int[] row : board) {

//print out all the columns within this row
for (int col : row) {

//generate a nice looking character that represents each spot on the board
String spot;
switch(col) {
case X:
spot = "X";
break;
case O:
spot = "O";
break;
default:
spot = "-";
};

//print out the column data with a space after it
System.out.print(spot + " ");
}

//print a line break
System.out.println("");

}
}

public static int[] getIntArray(String[] coords) {
//convert these coords, which are currently stored as Strings, into ints
int[] coordsAsInts = new int[2];

//loop through the string array of coords
for (int i=0; i<coords.length; i++) {
//copy each value into the int array of coords, as ints of course
//remember that the arrays in the board start counting from zero, while the person started counting from 1!
coordsAsInts[i] = Integer.parseInt(coords[i]) - 1;
}

return coordsAsInts;
}

public static boolean isFreeSpot(int y, int x) {
return board[y][x] == BLANK;
}

public static void makeMove(int y, int x) {
board[y][x] = currentPlayer;
}

public static void changePlayers() {
currentPlayer = (currentPlayer == X) ? O : X;
}

public static void main(String[] args) {

//declare,allocate array, and populate it with blanks

Scanner in = new Scanner(System.in);

//keep track of whether the game is over or not with a flag
boolean gameOver = false;

//loop as long as the game is on
while (!gameOver) {

//print out the board
printBoard();

//determine whose turn it is and output a nice  message appropriately
String playerName = (currentPlayer == X) ? "X" :  "O";
System.out.println("Player " + playerName + ",  please go!");

//get the user's move... assuming they entered it correctly]
//assuming the user types the move as "<row>,<col>"
String response = in.nextLine();

//split the response along the comma
String[] coords = response.split(",");

//get an int array version of this string array
int[] coordsAsInt = getIntArray(coords);

int yCoord = coordsAsInt[0];
int xCoord = coordsAsInt[1];

//check whether this move is permissible
if (isFreeSpot(yCoord, xCoord)) {

//make the move
makeMove(yCoord, xCoord);

//change players
changePlayers();

}
else {
System.out.println("That move is not allowed!");
}

}

}

}
```