mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 20:28:00 +00:00
- Added scheme: Choose Your Champion and supporting AI logic.
- Added a basic board state evaluation that returns the player from a list with the best rating. Could probably be improved with better weightings.
This commit is contained in:
1
.gitattributes
vendored
1
.gitattributes
vendored
@@ -1811,6 +1811,7 @@ res/cardsfolder/c/choking_fumes.txt svneol=native#text/plain
|
|||||||
res/cardsfolder/c/choking_sands.txt svneol=native#text/plain
|
res/cardsfolder/c/choking_sands.txt svneol=native#text/plain
|
||||||
res/cardsfolder/c/choking_tethers.txt svneol=native#text/plain
|
res/cardsfolder/c/choking_tethers.txt svneol=native#text/plain
|
||||||
res/cardsfolder/c/choking_vines.txt -text
|
res/cardsfolder/c/choking_vines.txt -text
|
||||||
|
res/cardsfolder/c/choose_your_champion.txt -text
|
||||||
res/cardsfolder/c/chord_of_calling.txt -text
|
res/cardsfolder/c/chord_of_calling.txt -text
|
||||||
res/cardsfolder/c/chorus_of_might.txt -text
|
res/cardsfolder/c/chorus_of_might.txt -text
|
||||||
res/cardsfolder/c/chorus_of_woe.txt svneol=native#text/plain
|
res/cardsfolder/c/chorus_of_woe.txt svneol=native#text/plain
|
||||||
|
|||||||
10
res/cardsfolder/c/choose_your_champion.txt
Normal file
10
res/cardsfolder/c/choose_your_champion.txt
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
Name:Choose Your Champion
|
||||||
|
ManaCost:no cost
|
||||||
|
Types:Scheme
|
||||||
|
T:Mode$ SetInMotion | ValidCard$ Card.Self | Execute$ ChooseChampion | TriggerZones$ Command | TriggerDescription$ When you set this scheme in motion, target opponent chooses a player. Until your next turn, only you and the chosen player can cast spells and attack with creatures.
|
||||||
|
SVar:ChooseChampion:AB$ ChoosePlayer | Cost$ 0 | ValidTgts$ Opponent | Choices$ Player | AILogic$ BestAllyBoardPosition | SubAbility$ PrepChamps
|
||||||
|
SVar:PrepChamps:DB$ Effect | RememberObjects$ ChosenPlayer,You | Name$ Choose Your Champion Scheme | Duration$ UntilYourNextTurn | StaticAbilities$ RestrictAttackers,RestrictCasting
|
||||||
|
SVar:RestrictAttackers:Mode$ Continuous | Affected$ Creature.nonRememberedPlayerCtrl | AddHiddenKeyword$ CARDNAME can't attack. | EffectZone$ Command | Description$ Until your next turn, only you and the chosen player can attack with creatures.
|
||||||
|
SVar:RestrictCasting:Mode$ CantBeCast | ValidCard$ Card | Caster$ Player.IsNotRemembered | EffectZone$ Command | Description$ Until your next turn, only you and the chosen player can cast spells.
|
||||||
|
SVar:Picture:http://www.cardforge.org/fpics/lq_schemes/choose_your_champion.jpg
|
||||||
|
Oracle:When you set this scheme in motion, target opponent chooses a player. Until your next turn, only you and the chosen player can cast spells and attack with creatures.
|
||||||
@@ -5386,6 +5386,17 @@ public class Card extends GameEntity implements Comparable<Card> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (property.startsWith("nonRememberedPlayerCtrl")) {
|
||||||
|
if (source.getRemembered().isEmpty()) {
|
||||||
|
final Card newCard = game.getCardState(source);
|
||||||
|
if (newCard.getRemembered().contains(this.getController())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (source.getRemembered().contains(this.getController())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
} else if (property.equals("TargetedPlayerCtrl")) {
|
} else if (property.equals("TargetedPlayerCtrl")) {
|
||||||
for (final SpellAbility sa : source.getCharacteristics().getSpellAbility()) {
|
for (final SpellAbility sa : source.getCharacteristics().getSpellAbility()) {
|
||||||
final SpellAbility saTargeting = sa.getSATargetingPlayer();
|
final SpellAbility saTargeting = sa.getSATargetingPlayer();
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import java.util.List;
|
|||||||
|
|
||||||
import forge.card.ability.SpellAbilityAi;
|
import forge.card.ability.SpellAbilityAi;
|
||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
|
import forge.game.ai.ComputerUtilCard;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
|
|
||||||
public class ChoosePlayerAi extends SpellAbilityAi {
|
public class ChoosePlayerAi extends SpellAbilityAi {
|
||||||
@@ -45,6 +46,16 @@ public class ChoosePlayerAi extends SpellAbilityAi {
|
|||||||
}
|
}
|
||||||
} else if ("Pump".equals(sa.getParam("AILogic"))) {
|
} else if ("Pump".equals(sa.getParam("AILogic"))) {
|
||||||
chosen = choices.contains(ai) ? ai : choices.get(0);
|
chosen = choices.contains(ai) ? ai : choices.get(0);
|
||||||
|
} else if ("BestAllyBoardPosition".equals(sa.getParam("AILogic"))) {
|
||||||
|
List<Player> prefChoices = choices;
|
||||||
|
prefChoices.removeAll(ai.getOpponents());
|
||||||
|
if (!prefChoices.isEmpty()) {
|
||||||
|
chosen = ComputerUtilCard.evaluateBoardPosition(prefChoices);
|
||||||
|
}
|
||||||
|
if (chosen == null) {
|
||||||
|
System.out.println("No good curse choices. Picking first available: " + choices.get(0));
|
||||||
|
chosen = choices.get(0);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
System.out.println("Default player choice logic.");
|
System.out.println("Default player choice logic.");
|
||||||
chosen = choices.contains(ai) ? ai : choices.get(0);
|
chosen = choices.contains(ai) ? ai : choices.get(0);
|
||||||
|
|||||||
@@ -169,8 +169,10 @@ public class EffectEffect extends SpellAbilityEffect {
|
|||||||
|
|
||||||
// Set Remembered
|
// Set Remembered
|
||||||
if (effectRemembered != null) {
|
if (effectRemembered != null) {
|
||||||
for (final Object o : AbilityUtils.getDefinedObjects(hostCard, effectRemembered, sa)) {
|
for (final String rem : effectRemembered.split(",")) {
|
||||||
eff.addRemembered(o);
|
for (final Object o : AbilityUtils.getDefinedObjects(hostCard, rem, sa)) {
|
||||||
|
eff.addRemembered(o);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import java.util.HashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
import org.apache.commons.lang3.tuple.MutablePair;
|
import org.apache.commons.lang3.tuple.MutablePair;
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
|
||||||
@@ -31,6 +32,7 @@ import forge.deck.Deck;
|
|||||||
import forge.deck.DeckSection;
|
import forge.deck.DeckSection;
|
||||||
import forge.game.combat.Combat;
|
import forge.game.combat.Combat;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
|
import forge.game.zone.ZoneType;
|
||||||
import forge.item.PaperCard;
|
import forge.item.PaperCard;
|
||||||
import forge.util.Aggregates;
|
import forge.util.Aggregates;
|
||||||
|
|
||||||
@@ -820,4 +822,40 @@ public class ComputerUtilCard {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* evaluateBoardPosition.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param listToEvaluate
|
||||||
|
* a list of players to evaluate.
|
||||||
|
* @return a Player.
|
||||||
|
*/
|
||||||
|
public static Player evaluateBoardPosition(final List<Player> listToEvaluate) {
|
||||||
|
Player bestBoardPosition = listToEvaluate.get(0);
|
||||||
|
int bestBoardRating = 0;
|
||||||
|
|
||||||
|
for (final Player p : listToEvaluate) {
|
||||||
|
int pRating = p.getLife() * 3;
|
||||||
|
pRating += p.getLandsInPlay().size() * 2;
|
||||||
|
|
||||||
|
for (final Card c : p.getCardsIn(ZoneType.Battlefield)) {
|
||||||
|
pRating += ComputerUtilCard.evaluateCreature(c) / 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p.getCardsIn(ZoneType.Library).size() < 3) {
|
||||||
|
pRating /= 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("Board position evaluation for " + p + ": " + pRating);
|
||||||
|
|
||||||
|
if (pRating > bestBoardRating) {
|
||||||
|
bestBoardRating = pRating;
|
||||||
|
bestBoardPosition = p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return bestBoardPosition;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user