AI fixes and deck construction

This commit is contained in:
BetaSteward 2011-02-18 23:22:31 -05:00
parent 4f74ae204d
commit 659f790325
27 changed files with 271 additions and 119 deletions

View file

@ -27,7 +27,7 @@
<DimensionLayout dim="0"> <DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Component id="jPanel1" alignment="0" max="32767" attributes="0"/> <Component id="jPanel1" alignment="0" max="32767" attributes="0"/>
<Component id="jScrollPane1" alignment="0" pref="553" max="32767" attributes="0"/> <Component id="jScrollPane1" alignment="0" pref="639" max="32767" attributes="0"/>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
<DimensionLayout dim="1"> <DimensionLayout dim="1">
@ -35,7 +35,7 @@
<Group type="102" attributes="0"> <Group type="102" attributes="0">
<Component id="jPanel1" min="-2" max="-2" attributes="0"/> <Component id="jPanel1" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="0" max="-2" attributes="0"/> <EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
<Component id="jScrollPane1" pref="23" max="32767" attributes="0"/> <Component id="jScrollPane1" pref="397" max="32767" attributes="0"/>
</Group> </Group>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
@ -57,13 +57,13 @@
<DimensionLayout dim="0"> <DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0"> <Group type="102" alignment="1" attributes="0">
<Component id="lblCount" max="32767" attributes="0"/> <Component id="lblCount" min="-2" pref="81" max="-2" attributes="0"/>
<EmptySpace type="unrelated" min="-2" max="-2" attributes="0"/> <EmptySpace type="unrelated" min="-2" max="-2" attributes="0"/>
<Component id="lblCreatureCount" max="32767" attributes="0"/> <Component id="lblCreatureCount" min="-2" pref="100" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/> <EmptySpace type="unrelated" min="-2" max="-2" attributes="0"/>
<Component id="lblLandCount" min="-2" max="-2" attributes="0"/> <Component id="lblLandCount" min="-2" pref="75" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/> <EmptySpace type="unrelated" min="-2" max="-2" attributes="0"/>
<Component id="cbSortBy" min="-2" pref="338" max="-2" attributes="0"/> <Component id="cbSortBy" pref="353" max="32767" attributes="0"/>
</Group> </Group>
</Group> </Group>
</DimensionLayout> </DimensionLayout>

View file

@ -200,13 +200,13 @@ public class CardsList extends javax.swing.JPanel implements MouseListener {
jPanel1Layout.setHorizontalGroup( jPanel1Layout.setHorizontalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
.addComponent(lblCount, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(lblCount, javax.swing.GroupLayout.PREFERRED_SIZE, 81, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(lblCreatureCount, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(lblCreatureCount, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(lblLandCount) .addComponent(lblLandCount, javax.swing.GroupLayout.PREFERRED_SIZE, 75, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(cbSortBy, javax.swing.GroupLayout.PREFERRED_SIZE, 338, javax.swing.GroupLayout.PREFERRED_SIZE)) .addComponent(cbSortBy, 0, 353, Short.MAX_VALUE))
); );
jPanel1Layout.setVerticalGroup( jPanel1Layout.setVerticalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
@ -222,14 +222,14 @@ public class CardsList extends javax.swing.JPanel implements MouseListener {
layout.setHorizontalGroup( layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 553, Short.MAX_VALUE) .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 639, Short.MAX_VALUE)
); );
layout.setVerticalGroup( layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup() .addGroup(layout.createSequentialGroup()
.addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(0, 0, 0) .addGap(0, 0, 0)
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 321, Short.MAX_VALUE)) .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 397, Short.MAX_VALUE))
); );
}// </editor-fold>//GEN-END:initComponents }// </editor-fold>//GEN-END:initComponents

View file

@ -15,11 +15,22 @@
<name>Mage Player AI</name> <name>Mage Player AI</name>
<dependencies> <dependencies>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.14</version>
<type>jar</type>
</dependency>
<dependency> <dependency>
<groupId>${project.groupId}</groupId> <groupId>${project.groupId}</groupId>
<artifactId>Mage</artifactId> <artifactId>Mage</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>Mage-Sets</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies> </dependencies>
<build> <build>

View file

