/******************************* FILE HEADER ********************************** Program: Tic Tac Toe, version 1 File: Board.java (replaces original version) Main File: TicTacToe1.java Author: James D. Skrentny copyright 2000, all rights reserved Course: CS 302, Fall 2000, Lectures 1 & 2 Compiler: CodeWarrior IDE 4.0 (JDK 1.2) Platform: Windows NT 4.0 **************************** 80 columns wide *********************************/ /** * The Board class represents the N by N grid on which players make * their marks in the game Tic Tac Toe. * * Bugs: none known **/ /* The following concepts are illustrated: * - use of a 2D array * - use of char type * - changing the internal structure of a class without affecting * the classes that use it * - changing private data members * - changing public method implementations * - elimination of private method (move2cell remove) * - addition of new method (see second constructor) */ public class Board { private char[][] board; // board change to a 2D array of chars private final char EMPTY = ' '; // space char for empty cells /** * Constructs a default 3 by 3 grid with empty cells for the playing board. **/ public Board () { board = new char[3][3]; for (int row = 0; row < 3; row++) for (int col = 0; col < 3; col++) board[row][col] = EMPTY; } /** * Constructs a N by N grid with empty cells for the playing board. **/ public Board (int n) { board = new char[n][n]; for (int row = 0; row < n; row++) for (int col = 0; col < n; col++) board[row][col] = EMPTY; } /** * Puts a player's mark in the cell corresponding to the specified move. * * @param move the specified move (i.e. row and column coordinates) * @param mark the player's mark to be made on the board, typically "X" or "O" **/ public void markMove(Move move, Mark mark) { board[move.getRow() - 1][move.getCol() - 1] = mark.toString().charAt(0); } /** * Displays the board in the console window. * Assumption: a player's mark is a single character and the board size * is no larger than 9 by 9. **/ public void display () { // display the column heading System.out.println(); System.out.print(" col "); for (int col = 0; col < board.length; col++) { System.out.print(col + 1); if (col < board.length - 1) System.out.print(":"); } System.out.println(); System.out.println(); // display the board for (int row = 0; row < board.length; row++) { System.out.print("row " + (row + 1) + ": "); for (int col = 0; col < board.length; col++) { System.out.print(board[row][col]); if (col < board.length - 1) System.out.print("|"); } if (row < board.length - 1) System.out.println("\n -----"); else System.out.println(); } System.out.println(); } /** * Checks if the cell is empty at the location of a specified move. * * @param move the specified move (i.e. row and column coordinates) * @return returns true if the cell is empty at the location specified by move, * otherwise false is returned **/ public boolean cellFree (Move move) { return board[move.getRow() - 1][move.getCol() - 1] == EMPTY; } /** * Checks if all marks in the specified row are the same as the specified mark. * * @param row the row specified to be checked, 1 <= row <= board size * @param mark the mark specified to be matched * @return true if all cells in the specified row have the specified mark, * otherwise false is returned **/ public boolean checkRow (int row, Mark mark) { // defensive: check if invalid row if (row < 1 || row > board.length) return false; // check for "N in a row" for (int col = 0; col < board.length; col++) if (board[row - 1][col] != mark.toString().charAt(0)) return false; // a cell didn't match // must be "N in a row" return true; } /** * Checks if all marks in the specified col are the same as the specified mark. * * @param col the column specified to be checked, 1 <= col <= board size * @param mark the mark specified to be matched * @return true if all cells in the specified column have the specified mark, * otherwise false is returned **/ public boolean checkCol (int col, Mark mark) { // defensive: check if invalid col if (col < 1 || col > board.length) return false; // check for "N in a col" for (int row = 0; row < board.length; row++) if (board[row][col - 1] != mark.toString().charAt(0)) return false; // a cell didn't match // must be "N in a col" return true; } /** * Checks if all marks in the specified diagonal are the same as the specified mark. * * @param diag the diagonal specified to be checked, must be 1 or 2 * 1 is the diagonal from upper-left to lower-right * 2 is the diagonal from upper-right to lower-left * @param mark the mark specified to be matched * @return true if all cells in the specified diagonal have the specified mark, * otherwise false is returned **/ public boolean checkDiag (int diag, Mark mark) { // defensive: check if invalid diag if (diag != 1 && diag != 2) return false; if (diag == 1) { // braces required to avoid dangling else // check for "N in a diag 1" for (int diag1 = 0; diag1 < board.length; diag1++) if (board[diag1][diag1] != mark.toString().charAt(0)) return false; // a cell didn't match } else // check for "N in a diag 2" for (int diag2 = 0; diag2 < board.length; diag2++) if (board[diag2][board.length - diag2 - 1] != mark.toString().charAt(0)) return false; // a cell didn't match // must be "N in a diag" return true; } }