mirror of
https://github.com/magefree/mage.git
synced 2026-01-23 03:39:54 -08:00
[mad ai] migrating to static attack\block algorithm
This commit is contained in:
parent
c60eb4d131
commit
f5acfcc58a
13 changed files with 135 additions and 78 deletions
|
|
@ -54,6 +54,7 @@ import mage.game.turn.*;
|
|||
import mage.player.ai.ma.optimizers.TreeOptimizer;
|
||||
import mage.player.ai.ma.optimizers.impl.EquipOptimizer;
|
||||
import mage.player.ai.ma.optimizers.impl.LevelUpOptimizer;
|
||||
import mage.player.ai.util.CombatUtil;
|
||||
import mage.players.Player;
|
||||
import mage.target.Target;
|
||||
import mage.target.TargetCard;
|
||||
|
|
@ -126,7 +127,6 @@ public class ComputerPlayer6 extends ComputerPlayer<ComputerPlayer6> implements
|
|||
pass();
|
||||
return false;
|
||||
case PRECOMBAT_MAIN:
|
||||
case DECLARE_BLOCKERS:
|
||||
case POSTCOMBAT_MAIN:
|
||||
if (game.getActivePlayerId().equals(playerId)) {
|
||||
printOutState(game, playerId);
|
||||
|
|
@ -140,22 +140,26 @@ public class ComputerPlayer6 extends ComputerPlayer<ComputerPlayer6> implements
|
|||
pass();
|
||||
}
|
||||
return false;
|
||||
case BEGIN_COMBAT:
|
||||
case BEGIN_COMBAT:
|
||||
case FIRST_COMBAT_DAMAGE:
|
||||
case COMBAT_DAMAGE:
|
||||
case END_COMBAT:
|
||||
pass();
|
||||
return false;
|
||||
case DECLARE_ATTACKERS:
|
||||
if (!game.getActivePlayerId().equals(playerId)) {
|
||||
printOutState(game, playerId);
|
||||
printOutState(game, game.getOpponents(playerId).iterator().next());
|
||||
if (actions.size() == 0) {
|
||||
calculateActions(game);
|
||||
}
|
||||
act(game);
|
||||
case DECLARE_ATTACKERS:
|
||||
if (game.getActivePlayerId().equals(playerId)) {
|
||||
declareAttackers(game, playerId);
|
||||
pass();
|
||||
return true;
|
||||
} else {
|
||||
pass();
|
||||
}
|
||||
return false;
|
||||
case DECLARE_BLOCKERS:
|
||||
if (!game.getActivePlayerId().equals(playerId)) {
|
||||
declareBlockers(game, playerId);
|
||||
pass();
|
||||
return true;
|
||||
//printOutState(game, playerId);
|
||||
} else {
|
||||
pass();
|
||||
}
|
||||
|
|
@ -729,51 +733,10 @@ public class ComputerPlayer6 extends ComputerPlayer<ComputerPlayer6> implements
|
|||
}
|
||||
if (!game.getStep().skipStep(game, game.getActivePlayerId())) {
|
||||
if (game.getTurn().getStepType() == PhaseStep.DECLARE_ATTACKERS) {
|
||||
game.fireEvent(new GameEvent(GameEvent.EventType.DECLARE_ATTACKERS_STEP_PRE, null, null, activePlayerId));
|
||||
if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.DECLARING_ATTACKERS, activePlayerId, activePlayerId))) {
|
||||
for (Combat engagement: ((SimulatedPlayer2)game.getPlayer(activePlayerId)).addAttackers(game)) {
|
||||
Game sim = game.copy();
|
||||
UUID defenderId = game.getOpponents(playerId).iterator().next();
|
||||
for (CombatGroup group: engagement.getGroups()) {
|
||||
for (UUID attackerId: group.getAttackers()) {
|
||||
sim.getPlayer(activePlayerId).declareAttacker(attackerId, defenderId, sim);
|
||||
}
|
||||
}
|
||||
sim.fireEvent(GameEvent.getEvent(GameEvent.EventType.DECLARED_ATTACKERS, playerId, playerId));
|
||||
SimulationNode2 newNode = new SimulationNode2(node, sim, node.getDepth()-1, activePlayerId);
|
||||
logger.debug("simulating -- node #:" + SimulationNode2.getCount() + " declare attakers");
|
||||
newNode.setCombat(sim.getCombat());
|
||||
node.children.add(newNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (game.getTurn().getStepType() == PhaseStep.DECLARE_BLOCKERS) {
|
||||
game.fireEvent(new GameEvent(GameEvent.EventType.DECLARE_BLOCKERS_STEP_PRE, null, null, activePlayerId));
|
||||
if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.DECLARING_BLOCKERS, activePlayerId, activePlayerId))) {
|
||||
for (UUID defenderId: game.getCombat().getDefenders()) {
|
||||
//check if defender is being attacked
|
||||
if (game.getCombat().isAttacked(defenderId, game)) {
|
||||
for (Combat engagement: ((SimulatedPlayer2)game.getPlayer(defenderId)).addBlockers(game)) {
|
||||
Game sim = game.copy();
|
||||
for (CombatGroup group: engagement.getGroups()) {
|
||||
List<UUID> blockers = new ArrayList<UUID>();
|
||||
blockers.addAll(group.getBlockers());
|
||||
for (UUID blockerId: blockers) {
|
||||
group.addBlocker(blockerId, defenderId, sim);
|
||||
}
|
||||
blockers = null;
|
||||
}
|
||||
sim.fireEvent(GameEvent.getEvent(GameEvent.EventType.DECLARED_BLOCKERS, playerId, playerId));
|
||||
SimulationNode2 newNode = new SimulationNode2(node, sim, node.getDepth()-1, defenderId);
|
||||
logger.debug("simulating -- node #:" + SimulationNode2.getCount() + " declare blockers");
|
||||
newNode.setCombat(sim.getCombat());
|
||||
node.children.add(newNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
declareAttackers(game, activePlayerId, node);
|
||||
} else if (game.getTurn().getStepType() == PhaseStep.DECLARE_BLOCKERS) {
|
||||
declareBlockers(game, activePlayerId, node);
|
||||
} else {
|
||||
game.getStep().beginStep(game, activePlayerId);
|
||||
}
|
||||
if (game.getStep().getHasPriority())
|
||||
|
|
@ -786,7 +749,104 @@ public class ComputerPlayer6 extends ComputerPlayer<ComputerPlayer6> implements
|
|||
game.checkStateAndTriggered();
|
||||
}
|
||||
|
||||
@Override
|
||||
private void declareBlockers(Game game, UUID activePlayerId) {
|
||||
game.fireEvent(new GameEvent(GameEvent.EventType.DECLARE_BLOCKERS_STEP_PRE, null, null, activePlayerId));
|
||||
if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.DECLARING_BLOCKERS, activePlayerId, activePlayerId))) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void declareBlockers(Game game, UUID activePlayerId, SimulationNode2 node) {
|
||||
game.fireEvent(new GameEvent(GameEvent.EventType.DECLARE_BLOCKERS_STEP_PRE, null, null, activePlayerId));
|
||||
if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.DECLARING_BLOCKERS, activePlayerId, activePlayerId))) {
|
||||
/*for (UUID defenderId: game.getCombat().getDefenders()) {
|
||||
//check if defender is being attacked
|
||||
if (game.getCombat().isAttacked(defenderId, game)) {
|
||||
for (Combat engagement: ((SimulatedPlayer2)game.getPlayer(defenderId)).addBlockers(game)) {
|
||||
Game sim = game.copy();
|
||||
for (CombatGroup group: engagement.getGroups()) {
|
||||
List<UUID> blockers = new ArrayList<UUID>();
|
||||
blockers.addAll(group.getBlockers());
|
||||
for (UUID blockerId: blockers) {
|
||||
group.addBlocker(blockerId, defenderId, sim);
|
||||
}
|
||||
blockers = null;
|
||||
}
|
||||
sim.fireEvent(GameEvent.getEvent(GameEvent.EventType.DECLARED_BLOCKERS, playerId, playerId));
|
||||
SimulationNode2 newNode = new SimulationNode2(node, sim, node.getDepth()-1, defenderId);
|
||||
logger.debug("simulating -- node #:" + SimulationNode2.getCount() + " declare blockers");
|
||||
newNode.setCombat(sim.getCombat());
|
||||
node.children.add(newNode);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Choose attackers based on static information.
|
||||
* That means that AI won't look to the future as it was before, but just choose attackers based on current state
|
||||
* of the game. This is worse, but at least it is easier to implement and won't lead to the case when AI doesn't
|
||||
* do anything - neither attack nor block.
|
||||
*
|
||||
* @param game
|
||||
* @param activePlayerId
|
||||
*/
|
||||
private void declareAttackers(Game game, UUID activePlayerId) {
|
||||
game.fireEvent(new GameEvent(GameEvent.EventType.DECLARE_ATTACKERS_STEP_PRE, null, null, activePlayerId));
|
||||
if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.DECLARING_ATTACKERS, activePlayerId, activePlayerId))) {
|
||||
|
||||
Player attackingPlayer = game.getPlayer(activePlayerId);
|
||||
UUID defenderId = game.getOpponents(playerId).iterator().next();
|
||||
Player defender = game.getPlayer(defenderId);
|
||||
|
||||
List<Permanent> attackersList = super.getAvailableAttackers(game);
|
||||
if (attackersList.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<Permanent> possibleBlockers = defender.getAvailableBlockers(game);
|
||||
|
||||
List<Permanent> killers = CombatUtil.canKillOpponent(game, attackersList, possibleBlockers, defender);
|
||||
if (!killers.isEmpty()) {
|
||||
for (Permanent attacker : killers) {
|
||||
attackingPlayer.declareAttacker(attacker.getId(), defenderId, game);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
CombatUtil.handleExalted();
|
||||
|
||||
int aggressionRate = 5;
|
||||
for (Permanent attacker : attackersList) {
|
||||
if (aggressionRate == 5) {
|
||||
attackingPlayer.declareAttacker(attacker.getId(), defenderId, game);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void declareAttackers(Game game, UUID activePlayerId, SimulationNode2 node) {
|
||||
game.fireEvent(new GameEvent(GameEvent.EventType.DECLARE_ATTACKERS_STEP_PRE, null, null, activePlayerId));
|
||||
if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.DECLARING_ATTACKERS, activePlayerId, activePlayerId))) {
|
||||
for (Combat engagement: ((SimulatedPlayer2)game.getPlayer(activePlayerId)).addAttackers(game)) {
|
||||
Game sim = game.copy();
|
||||
UUID defenderId = game.getOpponents(playerId).iterator().next();
|
||||
for (CombatGroup group: engagement.getGroups()) {
|
||||
for (UUID attackerId: group.getAttackers()) {
|
||||
sim.getPlayer(activePlayerId).declareAttacker(attackerId, defenderId, sim);
|
||||
}
|
||||
}
|
||||
sim.fireEvent(GameEvent.getEvent(GameEvent.EventType.DECLARED_ATTACKERS, playerId, playerId));
|
||||
SimulationNode2 newNode = new SimulationNode2(node, sim, node.getDepth()-1, activePlayerId);
|
||||
logger.debug("simulating -- node #:" + SimulationNode2.getCount() + " declare attakers");
|
||||
newNode.setCombat(sim.getCombat());
|
||||
node.children.add(newNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void selectAttackers(Game game) {
|
||||
logger.debug("selectAttackers");
|
||||
if (combat != null) {
|
||||
|
|
|
|||
|
|
@ -29,22 +29,16 @@
|
|||
package mage.player.ai;
|
||||
|
||||
import mage.Constants.AbilityType;
|
||||
import mage.Constants.PhaseStep;
|
||||
import mage.Constants.RangeOfInfluence;
|
||||
import mage.Constants.Zone;
|
||||
import mage.abilities.Ability;
|
||||
import mage.filter.FilterAbility;
|
||||
import mage.game.Game;
|
||||
import mage.game.combat.Combat;
|
||||
import mage.game.combat.CombatGroup;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.turn.*;
|
||||
import mage.players.Player;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
@ -243,24 +237,27 @@ public class ComputerPlayer7 extends ComputerPlayer6 implements Player {
|
|||
val = testScore;
|
||||
}
|
||||
else {
|
||||
switch (game.getTurn().getStepType()) {
|
||||
/*switch (game.getTurn().getStepType()) {
|
||||
case PRECOMBAT_MAIN:
|
||||
val = simulateCombat(game, node, depth-1, alpha, beta, false);
|
||||
break;
|
||||
case POSTCOMBAT_MAIN:
|
||||
//val = simulateCounterAttack(game, node, depth-1, alpha, beta);
|
||||
//break;
|
||||
val = simulateCounterAttack(game, node, depth-1, alpha, beta);
|
||||
break;
|
||||
default:
|
||||
val = GameStateEvaluator2.evaluate(playerId, game);
|
||||
break;
|
||||
}
|
||||
}*/
|
||||
val = GameStateEvaluator2.evaluate(playerId, game);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (game.getTurn().getStepType() == PhaseStep.DECLARE_ATTACKERS)
|
||||
val = GameStateEvaluator2.evaluate(playerId, game);
|
||||
/*if (game.getTurn().getStepType() == PhaseStep.DECLARE_ATTACKERS)
|
||||
val = simulateBlockers(game, node, playerId, depth-1, alpha, beta, true);
|
||||
else
|
||||
val = GameStateEvaluator2.evaluate(playerId, game);
|
||||
*/
|
||||
}
|
||||
}
|
||||
else if (node.getChildren().size() > 0) {
|
||||
|
|
@ -278,7 +275,7 @@ public class ComputerPlayer7 extends ComputerPlayer6 implements Player {
|
|||
|
||||
}
|
||||
|
||||
protected int simulateCombat(Game game, SimulationNode2 node, int depth, int alpha, int beta, boolean counter) {
|
||||
/*protected int simulateCombat(Game game, SimulationNode2 node, int depth, int alpha, int beta, boolean counter) {
|
||||
Integer val = null;
|
||||
if (Thread.interrupted()) {
|
||||
Thread.currentThread().interrupt();
|
||||
|
|
@ -320,10 +317,10 @@ public class ComputerPlayer7 extends ComputerPlayer6 implements Player {
|
|||
if (logger.isDebugEnabled())
|
||||
logger.debug("returning -- combat score: " + val + " depth:" + depth + " for player:" + game.getPlayer(node.getPlayerId()).getName());
|
||||
return val;
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
protected int simulateAttackers(Game game, SimulationNode2 node, UUID attackerId, int depth, int alpha, int beta, boolean counter) {
|
||||
/*protected int simulateAttackers(Game game, SimulationNode2 node, UUID attackerId, int depth, int alpha, int beta, boolean counter) {
|
||||
if (Thread.interrupted()) {
|
||||
Thread.currentThread().interrupt();
|
||||
logger.debug("interrupted");
|
||||
|
|
@ -395,9 +392,9 @@ public class ComputerPlayer7 extends ComputerPlayer6 implements Player {
|
|||
if (logger.isDebugEnabled())
|
||||
logger.debug("returning -- combat attacker score: " + val + " depth:" + depth + " for player:" + game.getPlayer(node.getPlayerId()).getName());
|
||||
return val;
|
||||
}
|
||||
}*/
|
||||
|
||||
protected int simulateBlockers(Game game, SimulationNode2 node, UUID defenderId, int depth, int alpha, int beta, boolean counter) {
|
||||
/*protected int simulateBlockers(Game game, SimulationNode2 node, UUID defenderId, int depth, int alpha, int beta, boolean counter) {
|
||||
if (Thread.interrupted()) {
|
||||
Thread.currentThread().interrupt();
|
||||
logger.debug("interrupted");
|
||||
|
|
@ -474,9 +471,9 @@ public class ComputerPlayer7 extends ComputerPlayer6 implements Player {
|
|||
if (logger.isDebugEnabled())
|
||||
logger.debug("returning -- combat blocker score: " + val + " depth:" + depth + " for player:" + game.getPlayer(node.getPlayerId()).getName());
|
||||
return val;
|
||||
}
|
||||
}*/
|
||||
|
||||
protected int simulateCounterAttack(Game game, SimulationNode2 node, int depth, int alpha, int beta) {
|
||||
/*protected int simulateCounterAttack(Game game, SimulationNode2 node, int depth, int alpha, int beta) {
|
||||
if (Thread.interrupted()) {
|
||||
Thread.currentThread().interrupt();
|
||||
logger.debug("interrupted");
|
||||
|
|
@ -501,7 +498,7 @@ public class ComputerPlayer7 extends ComputerPlayer6 implements Player {
|
|||
if (val == null)
|
||||
val = GameStateEvaluator2.evaluate(playerId, game);
|
||||
return val;
|
||||
}
|
||||
}*/
|
||||
|
||||
protected void simulateStep(Game game, Step step) {
|
||||
if (Thread.interrupted()) {
|
||||
|
|
@ -523,7 +520,7 @@ public class ComputerPlayer7 extends ComputerPlayer6 implements Player {
|
|||
}
|
||||
}
|
||||
|
||||
protected void finishCombat(Game game) {
|
||||
/*protected void finishCombat(Game game) {
|
||||
if (Thread.interrupted()) {
|
||||
Thread.currentThread().interrupt();
|
||||
logger.debug("interrupted");
|
||||
|
|
@ -532,7 +529,7 @@ public class ComputerPlayer7 extends ComputerPlayer6 implements Player {
|
|||
simulateStep(game, new FirstCombatDamageStep());
|
||||
simulateStep(game, new CombatDamageStep());
|
||||
simulateStep(game, new EndOfCombatStep());
|
||||
}
|
||||
}*/
|
||||
|
||||
protected int simulatePostCombatMain(Game game, SimulationNode2 node, int depth, int alpha, int beta) {
|
||||
if (Thread.interrupted()) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue