mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 20:28:00 +00:00
*Potential base for Partial Paris AI
This commit is contained in:
@@ -25,6 +25,8 @@ import forge.FThreads;
|
||||
import forge.game.GameState;
|
||||
import forge.game.GameType;
|
||||
import forge.game.MatchController;
|
||||
import forge.game.ai.ComputerUtil;
|
||||
import forge.game.player.AIPlayer;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.Zone;
|
||||
import forge.game.zone.ZoneType;
|
||||
@@ -47,6 +49,7 @@ public class InputPartialParisMulligan extends InputBase {
|
||||
private static final long serialVersionUID = -8112954303001155622L;
|
||||
|
||||
private final MatchController match;
|
||||
private final GameState game;
|
||||
|
||||
private final List<Card> lastExiled = new ArrayList<Card>();
|
||||
private final List<Card> allExiled = new ArrayList<Card>();
|
||||
@@ -54,6 +57,7 @@ public class InputPartialParisMulligan extends InputBase {
|
||||
public InputPartialParisMulligan(MatchController match0, Player humanPlayer) {
|
||||
super(humanPlayer);
|
||||
match = match0;
|
||||
game = match.getCurrentGame();
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@@ -88,12 +92,35 @@ public class InputPartialParisMulligan extends InputBase {
|
||||
public final void selectButtonCancel() {
|
||||
for(Card c : lastExiled)
|
||||
{
|
||||
match.getCurrentGame().action.exile(c);
|
||||
game.action.exile(c);
|
||||
}
|
||||
|
||||
player.drawCards(lastExiled.size()-1);
|
||||
allExiled.addAll(lastExiled);
|
||||
lastExiled.clear();
|
||||
|
||||
final List<Card> aiAllExiled = new ArrayList<Card>();
|
||||
for (Player p : game.getPlayers()) {
|
||||
if (!(p instanceof AIPlayer)) {
|
||||
continue;
|
||||
}
|
||||
int ppcandidates = -1;
|
||||
AIPlayer ai = (AIPlayer) p;
|
||||
|
||||
while (ComputerUtil.wantMulligan(ai) && ppcandidates != 0) {
|
||||
List<Card> cand = ComputerUtil.getPartialParisCandidates(ai);
|
||||
ppcandidates = cand.size();
|
||||
if(ppcandidates != 0)
|
||||
{
|
||||
aiAllExiled.addAll(cand);
|
||||
for(Card c : cand)
|
||||
{
|
||||
game.action.exile(c);
|
||||
}
|
||||
ai.drawCards(ppcandidates-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (player.getCardsIn(ZoneType.Hand).isEmpty()) {
|
||||
this.end();
|
||||
@@ -102,9 +129,7 @@ public class InputPartialParisMulligan extends InputBase {
|
||||
}
|
||||
}
|
||||
|
||||
final void end() {
|
||||
|
||||
final GameState game = match.getCurrentGame();
|
||||
final void end() {
|
||||
|
||||
for(Card c : allExiled)
|
||||
{
|
||||
@@ -113,17 +138,28 @@ public class InputPartialParisMulligan extends InputBase {
|
||||
player.shuffle();
|
||||
|
||||
// Computer mulligan
|
||||
//TODO: How should AI approach Partial Paris?
|
||||
/*
|
||||
final List<Card> aiAllExiled = new ArrayList<Card>();
|
||||
for (Player p : game.getPlayers()) {
|
||||
if (!(p instanceof AIPlayer)) {
|
||||
continue;
|
||||
}
|
||||
int ppcandidates = -1;
|
||||
AIPlayer ai = (AIPlayer) p;
|
||||
while (ComputerUtil.wantMulligan(ai)) {
|
||||
ai.doMulligan();
|
||||
|
||||
while (ComputerUtil.wantMulligan(ai) && ppcandidates != 0) {
|
||||
List<Card> cand = ComputerUtil.getPartialParisCandidates(ai);
|
||||
ppcandidates = cand.size();
|
||||
if(ppcandidates != 0)
|
||||
{
|
||||
aiAllExiled.addAll(cand);
|
||||
for(Card c : cand)
|
||||
{
|
||||
game.action.exile(c);
|
||||
}
|
||||
ai.drawCards(ppcandidates-1);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
// Human Leylines & Chancellors
|
||||
ButtonUtil.reset();
|
||||
@@ -158,7 +194,7 @@ public class InputPartialParisMulligan extends InputBase {
|
||||
if (GuiDialog.confirm(c0, "Use " + c0.getName() + "'s ability?")) {
|
||||
List<Card> hand = new ArrayList<Card>(c0.getController().getCardsIn(ZoneType.Hand));
|
||||
for (Card c : hand) {
|
||||
match.getCurrentGame().getAction().exile(c);
|
||||
game.getAction().exile(c);
|
||||
}
|
||||
c0.getController().drawCards(hand.size());
|
||||
}
|
||||
|
||||
@@ -19,7 +19,9 @@ package forge.game.ai;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
@@ -30,7 +32,9 @@ import forge.CardLists;
|
||||
import forge.CardPredicates;
|
||||
import forge.CardPredicates.Presets;
|
||||
import forge.CardUtil;
|
||||
import forge.Color;
|
||||
import forge.Singletons;
|
||||
import forge.card.MagicColor;
|
||||
import forge.card.ability.AbilityUtils;
|
||||
import forge.card.ability.ApiType;
|
||||
import forge.card.ability.effects.CharmEffect;
|
||||
@@ -39,6 +43,7 @@ import forge.card.cost.Cost;
|
||||
import forge.card.cost.CostDiscard;
|
||||
import forge.card.cost.CostPart;
|
||||
import forge.card.cost.CostPayment;
|
||||
import forge.card.spellability.AbilityManaPart;
|
||||
import forge.card.spellability.AbilityStatic;
|
||||
import forge.card.spellability.SpellAbility;
|
||||
import forge.card.spellability.Target;
|
||||
@@ -1226,6 +1231,67 @@ public class ComputerUtil {
|
||||
return (handList.size() > ai.getAi().getIntProperty(AiProps.AI_MULLIGAN_THRESHOLD)) && hasLittleCmc0Cards;
|
||||
|
||||
}
|
||||
|
||||
public static List<Card> getPartialParisCandidates(AIPlayer ai) {
|
||||
final List<Card> candidates = new ArrayList<Card>();
|
||||
final List<Card> handList = ai.getCardsIn(ZoneType.Hand);
|
||||
|
||||
final List<Card> lands = CardLists.getValidCards(handList, "Card.Land", ai, null);
|
||||
final List<Card> nonLands = CardLists.getValidCards(handList, "Card.nonLand", ai, null);
|
||||
CardLists.sortByCmcDesc(nonLands);
|
||||
|
||||
if(lands.size() >= 3 && lands.size() <= 4)
|
||||
return candidates;
|
||||
|
||||
if(lands.size() < 3)
|
||||
{
|
||||
//Not enough lands!
|
||||
int tgtCandidates = Math.max(Math.abs(lands.size()-nonLands.size()), 3);
|
||||
System.out.println("Partial Paris: " + ai.getName() + " lacks lands, aiming to exile " + tgtCandidates + " cards.");
|
||||
|
||||
for(int i=0;i<tgtCandidates;i++)
|
||||
{
|
||||
candidates.add(nonLands.get(i));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//Too many lands!
|
||||
//Init
|
||||
Map<Color,List<Card>> numProducers = new HashMap<Color,List<Card>>();
|
||||
for(Color col : Color.WUBRG)
|
||||
{
|
||||
numProducers.put(col, new ArrayList<Card>());
|
||||
}
|
||||
|
||||
|
||||
for(Card c : lands)
|
||||
{
|
||||
for(SpellAbility sa : c.getManaAbility())
|
||||
{
|
||||
AbilityManaPart abmana = sa.getManaPart();
|
||||
for(Color col : Color.WUBRG)
|
||||
{
|
||||
if(abmana.canProduce(col.toString()))
|
||||
{
|
||||
numProducers.get(col).add(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
System.out.print("Partial Paris: " + ai.getName() + " may exile ");
|
||||
for(Card c : candidates)
|
||||
{
|
||||
System.out.print(c.toString() + ", ");
|
||||
}
|
||||
System.out.println();
|
||||
|
||||
if(candidates.size() < 2)
|
||||
candidates.clear();
|
||||
return candidates;
|
||||
}
|
||||
|
||||
|
||||
public static boolean scryWillMoveCardToBottomOfLibrary(AIPlayer player, Card c) {
|
||||
|
||||
Reference in New Issue
Block a user