package net.ciklum.icfpc11.controller import net.ciklum.icfpc11.domain.Player import net.ciklum.icfpc11.parser.Command import net.ciklum.icfpc11.controller.ai.OpponentActivityMonitor import net.ciklum.icfpc11.controller.ai.Strategy import net.ciklum.icfpc11.controller.ai.StaticStrategy import net.ciklum.icfpc11.controller.ai.DumbLoopStrategy import net.ciklum.icfpc11.controller.ai.ReviveStrategy import net.ciklum.icfpc11.domain.Game import net.ciklum.icfpc11.domain.Slot import net.ciklum.icfpc11.controller.ai.UberpushkaStrategy import net.ciklum.icfpc11.controller.ai.HitZeroAgainStrategy import net.ciklum.icfpc11.controller.ai.DecWeaklingStrategy /** * Artificial Idiot for LtG. * @author vic */ @Typed class AiPlayer extends Player { private final OpponentActivityMonitor activityMonitor protected ReviveStrategy save0Strategy = null protected Strategy rushStrategy = null private ReviveStrategy saveSomeStrategy = null protected Strategy decStrategy = null protected Strategy betterDecStrategy = null protected Strategy uberpushkaStrategy = null protected Strategy attackZeroStrategy = null AiPlayer(String name) { super(name) activityMonitor = new OpponentActivityMonitor() rushStrategy = new StaticStrategy(StaticStrategy.COMMANDO42) decStrategy = new DumbLoopStrategy(DumbLoopStrategy.DEC_AFTER_COMMANDO45) } @Override Command getNextCommand() { try { currentStrategy.getNextCommand() } catch (e) { decStrategy.getNextCommand() } } @Override void respondCommand(Command response) { activityMonitor.commandIssued(response) super.respondCommand(response) //To change body of overridden methods use File | Settings | File Templates. } Strategy getCurrentStrategy() { if (save0Strategy != null && !save0Strategy.complete) { // continue saving slot 0 return save0Strategy } else { save0Strategy = null } int safeSlot = findSafeSlot() int deadSlot = Game.instance.currentProponent.slots.findIndexOf{ Slot it -> !it.alive } if (deadSlot in [0,1,2,4]) { // Rush uses 0,1,2,4 // start saving slot 0 save0Strategy = new ReviveStrategy(Game.instance, 0, safeSlot) return save0Strategy } if (!rushStrategy.complete) { // or go on with Commando return rushStrategy } // restore all our slots is second priority if (deadSlot >= 0) { //TODO maybe revive only important slots //TODO revive 255th faster = revive(get(zero)) if ((saveSomeStrategy == null) || saveSomeStrategy.complete) { saveSomeStrategy = new ReviveStrategy(Game.instance, deadSlot, safeSlot) } return saveSomeStrategy } // preserve 0th cell as dead if (Game.instance.currentOpponent.getSlot(0).alive) { if (Game.instance.currentOpponent.getSlot(0).vitality > 10) { if (attackZeroStrategy == null) { attackZeroStrategy = new HitZeroAgainStrategy(safeSlot) // we don't build there, just use its health } return attackZeroStrategy } else { return decStrategy } } int uberPushkaSlot = Game.instance.currentOpponent.slots.findIndexOf{ Slot it -> it.vitality > 8160} if (uberPushkaSlot >= 0) { if (uberpushkaStrategy == null || uberpushkaStrategy.complete) { uberpushkaStrategy = new UberpushkaStrategy(Game.instance, uberPushkaSlot) } return uberpushkaStrategy } int weakling = DecWeaklingStrategy.findWeakling(Game.instance) if (weakling > 0) { if (betterDecStrategy == null || betterDecStrategy.complete) { betterDecStrategy = new DecWeaklingStrategy(Game.instance, weakling, 16) } return betterDecStrategy } // otherwise, keep enemy's slot 0 dead decStrategy } protected int findSafeSlot() { (17..200).reverse().find { int it -> Game.instance.currentProponent.getSlot(it).vitality == 10000 } } }