package net.ciklum.icfpc11.controller.ai import net.ciklum.icfpc11.parser.Command import static net.ciklum.icfpc11.plan.FunctionTreeBuilder.* import net.ciklum.icfpc11.plan.MovePlanner import net.ciklum.icfpc11.parser.Application import net.ciklum.icfpc11.domain.Card import net.ciklum.icfpc11.domain.Game import net.ciklum.icfpc11.domain.greenspoon10.Identity /** * blabla * @author vic */ @Typed final class HitZeroAgainStrategy implements Strategy { // @Delegate private static final int GUN_SLOT = 11 private int currentStrategyIndex private boolean firstInvoke = true private final List strategies = [] HitZeroAgainStrategy(int healthDonorSlot) { def reattack0Tree = S(K(attack(get(succ(zero)), get(zero))), K(get(dbl(dbl(succ(zero)))))) MovePlanner planner = new MovePlanner(GUN_SLOT) List сommands = planner.plan(reattack0Tree) сommands.add(new Command(Application.RIGHT, GUN_SLOT, Card.zero)) currentStrategyIndex = 0 strategies << new BuildConstantStrategy(Game.instance, 1, healthDonorSlot) strategies << new BuildConstantStrategy(Game.instance, 4, 8160) strategies << new BuildConstantStrategy(Game.instance, 0, 255) strategies << new StaticStrategy(сommands) // now s0->255, 4->8160, 255->health donor seekNextStrategy() } List getUsedSlots() { [4, GUN_SLOT, 13, 255] } Command getNextCommand() { if (complete) { throw new IndexOutOfBoundsException('cant invoke on completed strategy') } seekNextStrategy() if (firstInvoke && Game.instance.currentProponent.getSlot(GUN_SLOT).value != Identity.IDENTITY) { return new Command(Application.LEFT, GUN_SLOT, Card.put) } firstInvoke = false Command res = strategies[currentStrategyIndex].getNextCommand() seekNextStrategy() res } private void seekNextStrategy() { while (strategies[currentStrategyIndex]?.complete && (currentStrategyIndex < strategies.size())) { currentStrategyIndex++ } } boolean isComplete() { currentStrategyIndex >= strategies.size() || ((currentStrategyIndex == strategies.size()-1) && strategies[currentStrategyIndex].complete) } }