*Potential base for Partial Paris AI

This commit is contained in:
Hellfish
2013-04-14 18:58:48 +00:00
parent 7bf79be1e4
commit 0a656dc1da
2 changed files with 112 additions and 10 deletions

View File

@@ -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());
}

View File

@@ -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) {