package net.demilich.metastone.game.logic; import java.util.ArrayList; import java.util.Collection; import java.util.List; import net.demilich.metastone.game.Attribute; import net.demilich.metastone.game.GameContext; import net.demilich.metastone.game.Player; import net.demilich.metastone.game.TurnState; import net.demilich.metastone.game.actions.EndTurnAction; import net.demilich.metastone.game.actions.GameAction; import net.demilich.metastone.game.actions.PhysicalAttackAction; import net.demilich.metastone.game.cards.Card; import net.demilich.metastone.game.cards.IChooseOneCard; import net.demilich.metastone.game.entities.Entity; import net.demilich.metastone.game.entities.heroes.Hero; import net.demilich.metastone.game.entities.minions.Minion; import net.demilich.metastone.game.heroes.powers.HeroPower; import net.demilich.metastone.game.targeting.CardLocation; import net.demilich.metastone.game.targeting.CardReference; import net.demilich.metastone.game.targeting.TargetSelection; public class ActionLogic { private final TargetLogic targetLogic = new TargetLogic(); public GameAction getAutoHeroPower(GameContext context, Player player) { return getHeroPowerActions(context, player).get(0); } private List<GameAction> getHeroAttackActions(GameContext context, Player player) { List<GameAction> heroAttackActions = new ArrayList<GameAction>(); Hero hero = player.getHero(); if (!hero.canAttackThisTurn()) { return heroAttackActions; } rollout(new PhysicalAttackAction(hero.getReference()), context, player, heroAttackActions); return heroAttackActions; } private List<GameAction> getHeroPowerActions(GameContext context, Player player) { List<GameAction> heroPowerActions = new ArrayList<GameAction>(); HeroPower heroPower = player.getHero().getHeroPower(); heroPower.onWillUse(context, player); CardReference heroPowerReference = new CardReference(player.getId(), CardLocation.HERO_POWER, heroPower.getId(), heroPower.getName()); if (!context.getLogic().canPlayCard(player.getId(), heroPowerReference)) { return heroPowerActions; } if (heroPower.hasAttribute(Attribute.CHOOSE_ONE)) { IChooseOneCard chooseOneCard = (IChooseOneCard) heroPower; for (GameAction chooseOneAction : chooseOneCard.playOptions()) { rollout(chooseOneAction, context, player, heroPowerActions); } } else { rollout(heroPower.play(), context, player, heroPowerActions); } return heroPowerActions; } private List<GameAction> getPhysicalAttackActions(GameContext context, Player player) { List<GameAction> physicalAttackActions = new ArrayList<GameAction>(); physicalAttackActions.addAll(getHeroAttackActions(context, player)); for (Minion minion : player.getMinions()) { if (!minion.canAttackThisTurn()) { continue; } rollout(new PhysicalAttackAction(minion.getReference()), context, player, physicalAttackActions); } return physicalAttackActions; } private List<GameAction> getPlayCardActions(GameContext context, Player player) { List<GameAction> playCardActions = new ArrayList<GameAction>(); playCardActions.addAll(getHeroPowerActions(context, player)); for (Card card : player.getHand()) { CardReference cardReference = new CardReference(player.getId(), CardLocation.HAND, card.getId(), card.getName()); if (!context.getLogic().canPlayCard(player.getId(), cardReference)) { continue; } if (card.hasAttribute(Attribute.CHOOSE_ONE)) { IChooseOneCard chooseOneCard = (IChooseOneCard) card; if (context.getLogic().hasAttribute(player, Attribute.BOTH_CHOOSE_ONE_OPTIONS) && chooseOneCard.hasBothOptions()) { GameAction chooseOneAction = chooseOneCard.playBothOptions(); rollout(chooseOneAction, context, player, playCardActions); } else { for (GameAction chooseOneAction : chooseOneCard.playOptions()) { rollout(chooseOneAction, context, player, playCardActions); } } } else { rollout(card.play(), context, player, playCardActions); } } return playCardActions; } public List<GameAction> getValidActions(GameContext context, Player player) { List<GameAction> validActions = new ArrayList<GameAction>(); validActions.addAll(getPhysicalAttackActions(context, player)); validActions.addAll(getPlayCardActions(context, player)); if (context.getTurnState() != TurnState.TURN_ENDED) { validActions.add(new EndTurnAction()); } return validActions; } public boolean hasAutoHeroPower(GameContext context, Player player) { HeroPower heroPower = player.getHero().getHeroPower(); heroPower.onWillUse(context, player); CardReference heroPowerReference = new CardReference(player.getId(), CardLocation.HERO_POWER, heroPower.getId(), heroPower.getName()); return (context.getLogic().canPlayCard(player.getId(), heroPowerReference) && heroPower.getTargetRequirement() == TargetSelection.AUTO); } public void rollout(GameAction action, GameContext context, Player player, Collection<GameAction> actions) { context.getLogic().processTargetModifiers(player, action); if (action.getTargetRequirement() == TargetSelection.NONE || action.getTargetRequirement() == TargetSelection.AUTO) { actions.add(action); } else { for (Entity validTarget : targetLogic.getValidTargets(context, player, action)) { GameAction rolledOutAction = action.clone(); rolledOutAction.setTarget(validTarget); actions.add(rolledOutAction); } } } }