package net.ciklum.icfpc11.controller.ai import net.ciklum.icfpc11.parser.Command import net.ciklum.icfpc11.domain.Game import net.ciklum.icfpc11.domain.greenspoon10.ConstantFunction import net.ciklum.icfpc11.domain.greenspoon10.Function import static net.ciklum.icfpc11.parser.Application.LEFT import static net.ciklum.icfpc11.parser.Application.RIGHT import static net.ciklum.icfpc11.domain.Card.* import net.ciklum.icfpc11.domain.Card import net.ciklum.icfpc11.plan.ConstantCommandPlanner import net.ciklum.icfpc11.domain.greenspoon10.Identity /** * A Strategy that builds a given constant in a given slot. * Used for utility purpose by other strategies. * @author vic */ @Typed final class BuildConstantStrategy implements Strategy { private final int slot private final int target private final Game game private final ConstantCommandPlanner constPlanner = new ConstantCommandPlanner() BuildConstantStrategy(Game game, int slot, int target) { this.slot = slot this.target = target this.game = game } Command getNextCommand() { if (complete) { throw new IndexOutOfBoundsException('BuildConstant is complete or cant complete') } Function current = game.currentProponent.getSlot(slot).value // prepare the working place if (current == Identity.IDENTITY) { return new Command(RIGHT, slot, zero) } if (!(current instanceof ConstantFunction)) { return new Command(LEFT, slot, put) } Card nextCard = constPlanner.nextCardToObtainConstant(target, current.value) if (nextCard == null) { return new Command(LEFT, slot, put) } return new Command(LEFT, slot, nextCard) } boolean isComplete() { // failure if (!game.currentProponent.getSlot(slot).alive) return true def addrSlotValue = game.currentProponent.getSlot(slot).value if (addrSlotValue instanceof ConstantFunction) { // success return (addrSlotValue as ConstantFunction).value == target } return false } int getStepsToComplete() { Function current = game.currentProponent.getSlot(slot).value if (!(current instanceof ConstantFunction)) { constPlanner.stepsToReach(target, 0) + 1 } constPlanner.stepsToReach(target, current.value) } }