package com.m00ware.vindinium;
import vindinium.*;
import vindinium.Board.HeroTile;
import vindinium.Board.Mine;
import vindinium.Board.Tile;
public class M00Bot implements Bot {
private static final boolean LOGGING = true;
public static final int MAX_HP = 100;
public static final int CRITICAL_HP = MAX_HP / 3;
private static final int PURSIT_TICKETS = 10;
private static final int PURSIT_COOL_DOWN = 2;
private boolean isReloading = false;
private int pursuitTickets = PURSIT_TICKETS;
@Override
public Direction nextMove(State state) {
long t = System.nanoTime();
try {
Hero player = state.hero();
if (!isReloading) {
if (player.state.life > CRITICAL_HP) {
if (pursuitTickets > 0) {
Direction pathEnemy = nearestWeakerEnemy(player, state);
if (pathEnemy != null) {
pursuitTickets--;
log("Going to an enemy, " + pathEnemy);
return pathEnemy;
}
} else if (pursuitTickets-- < -PURSIT_COOL_DOWN) {
pursuitTickets = PURSIT_TICKETS;
}
Direction pathToMine = nearestAvailableMine(player, state.game.board);
if (pathToMine != null) {
log("Going to a mine, " + pathToMine);
return pathToMine;
}
} else {
isReloading = true;
}
} else if (player.state.life >= MAX_HP - 1) {
isReloading = false;
} else {
log("Trying to reload... life= " + player.state.life);
}
pursuitTickets = PURSIT_TICKETS;
Direction pathToTavern = nearestTavern(player, state.game.board, true);
if (pathToTavern != null) {
log("Going to a tavern, " + pathToTavern);
return pathToTavern;
}
Direction pathToTavernUnsafe = nearestTavern(player, state.game.board, false);
if (pathToTavernUnsafe != null) {
log("Going to a tavern, UNSAFE! " + pathToTavernUnsafe);
return pathToTavernUnsafe;
}
log("No path :(");
return Direction.STAY;
} finally {
t = System.nanoTime() - t;
log("Next step took " + t / 1000000.0);
}
}
public static void log(String s) {
if (LOGGING) {
System.out.println(s);
}
}
public Direction nearestAvailableMine(final Hero player, final Board board) {
return new PathFinder(false, player, board).findNearest(new Predicate<PathFinder.State>() {
@Override
public boolean apply(PathFinder.State state) {
Tile t = board.tileAt(state.hero.position);
return t instanceof Mine && !((Mine) t).isOwnedBy(player);
}
});
}
public Direction nearestTavern(final Hero player, final Board board, boolean safe) {
return new PathFinder(safe, player, board).findNearest(new Predicate<PathFinder.State>() {
@Override
public boolean apply(PathFinder.State state) {
Tile t = board.tileAt(state.hero.position);
return t == Tile.TAVERN;
}
});
}
public Direction nearestWeakerEnemy(final Hero player, final State gameState) {
return new PathFinder(false, player, gameState.game.board, PURSIT_TICKETS).findNearest(new Predicate<PathFinder.State>() {
@Override
public boolean apply(PathFinder.State state) {
Game game = gameState.game;
Board board = game.board;
Tile t = board.tileAt(state.hero.position);
if (t instanceof HeroTile) {
HeroTile heroTile = (HeroTile) t;
if (!heroTile.is(player)) {
Hero hero = game.findHero(heroTile.getHeroId());
if (hero.state.life < player.state.life - PathFinder.HP_LOSS_HERO_FIGHT && board.minesForHero(hero) > 0) {
return true;
}
}
}
return false;
}
});
}
}