/** * This routine computes which positions on the board have to be flipped when a certain move is * made. The move is specified by the position <code>pos</code> and the player color <code>color * </code>. The array <code>flipped</code> will be filled with the result. A "0" indicates no * flip, while a "1" indicates that the stone at this position will be flipped when the * corresponding move is made. */ void computeTokensToFlip(GameBoard gb, Coordinates pos, int color, int[][] toFlip) { int drow, dcol; int opposite = color == GameBoard.RED ? GameBoard.GREEN : GameBoard.RED; boolean oneFlipped; int[][] currentBoard = new int[BOARD_LENGTH][BOARD_LENGTH]; int row = pos.getRow() - 1; int col = pos.getCol() - 1; try { for (int i = 1; i <= BOARD_LENGTH; i++) { for (int j = 1; j <= BOARD_LENGTH; j++) { currentBoard[i - 1][j - 1] = gb.getPosition(new Coordinates(i, j)); toFlip[i - 1][j - 1] = 0; } } } catch (OutOfBoundsException e) { System.out.println("I checked an illegal position. I am sorry."); } for (int idx = 0; idx < direction.length; idx += 2) { int delta_row = direction[idx]; int delta_col = direction[idx + 1]; drow = row + delta_row; dcol = col + delta_col; oneFlipped = false; while (onBoard(drow, dcol) && currentBoard[drow][dcol] == opposite) { oneFlipped = true; drow += delta_row; dcol += delta_col; } if (onBoard(drow, dcol) && oneFlipped && currentBoard[drow][dcol] == color) { drow = row + delta_row; dcol = col + delta_col; while (currentBoard[drow][dcol] == opposite) { toFlip[drow][dcol] = 1; drow += delta_row; dcol += delta_col; } } } }
Coordinates performMove(int player, TextGameBoard board) throws InterruptedException, IllegalMoveException, TimeExceededException { Coordinates currentMove = null; int[][] toFlip = new int[BOARD_LENGTH][BOARD_LENGTH]; boolean legalMove; statusText = ""; if (player != GameBoard.RED && player != GameBoard.GREEN) { throw new IllegalArgumentException("Player has to be RED or GREEN!"); } String playerName; String playerColor; ReversiPlayer reversiPlayer; if (player == GameBoard.RED) { playerColor = "Red"; playerName = name_red; reversiPlayer = player_red; } else { playerColor = "Green"; playerName = name_green; reversiPlayer = player_green; } if (!params.getSilent() && params.getAnimations()) { // show possible moves of the current player (if any) visualization.showPossibleMoves(board, player); visualization.setStatusLine(playerName + " thinking..."); } // only for animation reasons try { Thread.sleep(params.getDelay()); } catch (InterruptedException e) { } try { currentMove = makeMove(reversiPlayer, board); } catch (TimeExceededException e) { writeToLog(playerColor + " exceeds time limit"); cheatedFinish(player, GameState.CHEATED_TIME_EXCEEDED, board); statusText = playerColor + " exceeds time limit."; throw new TimeExceededException(); } // the InterruptedException is passed to the caller writeToLog( playerColor + "move=" + (currentMove == null ? "null" : currentMove.getRow() + "," + currentMove.getCol())); if (currentMove == null) { System.out.println(playerColor + " passes."); } legalMove = board.checkMove(player, currentMove); if (!legalMove) { System.out.println(playerColor + " makes illegal move: " + currentMove); writeToLog(playerColor + " makes illegal move"); if (verbose) { System.out.println(board.toString()); } cheatedFinish(player, GameState.CHEATED_ILLEGAL_MOVE, board); statusText = playerColor + " makes illegal move."; throw new IllegalMoveException( "Illegal move by player " + playerColor + "(" + currentMove + ")", currentMove); } if (currentMove != null) { computeTokensToFlip(board, currentMove, player, toFlip); if (!params.getSilent() && params.getAnimations()) { visualization.animateMove(board, currentMove, player, toFlip); } } board.makeMove(player, currentMove); if (!params.getSilent()) { visualization.setInfoLine2( name_red + " (red) vs " + name_green + " (green): " + board.countStones(GameBoard.RED) + ":" + board.countStones(GameBoard.GREEN)); } return currentMove; }