public void setIndex(int index, Individual player) { /* * sets the location on the board with a player piece (1 for 'X', 2 for 'O') */ board[index] = player.getValue(); }
public int playGame(Individual startingPlayer, Individual secondPlayer) { int result = -1; // set the starting player value to 1 ('X') startingPlayer.setValue(1); // set the second player value to 2 ('O') secondPlayer.setValue(2); while (true) { // starting player code block ////////////////////////////////////// // can make either a random move or a move using the strategy tree if (!startingPlayer.makeStrategyMove()) { // an attempt to make a move on an occupied space was made // abort the game Console.WriteLine("Move " + startingPlayer.getValue() + " Failed"); Console.WriteLine("SHUTTING GAME DOWN: OBSOLETE GARBAGE"); break; } // check if the starting player move resulted in a win result = board.checkWin(startingPlayer); if (result != 0) { break; } ////////////////////////////////////// // starting player code block end // second player code block ////////////////////////////////////// if (!secondPlayer.makeStrategyMove()) { Console.WriteLine("Move " + secondPlayer.getValue() + " Failed"); Console.WriteLine("SHUTTING GAME DOWN: OBSOLETE GARBAGE"); break; } result = board.checkWin(secondPlayer); if (result != 0) { break; } ////////////////////////////////////// } // add the result accordingly switch (result) { case DRAW: startingPlayer.addDraw(true); secondPlayer.addDraw(false); break; case START_WIN: startingPlayer.addWin(true); secondPlayer.addLoss(false); break; case SECOND_WIN: secondPlayer.addWin(false); startingPlayer.addLoss(true); break; case INCOMPLETE_TREE: Console.WriteLine("Incomplete Tree Error"); break; default: Console.WriteLine("CATASTROPHIC FAILURE!!!"); break; } return(result); }
public int Eval(int index) { /* * evaluation of a terminal * calls the proper method according to the terminal type (methods are in Board class) */ int grade = 0; int playerNum = 0; if (friendOrEnemy == 1) { // if the terminal checks for friendly pieces // check if the individual value is 1 ('X') and assign 1 to playerNum, else assign 2 if (individual.getValue() == 1) { playerNum = 1; } else { playerNum = 2; } } else { // if the terminal checks for enemy pieces // check if the individual value is ('X') and assign 2 to playerNum, else assign 1 if (individual.getValue() == 1) { playerNum = 2; } else { playerNum = 1; } } // call the proper method (stored as a string in terminalIdentity variable) // all methods but the countCorners receives 2 arguments: // index argument and playerNum argument which represent looking for a friend or an enemy if (terminalIdentity.Equals("WinMove", StringComparison.OrdinalIgnoreCase)) { grade = (board.willWinBlock(index, playerNum)) ? 99999 : 0; } if (terminalIdentity.Equals("LoseMove", StringComparison.OrdinalIgnoreCase)) { grade = (board.willWinBlock(index, playerNum % 2 + 1)) ? 33333 : 0; } if (terminalIdentity.Equals("NeightborsAmount", StringComparison.OrdinalIgnoreCase)) { grade = board.countNeighbors(index, playerNum); } if (terminalIdentity.Equals("RowAmount", StringComparison.OrdinalIgnoreCase)) { grade = board.countRow(index, playerNum); } if (terminalIdentity.Equals("RowStreak", StringComparison.OrdinalIgnoreCase)) { grade = board.countRowStreak(index, playerNum); } if (terminalIdentity.Equals("ColumnAmount", StringComparison.OrdinalIgnoreCase)) { grade = board.countColumn(index, playerNum); } if (terminalIdentity.Equals("ColumnStreak", StringComparison.OrdinalIgnoreCase)) { grade = board.countColumnStreak(index, playerNum); } if (terminalIdentity.Equals("PrimaryDiagStreak", StringComparison.OrdinalIgnoreCase)) { grade = board.countDiagMainStreak(index, playerNum); } if (terminalIdentity.Equals("SecDiagStreak", StringComparison.OrdinalIgnoreCase)) { grade = board.countDiagSecStreak(index, playerNum); } if (terminalIdentity.Equals("RandVal", StringComparison.OrdinalIgnoreCase)) { grade = value; } return(grade); }
public int checkWin(Individual player) { /* * Checks whether a board has a winning state in it * row, column or a diagonal streak of SIZE/2 * * player == 1 --> 'X' * player == 2 --> 'O' * returned value of 0 means there is no winner and there are still blank locations to play * returned value of -1 means the game ended as a draw */ // counter for a streak of player pieces int count = 0; // check rows for (int i = 0; i < SIZE * SIZE; i++) { // encountered player piece --> increase counter if (board[i] == player.getValue()) { count++; } else // streak is broken --> reset the counter { count = 0; } // if the counter has sufficient streak, return the player as the winner if (count == streak) { return(player.getValue()); // player won } // reached the end of a row (last column) --> reset the counter if (i % SIZE == SIZE - 1) { count = 0; } } // check columns for (int i = 0, col = 0; i < SIZE * SIZE; i++) { /* col is a variable which represent the current column and is increased when starting a new column count * board[col + (i%SIZE)*SIZE] example: * 0 1 2 * --------- * 0| 0 1 2 * 1| 3 4 5 * 2| 6 7 8 * * for location 0, 3, 6 checking * location 0: col=0 i=0 SIZE=3 --> col + (i%SIZE)*SIZE = 0 + (0%3)*3 = 0 + 0 = 0 * location 3: col=0 i=1 SIZE=3 --> col + (i%SIZE)*SIZE = 0 + (1%3)*3 = 0 + 3 = 3 * location 6: col=0 i=2 SIZE=3 --> col + (i%SIZE)*SIZE = 0 + (2%3)*3 = 0 + 6 = 6 * * for location 1, 4, 7 checking * location 0: col=1 i=3 SIZE=3 --> col + (i%SIZE)*SIZE = 1 + (3%3)*3 = 1 + 0 = 1 * location 3: col=1 i=4 SIZE=3 --> col + (i%SIZE)*SIZE = 1 + (4%3)*3 = 1 + 3 = 3 * location 6: col=1 i=5 SIZE=3 --> col + (i%SIZE)*SIZE = 1 + (5%3)*3 = 1 + 6 = 6 * * for location 2, 5, 8 checking * location 0: col=2 i=6 SIZE=3 --> col + (i%SIZE)*SIZE = 2 + (6%3)*3 = 2 + 0 = 2 * location 3: col=2 i=7 SIZE=3 --> col + (i%SIZE)*SIZE = 2 + (7%3)*3 = 2 + 3 = 5 * location 6: col=2 i=8 SIZE=3 --> col + (i%SIZE)*SIZE = 2 + (8%3)*3 = 2 + 6 = 8 * */ // encountered player piece --> increase counter if (board[col + (i % SIZE) * SIZE] == player.getValue()) { count++; } else // streak is broken --> reset the counter { count = 0; } // if the counter has sufficient streak, return the player as the winner if (count == streak) { return(player.getValue()); // player won } // reached the end of a column (last row) --> reset the counter if (i % SIZE == SIZE - 1) { count = 0; // only increase col variable after the first iteration (the above 'if' is invoked at i==0) if (i > 0) { col++; } } } // check Left To Right diagonals from top to bottom (main diagonals) for (int i = 0; i < SIZE * SIZE; i++) { // for each iteration of i, reset the counter count = 0; // start at i and iterate to the last index // increment j with SIZE+1 // (+SIZE will result in getting the next row, +1 will result in one index to the right) for (int j = i; j < SIZE * SIZE; j += SIZE + 1) { // count player pieces if (board[j] == player.getValue()) { count++; } else // reset the counter if the streak is broken { count = 0; } // check if the count streak is sufficient for a win if (count == streak) { return(player.getValue()); } // if j is out of bound of the array index // or reached the right border (j % SIZE == SIZE-1), break the loop if (j >= SIZE * SIZE || j % SIZE == SIZE - 1) { break; } } } // check Left To Right diagonals from bottom to top (secondary diagonals) // start at the end of the board (last index) and go backward until reaching 0 for (int i = SIZE * SIZE - 1; i >= 0; i--) { // for each iteration of i, reset the counter count = 0; // start at i and iterate to the last index // decrement j with SIZE-1 // (-SIZE will result in getting the previous row, -1 will result in one index to the left) for (int j = i; j > 0; j -= (SIZE - 1)) { // count player pieces if (board[j] == player.getValue()) { count++; } else // reset the counter if the streak is broken { count = 0; } // check if the count streak is sufficient for a win if (count == streak) { return(player.getValue()); } // if j is out of bound of the array index // or reached the right border (j % SIZE == 0), break the loop if (j < 0 || j % SIZE == SIZE - 1) { break; } } } // check draw for (int i = 0; i < SIZE * SIZE; i++) { // if encountered a blank location, return 0 meaning the game can still be played if (board[i] == 0) { return(0); } } // none of the above returns invoked --> game ended as a draw return(-1); }