import java.io.*; /** * This is the Gameboard class. It implements a two dimension array that * represents a connect four gameboard. It keeps track of the player making * the next play based on the number of pieces on the game board. It provides * all of the methods needed to implement the playing of a max connect four * game. * * @author James Spargo * */ public class GameBoard { // class fields private int[][] playBoard; private int pieceCount; private int currentTurn; /** * This constructor creates a GameBoard object based on the input file * given as an argument. It reads data from the input file and provides * lines that, when uncommented, will display exactly what has been read * in from the input file. You can find these lines by looking for * * @param inputFile the path of the input file for the game */ public GameBoard( String inputFile ) { this.playBoard = new int[6][7]; this.pieceCount = 0; int counter = 0; BufferedReader input = null; String gameData = null; // open the input file try { input = new BufferedReader( new FileReader( inputFile ) ); } catch( IOException e ) { System.out.println("\nProblem opening the input file!\nTry again." + "\n"); e.printStackTrace(); } //read the game data from the input file for(int i = 0; i < 6; i++) { try { gameData = input.readLine(); // testing // uncomment the next 2 lines to see the whole line read in //System.out.println("I just read ->" + gameData + "<- " + // "outer for loop"); // read each piece from the input file for( int j = 0; j < 7; j++ ) { //testing- uncomment the next 3 lines to see each piece // that was read in //System.out.println("I just read ->" + // ( gameData.charAt( counter ) - 48 ) + // "<- inner for loop"); this.playBoard[ i ][ j ] = gameData.charAt( counter++ ) - 48; // sanity check if( !( ( this.playBoard[ i ][ j ] == 0 ) || ( this.playBoard[ i ][ j ] == 1 ) || ( this.playBoard[ i ][ j ] == 2 ) ) ) { System.out.println("\nProblems!\n--The piece read " + "from the input file was not a 1, a 2 or a 0" ); this.exit_function( 0 ); } if( this.playBoard[ i ][ j ] > 0 ) { this.pieceCount++; } } } catch( Exception e ) { System.out.println("\nProblem reading the input file!\n" + "Try again.\n"); e.printStackTrace(); this.exit_function( 0 ); } //reset the counter counter = 0; } // end for loop // read one more line to get the next players turn try { gameData = input.readLine(); } catch( Exception e ) { System.out.println("\nProblem reading the next turn!\n" + "--Try again.\n"); e.printStackTrace(); } this.currentTurn = gameData.charAt( 0 ) - 48; //testing-uncomment the next 2 lines to see which current turn was read //System.out.println("the current turn i read was->" + // this.currentTurn ); // make sure the turn corresponds to the number of pcs played already if(!( ( this.currentTurn == 1) || ( this.currentTurn == 2 ) ) ) { System.out.println("Problems!\n the current turn read is not a " + "1 or a 2!"); this.exit_function( 0 ); } else if ( this.getCurrentTurn() != this.currentTurn ) { System.out.println("Problems!\n the current turn read does not " + "correspond to the number of pieces played!"); this.exit_function( 0 ); } } // end GameBoard( String ) /** * This constructor creates a GameBoard object from another double * indexed array. * * @param masterGame a dual indexed array */ public GameBoard( int masterGame[][] ) { this.playBoard = new int[6][7]; this.pieceCount = 0; for( int i = 0; i < 6; i++ ) { for( int j = 0; j < 7; j++) { this.playBoard[ i ][ j ] = masterGame[ i ][ j ]; if( this.playBoard[i][j] > 0 ) { this.pieceCount++; } } } } // end GameBoard( int[][] ) /** * this method returns the score for the player given as an argument. * it checks horizontally, vertically, and each direction diagonally. * currently, it uses for loops, but i'm sure that it can be made * more efficient. * * @param player the player whose score is being requested. valid * values are 1 or 2 * @return the integer of the players score */ public int getScore( int player ) { //reset the scores int playerScore = 0; //check horizontally for( int i = 0; i < 6; i++ ) { for( int j = 0; j < 4; j++ ) { if( ( this.playBoard[ i ][j] == player ) && ( this.playBoard[ i ][ j+1 ] == player ) && ( this.playBoard[ i ][ j+2 ] == player ) && ( this.playBoard[ i ][ j+3 ] == player ) ) { playerScore++; } } } // end horizontal //check vertically for( int i = 0; i < 3; i++ ) { for( int j = 0; j < 7; j++ ) { if( ( this.playBoard[ i ][ j ] == player ) && ( this.playBoard[ i+1 ][ j ] == player ) && ( this.playBoard[ i+2 ][ j ] == player ) && ( this.playBoard[ i+3 ][ j ] == player ) ) { playerScore++; } } } // end verticle //check diagonally - backs lash -> \ for( int i = 0; i < 3; i++ ){ for( int j = 0; j < 4; j++ ) { if( ( this.playBoard[ i ][ j ] == player ) && ( this.playBoard[ i+1 ][ j+1 ] == player ) && ( this.playBoard[ i+2 ][ j+2 ] == player ) && ( this.playBoard[ i+3 ][ j+3 ] == player ) ) { playerScore++; } } } //check diagonally - forward slash -> / for( int i = 0; i < 3; i++ ){ for( int j = 0; j < 4; j++ ) { if( ( this.playBoard[ i+3 ][ j ] == player ) && ( this.playBoard[ i+2 ][ j+1 ] == player ) && ( this.playBoard[ i+1 ][ j+2 ] == player ) && ( this.playBoard[ i ][ j+3 ] == player ) ) { playerScore++; } } }// end player score check return playerScore; } // end getScore /** * the method gets the current turn * @return an int value representing whose turn it is. either a 1 or a 2 */ public int getCurrentTurn() { return ( this.pieceCount % 2 ) + 1 ; } // end getCurrentTurn /** * this method returns the number of pieces that have been played on the * board * * @return an int representing the number of pieces that have been played * on board alread */ public int getPieceCount() { return this.pieceCount; } /** * this method returns the whole gameboard as a dual indexed array * @return a dual indexed array representing the gameboard */ public int[][] getGameBoard() { return this.playBoard; } /** * a method that determines if a play is valid or not. It checks to see if * the column is within bounds. If the column is within bounds, and the * column is not full, then the play is valid. * @param column an int representing the column to be played in. * @return true if the play is valid
* false if it is either out of bounds or the column is full */ public boolean isValidPlay( int column ) { if ( !( column >= 0 && column <= 7 ) ) { // check the column bounds return false; } else if( this.playBoard[0][ column ] > 0 ) { // check if column is full return false; } else { // column is NOT full and the column is within bounds return true; } } /** * This method plays a piece on the game board. * @param column the column where the piece is to be played. * @return true if the piece was successfully played
* false otherwise */ public boolean playPiece( int column ) { // check if the column choice is a valid play if( !this.isValidPlay( column ) ) { return false; } else { //starting at the bottom of the board, //place the piece into the first empty spot for( int i = 5; i >= 0; i-- ) { if( this.playBoard[i][column] == 0 ) { if( this.pieceCount % 2 == 0 ){ this.playBoard[i][column] = 1; this.pieceCount++; } else { this.playBoard[i][column] = 2; this.pieceCount++; } //testing //warning: uncommenting the next 3 lines will //potentially produce LOTS of output //System.out.println("i just played piece in column ->" + // column + "<-"); //this.printGameBoard(); //end testing return true; } } //the pgm shouldn't get here System.out.println("Something went wrong with playPiece()"); return false; } } //end playPiece /*************************** solution methods **************************/ /** * this method removes the top piece from the game board * @param column the column to remove a piece from */ public void removePiece( int column ) { // starting looking at the top of the game board, // and remove the top piece for( int i = 0; i < 6; i++ ) { if( this.playBoard[ i ][ column ] > 0 ) { this.playBoard[ i ][ column ] = 0; this.pieceCount--; break; } } //testing //WARNING: uncommenting the next 3 lines will potentially //produce LOTS of output //System.out.println("gameBoard.removePiece(). I am removing the " + // "piece in column ->" + column + "<-"); //this.printGameBoard(); //end testing } // end remove piece /************************ end solution methods **************************/ /** * this method prints the GameBoard to the screen in a nice, pretty, * readable format */ public void printGameBoard() { System.out.println(" -----------------"); for( int i = 0; i < 6; i++ ) { System.out.print(" | "); for( int j = 0; j < 7; j++ ) { System.out.print( this.playBoard[i][j] + " " ); } System.out.println("| "); } System.out.println(" -----------------"); } // end printGameBoard /** * this method prints the GameBoard to an output file to be used for * inspection or by another running of the application * @param outputFile the path and file name of the file to be written */ public void printGameBoardToFile( String outputFile ) { try { BufferedWriter output = new BufferedWriter( new FileWriter( outputFile ) ); for( int i = 0; i < 6; i++ ) { for( int j = 0; j < 7; j++ ) { output.write( this.playBoard[i][j] + 48 ); } output.write("\r\n"); } //write the current turn output.write( this.getCurrentTurn() + "\r\n"); output.close(); } catch( IOException e ) { System.out.println("\nProblem writing to the output file!\n" + "Try again."); e.printStackTrace(); } } // end printGameBoardToFile() private void exit_function( int value ){ System.out.println("exiting from GameBoard.java!\n\n"); System.exit( value ); } } // end GameBoard class