@ -33,11 +33,10 @@ import java.io.IOException;
import java.io.Serializable; import java.io.Serializable;
import java.util.*; import java.util.*;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.logging.Level;
import java.util.logging.Logger;
import mage.Constants; import mage.Constants;
import mage.Constants.CardType; import mage.Constants.CardType;
import mage.Constants.ColoredManaSymbol;
import mage.Constants.Outcome; import mage.Constants.Outcome;
import mage.Constants.RangeOfInfluence; import mage.Constants.RangeOfInfluence;
import mage.Constants.Zone; import mage.Constants.Zone;
@ -83,6 +82,7 @@ import mage.game.tournament.Tournament;
import mage.player.ai.utils.RateCard; import mage.player.ai.utils.RateCard;
import mage.players.Player; import mage.players.Player;
import mage.players.PlayerImpl; import mage.players.PlayerImpl;
import mage.sets.Sets;
import mage.target.Target; import mage.target.Target;
import mage.target.TargetAmount; import mage.target.TargetAmount;
import mage.target.TargetCard; import mage.target.TargetCard;
@ -93,8 +93,8 @@ import mage.target.common.TargetDiscard;
import mage.target.common.TargetControlledPermanent; import mage.target.common.TargetControlledPermanent;
import mage.target.common.TargetCreatureOrPlayerAmount; import mage.target.common.TargetCreatureOrPlayerAmount;
import mage.util.Copier; import mage.util.Copier;
import mage.util.Logging;
import mage.util.TreeNode; import mage.util.TreeNode;
import org.apache.log4j.Logger;
/** /**
* *
@ -104,7 +104,7 @@ import mage.util.TreeNode;
*/ */
public class ComputerPlayer<T extends ComputerPlayer<T>> extends PlayerImpl<T> implements Player { public class ComputerPlayer<T extends ComputerPlayer<T>> extends PlayerImpl<T> implements Player {
private final static transient Logger logger = Logging.getLogger(ComputerPlayer.class.getName()); private final static transient Logger logger = Logger.getLogger(ComputerPlayer.class);
private transient Map<Mana, Card> unplayable = new TreeMap<Mana, Card>(); private transient Map<Mana, Card> unplayable = new TreeMap<Mana, Card>();
private transient List<Card> playableNonInstant = new ArrayList<Card>(); private transient List<Card> playableNonInstant = new ArrayList<Card>();
private transient List<Card> playableInstant = new ArrayList<Card>(); private transient List<Card> playableInstant = new ArrayList<Card>();
@ -127,7 +127,7 @@ public class ComputerPlayer<T extends ComputerPlayer<T>> extends PlayerImpl<T> i
@Override @Override
public boolean chooseMulligan(Game game) { public boolean chooseMulligan(Game game) {
logger.fine("chooseMulligan"); logger.debug("chooseMulligan");
if (hand.size() < 6) if (hand.size() < 6)
return false; return false;
Set<Card> lands = hand.getCards(new FilterLandCard(), game); Set<Card> lands = hand.getCards(new FilterLandCard(), game);
@ -143,8 +143,8 @@ public class ComputerPlayer<T extends ComputerPlayer<T>> extends PlayerImpl<T> i
@Override @Override
public boolean choose(Outcome outcome, Target target, Game game, Map<String, Serializable> options) { public boolean choose(Outcome outcome, Target target, Game game, Map<String, Serializable> options) {
if (logger.isLoggable(Level.FINE)) if (logger.isDebugEnabled())
logger.fine("chooseTarget: " + outcome.toString() + ":" + target.toString()); logger.debug("chooseTarget: " + outcome.toString() + ":" + target.toString());
UUID opponentId = game.getOpponents(playerId).iterator().next(); UUID opponentId = game.getOpponents(playerId).iterator().next();
if (target instanceof TargetPlayer) { if (target instanceof TargetPlayer) {
if (outcome.isGood()) { if (outcome.isGood()) {
@ -209,8 +209,8 @@ public class ComputerPlayer<T extends ComputerPlayer<T>> extends PlayerImpl<T> i
@Override @Override
public boolean chooseTarget(Outcome outcome, Target target, Ability source, Game game) { public boolean chooseTarget(Outcome outcome, Target target, Ability source, Game game) {
if (logger.isLoggable(Level.FINE)) if (logger.isDebugEnabled())
logger.fine("chooseTarget: " + outcome.toString() + ":" + target.toString()); logger.debug("chooseTarget: " + outcome.toString() + ":" + target.toString());
UUID opponentId = game.getOpponents(playerId).iterator().next(); UUID opponentId = game.getOpponents(playerId).iterator().next();
if (target instanceof TargetPlayer) { if (target instanceof TargetPlayer) {
if (outcome.isGood()) { if (outcome.isGood()) {
@ -303,8 +303,8 @@ public class ComputerPlayer<T extends ComputerPlayer<T>> extends PlayerImpl<T> i
@Override @Override
public boolean chooseTargetAmount(Outcome outcome, TargetAmount target, Ability source, Game game) { public boolean chooseTargetAmount(Outcome outcome, TargetAmount target, Ability source, Game game) {
if (logger.isLoggable(Level.FINE)) if (logger.isDebugEnabled())
logger.fine("chooseTarget: " + outcome.toString() + ":" + target.toString()); logger.debug("chooseTarget: " + outcome.toString() + ":" + target.toString());
UUID opponentId = game.getOpponents(playerId).iterator().next(); UUID opponentId = game.getOpponents(playerId).iterator().next();
if (target instanceof TargetCreatureOrPlayerAmount) { if (target instanceof TargetCreatureOrPlayerAmount) {
if (game.getPlayer(opponentId).getLife() <= target.getAmountRemaining()) { if (game.getPlayer(opponentId).getLife() <= target.getAmountRemaining()) {
@ -332,7 +332,7 @@ public class ComputerPlayer<T extends ComputerPlayer<T>> extends PlayerImpl<T> i
@Override @Override
public void priority(Game game) { public void priority(Game game) {
logger.fine("priority"); logger.debug("priority");
UUID opponentId = game.getOpponents(playerId).iterator().next(); UUID opponentId = game.getOpponents(playerId).iterator().next();
if (game.getActivePlayerId().equals(playerId)) { if (game.getActivePlayerId().equals(playerId)) {
if (game.isMainPhase() && game.getStack().isEmpty()) { if (game.isMainPhase() && game.getStack().isEmpty()) {
@ -418,7 +418,7 @@ public class ComputerPlayer<T extends ComputerPlayer<T>> extends PlayerImpl<T> i
} }
protected void playLand(Game game) { protected void playLand(Game game) {
logger.fine("playLand"); logger.debug("playLand");
Set<Card> lands = hand.getCards(new FilterLandCard(), game); Set<Card> lands = hand.getCards(new FilterLandCard(), game);
while (lands.size() > 0 && this.landsPlayed < this.landsPerTurn) { while (lands.size() > 0 && this.landsPlayed < this.landsPerTurn) {
if (lands.size() == 1) if (lands.size() == 1)
@ -430,7 +430,7 @@ public class ComputerPlayer<T extends ComputerPlayer<T>> extends PlayerImpl<T> i
} }
protected void playALand(Set<Card> lands, Game game) { protected void playALand(Set<Card> lands, Game game) {
logger.fine("playALand"); logger.debug("playALand");
//play a land that will allow us to play an unplayable //play a land that will allow us to play an unplayable
for (Mana mana: unplayable.keySet()) { for (Mana mana: unplayable.keySet()) {
for (Card card: lands) { for (Card card: lands) {
@ -538,19 +538,19 @@ public class ComputerPlayer<T extends ComputerPlayer<T>> extends PlayerImpl<T> i
} }
} }
} }
if (logger.isLoggable(Level.FINE)) if (logger.isDebugEnabled())
logger.fine("findPlayables: " + playableInstant.toString() + "---" + playableNonInstant.toString() + "---" + playableAbilities.toString() ); logger.debug("findPlayables: " + playableInstant.toString() + "---" + playableNonInstant.toString() + "---" + playableAbilities.toString() );
} }
@Override @Override
protected ManaOptions getManaAvailable(Game game) { protected ManaOptions getManaAvailable(Game game) {
// logger.fine("getManaAvailable"); // logger.debug("getManaAvailable");
return super.getManaAvailable(game); return super.getManaAvailable(game);
} }
@Override @Override
public boolean playMana(ManaCost unpaid, Game game) { public boolean playMana(ManaCost unpaid, Game game) {
// logger.fine("playMana"); // logger.debug("playMana");
ManaCost cost; ManaCost cost;
List<Permanent> producers; List<Permanent> producers;
if (unpaid instanceof ManaCosts) { if (unpaid instanceof ManaCosts) {
@ -627,8 +627,14 @@ public class ComputerPlayer<T extends ComputerPlayer<T>> extends PlayerImpl<T> i
} }
} }
} }
if (score > 0) // score mana producers that produce other types higher if (score > 0) { // score mana producers that produce other mana types and have other uses higher
score += permanent.getAbilities().getManaAbilities(Zone.BATTLEFIELD).size(); score += permanent.getAbilities().getManaAbilities(Zone.BATTLEFIELD).size();
score += permanent.getAbilities().getActivatedAbilities(Zone.BATTLEFIELD).size();
if (!permanent.getCardType().contains(CardType.LAND))
score+=2;
else if(permanent.getCardType().contains(CardType.CREATURE))
score+=2;
}
scored.put(permanent, score); scored.put(permanent, score);
} }
return sortByValue(scored); return sortByValue(scored);
@ -652,7 +658,7 @@ public class ComputerPlayer<T extends ComputerPlayer<T>> extends PlayerImpl<T> i
@Override @Override
public boolean playXMana(VariableManaCost cost, Game game) { public boolean playXMana(VariableManaCost cost, Game game) {
logger.fine("playXMana"); logger.debug("playXMana");
//put everything into X //put everything into X
for (Permanent perm: this.getAvailableManaProducers(game)) { for (Permanent perm: this.getAvailableManaProducers(game)) {
for (ManaAbility ability: perm.getAbilities().getManaAbilities(Zone.BATTLEFIELD)) { for (ManaAbility ability: perm.getAbilities().getManaAbilities(Zone.BATTLEFIELD)) {
@ -671,14 +677,14 @@ public class ComputerPlayer<T extends ComputerPlayer<T>> extends PlayerImpl<T> i
@Override @Override
public boolean chooseUse(Outcome outcome, String message, Game game) { public boolean chooseUse(Outcome outcome, String message, Game game) {
logger.fine("chooseUse"); logger.debug("chooseUse");
//TODO: improve this //TODO: improve this
return outcome.isGood(); return outcome.isGood();
} }
@Override @Override
public boolean choose(Outcome outcome, Choice choice, Game game) { public boolean choose(Outcome outcome, Choice choice, Game game) {
logger.fine("choose"); logger.debug("choose");
//TODO: improve this //TODO: improve this
choice.setChoice(choice.getChoices().iterator().next()); choice.setChoice(choice.getChoices().iterator().next());
return true; return true;
@ -686,7 +692,7 @@ public class ComputerPlayer<T extends ComputerPlayer<T>> extends PlayerImpl<T> i
@Override @Override
public boolean chooseTarget(Cards cards, TargetCard target, Ability source, Game game) { public boolean chooseTarget(Cards cards, TargetCard target, Ability source, Game game) {
logger.fine("chooseTarget"); logger.debug("chooseTarget");
//TODO: improve this //TODO: improve this
//return first match //return first match
if (!target.doneChosing()) { if (!target.doneChosing()) {
@ -702,7 +708,7 @@ public class ComputerPlayer<T extends ComputerPlayer<T>> extends PlayerImpl<T> i
@Override @Override
public boolean choose(Cards cards, TargetCard target, Game game) { public boolean choose(Cards cards, TargetCard target, Game game) {
logger.fine("choose"); logger.debug("choose");
//TODO: improve this //TODO: improve this
//return first match //return first match
if (!target.doneChosing()) { if (!target.doneChosing()) {
@ -718,7 +724,7 @@ public class ComputerPlayer<T extends ComputerPlayer<T>> extends PlayerImpl<T> i
@Override @Override
public void selectAttackers(Game game) { public void selectAttackers(Game game) {
logger.fine("selectAttackers"); logger.debug("selectAttackers");
UUID opponentId = game.getCombat().getDefenders().iterator().next(); UUID opponentId = game.getCombat().getDefenders().iterator().next();
Attackers attackers = getPotentialAttackers(game); Attackers attackers = getPotentialAttackers(game);
List<Permanent> blockers = getOpponentBlockers(opponentId, game); List<Permanent> blockers = getOpponentBlockers(opponentId, game);
@ -745,7 +751,7 @@ public class ComputerPlayer<T extends ComputerPlayer<T>> extends PlayerImpl<T> i
@Override @Override
public void selectBlockers(Game game) { public void selectBlockers(Game game) {
logger.fine("selectBlockers"); logger.debug("selectBlockers");
List<Permanent> blockers = getAvailableBlockers(game); List<Permanent> blockers = getAvailableBlockers(game);
@ -761,14 +767,14 @@ public class ComputerPlayer<T extends ComputerPlayer<T>> extends PlayerImpl<T> i
@Override @Override
public int chooseEffect(List<ReplacementEffect> rEffects, Game game) { public int chooseEffect(List<ReplacementEffect> rEffects, Game game) {
logger.fine("chooseEffect"); logger.debug("chooseEffect");
//TODO: implement this //TODO: implement this
return 0; return 0;
} }
@Override @Override
public TriggeredAbility chooseTriggeredAbility(TriggeredAbilities abilities, Game game) { public TriggeredAbility chooseTriggeredAbility(TriggeredAbilities abilities, Game game) {
logger.fine("chooseTriggeredAbility"); logger.debug("chooseTriggeredAbility");
//TODO: improve this //TODO: improve this
if (abilities.size() > 0) if (abilities.size() > 0)
return abilities.get(0); return abilities.get(0);
@ -777,21 +783,21 @@ public class ComputerPlayer<T extends ComputerPlayer<T>> extends PlayerImpl<T> i
@Override @Override
public void assignDamage(int damage, List<UUID> targets, UUID sourceId, Game game) { public void assignDamage(int damage, List<UUID> targets, UUID sourceId, Game game) {
logger.fine("assignDamage"); logger.debug("assignDamage");
//TODO: improve this //TODO: improve this
game.getPermanent(targets.get(0)).damage(damage, sourceId, game, true, false); game.getPermanent(targets.get(0)).damage(damage, sourceId, game, true, false);
} }
@Override @Override
public int getAmount(int min, int max, String message, Game game) { public int getAmount(int min, int max, String message, Game game) {
logger.fine("getAmount"); logger.debug("getAmount");
//TODO: improve this //TODO: improve this
return min; return min;
} }
@Override @Override
protected List<Permanent> getAvailableManaProducers(Game game) { protected List<Permanent> getAvailableManaProducers(Game game) {
// logger.fine("getAvailableManaProducers"); // logger.debug("getAvailableManaProducers");
return super.getAvailableManaProducers(game); return super.getAvailableManaProducers(game);
} }
@ -803,12 +809,73 @@ public class ComputerPlayer<T extends ComputerPlayer<T>> extends PlayerImpl<T> i
@Override @Override
public void construct(Tournament tournament, Deck deck) { public void construct(Tournament tournament, Deck deck) {
//TODO: improve this
if (deck.getCards().size() < 40) { if (deck.getCards().size() < 40) {
while (deck.getCards().size() < 40) { //pick the top 23 cards
Card card = deck.getSideboard().iterator().next(); if (chosenColors == null) {
deck.getCards().add(card); for (Card card: deck.getSideboard()) {
deck.getSideboard().remove(card); rememberPick(card, RateCard.rateCard(card, null));
}
chosenColors = chooseDeckColorsIfPossible();
}
List<Card> sortedCards = new ArrayList<Card>(deck.getSideboard());
Collections.sort(sortedCards, new Comparator<Card>() {
@Override
public int compare(Card o1, Card o2) {
Integer score1 = RateCard.rateCard(o1, chosenColors);
Integer score2 = RateCard.rateCard(o2, chosenColors);
return score2.compareTo(score1);
}
});
int cardNum = 0;
while (deck.getCards().size() < 23 && sortedCards.size() > cardNum) {
Card card = sortedCards.get(cardNum);
if (!card.getSupertype().contains("Basic")) {
deck.getCards().add(card);
deck.getSideboard().remove(card);
}
cardNum++;
}
// add basic lands
// TODO: compensate for non basic lands
Mana mana = new Mana();
for (Card card: deck.getCards()) {
mana.add(card.getManaCost().getMana());
}
double total = mana.getBlack() + mana.getBlue() + mana.getGreen() + mana.getRed() + mana.getWhite();
if (mana.getGreen() > 0) {
int numGreen = (int) Math.round(mana.getGreen() / total * 17);
for (int i = 0; i < numGreen; i++) {
Card land = Sets.findCard("Forest", true);
deck.getCards().add(land);
}
}
if (mana.getBlack() > 0) {
int numBlack = (int) Math.round(mana.getBlack() / total * 17);
for (int i = 0; i < numBlack; i++) {
Card land = Sets.findCard("Swamp", true);
deck.getCards().add(land);
}
}
if (mana.getBlue() > 0) {
int numBlue = (int) Math.round(mana.getBlue() / total * 17);
for (int i = 0; i < numBlue; i++) {
Card land = Sets.findCard("Island", true);
deck.getCards().add(land);
}
}
if (mana.getWhite() > 0) {
int numWhite = (int) Math.round(mana.getWhite() / total * 17);
for (int i = 0; i < numWhite; i++) {
Card land = Sets.findCard("Plains", true);
deck.getCards().add(land);
}
}
if (mana.getRed() > 0) {
int numRed = (int) Math.round(mana.getRed() / total * 17);
for (int i = 0; i < numRed; i++) {
Card land = Sets.findCard("Mountain", true);
deck.getCards().add(land);
}
} }
} }
tournament.submitDeck(playerId, deck); tournament.submitDeck(playerId, deck);
@ -926,7 +993,7 @@ public class ComputerPlayer<T extends ComputerPlayer<T>> extends PlayerImpl<T> i
} }
protected Attackers getPotentialAttackers(Game game) { protected Attackers getPotentialAttackers(Game game) {
logger.fine("getAvailableAttackers"); logger.debug("getAvailableAttackers");
Attackers attackers = new Attackers(); Attackers attackers = new Attackers();
List<Permanent> creatures = super.getAvailableAttackers(game); List<Permanent> creatures = super.getAvailableAttackers(game);
for (Permanent creature: creatures) { for (Permanent creature: creatures) {
@ -942,7 +1009,7 @@ public class ComputerPlayer<T extends ComputerPlayer<T>> extends PlayerImpl<T> i
} }
protected int combatPotential(Permanent creature, Game game) { protected int combatPotential(Permanent creature, Game game) {
logger.fine("combatPotential"); logger.debug("combatPotential");
if (!creature.canAttack(game)) if (!creature.canAttack(game))
return 0; return 0;
int potential = creature.getPower().getValue(); int potential = creature.getPower().getValue();
@ -955,21 +1022,21 @@ public class ComputerPlayer<T extends ComputerPlayer<T>> extends PlayerImpl<T> i
} }
// protected List<Permanent> getAvailableBlockers(Game game) { // protected List<Permanent> getAvailableBlockers(Game game) {
// logger.fine("getAvailableBlockers"); // logger.debug("getAvailableBlockers");
// FilterCreatureForCombat blockFilter = new FilterCreatureForCombat(); // FilterCreatureForCombat blockFilter = new FilterCreatureForCombat();
// List<Permanent> blockers = game.getBattlefield().getAllActivePermanents(blockFilter, playerId); // List<Permanent> blockers = game.getBattlefield().getAllActivePermanents(blockFilter, playerId);
// return blockers; // return blockers;
// } // }
protected List<Permanent> getOpponentBlockers(UUID opponentId, Game game) { protected List<Permanent> getOpponentBlockers(UUID opponentId, Game game) {
logger.fine("getOpponentBlockers"); logger.debug("getOpponentBlockers");
FilterCreatureForCombat blockFilter = new FilterCreatureForCombat(); FilterCreatureForCombat blockFilter = new FilterCreatureForCombat();
List<Permanent> blockers = game.getBattlefield().getAllActivePermanents(blockFilter, opponentId); List<Permanent> blockers = game.getBattlefield().getAllActivePermanents(blockFilter, opponentId);
return blockers; return blockers;
} }
protected CombatSimulator simulateAttack(Attackers attackers, List<Permanent> blockers, UUID opponentId, Game game) { protected CombatSimulator simulateAttack(Attackers attackers, List<Permanent> blockers, UUID opponentId, Game game) {
logger.fine("simulateAttack"); logger.debug("simulateAttack");
List<Permanent> attackersList = attackers.getAttackers(); List<Permanent> attackersList = attackers.getAttackers();
CombatSimulator best = new CombatSimulator(); CombatSimulator best = new CombatSimulator();
int bestResult = 0; int bestResult = 0;
@ -1000,7 +1067,7 @@ public class ComputerPlayer<T extends ComputerPlayer<T>> extends PlayerImpl<T> i
} }
protected CombatSimulator simulateBlock(CombatSimulator combat, List<Permanent> blockers, Game game) { protected CombatSimulator simulateBlock(CombatSimulator combat, List<Permanent> blockers, Game game) {
logger.fine("simulateBlock"); logger.debug("simulateBlock");
TreeNode<CombatSimulator> simulations; TreeNode<CombatSimulator> simulations;
@ -1073,8 +1140,8 @@ public class ComputerPlayer<T extends ComputerPlayer<T>> extends PlayerImpl<T> i
} }
protected void logState(Game game) { protected void logState(Game game) {
if (logger.isLoggable(Level.FINE)) if (logger.isDebugEnabled())
logList("computer player hand: ", new ArrayList(hand.getCards(game))); logList("computer player " + name + " hand: ", new ArrayList(hand.getCards(game)));
} }
protected void logList(String message, List<MageObject> list) { protected void logList(String message, List<MageObject> list) {
@ -1083,7 +1150,7 @@ public class ComputerPlayer<T extends ComputerPlayer<T>> extends PlayerImpl<T> i
for (MageObject object: list) { for (MageObject object: list) {
sb.append(object.getName()).append(","); sb.append(object.getName()).append(",");
} }
logger.fine(sb.toString()); logger.debug(sb.toString());
} }
protected void logAbilityList(String message, List<Ability> list) { protected void logAbilityList(String message, List<Ability> list) {
@ -1092,7 +1159,7 @@ public class ComputerPlayer<T extends ComputerPlayer<T>> extends PlayerImpl<T> i
for (Ability ability: list) { for (Ability ability: list) {
sb.append(ability.getRule()).append(","); sb.append(ability.getRule()).append(",");
} }
logger.fine(sb.toString()); logger.debug(sb.toString());
} }
private void playRemoval(List<UUID> creatures, Game game) { private void playRemoval(List<UUID> creatures, Game game) {
@ -1146,4 +1213,3 @@ public class ComputerPlayer<T extends ComputerPlayer<T>> extends PlayerImpl<T> i
} }
} }

View file

@ -44,6 +44,7 @@ import mage.Constants.PhaseStep;
import mage.Constants.RangeOfInfluence; import mage.Constants.RangeOfInfluence;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.ActivatedAbility; import mage.abilities.ActivatedAbility;
import mage.abilities.common.PassAbility;
import mage.abilities.effects.Effect; import mage.abilities.effects.Effect;
import mage.abilities.effects.SearchEffect; import mage.abilities.effects.SearchEffect;
import mage.cards.Cards; import mage.cards.Cards;
@ -161,6 +162,8 @@ public class ComputerPlayer2 extends ComputerPlayer<ComputerPlayer2> implements
while (actions.peek() != null) { while (actions.peek() != null) {
Ability ability = actions.poll(); Ability ability = actions.poll();
this.activateAbility((ActivatedAbility) ability, game); this.activateAbility((ActivatedAbility) ability, game);
if (logger.isDebugEnabled())
logger.debug("activating: " + ability);
if (ability.isUsesStack()) if (ability.isUsesStack())
usedStack = true; usedStack = true;
} }
@ -174,7 +177,7 @@ public class ComputerPlayer2 extends ComputerPlayer<ComputerPlayer2> implements
if (!getNextAction(game)) { if (!getNextAction(game)) {
Game sim = createSimulation(game); Game sim = createSimulation(game);
SimulationNode.resetCount(); SimulationNode.resetCount();
root = new SimulationNode(sim, maxDepth, playerId); root = new SimulationNode(null, sim, maxDepth, playerId);
logger.debug("simulating actions"); logger.debug("simulating actions");
addActionsTimed(new FilterAbility()); addActionsTimed(new FilterAbility());
if (root.children.size() > 0) { if (root.children.size() > 0) {
@ -224,7 +227,7 @@ public class ComputerPlayer2 extends ComputerPlayer<ComputerPlayer2> implements
if (val < beta) { if (val < beta) {
beta = val; beta = val;
bestChild = child; bestChild = child;
if (node.getCombat() == null) // if (node.getCombat() == null)
node.setCombat(child.getCombat()); node.setCombat(child.getCombat());
} }
} }
@ -232,7 +235,7 @@ public class ComputerPlayer2 extends ComputerPlayer<ComputerPlayer2> implements
if (val > alpha) { if (val > alpha) {
alpha = val; alpha = val;
bestChild = child; bestChild = child;
if (node.getCombat() == null) // if (node.getCombat() == null)
node.setCombat(child.getCombat()); node.setCombat(child.getCombat());
} }
} }
@ -272,7 +275,7 @@ public class ComputerPlayer2 extends ComputerPlayer<ComputerPlayer2> implements
SearchEffect newEffect = getSearchEffect((StackAbility) newAbility); SearchEffect newEffect = getSearchEffect((StackAbility) newAbility);
newEffect.getTarget().addTarget(targetId, newAbility, sim); newEffect.getTarget().addTarget(targetId, newAbility, sim);
sim.getStack().push(newAbility); sim.getStack().push(newAbility);
SimulationNode newNode = new SimulationNode(sim, depth, ability.getControllerId()); SimulationNode newNode = new SimulationNode(node, sim, depth, ability.getControllerId());
node.children.add(newNode); node.children.add(newNode);
newNode.getTargets().add(targetId); newNode.getTargets().add(targetId);
logger.debug("simulating search -- node#: " + SimulationNode.getCount() + "for player: " + sim.getPlayer(ability.getControllerId()).getName()); logger.debug("simulating search -- node#: " + SimulationNode.getCount() + "for player: " + sim.getPlayer(ability.getControllerId()).getName());
@ -381,12 +384,14 @@ public class ComputerPlayer2 extends ComputerPlayer<ComputerPlayer2> implements
Game sim = game.copy(); Game sim = game.copy();
if (sim.getPlayer(currentPlayer.getId()).activateAbility((ActivatedAbility) action.copy(), sim)) { if (sim.getPlayer(currentPlayer.getId()).activateAbility((ActivatedAbility) action.copy(), sim)) {
sim.applyEffects(); sim.applyEffects();
if (checkForRepeatedAction(sim, node, action, currentPlayer.getId()))
continue;
if (!sim.isGameOver() && action.isUsesStack()) { if (!sim.isGameOver() && action.isUsesStack()) {
// only pass if the last action uses the stack // only pass if the last action uses the stack
sim.getPlayer(currentPlayer.getId()).pass(); sim.getPlayer(currentPlayer.getId()).pass();
sim.getPlayerList().getNext(); sim.getPlayerList().getNext();
} }
SimulationNode newNode = new SimulationNode(sim, action, depth, currentPlayer.getId()); SimulationNode newNode = new SimulationNode(node, sim, action, depth, currentPlayer.getId());
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
logger.debug("simulating -- node #:" + SimulationNode.getCount() + " actions:" + action); logger.debug("simulating -- node #:" + SimulationNode.getCount() + " actions:" + action);
sim.checkStateAndTriggered(); sim.checkStateAndTriggered();
@ -561,7 +566,7 @@ public class ComputerPlayer2 extends ComputerPlayer<ComputerPlayer2> implements
} }
} }
sim.fireEvent(GameEvent.getEvent(GameEvent.EventType.DECLARED_ATTACKERS, playerId, playerId)); sim.fireEvent(GameEvent.getEvent(GameEvent.EventType.DECLARED_ATTACKERS, playerId, playerId));
SimulationNode newNode = new SimulationNode(sim, node.getDepth()-1, activePlayerId); SimulationNode newNode = new SimulationNode(node, sim, node.getDepth()-1, activePlayerId);
logger.debug("simulating -- node #:" + SimulationNode.getCount() + " declare attakers"); logger.debug("simulating -- node #:" + SimulationNode.getCount() + " declare attakers");
newNode.setCombat(sim.getCombat()); newNode.setCombat(sim.getCombat());
node.children.add(newNode); node.children.add(newNode);
@ -582,7 +587,7 @@ public class ComputerPlayer2 extends ComputerPlayer<ComputerPlayer2> implements
} }
} }
sim.fireEvent(GameEvent.getEvent(GameEvent.EventType.DECLARED_BLOCKERS, playerId, playerId)); sim.fireEvent(GameEvent.getEvent(GameEvent.EventType.DECLARED_BLOCKERS, playerId, playerId));
SimulationNode newNode = new SimulationNode(sim, node.getDepth()-1, defenderId); SimulationNode newNode = new SimulationNode(node, sim, node.getDepth()-1, defenderId);
logger.debug("simulating -- node #:" + SimulationNode.getCount() + " declare blockers"); logger.debug("simulating -- node #:" + SimulationNode.getCount() + " declare blockers");
newNode.setCombat(sim.getCombat()); newNode.setCombat(sim.getCombat());
node.children.add(newNode); node.children.add(newNode);
@ -648,4 +653,22 @@ public class ComputerPlayer2 extends ComputerPlayer<ComputerPlayer2> implements
return sim; return sim;
} }
private boolean checkForRepeatedAction(Game sim, SimulationNode node, Ability action, UUID playerId) {
if (action instanceof PassAbility)
return false;
int val = GameStateEvaluator.evaluate(playerId, sim);
SimulationNode test = node.getParent();
while (test != null && !test.getPlayerId().equals(playerId)) {
test = test.getParent();
}
if (test != null && test.getAbilities() != null && test.getAbilities().size() == 1) {
if (action.toString().equals(test.getAbilities().get(0).toString()) && GameStateEvaluator.evaluate(playerId, sim) == val) {
if (logger.isDebugEnabled())
logger.debug("found repeated action " + action);
return true;
}
}
return false;
}
} }

View file

@ -98,6 +98,8 @@ public class ComputerPlayer3 extends ComputerPlayer2 implements Player {
@Override @Override
public void priority(Game game) { public void priority(Game game) {
logState(game); logState(game);
if (logger.isDebugEnabled())
logger.debug("Game State: Turn-" + game.getTurnNum() + " Step-" + game.getTurn().getStepType() + " ActivePlayer-" + game.getPlayer(game.getActivePlayerId()).getName() + " PriorityPlayer-" + name);
game.firePriorityEvent(playerId); game.firePriorityEvent(playerId);
switch (game.getTurn().getStepType()) { switch (game.getTurn().getStepType()) {
case UPKEEP: case UPKEEP:
@ -154,7 +156,7 @@ public class ComputerPlayer3 extends ComputerPlayer2 implements Player {
currentScore = GameStateEvaluator.evaluate(playerId, game); currentScore = GameStateEvaluator.evaluate(playerId, game);
Game sim = createSimulation(game); Game sim = createSimulation(game);
SimulationNode.resetCount(); SimulationNode.resetCount();
root = new SimulationNode(sim, maxDepth, playerId); root = new SimulationNode(null, sim, maxDepth, playerId);
logger.debug("simulating pre combat actions -----------------------------------------------------------------------------------------"); logger.debug("simulating pre combat actions -----------------------------------------------------------------------------------------");
addActionsTimed(new FilterAbility()); addActionsTimed(new FilterAbility());
@ -171,7 +173,7 @@ public class ComputerPlayer3 extends ComputerPlayer2 implements Player {
currentScore = GameStateEvaluator.evaluate(playerId, game); currentScore = GameStateEvaluator.evaluate(playerId, game);
Game sim = createSimulation(game); Game sim = createSimulation(game);
SimulationNode.resetCount(); SimulationNode.resetCount();
root = new SimulationNode(sim, maxDepth, playerId); root = new SimulationNode(null, sim, maxDepth, playerId);
logger.debug("simulating post combat actions ----------------------------------------------------------------------------------------"); logger.debug("simulating post combat actions ----------------------------------------------------------------------------------------");
addActionsTimed(new FilterAbility()); addActionsTimed(new FilterAbility());
if (root.children.size() > 0) { if (root.children.size() > 0) {
@ -227,13 +229,13 @@ public class ComputerPlayer3 extends ComputerPlayer2 implements Player {
else { else {
switch (game.getTurn().getStepType()) { switch (game.getTurn().getStepType()) {
case PRECOMBAT_MAIN: case PRECOMBAT_MAIN:
val = -simulateCombat(game, node, depth-1, alpha, beta, false); val = simulateCombat(game, node, depth-1, alpha, beta, false);
break; break;
case POSTCOMBAT_MAIN: case POSTCOMBAT_MAIN:
val = -simulateCounterAttack(game, node, depth-1, alpha, beta); val = simulateCounterAttack(game, node, depth-1, alpha, beta);
break; break;
default: default:
val = -GameStateEvaluator.evaluate(playerId, game); val = GameStateEvaluator.evaluate(playerId, game);
break; break;
} }
} }
@ -316,6 +318,8 @@ public class ComputerPlayer3 extends ComputerPlayer2 implements Player {
SimulationNode bestNode = null; SimulationNode bestNode = null;
SimulatedPlayer attacker = (SimulatedPlayer) game.getPlayer(attackerId); SimulatedPlayer attacker = (SimulatedPlayer) game.getPlayer(attackerId);
if (logger.isDebugEnabled())
logger.debug(attacker.getName() + "'s possible attackers: " + attacker.getAvailableAttackers(game));
for (Combat engagement: attacker.addAttackers(game)) { for (Combat engagement: attacker.addAttackers(game)) {
if (alpha >= beta) { if (alpha >= beta) {
logger.debug("simulating -- pruning attackers"); logger.debug("simulating -- pruning attackers");
@ -329,9 +333,9 @@ public class ComputerPlayer3 extends ComputerPlayer2 implements Player {
} }
} }
sim.fireEvent(GameEvent.getEvent(GameEvent.EventType.DECLARED_ATTACKERS, playerId, playerId)); sim.fireEvent(GameEvent.getEvent(GameEvent.EventType.DECLARED_ATTACKERS, playerId, playerId));
SimulationNode newNode = new SimulationNode(sim, depth, game.getActivePlayerId()); SimulationNode newNode = new SimulationNode(node, sim, depth, attackerId);
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
logger.debug("simulating attack -- node#: " + SimulationNode.getCount()); logger.debug("simulating attack for player:" + game.getPlayer(newNode.getPlayerId()).getName());
sim.checkStateAndTriggered(); sim.checkStateAndTriggered();
while (!sim.getStack().isEmpty()) { while (!sim.getStack().isEmpty()) {
sim.getStack().resolve(sim); sim.getStack().resolve(sim);
@ -379,6 +383,8 @@ public class ComputerPlayer3 extends ComputerPlayer2 implements Player {
//check if defender is being attacked //check if defender is being attacked
if (game.getCombat().isAttacked(defenderId, game)) { if (game.getCombat().isAttacked(defenderId, game)) {
SimulatedPlayer defender = (SimulatedPlayer) game.getPlayer(defenderId); SimulatedPlayer defender = (SimulatedPlayer) game.getPlayer(defenderId);
if (logger.isDebugEnabled())
logger.debug(defender.getName() + "'s possible blockers: " + defender.getAvailableBlockers(game));
for (Combat engagement: defender.addBlockers(game)) { for (Combat engagement: defender.addBlockers(game)) {
if (alpha >= beta) { if (alpha >= beta) {
logger.debug("simulating -- pruning blockers"); logger.debug("simulating -- pruning blockers");
@ -394,9 +400,9 @@ public class ComputerPlayer3 extends ComputerPlayer2 implements Player {
} }
} }
sim.fireEvent(GameEvent.getEvent(GameEvent.EventType.DECLARED_BLOCKERS, playerId, playerId)); sim.fireEvent(GameEvent.getEvent(GameEvent.EventType.DECLARED_BLOCKERS, playerId, playerId));
SimulationNode newNode = new SimulationNode(sim, depth, defenderId); SimulationNode newNode = new SimulationNode(node, sim, depth, defenderId);
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
logger.debug("simulating block -- node#: " + SimulationNode.getCount()); logger.debug("simulating block for player:" + game.getPlayer(newNode.getPlayerId()).getName());
sim.checkStateAndTriggered(); sim.checkStateAndTriggered();
while (!sim.getStack().isEmpty()) { while (!sim.getStack().isEmpty()) {
sim.getStack().resolve(sim); sim.getStack().resolve(sim);

View file

@ -6,8 +6,6 @@
package mage.player.ai; package mage.player.ai;
import java.util.UUID; import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
import mage.Constants.CardType; import mage.Constants.CardType;
import mage.Constants.Zone; import mage.Constants.Zone;
import mage.abilities.ActivatedAbility; import mage.abilities.ActivatedAbility;
@ -18,7 +16,7 @@ import mage.abilities.mana.ManaAbility;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.players.Player; import mage.players.Player;
import mage.util.Logging; import org.apache.log4j.Logger;
/** /**
* *
@ -29,7 +27,7 @@ import mage.util.Logging;
*/ */
public class GameStateEvaluator { public class GameStateEvaluator {
private final static transient Logger logger = Logging.getLogger(GameStateEvaluator.class.getName()); private final static transient Logger logger = Logger.getLogger(GameStateEvaluator.class);
private static final int LIFE_FACTOR = Config.evaluatorLifeFactor; private static final int LIFE_FACTOR = Config.evaluatorLifeFactor;
private static final int PERMANENT_FACTOR = Config.evaluatorPermanentFactor; private static final int PERMANENT_FACTOR = Config.evaluatorPermanentFactor;
@ -56,13 +54,12 @@ public class GameStateEvaluator {
permanentScore *= PERMANENT_FACTOR; permanentScore *= PERMANENT_FACTOR;
int handScore = 0; int handScore = 0;
handScore = 7 - opponent.getHand().size(); handScore = player.getHand().size() - opponent.getHand().size();
handScore += Math.min(7, player.getHand().size());
handScore *= HAND_FACTOR; handScore *= HAND_FACTOR;
int score = lifeScore + permanentScore + handScore; int score = lifeScore + permanentScore + handScore;
if (logger.isLoggable(Level.FINE)) if (logger.isDebugEnabled())
logger.fine("game state evaluated to- lifeScore:" + lifeScore + " permanentScore:" + permanentScore + " handScore:" + handScore + " total:" + score); logger.debug("game state evaluated to- lifeScore:" + lifeScore + " permanentScore:" + permanentScore + " handScore:" + handScore + " total:" + score);
return score; return score;
} }

View file

@ -221,7 +221,7 @@ public class SimulatedPlayer extends ComputerPlayer<SimulatedPlayer> {
sim.getStack().push(new StackAbility(ability, playerId)); sim.getStack().push(new StackAbility(ability, playerId));
ability.activate(sim, false); ability.activate(sim, false);
sim.applyEffects(); sim.applyEffects();
SimulationNode newNode = new SimulationNode(sim, depth, playerId); SimulationNode newNode = new SimulationNode(parent, sim, depth, playerId);
logger.debug("simulating -- node #:" + SimulationNode.getCount() + " triggered ability option"); logger.debug("simulating -- node #:" + SimulationNode.getCount() + " triggered ability option");
for (Target target: ability.getTargets()) { for (Target target: ability.getTargets()) {
for (UUID targetId: target.getTargets()) { for (UUID targetId: target.getTargets()) {

View file

@ -49,12 +49,14 @@ public class SimulationNode implements Serializable {
protected List<Ability> abilities; protected List<Ability> abilities;
protected int depth; protected int depth;
protected List<SimulationNode> children = new ArrayList<SimulationNode>(); protected List<SimulationNode> children = new ArrayList<SimulationNode>();
protected SimulationNode parent;
protected List<UUID> targets = new ArrayList<UUID>(); protected List<UUID> targets = new ArrayList<UUID>();
protected List<String> choices = new ArrayList<String>(); protected List<String> choices = new ArrayList<String>();
protected UUID playerId; protected UUID playerId;
protected Combat combat; protected Combat combat;
public SimulationNode(Game game, int depth, UUID playerId) { public SimulationNode(SimulationNode parent, Game game, int depth, UUID playerId) {
this.parent = parent;
this.game = game; this.game = game;
this.depth = depth; this.depth = depth;
this.playerId = playerId; this.playerId = playerId;
@ -62,13 +64,13 @@ public class SimulationNode implements Serializable {
nodeCount++; nodeCount++;
} }
public SimulationNode(Game game, List<Ability> abilities, int depth, UUID playerId) { public SimulationNode(SimulationNode parent, Game game, List<Ability> abilities, int depth, UUID playerId) {
this(game, depth, playerId); this(parent, game, depth, playerId);
this.abilities = abilities; this.abilities = abilities;
} }
public SimulationNode(Game game, Ability ability, int depth, UUID playerId) { public SimulationNode(SimulationNode parent, Game game, Ability ability, int depth, UUID playerId) {
this(game, depth, playerId); this(parent, game, depth, playerId);
this.abilities = new ArrayList<Ability>(); this.abilities = new ArrayList<Ability>();
abilities.add(ability); abilities.add(ability);
} }
@ -97,6 +99,10 @@ public class SimulationNode implements Serializable {
return this.abilities; return this.abilities;
} }
public SimulationNode getParent() {
return this.parent;
}
public List<SimulationNode> getChildren() { public List<SimulationNode> getChildren() {
return this.children; return this.children;
} }

Binary file not shown.

View file

@ -191,7 +191,7 @@ public class TournamentController {
TableManager.getInstance().construct(tableId); TableManager.getInstance().construct(tableId);
} }
private synchronized void construct(UUID sessionId, Deck deck, int timeout) { private void construct(UUID sessionId, Deck deck, int timeout) {
if (tournamentSessions.containsKey(sessionId)) if (tournamentSessions.containsKey(sessionId))
tournamentSessions.get(sessionId).construct(deck, timeout); tournamentSessions.get(sessionId).construct(deck, timeout);
} }

View file

@ -66,6 +66,26 @@ public class Mana implements Comparable<Mana>, Serializable, Copyable<Mana> {
any = mana.any; any = mana.any;
} }
public Mana(ColoredManaSymbol color) {
switch (color) {
case G:
green = 1;
break;
case R:
red = 1;
break;
case B:
black = 1;
break;
case U:
blue = 1;
break;
case W:
white = 1;
break;
}
}
public static Mana RedMana(int num) { public static Mana RedMana(int num) {
return new Mana(num, 0, 0, 0, 0, 0, 0); return new Mana(num, 0, 0, 0, 0, 0, 0);
} }

View file

@ -38,6 +38,7 @@ public class ColoredManaCost extends ManaCostImpl<ColoredManaCost> {
public ColoredManaCost(ColoredManaSymbol mana) { public ColoredManaCost(ColoredManaSymbol mana) {
this.mana = mana; this.mana = mana;
this.cost = new Mana(mana);
addColoredOption(mana); addColoredOption(mana);
} }
@ -46,10 +47,6 @@ public class ColoredManaCost extends ManaCostImpl<ColoredManaCost> {
this.mana = cost.mana; this.mana = cost.mana;
} }
public ColoredManaSymbol getMana() {
return mana;
}
@Override @Override
public int convertedManaCost() { public int convertedManaCost() {
return 1; return 1;

View file

@ -37,6 +37,7 @@ public class GenericManaCost extends ManaCostImpl<GenericManaCost> {
public GenericManaCost(int mana) { public GenericManaCost(int mana) {
this.mana = mana; this.mana = mana;
this.cost = Mana.ColorlessMana(mana);
this.options.addMana(Mana.ColorlessMana(mana)); this.options.addMana(Mana.ColorlessMana(mana));
} }
@ -45,10 +46,6 @@ public class GenericManaCost extends ManaCostImpl<GenericManaCost> {
this.mana = cost.mana; this.mana = cost.mana;
} }
public int getMana() {
return mana;
}
public void setMana(int mana) { public void setMana(int mana) {
this.mana = mana; this.mana = mana;
} }

View file

@ -39,6 +39,8 @@ public class HybridManaCost extends ManaCostImpl<HybridManaCost> {
public HybridManaCost(ColoredManaSymbol mana1, ColoredManaSymbol mana2) { public HybridManaCost(ColoredManaSymbol mana1, ColoredManaSymbol mana2) {
this.mana1 = mana1; this.mana1 = mana1;
this.mana2 = mana2; this.mana2 = mana2;
this.cost = new Mana(mana1);
this.cost.add(new Mana(mana2));
addColoredOption(mana1); addColoredOption(mana1);
addColoredOption(mana2); addColoredOption(mana2);
} }
@ -54,14 +56,6 @@ public class HybridManaCost extends ManaCostImpl<HybridManaCost> {
return 1; return 1;
} }
public ColoredManaSymbol getMana1() {
return mana1;
}
public ColoredManaSymbol getMana2() {
return mana2;
}
@Override @Override
public boolean isPaid() { public boolean isPaid() {
if (paid || isColoredPaid(this.mana1) || isColoredPaid(this.mana2)) if (paid || isColoredPaid(this.mana1) || isColoredPaid(this.mana2))

View file

@ -36,6 +36,7 @@ import mage.players.ManaPool;
public interface ManaCost extends Cost { public interface ManaCost extends Cost {
public int convertedManaCost(); public int convertedManaCost();
public Mana getMana();
public Mana getPayment(); public Mana getPayment();
public void assignPayment(ManaPool pool); public void assignPayment(ManaPool pool);
@Override @Override
@ -46,4 +47,5 @@ public interface ManaCost extends Cost {
@Override @Override
public ManaCost copy(); public ManaCost copy();
} }

View file

@ -31,7 +31,6 @@ package mage.abilities.costs.mana;
import java.util.UUID; import java.util.UUID;
import mage.Constants.ColoredManaSymbol; import mage.Constants.ColoredManaSymbol;
import mage.Mana; import mage.Mana;
import mage.abilities.Ability;
import mage.abilities.costs.CostImpl; import mage.abilities.costs.CostImpl;
import mage.abilities.mana.ManaOptions; import mage.abilities.mana.ManaOptions;
import mage.game.Game; import mage.game.Game;
@ -41,6 +40,7 @@ import mage.players.Player;
public abstract class ManaCostImpl<T extends ManaCostImpl<T>> extends CostImpl<T> implements ManaCost { public abstract class ManaCostImpl<T extends ManaCostImpl<T>> extends CostImpl<T> implements ManaCost {
protected Mana payment; protected Mana payment;
protected Mana cost;
protected ManaOptions options; protected ManaOptions options;
@Override @Override
@ -62,6 +62,11 @@ public abstract class ManaCostImpl<T extends ManaCostImpl<T>> extends CostImpl<T
return payment; return payment;
} }
@Override
public Mana getMana() {
return cost;
}
@Override @Override
public ManaOptions getOptions() { public ManaOptions getOptions() {
return options; return options;

View file

@ -29,6 +29,7 @@
package mage.abilities.costs.mana; package mage.abilities.costs.mana;
import java.util.List; import java.util.List;
import mage.Mana;
import mage.abilities.costs.VariableCost; import mage.abilities.costs.VariableCost;
/** /**
@ -41,6 +42,7 @@ public interface ManaCosts<T extends ManaCost> extends List<T>, ManaCost {
public List<VariableCost> getVariableCosts(); public List<VariableCost> getVariableCosts();
public void load(String mana); public void load(String mana);
public List<String> getSymbols(); public List<String> getSymbols();
public Mana getMana();
@Override @Override
public ManaCosts<T> copy(); public ManaCosts<T> copy();

View file

@ -81,6 +81,15 @@ public class ManaCostsImpl<T extends ManaCost> extends ArrayList<T> implements M
return total; return total;
} }
@Override
public Mana getMana() {
Mana mana = new Mana();
for (ManaCost cost: this) {
mana.add(cost.getMana());
}
return mana;
}
@Override @Override
public Mana getPayment() { public Mana getPayment() {
Mana manaTotal = new Mana(); Mana manaTotal = new Mana();

View file

@ -39,6 +39,8 @@ public class MonoHybridManaCost extends ManaCostImpl<MonoHybridManaCost> {
public MonoHybridManaCost(ColoredManaSymbol mana) { public MonoHybridManaCost(ColoredManaSymbol mana) {
this.mana = mana; this.mana = mana;
this.cost = new Mana(mana);
this.cost.add(Mana.ColorlessMana(2));
addColoredOption(mana); addColoredOption(mana);
options.add(Mana.ColorlessMana(2)); options.add(Mana.ColorlessMana(2));
} }
@ -54,10 +56,6 @@ public class MonoHybridManaCost extends ManaCostImpl<MonoHybridManaCost> {
return 2; return 2;
} }
public ColoredManaSymbol getMana() {
return mana;
}
@Override @Override
public boolean isPaid() { public boolean isPaid() {
if (paid || isColoredPaid(this.mana)) if (paid || isColoredPaid(this.mana))

View file

@ -43,6 +43,7 @@ public class VariableManaCost extends ManaCostImpl<VariableManaCost> implements
public VariableManaCost() { public VariableManaCost() {
this(1); this(1);
this.cost = new Mana();
options.add(new Mana()); options.add(new Mana());
} }

View file

@ -58,7 +58,7 @@ public abstract class DraftImpl<T extends DraftImpl<T>> implements Draft {
protected int boosterNum = 0; protected int boosterNum = 0;
protected int cardNum = 0; protected int cardNum = 0;
protected TimingOption timing; protected TimingOption timing;
protected int[] times = {40, 40, 35, 30, 25, 25, 20, 20, 15, 10, 10, 5, 5, 5, 5}; protected int[] times = {75, 70, 65, 60, 55, 50, 45, 40, 35, 30, 25, 20, 15, 10, 5};
protected transient TableEventSource tableEventSource = new TableEventSource(); protected transient TableEventSource tableEventSource = new TableEventSource();
protected transient PlayerQueryEventSource playerQueryEventSource = new PlayerQueryEventSource(); protected transient PlayerQueryEventSource playerQueryEventSource = new PlayerQueryEventSource();

View file

@ -28,6 +28,7 @@
package mage.game.draft; package mage.game.draft;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import mage.cards.Card; import mage.cards.Card;
@ -68,12 +69,16 @@ public class DraftPlayer {
public void addPick(Card card) { public void addPick(Card card) {
deck.getSideboard().add(card); deck.getSideboard().add(card);
booster.remove(card); synchronized(booster) {
booster.remove(card);
}
picking = false; picking = false;
} }
public void openBooster(ExpansionSet set) { public void openBooster(ExpansionSet set) {
booster = set.createBooster(); synchronized(booster) {
booster = set.createBooster();
}
} }
public void setBooster(List<Card> booster) { public void setBooster(List<Card> booster) {
@ -81,7 +86,9 @@ public class DraftPlayer {
} }
public List<Card> getBooster() { public List<Card> getBooster() {
return booster; synchronized(booster) {
return new ArrayList<Card>(booster);
}
} }
public void setPicking() { public void setPicking() {

View file

@ -104,6 +104,11 @@ public abstract class PermanentImpl<T extends PermanentImpl<T>> extends CardImpl
this.attachedTo = permanent.attachedTo; this.attachedTo = permanent.attachedTo;
} }
@Override
public String toString() {
return this.name + "-" + this.expansionSetCode;
}
@Override @Override
public void reset(Game game) { public void reset(Game game) {
// this.controllerId = ownerId; // this.controllerId = ownerId;

View file

@ -228,9 +228,15 @@ public abstract class TournamentImpl implements Tournament {
public void construct() { public void construct() {
tableEventSource.fireTableEvent(EventType.CONSTRUCT); tableEventSource.fireTableEvent(EventType.CONSTRUCT);
for (TournamentPlayer player: players.values()) { for (final TournamentPlayer player: players.values()) {
player.setConstructing(); player.setConstructing();
player.getPlayer().construct(this, player.getDeck()); new Thread(
new Runnable() {
public void run() {
player.getPlayer().construct(TournamentImpl.this, player.getDeck());
}
}
).start();
} }
synchronized(this) { synchronized(this) {
while (!isDoneConstructing()) { while (!isDoneConstructing()) {