private Move getBestOnePixelOffMove(Board board) { List<Move> otherPlayersMove = board.getPrevMovesByPlayerId(1); double maxScore = 0; Move bestMove = null; for (int j = 0; j < otherPlayersMove.size(); j++) { Move prevMove = otherPlayersMove.get(j); for (int i = 0; i < directions.length; i++) { int nextX = prevMove.x + directions[i][0]; int nextY = prevMove.y + directions[i][1]; if (isValidMove(board, nextX, nextY)) { Move thisMove = Move.createMyMove(nextX, nextY); double thisScore = board.testMyScoreWithThisMove(thisMove); if (thisScore > maxScore) { maxScore = thisScore; bestMove = thisMove; } } else { int nextX2 = prevMove.x + directions[i][0] * 2; int nextY2 = prevMove.y + directions[i][1] * 2; if (isValidMove(board, nextX2, nextY2)) { Move thisMove = Move.createMyMove(nextX2, nextY2); double thisScore = board.testMyScoreWithThisMove(thisMove); if (thisScore > maxScore) { maxScore = thisScore; bestMove = thisMove; } } } } } return bestMove; }
private boolean isValidMove(Board board, int x, int y) { if (x < 0 || y < 0 || x >= board.getBoardSize() || y >= board.getBoardSize() || !board.isEmptyAt(x, y)) { return false; } return true; }
private Move getMinMaxBestMove(Board board, List<Move> moves) { int size = board.getBoardSize(); int maxScore = 0; Move myBestMove = moves.get(0); for (int k = 0; k < moves.size(); k++) { Move myMove = moves.get(k); int minScore = Integer.MAX_VALUE; for (int i = interval; i < size; i += interval) { for (int j = interval; j < size; j += interval) { Move othersMove = Move.createOthersMove(1, i, j); int thisScore = testMyScoreWithThisMove(board, myMove, othersMove); if (thisScore < minScore) { minScore = thisScore; } } } if (minScore > maxScore) { maxScore = minScore; myBestMove = myMove; } } return myBestMove; }
private Move getBestRandomMove(Board board, int startX, int startY, int offset) { int poolNo = 1000; Move bestMove = null; double maxScore = 0; for (int i = 0; i < poolNo; i++) { Move nextMove = null; while (nextMove == null) { int x = startX + r.nextInt(offset); int y = startY + r.nextInt(offset); // if this position is empty and the color of this position is not mine, then accept this // move if (isValidMove(board, x, y)) { nextMove = Move.createMyMove(x, y); double thisScoreDiff = board.testMyScoreWithThisMove(nextMove); if (thisScoreDiff > maxScore) { maxScore = thisScoreDiff; bestMove = nextMove; } } } } return bestMove; }
private void addSampleMoves(Board board) { int size = board.getBoardSize(); for (int i = interval; i < size; i += interval) { for (int j = interval; j < size; j += interval) { sampleMoves.add(Move.createMyMove(i, j)); } } }
@Override public Move makeAMove(Board board) { if (sampleMoves.size() == 0) { addSampleMoves(board); } if (board.getPrevMoves().size() == 0) { firstPlayer = true; return Move.createMyMove(board.getBoardSize() / 2, board.getBoardSize() / 2); } if (firstPlayer) { Move myMove = getMinMaxBestMove(board, sampleMoves); Move bestMove = getBestRandomMove(board, myMove.x - 50, myMove.y - 50, 100); return bestMove; } else { return getBestOnePixelOffMove(board); } }
public int testMyScoreWithThisMove(Board board, Move myMove, Move othersMove) { double[][][] currPull = board.getCurrPull(); int size = board.getBoardSize(); int myScore = 0; for (int i = 0; i < size; i++) { for (int j = 0; j < size; j++) { double newMyPull = currPull[i][j][0] + 1 / AbsPlayer.getDistanceSq(i, j, myMove); double newOthersPull = currPull[i][j][1] + 1 / AbsPlayer.getDistanceSq(i, j, othersMove); if (newMyPull > newOthersPull) { myScore++; } else { myScore--; } } } return myScore; }