mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-18 19:58:00 +00:00
- Fixed accidental revert of PlayerControllerAi by r31697
This commit is contained in:
@@ -55,6 +55,7 @@ import org.apache.commons.lang3.tuple.Pair;
|
|||||||
import java.security.InvalidParameterException;
|
import java.security.InvalidParameterException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A prototype for player controller class
|
* A prototype for player controller class
|
||||||
*
|
*
|
||||||
@@ -69,7 +70,7 @@ public class PlayerControllerAi extends PlayerController {
|
|||||||
brains = new AiController(p, game);
|
brains = new AiController(p, game);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void allowCheatShuffle(boolean value) {
|
public void allowCheatShuffle(boolean value){
|
||||||
brains.allowCheatShuffle(value);
|
brains.allowCheatShuffle(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,7 +81,8 @@ public class PlayerControllerAi extends PlayerController {
|
|||||||
public SpellAbility getAbilityToPlay(Card hostCard, List<SpellAbility> abilities, ITriggerEvent triggerEvent) {
|
public SpellAbility getAbilityToPlay(Card hostCard, List<SpellAbility> abilities, ITriggerEvent triggerEvent) {
|
||||||
if (abilities.size() == 0) {
|
if (abilities.size() == 0) {
|
||||||
return null;
|
return null;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return abilities.get(0);
|
return abilities.get(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -101,20 +103,17 @@ public class PlayerControllerAi extends PlayerController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<Card, Integer> assignCombatDamage(Card attacker, CardCollectionView blockers, int damageDealt,
|
public Map<Card, Integer> assignCombatDamage(Card attacker, CardCollectionView blockers, int damageDealt, GameEntity defender, boolean overrideOrder) {
|
||||||
GameEntity defender, boolean overrideOrder) {
|
|
||||||
return ComputerUtilCombat.distributeAIDamage(attacker, blockers, damageDealt, defender, overrideOrder);
|
return ComputerUtilCombat.distributeAIDamage(attacker, blockers, damageDealt, defender, overrideOrder);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Integer announceRequirements(SpellAbility ability, String announce, boolean allowZero) {
|
public Integer announceRequirements(SpellAbility ability, String announce, boolean allowZero) {
|
||||||
// For now, these "announcements" are made within the AI classes of the
|
// For now, these "announcements" are made within the AI classes of the appropriate SA effects
|
||||||
// appropriate SA effects
|
|
||||||
if (ability.getApi() != null) {
|
if (ability.getApi() != null) {
|
||||||
switch (ability.getApi()) {
|
switch (ability.getApi()) {
|
||||||
case ChooseNumber:
|
case ChooseNumber:
|
||||||
return ability.getActivatingPlayer().isOpponentOf(player) ? 0
|
return ability.getActivatingPlayer().isOpponentOf(player) ? 0 : ComputerUtilMana.determineLeftoverMana(ability, player);
|
||||||
: ComputerUtilMana.determineLeftoverMana(ability, player);
|
|
||||||
case BidLife:
|
case BidLife:
|
||||||
return 0;
|
return 0;
|
||||||
default:
|
default:
|
||||||
@@ -125,36 +124,30 @@ public class PlayerControllerAi extends PlayerController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CardCollectionView choosePermanentsToSacrifice(SpellAbility sa, int min, int max,
|
public CardCollectionView choosePermanentsToSacrifice(SpellAbility sa, int min, int max, CardCollectionView validTargets, String message) {
|
||||||
CardCollectionView validTargets, String message) {
|
|
||||||
return ComputerUtil.choosePermanentsToSacrifice(player, validTargets, max, sa, false, min == 0);
|
return ComputerUtil.choosePermanentsToSacrifice(player, validTargets, max, sa, false, min == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CardCollectionView choosePermanentsToDestroy(SpellAbility sa, int min, int max,
|
public CardCollectionView choosePermanentsToDestroy(SpellAbility sa, int min, int max, CardCollectionView validTargets, String message) {
|
||||||
CardCollectionView validTargets, String message) {
|
|
||||||
return ComputerUtil.choosePermanentsToSacrifice(player, validTargets, max, sa, true, min == 0);
|
return ComputerUtil.choosePermanentsToSacrifice(player, validTargets, max, sa, true, min == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CardCollectionView chooseCardsForEffect(CardCollectionView sourceList, SpellAbility sa, String title,
|
public CardCollectionView chooseCardsForEffect(CardCollectionView sourceList, SpellAbility sa, String title, int min, int max, boolean isOptional) {
|
||||||
int min, int max, boolean isOptional) {
|
|
||||||
return brains.chooseCardsForEffect(sourceList, sa, min, max, isOptional);
|
return brains.chooseCardsForEffect(sourceList, sa, min, max, isOptional);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T extends GameEntity> T chooseSingleEntityForEffect(FCollectionView<T> optionList,
|
public <T extends GameEntity> T chooseSingleEntityForEffect(FCollectionView<T> optionList, DelayedReveal delayedReveal, SpellAbility sa, String title, boolean isOptional, Player targetedPlayer) {
|
||||||
DelayedReveal delayedReveal, SpellAbility sa, String title, boolean isOptional, Player targetedPlayer) {
|
|
||||||
if (delayedReveal != null) {
|
if (delayedReveal != null) {
|
||||||
reveal(delayedReveal.getCards(), delayedReveal.getZone(), delayedReveal.getOwner(),
|
reveal(delayedReveal.getCards(), delayedReveal.getZone(), delayedReveal.getOwner(), delayedReveal.getMessagePrefix());
|
||||||
delayedReveal.getMessagePrefix());
|
|
||||||
}
|
}
|
||||||
ApiType api = sa.getApi();
|
ApiType api = sa.getApi();
|
||||||
if (null == api) {
|
if (null == api) {
|
||||||
throw new InvalidParameterException("SA is not api-based, this is not supported yet");
|
throw new InvalidParameterException("SA is not api-based, this is not supported yet");
|
||||||
}
|
}
|
||||||
return SpellApiToAi.Converter.get(api).chooseSingleEntity(player, sa, (FCollection<T>) optionList, isOptional,
|
return SpellApiToAi.Converter.get(api).chooseSingleEntity(player, sa, (FCollection<T>)optionList, isOptional, targetedPlayer);
|
||||||
targetedPlayer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -172,8 +165,8 @@ public class PlayerControllerAi extends PlayerController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean confirmBidAction(SpellAbility sa, PlayerActionConfirmMode mode, String string, int bid,
|
public boolean confirmBidAction(SpellAbility sa, PlayerActionConfirmMode mode, String string,
|
||||||
Player winner) {
|
int bid, Player winner) {
|
||||||
return getAi().confirmBidAction(sa, mode, string, bid, winner);
|
return getAi().confirmBidAction(sa, mode, string, bid, winner);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,14 +176,12 @@ public class PlayerControllerAi extends PlayerController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean confirmTrigger(SpellAbility sa, Trigger regtrig, Map<String, String> triggerParams,
|
public boolean confirmTrigger(SpellAbility sa, Trigger regtrig, Map<String, String> triggerParams, boolean isMandatory) {
|
||||||
boolean isMandatory) {
|
|
||||||
if (sa.getHostCard().getName().equals("Deathmist Raptor")) {
|
if (sa.getHostCard().getName().equals("Deathmist Raptor")) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (triggerParams.containsKey("DelayedTrigger") || isMandatory) {
|
if (triggerParams.containsKey("DelayedTrigger") || isMandatory) {
|
||||||
// TODO: The only card with an optional delayed trigger is Shirei,
|
//TODO: The only card with an optional delayed trigger is Shirei, Shizo's Caretaker,
|
||||||
// Shizo's Caretaker,
|
|
||||||
// needs to be expanded when a more difficult cards comes up
|
// needs to be expanded when a more difficult cards comes up
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -210,10 +201,8 @@ public class PlayerControllerAi extends PlayerController {
|
|||||||
subtc = sub.getTargets();
|
subtc = sub.getTargets();
|
||||||
sub.resetTargets();
|
sub.resetTargets();
|
||||||
}
|
}
|
||||||
// There is no way this doTrigger here will have the same target as
|
// There is no way this doTrigger here will have the same target as stored above
|
||||||
// stored above
|
// So it's possible it's making a different decision here than will actually happen
|
||||||
// So it's possible it's making a different decision here than will
|
|
||||||
// actually happen
|
|
||||||
if (!brains.doTrigger(sa, false)) {
|
if (!brains.doTrigger(sa, false)) {
|
||||||
ret = false;
|
ret = false;
|
||||||
}
|
}
|
||||||
@@ -264,10 +253,11 @@ public class PlayerControllerAi extends PlayerController {
|
|||||||
CardCollection toBottom = new CardCollection();
|
CardCollection toBottom = new CardCollection();
|
||||||
CardCollection toTop = new CardCollection();
|
CardCollection toTop = new CardCollection();
|
||||||
|
|
||||||
for (Card c : topN) {
|
for (Card c: topN) {
|
||||||
if (ComputerUtil.scryWillMoveCardToBottomOfLibrary(player, c)) {
|
if (ComputerUtil.scryWillMoveCardToBottomOfLibrary(player, c)) {
|
||||||
toBottom.add(c);
|
toBottom.add(c);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
toTop.add(c);
|
toTop.add(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -279,38 +269,37 @@ public class PlayerControllerAi extends PlayerController {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean willPutCardOnTop(Card c) {
|
public boolean willPutCardOnTop(Card c) {
|
||||||
return true; // AI does not know what will happen next (another clash or
|
return true; // AI does not know what will happen next (another clash or that would become his topdeck)
|
||||||
// that would become his topdeck)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CardCollectionView orderMoveToZoneList(CardCollectionView cards, ZoneType destinationZone) {
|
public CardCollectionView orderMoveToZoneList(CardCollectionView cards, ZoneType destinationZone) {
|
||||||
// TODO Add logic for AI ordering here
|
//TODO Add logic for AI ordering here
|
||||||
return cards;
|
return cards;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CardCollection chooseCardsToDiscardFrom(Player p, SpellAbility sa, CardCollection validCards, int min,
|
public CardCollection chooseCardsToDiscardFrom(Player p, SpellAbility sa, CardCollection validCards, int min, int max) {
|
||||||
int max) {
|
|
||||||
if (p == player) {
|
if (p == player) {
|
||||||
return brains.getCardsToDiscard(min, max, validCards, sa);
|
return brains.getCardsToDiscard(min, max, validCards, sa);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isTargetFriendly = !p.isOpponentOf(player);
|
boolean isTargetFriendly = !p.isOpponentOf(player);
|
||||||
|
|
||||||
return isTargetFriendly ? ComputerUtil.getCardsToDiscardFromFriend(player, p, sa, validCards, min, max)
|
return isTargetFriendly
|
||||||
|
? ComputerUtil.getCardsToDiscardFromFriend(player, p, sa, validCards, min, max)
|
||||||
: ComputerUtil.getCardsToDiscardFromOpponent(player, p, sa, validCards, min, max);
|
: ComputerUtil.getCardsToDiscardFromOpponent(player, p, sa, validCards, min, max);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void playSpellAbilityForFree(SpellAbility copySA, boolean mayChooseNewTargets) {
|
public void playSpellAbilityForFree(SpellAbility copySA, boolean mayChooseNewTargets) {
|
||||||
// Ai is known to set targets in doTrigger, so if it cannot choose new
|
// Ai is known to set targets in doTrigger, so if it cannot choose new targets, we won't call canPlays
|
||||||
// targets, we won't call canPlays
|
|
||||||
if (mayChooseNewTargets) {
|
if (mayChooseNewTargets) {
|
||||||
if (copySA instanceof Spell) {
|
if (copySA instanceof Spell) {
|
||||||
Spell spell = (Spell) copySA;
|
Spell spell = (Spell) copySA;
|
||||||
((PlayerControllerAi) player.getController()).getAi().canPlayFromEffectAI(spell, true, true);
|
((PlayerControllerAi) player.getController()).getAi().canPlayFromEffectAI(spell, true, true);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
getAi().canPlaySa(copySA);
|
getAi().canPlaySa(copySA);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -320,9 +309,7 @@ public class PlayerControllerAi extends PlayerController {
|
|||||||
@Override
|
@Override
|
||||||
public void playSpellAbilityNoStack(SpellAbility effectSA, boolean canSetupTargets) {
|
public void playSpellAbilityNoStack(SpellAbility effectSA, boolean canSetupTargets) {
|
||||||
if (canSetupTargets)
|
if (canSetupTargets)
|
||||||
brains.doTrigger(effectSA, true); // first parameter does not
|
brains.doTrigger(effectSA, true); // first parameter does not matter, since return value won't be used
|
||||||
// matter, since return value
|
|
||||||
// won't be used
|
|
||||||
ComputerUtil.playNoStack(player, effectSA, game);
|
ComputerUtil.playNoStack(player, effectSA, game);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -338,34 +325,33 @@ public class PlayerControllerAi extends PlayerController {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TargetChoices chooseNewTargetsFor(SpellAbility ability) {
|
public TargetChoices chooseNewTargetsFor(SpellAbility ability) {
|
||||||
// AI currently can't do this. But when it can it will need to be based
|
// AI currently can't do this. But when it can it will need to be based on Ability API
|
||||||
// on Ability API
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CardCollectionView chooseCardsToDiscardUnlessType(int num, CardCollectionView hand, String uType,
|
public CardCollectionView chooseCardsToDiscardUnlessType(int num, CardCollectionView hand, String uType, SpellAbility sa) {
|
||||||
SpellAbility sa) {
|
|
||||||
final CardCollectionView cardsOfType = CardLists.getType(hand, uType);
|
final CardCollectionView cardsOfType = CardLists.getType(hand, uType);
|
||||||
if (!cardsOfType.isEmpty()) {
|
if (!cardsOfType.isEmpty()) {
|
||||||
Card toDiscard = Aggregates.itemWithMin(cardsOfType, CardPredicates.Accessors.fnGetCmc);
|
Card toDiscard = Aggregates.itemWithMin(cardsOfType, CardPredicates.Accessors.fnGetCmc);
|
||||||
return new CardCollection(toDiscard);
|
return new CardCollection(toDiscard);
|
||||||
}
|
}
|
||||||
return getAi().getCardsToDiscard(num, (String[]) null, sa);
|
return getAi().getCardsToDiscard(num, (String[])null, sa);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Mana chooseManaFromPool(List<Mana> manaChoices) {
|
public Mana chooseManaFromPool(List<Mana> manaChoices) {
|
||||||
return manaChoices.get(0); // no brains used
|
return manaChoices.get(0); // no brains used
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String chooseSomeType(String kindOfType, SpellAbility sa, List<String> validTypes, List<String> invalidTypes,
|
public String chooseSomeType(String kindOfType, SpellAbility sa, List<String> validTypes, List<String> invalidTypes, boolean isOptional) {
|
||||||
boolean isOptional) {
|
|
||||||
String chosen = ComputerUtil.chooseSomeType(player, kindOfType, sa.getParam("AILogic"), invalidTypes);
|
String chosen = ComputerUtil.chooseSomeType(player, kindOfType, sa.getParam("AILogic"), invalidTypes);
|
||||||
if (StringUtils.isBlank(chosen) && !validTypes.isEmpty()) {
|
if (StringUtils.isBlank(chosen) && !validTypes.isEmpty())
|
||||||
|
{
|
||||||
chosen = validTypes.get(0);
|
chosen = validTypes.get(0);
|
||||||
Log.warn("AI has no idea how to choose " + kindOfType + ", defaulting to 1st element: chosen");
|
Log.warn("AI has no idea how to choose " + kindOfType +", defaulting to 1st element: chosen");
|
||||||
}
|
}
|
||||||
game.getAction().nofityOfValue(sa, null, "Computer picked: " + chosen, player);
|
game.getAction().nofityOfValue(sa, null, "Computer picked: " + chosen, player);
|
||||||
return chosen;
|
return chosen;
|
||||||
@@ -377,8 +363,7 @@ public class PlayerControllerAi extends PlayerController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean confirmReplacementEffect(ReplacementEffect replacementEffect, SpellAbility effectSA,
|
public boolean confirmReplacementEffect(ReplacementEffect replacementEffect, SpellAbility effectSA, String question) {
|
||||||
String question) {
|
|
||||||
return brains.aiShouldRun(replacementEffect, effectSA);
|
return brains.aiShouldRun(replacementEffect, effectSA);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -418,22 +403,18 @@ public class PlayerControllerAi extends PlayerController {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CardCollection chooseCardsToDiscardToMaximumHandSize(int numDiscard) {
|
public CardCollection chooseCardsToDiscardToMaximumHandSize(int numDiscard) {
|
||||||
return brains.getCardsToDiscard(numDiscard, (String[]) null, null);
|
return brains.getCardsToDiscard(numDiscard, (String[])null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CardCollection chooseCardsToRevealFromHand(int min, int max, CardCollectionView valid) {
|
public CardCollection chooseCardsToRevealFromHand(int min, int max, CardCollectionView valid) {
|
||||||
int numCardsToReveal = Math.min(max, valid.size());
|
int numCardsToReveal = Math.min(max, valid.size());
|
||||||
return numCardsToReveal == 0 ? new CardCollection() : (CardCollection) valid.subList(0, numCardsToReveal);
|
return numCardsToReveal == 0 ? new CardCollection() : (CardCollection)valid.subList(0, numCardsToReveal);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean payManaOptional(Card c, Cost cost, SpellAbility sa, String prompt, ManaPaymentPurpose purpose) {
|
public boolean payManaOptional(Card c, Cost cost, SpellAbility sa, String prompt, ManaPaymentPurpose purpose) {
|
||||||
final Ability ability = new AbilityStatic(c, cost, null) {
|
final Ability ability = new AbilityStatic(c, cost, null) { @Override public void resolve() {} };
|
||||||
@Override
|
|
||||||
public void resolve() {
|
|
||||||
}
|
|
||||||
};
|
|
||||||
ability.setActivatingPlayer(c.getController());
|
ability.setActivatingPlayer(c.getController());
|
||||||
|
|
||||||
if (ComputerUtilCost.canPayCost(ability, c.getController())) {
|
if (ComputerUtilCost.canPayCost(ability, c.getController())) {
|
||||||
@@ -445,8 +426,7 @@ public class PlayerControllerAi extends PlayerController {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<SpellAbility> chooseSaToActivateFromOpeningHand(List<SpellAbility> usableFromOpeningHand) {
|
public List<SpellAbility> chooseSaToActivateFromOpeningHand(List<SpellAbility> usableFromOpeningHand) {
|
||||||
// AI would play everything. But limits to one copy of (Leyline of
|
// AI would play everything. But limits to one copy of (Leyline of Singularity) and (Gemstone Caverns)
|
||||||
// Singularity) and (Gemstone Caverns)
|
|
||||||
return brains.chooseSaToActivateFromOpeningHand(usableFromOpeningHand);
|
return brains.chooseSaToActivateFromOpeningHand(usableFromOpeningHand);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -459,11 +439,8 @@ public class PlayerControllerAi extends PlayerController {
|
|||||||
return brains.chooseNumber(sa, title, options, relatedPlayer);
|
return brains.chooseNumber(sa, title, options, relatedPlayer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* (non-Javadoc)
|
||||||
* (non-Javadoc)
|
* @see forge.game.player.PlayerController#chooseFlipResult(forge.Card, forge.game.player.Player, java.lang.String[], boolean)
|
||||||
*
|
|
||||||
* @see forge.game.player.PlayerController#chooseFlipResult(forge.Card,
|
|
||||||
* forge.game.player.Player, java.lang.String[], boolean)
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean chooseFlipResult(SpellAbility sa, Player flipper, boolean[] results, boolean call) {
|
public boolean chooseFlipResult(SpellAbility sa, Player flipper, boolean[] results, boolean call) {
|
||||||
@@ -485,37 +462,31 @@ public class PlayerControllerAi extends PlayerController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Pair<SpellAbilityStackInstance, GameObject> chooseTarget(SpellAbility saSrc,
|
public Pair<SpellAbilityStackInstance, GameObject> chooseTarget(SpellAbility saSrc, List<Pair<SpellAbilityStackInstance, GameObject>> allTargets) {
|
||||||
List<Pair<SpellAbilityStackInstance, GameObject>> allTargets) {
|
|
||||||
// TODO Teach AI how to use Spellskite
|
// TODO Teach AI how to use Spellskite
|
||||||
return allTargets.get(0);
|
return allTargets.get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void notifyOfValue(SpellAbility saSource, GameObject realtedTarget, String value) {
|
public void notifyOfValue(SpellAbility saSource, GameObject realtedTarget, String value) {
|
||||||
// AI should take into consideration creature types, numbers and other
|
// AI should take into consideration creature types, numbers and other information (mostly choices) arriving through this channel
|
||||||
// information (mostly choices) arriving through this channel
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean chooseBinary(SpellAbility sa, String question, BinaryChoiceType kindOfChoice, Boolean defaultVal) {
|
public boolean chooseBinary(SpellAbility sa, String question, BinaryChoiceType kindOfChoice, Boolean defaultVal) {
|
||||||
switch (kindOfChoice) {
|
switch(kindOfChoice) {
|
||||||
case TapOrUntap:
|
case TapOrUntap: return true;
|
||||||
return true;
|
case UntapOrLeaveTapped: return defaultVal != null && defaultVal.booleanValue();
|
||||||
case UntapOrLeaveTapped:
|
case UntapTimeVault: return false; // TODO Should AI skip his turn for time vault?
|
||||||
return defaultVal != null && defaultVal.booleanValue();
|
case LeftOrRight: return brains.chooseDirection(sa);
|
||||||
case UntapTimeVault:
|
|
||||||
return false; // TODO Should AI skip his turn for time vault?
|
|
||||||
case LeftOrRight:
|
|
||||||
return brains.chooseDirection(sa);
|
|
||||||
default:
|
default:
|
||||||
return MyRandom.getRandom().nextBoolean();
|
return MyRandom.getRandom().nextBoolean();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Card chooseProtectionShield(GameEntity entityBeingDamaged, List<String> options,
|
public Card chooseProtectionShield(GameEntity entityBeingDamaged, List<String> options, Map<String, Card> choiceMap) {
|
||||||
Map<String, Card> choiceMap) {
|
|
||||||
int i = MyRandom.getRandom().nextInt(options.size());
|
int i = MyRandom.getRandom().nextInt(options.size());
|
||||||
return choiceMap.get(options.get(i));
|
return choiceMap.get(options.get(i));
|
||||||
}
|
}
|
||||||
@@ -537,10 +508,9 @@ public class PlayerControllerAi extends PlayerController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Pair<CounterType, String> chooseAndRemoveOrPutCounter(Card cardWithCounter) {
|
public Pair<CounterType,String> chooseAndRemoveOrPutCounter(Card cardWithCounter) {
|
||||||
if (!cardWithCounter.hasCounters()) {
|
if (!cardWithCounter.hasCounters()) {
|
||||||
System.out.println(
|
System.out.println("chooseCounterType was reached with a card with no counters on it. Consider filtering this card out earlier");
|
||||||
"chooseCounterType was reached with a card with no counters on it. Consider filtering this card out earlier");
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -563,18 +533,20 @@ public class PlayerControllerAi extends PlayerController {
|
|||||||
|
|
||||||
if (!countersToIncrease.isEmpty()) {
|
if (!countersToIncrease.isEmpty()) {
|
||||||
int random = MyRandom.getRandom().nextInt(countersToIncrease.size());
|
int random = MyRandom.getRandom().nextInt(countersToIncrease.size());
|
||||||
return new ImmutablePair<CounterType, String>(countersToIncrease.get(random), "Put");
|
return new ImmutablePair<CounterType,String>(countersToIncrease.get(random),"Put");
|
||||||
} else if (!countersToDecrease.isEmpty()) {
|
}
|
||||||
|
else if (!countersToDecrease.isEmpty()) {
|
||||||
int random = MyRandom.getRandom().nextInt(countersToDecrease.size());
|
int random = MyRandom.getRandom().nextInt(countersToDecrease.size());
|
||||||
return new ImmutablePair<CounterType, String>(countersToDecrease.get(random), "Remove");
|
return new ImmutablePair<CounterType,String>(countersToDecrease.get(random),"Remove");
|
||||||
}
|
}
|
||||||
|
|
||||||
// shouldn't reach here but just in case, remove random counter
|
// shouldn't reach here but just in case, remove random counter
|
||||||
List<CounterType> countersOnCard = new ArrayList<CounterType>();
|
List<CounterType> countersOnCard = new ArrayList<CounterType>();
|
||||||
int random = MyRandom.getRandom().nextInt(countersOnCard.size());
|
int random = MyRandom.getRandom().nextInt(countersOnCard.size());
|
||||||
return new ImmutablePair<CounterType, String>(countersOnCard.get(random), "Remove");
|
return new ImmutablePair<CounterType,String>(countersOnCard.get(random),"Remove");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte chooseColorAllowColorless(String message, Card card, ColorSet colors) {
|
public byte chooseColorAllowColorless(String message, Card card, ColorSet colors) {
|
||||||
final String c = ComputerUtilCard.getMostProminentColor(player.getCardsIn(ZoneType.Hand));
|
final String c = ComputerUtilCard.getMostProminentColor(player.getCardsIn(ZoneType.Hand));
|
||||||
@@ -582,7 +554,7 @@ public class PlayerControllerAi extends PlayerController {
|
|||||||
if ((colors.getColor() & chosenColorMask) != 0) {
|
if ((colors.getColor() & chosenColorMask) != 0) {
|
||||||
return chosenColorMask;
|
return chosenColorMask;
|
||||||
} else {
|
} else {
|
||||||
return Iterables.getFirst(colors, (byte) 0);
|
return Iterables.getFirst(colors, (byte)0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -598,20 +570,16 @@ public class PlayerControllerAi extends PlayerController {
|
|||||||
|
|
||||||
if ((colors.getColor() & chosenColorMask) != 0) {
|
if ((colors.getColor() & chosenColorMask) != 0) {
|
||||||
return chosenColorMask;
|
return chosenColorMask;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return Iterables.getFirst(colors, MagicColor.WHITE);
|
return Iterables.getFirst(colors, MagicColor.WHITE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PaperCard chooseSinglePaperCard(SpellAbility sa, String message, Predicate<PaperCard> cpp, String name) {
|
public PaperCard chooseSinglePaperCard(SpellAbility sa, String message,
|
||||||
throw new UnsupportedOperationException("Should not be called for AI"); // or
|
Predicate<PaperCard> cpp, String name) {
|
||||||
// implement
|
throw new UnsupportedOperationException("Should not be called for AI"); // or implement it if you know how
|
||||||
// it
|
|
||||||
// if
|
|
||||||
// you
|
|
||||||
// know
|
|
||||||
// how
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -621,8 +589,7 @@ public class PlayerControllerAi extends PlayerController {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CounterType chooseCounterType(List<CounterType> options, SpellAbility sa, String prompt) {
|
public CounterType chooseCounterType(List<CounterType> options, SpellAbility sa, String prompt) {
|
||||||
// may write a smarter AI if you need to (with calls to AI-clas for
|
// may write a smarter AI if you need to (with calls to AI-clas for given API ability)
|
||||||
// given API ability)
|
|
||||||
|
|
||||||
// TODO: ArsenalNut (06 Feb 12)computer needs
|
// TODO: ArsenalNut (06 Feb 12)computer needs
|
||||||
// better logic to pick a counter type and probably
|
// better logic to pick a counter type and probably
|
||||||
@@ -633,15 +600,11 @@ public class PlayerControllerAi extends PlayerController {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean confirmPayment(CostPart costPart, String prompt) {
|
public boolean confirmPayment(CostPart costPart, String prompt) {
|
||||||
return brains.confirmPayment(costPart); // AI is expected to know what
|
return brains.confirmPayment(costPart); // AI is expected to know what it is paying for at the moment (otherwise add another parameter to this method)
|
||||||
// it is paying for at the
|
|
||||||
// moment (otherwise add another
|
|
||||||
// parameter to this method)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ReplacementEffect chooseSingleReplacementEffect(String prompt, List<ReplacementEffect> possibleReplacers,
|
public ReplacementEffect chooseSingleReplacementEffect(String prompt, List<ReplacementEffect> possibleReplacers, Map<String, Object> runParams) {
|
||||||
Map<String, Object> runParams) {
|
|
||||||
// AI logic for choosing which replacement effect to apply
|
// AI logic for choosing which replacement effect to apply
|
||||||
// happens here.
|
// happens here.
|
||||||
return possibleReplacers.get(0);
|
return possibleReplacers.get(0);
|
||||||
@@ -650,7 +613,7 @@ public class PlayerControllerAi extends PlayerController {
|
|||||||
@Override
|
@Override
|
||||||
public String chooseProtectionType(String string, SpellAbility sa, List<String> choices) {
|
public String chooseProtectionType(String string, SpellAbility sa, List<String> choices) {
|
||||||
String choice = choices.get(0);
|
String choice = choices.get(0);
|
||||||
SpellAbility hostsa = null; // for Protect sub-ability
|
SpellAbility hostsa = null; //for Protect sub-ability
|
||||||
if (game.stack.size() > 1) {
|
if (game.stack.size() > 1) {
|
||||||
for (SpellAbilityStackInstance si : game.getStack()) {
|
for (SpellAbilityStackInstance si : game.getStack()) {
|
||||||
SpellAbility spell = si.getSpellAbility(true);
|
SpellAbility spell = si.getSpellAbility(true);
|
||||||
@@ -690,8 +653,7 @@ public class PlayerControllerAi extends PlayerController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
final PhaseHandler ph = game.getPhaseHandler();
|
final PhaseHandler ph = game.getPhaseHandler();
|
||||||
if (ph.getPlayerTurn() == sa.getActivatingPlayer() && ph.getPhase() == PhaseType.MAIN1
|
if (ph.getPlayerTurn() == sa.getActivatingPlayer() && ph.getPhase() == PhaseType.MAIN1 && sa.getTargetCard() != null) {
|
||||||
&& sa.getTargetCard() != null) {
|
|
||||||
AiAttackController aiAtk = new AiAttackController(sa.getActivatingPlayer(), sa.getTargetCard());
|
AiAttackController aiAtk = new AiAttackController(sa.getActivatingPlayer(), sa.getTargetCard());
|
||||||
String s = aiAtk.toProtectAttacker(sa);
|
String s = aiAtk.toProtectAttacker(sa);
|
||||||
if (s != null) {
|
if (s != null) {
|
||||||
@@ -715,22 +677,12 @@ public class PlayerControllerAi extends PlayerController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean payCostToPreventEffect(Cost cost, SpellAbility sa, boolean alreadyPaid,
|
public boolean payCostToPreventEffect(Cost cost, SpellAbility sa, boolean alreadyPaid, FCollectionView<Player> allPayers) {
|
||||||
FCollectionView<Player> allPayers) {
|
|
||||||
final Card source = sa.getHostCard();
|
final Card source = sa.getHostCard();
|
||||||
final Ability emptyAbility = new AbilityStatic(source, cost, sa.getTargetRestrictions()) {
|
final Ability emptyAbility = new AbilityStatic(source, cost, sa.getTargetRestrictions()) { @Override public void resolve() { } };
|
||||||
@Override
|
|
||||||
public void resolve() {
|
|
||||||
}
|
|
||||||
};
|
|
||||||
emptyAbility.setActivatingPlayer(player);
|
emptyAbility.setActivatingPlayer(player);
|
||||||
if (ComputerUtilCost.willPayUnlessCost(sa, player, cost, alreadyPaid, allPayers)
|
if (ComputerUtilCost.willPayUnlessCost(sa, player, cost, alreadyPaid, allPayers) && ComputerUtilCost.canPayCost(emptyAbility, player)) {
|
||||||
&& ComputerUtilCost.canPayCost(emptyAbility, player)) {
|
ComputerUtil.playNoStack(player, emptyAbility, game); // AI needs something to resolve to pay that cost
|
||||||
ComputerUtil.playNoStack(player, emptyAbility, game); // AI needs
|
|
||||||
// something
|
|
||||||
// to resolve
|
|
||||||
// to pay that
|
|
||||||
// cost
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -739,12 +691,12 @@ public class PlayerControllerAi extends PlayerController {
|
|||||||
@Override
|
@Override
|
||||||
public void orderAndPlaySimultaneousSa(List<SpellAbility> activePlayerSAs) {
|
public void orderAndPlaySimultaneousSa(List<SpellAbility> activePlayerSAs) {
|
||||||
for (final SpellAbility sa : activePlayerSAs) {
|
for (final SpellAbility sa : activePlayerSAs) {
|
||||||
prepareSingleSa(sa.getHostCard(), sa, true);
|
prepareSingleSa(sa.getHostCard(),sa,true);
|
||||||
ComputerUtil.playStack(sa, player, game);
|
ComputerUtil.playStack(sa, player, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void prepareSingleSa(final Card host, final SpellAbility sa, boolean isMandatory) {
|
private void prepareSingleSa(final Card host, final SpellAbility sa, boolean isMandatory){
|
||||||
if (sa.hasParam("TargetingPlayer")) {
|
if (sa.hasParam("TargetingPlayer")) {
|
||||||
Player targetingPlayer = AbilityUtils.getDefinedPlayers(host, sa.getParam("TargetingPlayer"), sa).get(0);
|
Player targetingPlayer = AbilityUtils.getDefinedPlayers(host, sa.getParam("TargetingPlayer"), sa).get(0);
|
||||||
sa.setTargetingPlayer(targetingPlayer);
|
sa.setTargetingPlayer(targetingPlayer);
|
||||||
@@ -789,19 +741,15 @@ public class PlayerControllerAi extends PlayerController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean chooseCardsPile(SpellAbility sa, CardCollectionView pile1, CardCollectionView pile2,
|
public boolean chooseCardsPile(SpellAbility sa, CardCollectionView pile1, CardCollectionView pile2, boolean faceUp) {
|
||||||
boolean faceUp) {
|
|
||||||
if (!faceUp) {
|
if (!faceUp) {
|
||||||
// AI will choose the first pile if it is larger or the same
|
// AI will choose the first pile if it is larger or the same
|
||||||
// TODO Improve this to be slightly more random to not be so
|
// TODO Improve this to be slightly more random to not be so predictable
|
||||||
// predictable
|
|
||||||
return pile1.size() >= pile2.size();
|
return pile1.size() >= pile2.size();
|
||||||
} else {
|
} else {
|
||||||
boolean allCreatures = Iterables.all(Iterables.concat(pile1, pile2), CardPredicates.Presets.CREATURES);
|
boolean allCreatures = Iterables.all(Iterables.concat(pile1, pile2), CardPredicates.Presets.CREATURES);
|
||||||
int cmc1 = allCreatures ? ComputerUtilCard.evaluateCreatureList(pile1)
|
int cmc1 = allCreatures ? ComputerUtilCard.evaluateCreatureList(pile1) : ComputerUtilCard.evaluatePermanentList(pile1);
|
||||||
: ComputerUtilCard.evaluatePermanentList(pile1);
|
int cmc2 = allCreatures ? ComputerUtilCard.evaluateCreatureList(pile2) : ComputerUtilCard.evaluatePermanentList(pile2);
|
||||||
int cmc2 = allCreatures ? ComputerUtilCard.evaluateCreatureList(pile2)
|
|
||||||
: ComputerUtilCard.evaluatePermanentList(pile2);
|
|
||||||
System.out.println("value:" + cmc1 + " " + cmc2);
|
System.out.println("value:" + cmc1 + " " + cmc2);
|
||||||
|
|
||||||
// for now, this assumes that the outcome will be bad
|
// for now, this assumes that the outcome will be bad
|
||||||
@@ -838,20 +786,17 @@ public class PlayerControllerAi extends PlayerController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean payManaCost(ManaCost toPay, CostPartMana costPartMana, SpellAbility sa,
|
public boolean payManaCost(ManaCost toPay, CostPartMana costPartMana, SpellAbility sa, String prompt /* ai needs hints as well */, boolean isActivatedSa) {
|
||||||
String prompt /* ai needs hints as well */, boolean isActivatedSa) {
|
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
ManaCostBeingPaid cost = isActivatedSa ? ComputerUtilMana.calculateManaCost(sa, false, 0)
|
ManaCostBeingPaid cost = isActivatedSa ? ComputerUtilMana.calculateManaCost(sa, false, 0) : new ManaCostBeingPaid(toPay);
|
||||||
: new ManaCostBeingPaid(toPay);
|
|
||||||
return ComputerUtilMana.payManaCost(cost, sa, player);
|
return ComputerUtilMana.payManaCost(cost, sa, player);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<Card, ManaCostShard> chooseCardsForConvoke(SpellAbility sa, ManaCost manaCost,
|
public Map<Card, ManaCostShard> chooseCardsForConvoke(SpellAbility sa, ManaCost manaCost, CardCollectionView untappedCreats0) {
|
||||||
CardCollectionView untappedCreats0) {
|
|
||||||
final Player ai = sa.getActivatingPlayer();
|
final Player ai = sa.getActivatingPlayer();
|
||||||
final PhaseHandler ph = ai.getGame().getPhaseHandler();
|
final PhaseHandler ph = ai.getGame().getPhaseHandler();
|
||||||
// Filter out mana sources that will interfere with payManaCost()
|
//Filter out mana sources that will interfere with payManaCost()
|
||||||
CardCollection untappedCreats = CardLists.filter(untappedCreats0, new Predicate<Card>() {
|
CardCollection untappedCreats = CardLists.filter(untappedCreats0, new Predicate<Card>() {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(final Card c) {
|
public boolean apply(final Card c) {
|
||||||
@@ -859,17 +804,17 @@ public class PlayerControllerAi extends PlayerController {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Only convoke after attackers have been declared
|
//Only convoke after attackers have been declared
|
||||||
if (ph.isPlayerTurn(ai) && ph.getPhase().isBefore(PhaseType.COMBAT_DECLARE_ATTACKERS)) {
|
if (ph.isPlayerTurn(ai) && ph.getPhase().isBefore(PhaseType.COMBAT_DECLARE_ATTACKERS)) {
|
||||||
return new HashMap<Card, ManaCostShard>();
|
return new HashMap<Card, ManaCostShard>();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do not convoke potential blockers until after opponent's attack
|
//Do not convoke potential blockers until after opponent's attack
|
||||||
final CardCollectionView blockers = ComputerUtilCard.getLikelyBlockers(ai, null);
|
final CardCollectionView blockers = ComputerUtilCard.getLikelyBlockers(ai, null);
|
||||||
if ((ph.isPlayerTurn(ai) && ph.getPhase().isAfter(PhaseType.COMBAT_BEGIN))
|
if ((ph.isPlayerTurn(ai) && ph.getPhase().isAfter(PhaseType.COMBAT_BEGIN)) ||
|
||||||
|| (!ph.isPlayerTurn(ai) && ph.getPhase().isBefore(PhaseType.COMBAT_DECLARE_BLOCKERS))) {
|
(!ph.isPlayerTurn(ai) && ph.getPhase().isBefore(PhaseType.COMBAT_DECLARE_BLOCKERS))) {
|
||||||
untappedCreats.removeAll((List<?>) blockers);
|
untappedCreats.removeAll((List<?>)blockers);
|
||||||
// Add threatened creatures
|
//Add threatened creatures
|
||||||
if (!ai.getGame().getStack().isEmpty()) {
|
if (!ai.getGame().getStack().isEmpty()) {
|
||||||
final List<GameObject> objects = ComputerUtil.predictThreatenedObjects(sa.getActivatingPlayer(), null);
|
final List<GameObject> objects = ComputerUtil.predictThreatenedObjects(sa.getActivatingPlayer(), null);
|
||||||
for (Card c : blockers) {
|
for (Card c : blockers) {
|
||||||
@@ -891,16 +836,14 @@ public class PlayerControllerAi extends PlayerController {
|
|||||||
} else if (logic.equals("MostProminentInHumanDeck")) {
|
} else if (logic.equals("MostProminentInHumanDeck")) {
|
||||||
return ComputerUtilCard.getMostProminentCardName(player.getOpponent().getCardsIn(ZoneType.Library));
|
return ComputerUtilCard.getMostProminentCardName(player.getOpponent().getCardsIn(ZoneType.Library));
|
||||||
} else if (logic.equals("MostProminentCreatureInComputerDeck")) {
|
} else if (logic.equals("MostProminentCreatureInComputerDeck")) {
|
||||||
CardCollectionView cards = CardLists.getValidCards(player.getCardsIn(ZoneType.Library), "Creature",
|
CardCollectionView cards = CardLists.getValidCards(player.getCardsIn(ZoneType.Library), "Creature", player, sa.getHostCard());
|
||||||
player, sa.getHostCard());
|
|
||||||
return ComputerUtilCard.getMostProminentCardName(cards);
|
return ComputerUtilCard.getMostProminentCardName(cards);
|
||||||
} else if (logic.equals("BestCreatureInComputerDeck")) {
|
} else if (logic.equals("BestCreatureInComputerDeck")) {
|
||||||
return ComputerUtilCard.getBestCreatureAI(player.getCardsIn(ZoneType.Library)).getName();
|
return ComputerUtilCard.getBestCreatureAI(player.getCardsIn(ZoneType.Library)).getName();
|
||||||
} else if (logic.equals("RandomInComputerDeck")) {
|
} else if (logic.equals("RandomInComputerDeck")) {
|
||||||
return Aggregates.random(player.getCardsIn(ZoneType.Library)).getName();
|
return Aggregates.random(player.getCardsIn(ZoneType.Library)).getName();
|
||||||
} else if (logic.equals("MostProminentSpellInComputerDeck")) {
|
} else if (logic.equals("MostProminentSpellInComputerDeck")) {
|
||||||
CardCollectionView cards = CardLists.getValidCards(player.getCardsIn(ZoneType.Library),
|
CardCollectionView cards = CardLists.getValidCards(player.getCardsIn(ZoneType.Library), "Card.Instant,Card.Sorcery", player, sa.getHostCard());
|
||||||
"Card.Instant,Card.Sorcery", player, sa.getHostCard());
|
|
||||||
return ComputerUtilCard.getMostProminentCardName(cards);
|
return ComputerUtilCard.getMostProminentCardName(cards);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -914,21 +857,19 @@ public class PlayerControllerAi extends PlayerController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Card chooseSingleCardForZoneChange(ZoneType destination, List<ZoneType> origin, SpellAbility sa,
|
public Card chooseSingleCardForZoneChange(ZoneType destination,
|
||||||
CardCollection fetchList, DelayedReveal delayedReveal, String selectPrompt, boolean isOptional,
|
List<ZoneType> origin, SpellAbility sa, CardCollection fetchList, DelayedReveal delayedReveal,
|
||||||
Player decider) {
|
String selectPrompt, boolean isOptional, Player decider) {
|
||||||
|
|
||||||
if (delayedReveal != null) {
|
if (delayedReveal != null) {
|
||||||
reveal(delayedReveal.getCards(), delayedReveal.getZone(), delayedReveal.getOwner(),
|
reveal(delayedReveal.getCards(), delayedReveal.getZone(), delayedReveal.getOwner(), delayedReveal.getMessagePrefix());
|
||||||
delayedReveal.getMessagePrefix());
|
|
||||||
}
|
}
|
||||||
return ChangeZoneAi.chooseCardToHiddenOriginChangeZone(destination, origin, sa, fetchList, player, decider);
|
return ChangeZoneAi.chooseCardToHiddenOriginChangeZone(destination, origin, sa, fetchList, player, decider);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void resetAtEndOfTurn() {
|
public void resetAtEndOfTurn() {
|
||||||
// TODO - if card memory is ever used to remember something for longer
|
// TODO - if card memory is ever used to remember something for longer than a turn, make sure it's not reset here.
|
||||||
// than a turn, make sure it's not reset here.
|
|
||||||
getAi().getCardMemory().clearAllRemembered();
|
getAi().getCardMemory().clearAllRemembered();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -941,7 +882,6 @@ public class PlayerControllerAi extends PlayerController {
|
|||||||
public void awaitNextInput() {
|
public void awaitNextInput() {
|
||||||
// Do nothing
|
// Do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void cancelAwaitNextInput() {
|
public void cancelAwaitNextInput() {
|
||||||
// Do nothing
|
// Do nothing
|
||||||
|
|||||||
Reference in New Issue
Block a user