@Override public Move getMove(Gameboard gameboard, Opponent opponent, Player player) throws NoItemException, MapOutOfBoundsException { // System.out.format("Turn NUm:%d\n", gameboard.getCurrentTurnNumber()); // Turret t = gameboard.getTurrets().get(2); // System.out.format("Turret: cool:%d fire:%d // isFiringNextTurn:%b\n",t.getCooldownTime(),t.getFireTime(),t.isFiringNextTurn()); buildBoardValue(gameboard, player, opponent); int maxVal = highestValueTile(gameboard); // System.out.format("maxVal:%d\n", maxVal); Move myMove = bfs( gameboard, player, opponent, player.getX(), player.getY(), player.getDirection(), maxVal); return myMove; // } // System.out.println("x:"+player.getX()+" y:"+player.getY()+" safe: // "+bulletSafe(gameboard,player.getX(),player.getY())); }
// augments bfs algorithm to navigate the board and decides the move private Move bfs( Gameboard gameboard, Player player, Opponent opponent, int x, int y, Direction dir, int maxVal) { Node record[][][] = new Node[gameboard.getWidth()][gameboard.getHeight()][4]; Node nextMove = null; Node lastMove = null; // System.out.println(dir); int d = 0; switch (dir) { case UP: d = 0; break; case DOWN: d = 2; break; case LEFT: d = 3; break; case RIGHT: d = 1; break; } queue.clear(); queue.add(new Node(x, y, null, 0, d)); while (!queue.isEmpty()) { Node curNode = queue.remove(); // System.out.println("CurNode: " + curNode.toString()); try { if (gameboard.isWallAtTile(curNode.x, curNode.y)) continue; else if (gameboard.isTurretAtTile(curNode.x, curNode.y)) continue; else if (opponent.getX() == curNode.x && opponent.getY() == curNode.y) continue; } catch (Exception e) { } if (tileValue[curNode.x][curNode.y] == maxVal) { // System.out.println("Target: " + curNode.toString()); nextMove = getPath(curNode); lastMove = curNode; break; } else if (tileValue[curNode.x][curNode.y] > 40 && curNode.steps <= 5) { // System.out.println("Target: " + curNode.toString()); nextMove = getPath(curNode); lastMove = curNode; break; } Node newNode = null; int curDir = -1; switch (curNode.d) { case UP: // System.out.println("Facing UP!"); newNode = new Node( curNode.x, (curNode.y - 1 + gameboard.getHeight()) % gameboard.getHeight(), curNode, curNode.steps + 1, 0); // System.out.println("Declared this node: " + newNode.toString()); if (record[newNode.x][newNode.y][newNode.getDirInt()] == null) { queue.add(newNode); record[newNode.x][newNode.y][newNode.getDirInt()] = newNode; // System.out.println("Pushed: " + newNode.toString()); } curDir = 0; break; case RIGHT: // System.out.println("Facing Right!"); newNode = new Node( (curNode.x + 1 + gameboard.getWidth()) % gameboard.getWidth(), curNode.y, curNode, curNode.steps + 1, 1); // System.out.println("Declared this node: " + newNode.toString()); if (record[newNode.x][newNode.y][newNode.getDirInt()] == null) { queue.add(newNode); record[newNode.x][newNode.y][newNode.getDirInt()] = newNode; // System.out.println("Pushed: " + newNode.toString()); } curDir = 1; break; case DOWN: newNode = new Node( curNode.x, (curNode.y + 1 + gameboard.getHeight()) % gameboard.getHeight(), curNode, curNode.steps + 1, 2); if (record[newNode.x][newNode.y][newNode.getDirInt()] == null) { queue.add(newNode); record[newNode.x][newNode.y][newNode.getDirInt()] = newNode; } curDir = 2; break; case LEFT: newNode = new Node( (curNode.x - 1 + gameboard.getWidth()) % gameboard.getWidth(), curNode.y, curNode, curNode.steps + 1, 3); if (record[newNode.x][newNode.y][newNode.getDirInt()] == null) { queue.add(newNode); record[newNode.x][newNode.y][newNode.getDirInt()] = newNode; } curDir = 3; break; } for (int i = 1; i <= 3; i++) { int fuDir = (curDir + i) % 4; switch (fuDir) { case 0: newNode = new Node( curNode.x, (curNode.y - 1 + gameboard.getHeight()) % gameboard.getHeight(), curNode, curNode.steps + 2, 0); if (record[newNode.x][newNode.y][newNode.getDirInt()] == null) { queue.add(newNode); record[newNode.x][newNode.y][newNode.getDirInt()] = newNode; // System.out.println("Pushed: " + newNode.toString()); } break; case 1: newNode = new Node( (curNode.x + 1 + gameboard.getWidth()) % gameboard.getWidth(), curNode.y, curNode, curNode.steps + 2, 1); if (record[newNode.x][newNode.y][newNode.getDirInt()] == null) { queue.add(newNode); record[newNode.x][newNode.y][newNode.getDirInt()] = newNode; // System.out.println("Pushed: " + newNode.toString()); } break; case 2: newNode = new Node( curNode.x, (curNode.y + 1 + gameboard.getHeight()) % gameboard.getHeight(), curNode, curNode.steps + 2, 2); if (record[newNode.x][newNode.y][newNode.getDirInt()] == null) { queue.add(newNode); record[newNode.x][newNode.y][newNode.getDirInt()] = newNode; // System.out.println("Pushed: " + newNode.toString()); } break; case 3: newNode = new Node( (curNode.x - 1 + gameboard.getWidth()) % gameboard.getWidth(), curNode.y, curNode, curNode.steps + 2, 3); if (record[newNode.x][newNode.y][newNode.getDirInt()] == null) { queue.add(newNode); record[newNode.x][newNode.y][newNode.getDirInt()] = newNode; // System.out.println("Pushed: " + newNode.toString()); } break; } } } // System.out.println("Nextmove: " + nextMove.toString()); if (nextMove.steps == 1 && tileValue[nextMove.x][nextMove.y] == -1) { if (player.getShieldCount() >= 1) { return Move.SHIELD; } else { return Move.NONE; } } else if (nextMove.steps == 1 && tileValue[nextMove.x][nextMove.y] == -2) { for (int i = 0; i < 4 && inReachBullet[nextMove.x][nextMove.y][i] != null; i++) { Bullet b = inReachBullet[nextMove.x][nextMove.y][i]; if (player.getDirection() == Direction.opposite(b.getDirection())) { return Direction.directionToMovement(Direction.clockwise(player.getDirection())); } else { return Move.NONE; } } } else if (lastMove.steps <= 1) { Turret t = inReachTurret[lastMove.x][lastMove.y][0]; if (tileValue[lastMove.x][lastMove.y] == 60 && t.getCooldownTime() >= 2) { // System.out.format("Turret x:%d y:%d cool:%d fire:%d\n", t.getX(), t.getY(), // t.getCooldownTime(), t.getFireTime()); int cycle = t.getCooldownTime() + t.getFireTime(); int fuStatus1 = gameboard.getCurrentTurnNumber() % cycle + 1; int fuStatus2 = gameboard.getCurrentTurnNumber() % cycle + 2; if (lastMove.steps == 1) { if (fuStatus1 > t.getFireTime() && fuStatus1 <= cycle && fuStatus2 > t.getFireTime() && fuStatus2 <= cycle) { return Move.FORWARD; } else { return Move.NONE; } } else if (lastMove.steps == 0) { return Move.LASER; } } else if (tileValue[lastMove.x][lastMove.y] == 43 || (t != null && t.getCooldownTime() <= 1 && player.getShieldCount() >= 1)) { // Turret t = inReachTurret[lastMove.x][lastMove.y][0]; // System.out.format("Turret x:%d y:%d cool:%d fire:%d\n", t.getX(), t.getY(), // t.getCooldownTime(), t.getFireTime()); int cycle = t.getCooldownTime() + t.getFireTime(); int fuStatus1 = gameboard.getCurrentTurnNumber() % cycle + 1; int fuStatus2 = gameboard.getCurrentTurnNumber() % cycle + 2; if (lastMove.steps == 1 && !player.isShieldActive()) { if (!t.isFiringNextTurn()) { return Move.FORWARD; } else if (fuStatus2 <= t.getFireTime()) { return Move.SHIELD; } else if (fuStatus2 > t.getFireTime() && fuStatus2 <= t.getCooldownTime()) { return Move.NONE; } } else if (player.isShieldActive()) { return Move.FORWARD; } else if (lastMove.steps == 0) { if (t.isFiringNextTurn()) { return Move.SHIELD; } else { return Move.NONE; } } } else if (tileValue[lastMove.x][lastMove.y] > 40 && tileValue[lastMove.x][lastMove.y] <= 50) { return Move.FORWARD; } else if (tileValue[lastMove.x][lastMove.y] == 100) { return Move.FORWARD; } else if (tileValue[player.getX()][player.getY()] < 0) { return Move.FORWARD; } } else { if (nextMove.steps == 2) { return Direction.directionToMovement(nextMove.d); } else { Turret t = inReachTurret[nextMove.x][nextMove.y][0]; if (t == null || !t.isFiringNextTurn()) { // System.out.println("1"); return Move.FORWARD; } else return Move.NONE; } } return Move.NONE; // for(int x=0;x<gameboard.getWidth();x++) { // for(int y=0;y<gameboard.getHeight();y++) { // record[x][y][] = new Node(0,1, null,-1, -1) // } // } }