mirror of
https://github.com/magefree/mage.git
synced 2025-12-22 03:22:00 -08:00
* Fixed that attacker has not always to assign all damage to multiple blockers. Improved AI behaviour of assigning damage to multiple blockers. Tries to kill blocker if possible now.
This commit is contained in:
parent
06caf2179d
commit
d02f272bca
7 changed files with 82 additions and 13 deletions
|
|
@ -1388,5 +1388,55 @@ public class ComputerPlayer6 extends ComputerPlayer implements Player {
|
|||
super.cleanUpOnMatchEnd();
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID chooseBlockerOrder(List<Permanent> blockers, CombatGroup combatGroup, List<UUID> blockerOrder, Game game) {
|
||||
if (combatGroup.getAttackers().size() == 1) {
|
||||
Permanent attacker = game.getPermanent(combatGroup.getAttackers().get(0));
|
||||
boolean attackerDeathtouch = attacker.getAbilities().containsKey(DeathtouchAbility.getInstance().getId());
|
||||
// boolean attackerFirstStrike = attacker.getAbilities().containsKey(FirstStrikeAbility.getInstance().getId());
|
||||
List<Permanent> blockerAlreadySet = getAlreadyBlockingPermanents(blockerOrder, game);
|
||||
int powerAlreadyNeeded = getPowerAlreadyNeeded(blockerAlreadySet, attackerDeathtouch);
|
||||
int powerLeftToKill = attacker.getPower().getValue() - powerAlreadyNeeded;
|
||||
// no possible damage left, order doesn't matter
|
||||
if (powerLeftToKill <= 0) {
|
||||
return blockers.iterator().next().getId();
|
||||
}
|
||||
for (Permanent blocker: blockers) {
|
||||
if (attackerDeathtouch || powerLeftToKill >= blocker.getToughness().getValue()) {
|
||||
if (!blocker.getAbilities().containsKey(IndestructibleAbility.getInstance().getId())) {
|
||||
return blocker.getId();
|
||||
}
|
||||
}
|
||||
}
|
||||
// Can't kill a blocker so it doesn't matter
|
||||
return blockers.iterator().next().getId();
|
||||
} else { // multiple attackers (like banding)
|
||||
//TODO: improve this
|
||||
return blockers.iterator().next().getId();
|
||||
}
|
||||
}
|
||||
|
||||
private List<Permanent> getAlreadyBlockingPermanents(List<UUID> blockerOrder, Game game) {
|
||||
List<Permanent> blockerAlreadySet = new ArrayList<>();
|
||||
for (UUID uuid :blockerOrder) {
|
||||
Permanent permanent = game.getPermanent(uuid);
|
||||
if (permanent != null) {
|
||||
blockerAlreadySet.add(permanent);
|
||||
}
|
||||
}
|
||||
return blockerAlreadySet;
|
||||
}
|
||||
|
||||
private int getPowerAlreadyNeeded(List<Permanent> blockerAlreadySet, boolean attackerDeathtouch) {
|
||||
int toughnessAlreadyNeeded = 0;
|
||||
if (attackerDeathtouch) {
|
||||
return blockerAlreadySet.size();
|
||||
}
|
||||
for (Permanent creature : blockerAlreadySet) {
|
||||
toughnessAlreadyNeeded += creature.getToughness().getValue();
|
||||
}
|
||||
return toughnessAlreadyNeeded;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@ import java.util.*;
|
|||
import java.util.HashSet;
|
||||
import java.util.Map.Entry;
|
||||
import mage.abilities.costs.VariableCost;
|
||||
import mage.abilities.keyword.DeathtouchAbility;
|
||||
import mage.abilities.keyword.FlashAbility;
|
||||
import mage.cards.repository.ExpansionInfo;
|
||||
import mage.cards.repository.ExpansionRepository;
|
||||
|
|
@ -1388,7 +1389,7 @@ public class ComputerPlayer extends PlayerImpl implements Player {
|
|||
}
|
||||
|
||||
@Override
|
||||
public UUID chooseBlockerOrder(List<Permanent> blockers, Game game) {
|
||||
public UUID chooseBlockerOrder(List<Permanent> blockers, CombatGroup combatGroup, List<UUID> blockerOrder, Game game) {
|
||||
//TODO: improve this
|
||||
return blockers.iterator().next().getId();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -353,8 +353,9 @@ public class SimulatedPlayerMCTS extends MCTSPlayer {
|
|||
|
||||
@Override
|
||||
public boolean choosePile(Outcome outcome, String message, List<? extends Card> pile1, List<? extends Card> pile2, Game game) {
|
||||
if (this.isHuman())
|
||||
if (this.isHuman()) {
|
||||
return rnd.nextBoolean();
|
||||
}
|
||||
return super.choosePile(outcome, message, pile1, pile2, game);
|
||||
}
|
||||
|
||||
|
|
@ -408,16 +409,18 @@ public class SimulatedPlayerMCTS extends MCTSPlayer {
|
|||
|
||||
@Override
|
||||
public UUID chooseAttackerOrder(List<Permanent> attackers, Game game) {
|
||||
if (this.isHuman())
|
||||
if (this.isHuman()) {
|
||||
return attackers.get(rnd.nextInt(attackers.size())).getId();
|
||||
}
|
||||
return super.chooseAttackerOrder(attackers, game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID chooseBlockerOrder(List<Permanent> blockers, Game game) {
|
||||
if (this.isHuman())
|
||||
public UUID chooseBlockerOrder(List<Permanent> blockers, CombatGroup combatGroup, List<UUID> blockerOrder, Game game) {
|
||||
if (this.isHuman()) {
|
||||
return blockers.get(rnd.nextInt(blockers.size())).getId();
|
||||
return super.chooseBlockerOrder(blockers, game);
|
||||
}
|
||||
return super.chooseBlockerOrder(blockers, combatGroup, blockerOrder, game);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -450,14 +453,16 @@ public class SimulatedPlayerMCTS extends MCTSPlayer {
|
|||
targets.remove(targetId);
|
||||
}
|
||||
}
|
||||
else
|
||||
else {
|
||||
super.assignDamage(damage, targets, singleTargetName, sourceId, game);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAmount(int min, int max, String message, Game game) {
|
||||
if (this.isHuman())
|
||||
if (this.isHuman()) {
|
||||
return rnd.nextInt(max - min) + min;
|
||||
}
|
||||
return super.getAmount(min, max, message, game);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -764,7 +764,7 @@ public class HumanPlayer extends PlayerImpl {
|
|||
|
||||
|
||||
@Override
|
||||
public UUID chooseBlockerOrder(List<Permanent> blockers, Game game) {
|
||||
public UUID chooseBlockerOrder(List<Permanent> blockers, CombatGroup combatGroup, List<UUID> blockerOrder, Game game) {
|
||||
updateGameStatePriority("chooseBlockerOrder", game);
|
||||
while (!abort) {
|
||||
game.fireSelectTargetEvent(playerId, "Pick blocker", blockers, true);
|
||||
|
|
|
|||
|
|
@ -384,7 +384,7 @@ public class RandomPlayer extends ComputerPlayer {
|
|||
}
|
||||
|
||||
@Override
|
||||
public UUID chooseBlockerOrder(List<Permanent> blockers, Game game) {
|
||||
public UUID chooseBlockerOrder(List<Permanent> blockers, CombatGroup combatGroup, List<UUID> blockerOrder, Game game) {
|
||||
return blockers.get(rnd.nextInt(blockers.size())).getId();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -304,12 +304,16 @@ public class CombatGroup implements Serializable, Copyable<CombatGroup> {
|
|||
}
|
||||
if (damage > 0 && hasTrample(attacker)) {
|
||||
defenderDamage(attacker, damage, game);
|
||||
} else {
|
||||
// Assign the damge left to first blocker
|
||||
int alreadyAssigned = assigned.get(blockerOrder.get(0));
|
||||
assigned.replace(blockerOrder.get(0), damage + alreadyAssigned);
|
||||
}
|
||||
}
|
||||
for (UUID blockerId: blockerOrder) {
|
||||
Integer power = blockerPower.get(blockerId);
|
||||
if (power != null) {
|
||||
attacker.markDamage(power.intValue(), blockerId, game, true, true);
|
||||
attacker.markDamage(power, blockerId, game, true, true);
|
||||
}
|
||||
}
|
||||
for (Map.Entry<UUID, Integer> entry : assigned.entrySet()) {
|
||||
|
|
@ -448,7 +452,7 @@ public class CombatGroup implements Serializable, Copyable<CombatGroup> {
|
|||
for (UUID blockerId: blockerList) {
|
||||
blockerPerms.add(game.getPermanent(blockerId));
|
||||
}
|
||||
UUID blockerId = player.chooseBlockerOrder(blockerPerms, game);
|
||||
UUID blockerId = player.chooseBlockerOrder(blockerPerms, this, blockerOrder, game);
|
||||
blockerOrder.add(blockerId);
|
||||
blockerList.remove(blockerId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ import mage.util.Copyable;
|
|||
|
||||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
import mage.game.combat.CombatGroup;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
@ -312,7 +313,15 @@ public interface Player extends MageItem, Copyable<Player> {
|
|||
void selectAttackers(Game game, UUID attackingPlayerId);
|
||||
void selectBlockers(Game game, UUID defendingPlayerId);
|
||||
UUID chooseAttackerOrder(List<Permanent> attacker, Game game);
|
||||
UUID chooseBlockerOrder(List<Permanent> blockers, Game game);
|
||||
/**
|
||||
* Choose the order in which blockers get damage assigned to
|
||||
* @param blockers list of blockers where to choose the next one from
|
||||
* @param combatGroup the concerning combat group
|
||||
* @param blockerOrder the already set order of blockers
|
||||
* @param game
|
||||
* @return blocker next to add to the blocker order
|
||||
*/
|
||||
UUID chooseBlockerOrder(List<Permanent> blockers, CombatGroup combatGroup, List<UUID> blockerOrder, Game game);
|
||||
void assignDamage(int damage, List<UUID> targets, String singleTargetName, UUID sourceId, Game game);
|
||||
int getAmount(int min, int max, String message, Game game);
|
||||
void sideboard(Match match, Deck deck);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue