Multidimensional arrays Section 8.7 Multidimensional arrays Two-dimensional array A structure for storing multiple values of the same type organized by rows and columns: int exam_scores[100][4]; This might be a collection of exam scores for a class of 100 students who took 4 exams. Scores for 4th student would be stored as: exam_scores[3][0], exam_scores[3][1], exam_scores[3][2], exam_scores[3][3] For a tic-tac-toe game, there is a board of 9 squares (3 rows and 3 columns) and each square contains a character:’X’, ‘O’, or ‘ ‘ (blank). char tic_tac_toe[3][3]; Or use the following to declare and initialize the array to all blanks: char tic_tac_toe[3][3] = { {‘ ‘, ‘ ‘, ‘ ‘}, {‘ ‘, ‘ ‘, ‘ ‘}, {‘ ‘, ‘ ‘,‘ ‘}}; or char tic_tac_toe[3][3] = { {‘X‘, ‘ ‘, ‘X‘}, {‘O‘, ‘O‘, ‘ ‘}, {‘X‘, ‘ ‘,‘O‘}}; X | |X O |O| X | |O Last element is tic_tac_toe[2][2] and its contents is ‘O’. How is tic_tac_toe actually stored in memory – memory is not “rectangular”, but is linear. Address contents 1000 tic_tac_toe[0][0] 1001 tic_tac_toe[0][1] first row 1002 tic_tac_toe[0][2] 1003 tic_tac_toe[1][0] 1004 tic_tac_toe[1][1] … 1008 tic_tac_toe[2][2] last element in last row Function diagonal-win . Returns 1 (true) if there is a winner in a diagonal for a specified player and 0 (false) if there is no diagonal winner. int diagonal_winner (char tic_tac_toe[][3], char player) { /* Return true if all 3 diagonal squares contain player */ if ((tic_tac_toe[0][0] == player) && (tic_tac_toe[1][1] == player) && (tic_tac_toe[2][2] == player)) || … return 1; else return 0; } int diagonal_winner (char tic_tac_toe[][3], char player) { /* Return true if all 3 diagonal squares contain player */ return ((tic_tac_toe[0][0] == player) && (tic_tac_toe[1][1] == player) && (tic_tac_toe[2][2] == player) || … } Let’s look at what is stored in tic_tac_toe in function data area: tic_tac_toe 1000 (address of tic_tac_toe[0][0]) From the formal argument declaration char tic_tac_toe[0][3], C compiler “knows” that there are 3 elements in each row, so when it has to access tic_tac_toe[1][1], it accesses the fifth element in the array that starts at address 1000 (3 elements in row 0, tic_tac_toe[1][0] and then tic_tac_toe[1][1] in 2nd row). Function get_move – to read and store the move of a human opponent (player): void get_move (tic_tac_toe[][3], char player) { int row, col; do { printf(“Enter row & then column of next move:”); row = get_integer(1, 3); col = get_integer(1, 3); row--; col--; /* check for empty square. */ if (tic_tac_toe[row][col] != ‘ ‘) printf(“Square if filled – try again”); } while (tic_tac_toe[row][col] != ‘ ‘); /* Human chose an empty square – fill it. */ tic_tac_toe[row][col] = player; } Write a move function for the computer. Computer moves to first empty square it finds. Begins looking in row 0, then row 1, then row 2. Store machine character in first empty square you find and then execute return statement (without a value). void make_move(tic_tac_toe[][3], char machine) { for ( ) for ( ) if ( ) { tictactoe[ ][ ] = machine; printf(“Machine moves to square in row %d”, row, “, column %d\n”, col); return; } } Think about what the main function might look like for a tic-tac-toe game player – computer plays ‘X’ and human plays ‘O’. #define human ‘O’ #define computer ‘X’ Read in next player (‘X’ or ‘O’) do { if next player is human { read human’s move next player is machine } else { compute machine’s move next player is human } display(tic_tac_toe); } while game is not over if winner is player ‘X’ display message that computer wins else if winner is player ‘O’ display message that human wins else display that game is a draw Back to the exam score array. int score[100][3]; Write a function that returns the average score on all 3 exams for a particular student indicated by the function argument stu_index. Write a function that returns the average score for all students (argument num_students indicates how many students there are) on a particular exam (argument exam_index).