use of mage.game.Game in project mage by magefree.
the class ComputerPlayer2 method simulatePriority.
protected int simulatePriority(SimulationNode node, Game game, int alpha, int beta) {
// NOT USED in real AI, see ComputerPlayer6
if (Thread.interrupted()) {
Thread.currentThread().interrupt();
logger.debug(indent(node.depth) + "interrupted");
return GameStateEvaluator.evaluate(playerId, game);
}
node.setGameValue(game.getState().getValue(true).hashCode());
SimulatedPlayer currentPlayer = (SimulatedPlayer) game.getPlayer(game.getPlayerList().get());
boolean isSimulatedPlayer = currentPlayer.getId().equals(playerId);
logger.debug(indent(node.depth) + "simulating priority -- player " + currentPlayer.getName());
SimulationNode bestNode = null;
List<Ability> allActions = currentPlayer.simulatePriority(game);
if (logger.isDebugEnabled())
logger.debug(indent(node.depth) + "simulating -- adding " + allActions.size() + " children:" + allActions);
for (Ability action : allActions) {
if (Thread.interrupted()) {
Thread.currentThread().interrupt();
logger.debug(indent(node.depth) + "interrupted");
break;
}
Game sim = game.copy();
if (sim.getPlayer(currentPlayer.getId()).activateAbility((ActivatedAbility) action.copy(), sim)) {
sim.applyEffects();
if (checkForUselessAction(sim, node, action, currentPlayer.getId())) {
logger.debug(indent(node.depth) + "found useless action: " + action);
continue;
}
if (!sim.checkIfGameIsOver() && action.isUsesStack()) {
// only pass if the last action uses the stack
sim.getPlayer(currentPlayer.getId()).pass(game);
sim.getPlayerList().getNext();
}
SimulationNode newNode = new SimulationNode(node, sim, action, currentPlayer.getId());
if (logger.isDebugEnabled())
logger.debug(indent(newNode.depth) + "simulating -- node #:" + SimulationNode.getCount() + " actions:" + action);
sim.checkStateAndTriggered();
int val = addActions(newNode, alpha, beta);
if (!isSimulatedPlayer) {
if (val < beta) {
beta = val;
bestNode = newNode;
node.setCombat(newNode.getCombat());
}
if (val == GameStateEvaluator.LOSE_SCORE) {
logger.debug(indent(node.depth) + "simulating -- lose, can't do worse than this");
break;
}
} else {
if (val > alpha) {
alpha = val;
bestNode = newNode;
node.setCombat(newNode.getCombat());
if (!node.getTargets().isEmpty())
targets = node.getTargets();
if (!node.getChoices().isEmpty())
choices = node.getChoices();
}
if (val == GameStateEvaluator.WIN_SCORE) {
logger.debug(indent(node.depth) + "simulating -- win, can't do better than this");
break;
}
}
if (alpha >= beta) {
logger.debug(indent(node.depth) + "simulating -- pruning");
break;
}
// if (SimulationNode.nodeCount > maxNodes) {
// logger.debug(indent(node.depth) + "simulating -- reached end-state");
// break;
// }
}
}
if (bestNode != null) {
node.children.clear();
node.children.add(bestNode);
}
if (!isSimulatedPlayer) {
logger.debug(indent(node.depth) + "returning priority beta: " + beta);
return beta;
} else {
logger.debug(indent(node.depth) + "returning priority alpha: " + alpha);
return alpha;
}
}
use of mage.game.Game in project mage by magefree.
the class SimulatedPlayer method addAbilityNode.
protected void addAbilityNode(SimulationNode parent, Ability ability, Game game) {
Game sim = game.copy();
sim.getStack().push(new StackAbility(ability, playerId));
ability.activate(sim, false);
if (ability.activate(sim, false) && ability.isUsesStack()) {
game.fireEvent(new GameEvent(GameEvent.EventType.TRIGGERED_ABILITY, ability.getId(), ability, ability.getControllerId()));
}
sim.applyEffects();
SimulationNode newNode = new SimulationNode(parent, sim, playerId);
logger.debug(indent(newNode.getDepth()) + "simulating -- node #:" + SimulationNode.getCount() + " triggered ability option");
for (Target target : ability.getTargets()) {
for (UUID targetId : target.getTargets()) {
newNode.getTargets().add(targetId);
}
}
parent.children.add(newNode);
}
use of mage.game.Game in project mage by magefree.
the class SimulatedPlayer method addBlocker.
protected void addBlocker(Game game, List<Permanent> blockers, Map<Integer, Combat> engagements) {
if (blockers.isEmpty())
return;
int numGroups = game.getCombat().getGroups().size();
// try to block each attacker with each potential blocker
Permanent blocker = blockers.get(0);
if (logger.isDebugEnabled())
logger.debug("simulating -- block:" + blocker);
List<Permanent> remaining = remove(blockers, blocker);
for (int i = 0; i < numGroups; i++) {
if (game.getCombat().getGroups().get(i).canBlock(blocker, game)) {
Game sim = game.copy();
sim.getCombat().getGroups().get(i).addBlocker(blocker.getId(), playerId, sim);
if (engagements.put(sim.getCombat().getValue().hashCode(), sim.getCombat()) != null)
logger.debug("simulating -- found redundant block combination");
// and recurse minus the used blocker
addBlocker(sim, remaining, engagements);
}
}
addBlocker(game, remaining, engagements);
}
use of mage.game.Game in project mage by magefree.
the class SimulatedPlayer method addAttackers.
/*@Override
public boolean playXMana(VariableManaCost cost, ManaCosts<ManaCost> costs, Game game) {
//simulateVariableCosts method adds a generic mana cost for each option
for (ManaCost manaCost: costs) {
if (manaCost instanceof GenericManaCost) {
cost.setPayment(manaCost.getPayment());
logger.debug("simulating -- X = " + cost.getPayment().count());
break;
}
}
cost.setPaid();
return true;
}*/
public List<Combat> addAttackers(Game game) {
Map<Integer, Combat> engagements = new HashMap<>();
// useful only for two player games - will only attack first opponent
UUID defenderId = game.getOpponents(playerId).iterator().next();
List<Permanent> attackersList = super.getAvailableAttackers(defenderId, game);
// use binary digits to calculate powerset of attackers
int powerElements = (int) Math.pow(2, attackersList.size());
StringBuilder binary = new StringBuilder();
for (int i = powerElements - 1; i >= 0; i--) {
Game sim = game.copy();
binary.setLength(0);
binary.append(Integer.toBinaryString(i));
while (binary.length() < attackersList.size()) {
binary.insert(0, '0');
}
for (int j = 0; j < attackersList.size(); j++) {
if (binary.charAt(j) == '1') {
// makes it possible to UNDO a declared attacker with costs from e.g. Propaganda
setStoredBookmark(sim.bookmarkState());
if (!sim.getCombat().declareAttacker(attackersList.get(j).getId(), defenderId, playerId, sim)) {
sim.undo(playerId);
}
}
}
if (engagements.put(sim.getCombat().getValue().hashCode(), sim.getCombat()) != null) {
logger.debug("simulating -- found redundant attack combination");
} else if (logger.isDebugEnabled()) {
logger.debug("simulating -- attack:" + sim.getCombat().getGroups().size());
}
}
return new ArrayList<>(engagements.values());
}
use of mage.game.Game in project mage by magefree.
the class ComputerPlayer3 method calculatePreCombatActions.
protected void calculatePreCombatActions(Game game) {
if (!getNextAction(game)) {
currentScore = GameStateEvaluator.evaluate(playerId, game);
Game sim = createSimulation(game);
SimulationNode.resetCount();
root = new SimulationNode(null, sim, playerId);
logger.debug("simulating pre combat actions -----------------------------------------------------------------------------------------");
if (!isTestMode)
addActionsTimed();
else
addActions(root, Integer.MIN_VALUE, Integer.MAX_VALUE);
logger.info(name + " simulated " + nodeCount + " nodes in " + thinkTime / 1000000000.0 + "s - average " + nodeCount / (thinkTime / 1000000000.0) + " nodes/s");
if (!root.children.isEmpty()) {
root = root.children.get(0);
actions = new LinkedList<>(root.abilities);
combat = root.combat;
if (logger.isDebugEnabled())
logger.debug("adding pre-combat actions:" + actions);
} else
logger.debug("no pre-combat actions added");
}
}
Aggregations