improved AI targetting

This commit is contained in:
BetaSteward 2011-03-31 23:34:16 -04:00
parent 6ea73a6726
commit aed200bc11
13 changed files with 129 additions and 105 deletions

View file

@ -566,9 +566,9 @@ public class ComputerPlayer6 extends ComputerPlayer<ComputerPlayer6> implements
}
@Override
public boolean chooseTarget(Cards cards, TargetCard target, Ability source, Game game) {
public boolean chooseTarget(Outcome outcome, Cards cards, TargetCard target, Ability source, Game game) {
if (targets.size() == 0)
return super.chooseTarget(cards, target, source, game);
return super.chooseTarget(outcome, cards, target, source, game);
if (!target.doneChosing()) {
for (UUID targetId: targets) {
target.addTarget(targetId, source, game);
@ -583,9 +583,9 @@ public class ComputerPlayer6 extends ComputerPlayer<ComputerPlayer6> implements
}
@Override
public boolean choose(Cards cards, TargetCard target, Game game) {
public boolean choose(Outcome outcome, Cards cards, TargetCard target, Game game) {
if (targets.size() == 0)
return super.choose(cards, target, game);
return super.choose(outcome, cards, target, game);
if (!target.doneChosing()) {
for (UUID targetId: targets) {
target.add(targetId, game);

View file

@ -363,13 +363,19 @@ public class ComputerPlayer<T extends ComputerPlayer<T>> extends PlayerImpl<T> i
else {
card = pickWorstCard(cards, null);
}
if (target.canTarget(card.getId(), source, game)) {
if (source != null) {
if (target.canTarget(card.getId(), source, game)) {
return card;
}
}
else {
return card;
}
cards.remove(card);
}
return null;
}
@Override
public boolean chooseTargetAmount(Outcome outcome, TargetAmount target, Ability source, Game game) {
if (logger.isDebugEnabled())
@ -768,33 +774,35 @@ public class ComputerPlayer<T extends ComputerPlayer<T>> extends PlayerImpl<T> i
}
@Override
public boolean chooseTarget(Cards cards, TargetCard target, Ability source, Game game) {
public boolean chooseTarget(Outcome outcome, Cards cards, TargetCard target, Ability source, Game game) {
logger.debug("chooseTarget");
//TODO: improve this
//return first match
if (!target.doneChosing()) {
for (Card card: cards.getCards(target.getFilter(), game)) {
target.addTarget(card.getId(), source, game);
if (target.doneChosing())
return true;
while (!target.doneChosing()) {
if (cards.isEmpty()) {
if (!target.isRequired())
return false;
return true;
}
Card card = pickTarget(new ArrayList<Card>(cards.getCards(target.getFilter(), game)), outcome, target, source, game);
if (card != null) {
target.addTarget(card.getId(), source, game);
}
return false;
}
return true;
}
@Override
public boolean choose(Cards cards, TargetCard target, Game game) {
public boolean choose(Outcome outcome, Cards cards, TargetCard target, Game game) {
logger.debug("choose");
//TODO: improve this
//return first match
if (!target.doneChosing()) {
for (Card card: cards.getCards(target.getFilter(), game)) {
target.add(card.getId(), game);
if (target.doneChosing())
return true;
while (!target.doneChosing()) {
if (cards.isEmpty()) {
if (!target.isRequired())
return false;
return true;
}
Card card = pickTarget(new ArrayList<Card>(cards.getCards(target.getFilter(), game)), outcome, target, null, game);
if (card != null) {
target.add(card.getId(), game);
}
return false;
}
return true;
}
@ -884,6 +892,77 @@ public class ComputerPlayer<T extends ComputerPlayer<T>> extends PlayerImpl<T> i
match.submitDeck(playerId, deck);
}
public static Deck buildDeck(List<Card> cardPool, final List<Constants.ColoredManaSymbol> colors) {
Deck deck = new Deck();
List<Card> sortedCards = new ArrayList<Card>(cardPool);
Collections.sort(sortedCards, new Comparator<Card>() {
@Override
public int compare(Card o1, Card o2) {
Integer score1 = RateCard.rateCard(o1, colors);
Integer score2 = RateCard.rateCard(o2, colors);
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);
}
}
while (deck.getCards().size() < 40) {
//TODO: improve this
Card land = Sets.findCard("Forest", true);
deck.getCards().add(land);
}
return deck;
}
@Override
public void construct(Tournament tournament, Deck deck) {
if (deck.getCards().size() < 40) {
@ -894,66 +973,7 @@ public class ComputerPlayer<T extends ComputerPlayer<T>> extends PlayerImpl<T> i
}
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);
}
}
deck = buildDeck(new ArrayList<Card>(deck.getSideboard()), chosenColors);
}
tournament.submitDeck(playerId, deck);
}

View file

@ -514,9 +514,9 @@ public class ComputerPlayer2 extends ComputerPlayer<ComputerPlayer2> implements
}
@Override
public boolean chooseTarget(Cards cards, TargetCard target, Ability source, Game game) {
public boolean chooseTarget(Outcome outcome, Cards cards, TargetCard target, Ability source, Game game) {
if (targets.size() == 0)
return super.chooseTarget(cards, target, source, game);
return super.chooseTarget(outcome, cards, target, source, game);
if (!target.doneChosing()) {
for (UUID targetId: targets) {
target.addTarget(targetId, source, game);
@ -531,9 +531,9 @@ public class ComputerPlayer2 extends ComputerPlayer<ComputerPlayer2> implements
}
@Override
public boolean choose(Cards cards, TargetCard target, Game game) {
public boolean choose(Outcome outcome, Cards cards, TargetCard target, Game game) {
if (targets.size() == 0)
return super.choose(cards, target, game);
return super.choose(outcome, cards, target, game);
if (!target.doneChosing()) {
for (UUID targetId: targets) {
target.add(targetId, game);

View file

@ -236,7 +236,7 @@ public class HumanPlayer extends PlayerImpl<HumanPlayer> {
}
@Override
public boolean choose(Cards cards, TargetCard target, Game game) {
public boolean choose(Outcome outcome, Cards cards, TargetCard target, Game game) {
while (!abort) {
game.fireSelectTargetEvent(playerId, target.getMessage(), cards, target.isRequired());
waitForResponse();
@ -253,7 +253,7 @@ public class HumanPlayer extends PlayerImpl<HumanPlayer> {
}
@Override
public boolean chooseTarget(Cards cards, TargetCard target, Ability source, Game game) {
public boolean chooseTarget(Outcome outcome, Cards cards, TargetCard target, Ability source, Game game) {
while (!abort) {
game.fireSelectTargetEvent(playerId, target.getMessage(), cards, target.isRequired());
waitForResponse();

View file

@ -100,7 +100,7 @@ class DuressEffect extends OneShotEffect<DuressEffect> {
Player you = game.getPlayer(source.getControllerId());
if (you != null) {
TargetCard target = new TargetCard(Zone.PICK, filter);
if (you.choose(player.getHand(), target, game)) {
if (you.choose(Outcome.Benefit, player.getHand(), target, game)) {
Card card = player.getHand().get(target.getFirstTarget(), game);
if (card != null) {
return player.discard(card, source, game);

View file

@ -110,7 +110,7 @@ class CultivateEffect extends OneShotEffect<CultivateEffect> {
if (target.getTargets().size() == 2) {
TargetCard target2 = new TargetCard(Zone.PICK, filter);
target2.setRequired(true);
player.choose(revealed, target2, game);
player.choose(Outcome.Benefit, revealed, target2, game);
Card card = revealed.get(target2.getFirstTarget(), game);
card.putOntoBattlefield(game, Zone.LIBRARY, source.getId(), source.getControllerId());
revealed.remove(card);

View file

@ -103,7 +103,7 @@ class InquisitionOfKozilekEffect extends OneShotEffect<InquisitionOfKozilekEffec
Player you = game.getPlayer(source.getControllerId());
if (you != null) {
TargetCard target = new TargetCard(Zone.PICK, filter);
if (you.choose(player.getHand(), target, game)) {
if (you.choose(Outcome.Benefit, player.getHand(), target, game)) {
Card card = player.getHand().get(target.getFirstTarget(), game);
if (card != null) {
return player.discard(card, source, game);

View file

@ -110,7 +110,7 @@ class SeaGateOracleEffect extends OneShotEffect<SeaGateOracleEffect> {
TargetCard target = new TargetCard(Zone.PICK, filter);
target.setRequired(true);
player.lookAtCards(cards, game);
player.choose(cards, target, game);
player.choose(Outcome.Benefit, cards, target, game);
card = cards.get(target.getFirstTarget(), game);
if (card != null) {
card.moveToZone(Zone.HAND, source.getId(), game, false);

View file

@ -90,7 +90,7 @@ class SeeBeyondEffect extends OneShotEffect<SeeBeyondEffect> {
if (player.getHand().size() > 0) {
TargetCard target = new TargetCard(Zone.HAND, filter);
target.setRequired(true);
player.choose(player.getHand(), target, game);
player.choose(Outcome.Detriment, player.getHand(), target, game);
Card card = player.getHand().get(target.getFirstTarget(), game);
if (card != null) {
player.removeFromHand(card, game);

View file

@ -97,7 +97,7 @@ class HalimarDepthsEffect extends OneShotEffect<HalimarDepthsEffect> {
TargetCard target2 = new TargetCard(Zone.PICK, filter2);
target2.setRequired(true);
while (cards.size() > 1) {
player.choose(cards, target2, game);
player.choose(Outcome.Detriment, cards, target2, game);
Card card = cards.get(target2.getFirstTarget(), game);
cards.remove(card);
card.moveToZone(Zone.LIBRARY, source.getId(), game, true);

View file

@ -71,20 +71,24 @@ public class ScryEffect extends OneShotEffect<ScryEffect> {
game.setZone(card.getId(), Zone.PICK);
}
TargetCard target1 = new TargetCard(Zone.PICK, filter1);
while (cards.size() > 0 && player.choose(cards, target1, game)) {
while (cards.size() > 0 && player.choose(Outcome.Detriment, cards, target1, game)) {
Card card = cards.get(target1.getFirstTarget(), game);
cards.remove(card);
card.moveToZone(Zone.LIBRARY, source.getId(), game, false);
if (card != null) {
cards.remove(card);
card.moveToZone(Zone.LIBRARY, source.getId(), game, false);
}
target1.clearChosen();
}
if (cards.size() > 1) {
TargetCard target2 = new TargetCard(Zone.PICK, filter2);
target2.setRequired(true);
while (cards.size() > 1) {
player.choose(cards, target2, game);
player.choose(Outcome.Benefit, cards, target2, game);
Card card = cards.get(target2.getFirstTarget(), game);
cards.remove(card);
card.moveToZone(Zone.LIBRARY, source.getId(), game, true);
if (card != null) {
cards.remove(card);
card.moveToZone(Zone.LIBRARY, source.getId(), game, true);
}
target2.clearChosen();
}
}

View file

@ -144,9 +144,9 @@ public interface Player extends MageItem, Copyable<Player> {
public abstract void priority(Game game);
public abstract boolean choose(Outcome outcome, Target target, Game game);
public abstract boolean choose(Outcome outcome, Target target, Game game, Map<String, Serializable> options);
public abstract boolean choose(Cards cards, TargetCard target, Game game);
public abstract boolean choose(Outcome outcome, Cards cards, TargetCard target, Game game);
public abstract boolean chooseTarget(Outcome outcome, Target target, Ability source, Game game);
public abstract boolean chooseTarget(Cards cards, TargetCard target, Ability source, Game game);
public abstract boolean chooseTarget(Outcome outcome, Cards cards, TargetCard target, Ability source, Game game);
public abstract boolean chooseTargetAmount(Outcome outcome, TargetAmount target, Ability source, Game game);
public abstract boolean chooseMulligan(Game game);
public abstract boolean chooseUse(Outcome outcome, String message, Game game);

View file

@ -70,13 +70,13 @@ public class TargetCardInLibrary extends TargetCard<TargetCardInLibrary> {
Player player = game.getPlayer(playerId);
while (!isChosen() && !doneChosing()) {
chosen = targets.size() >= minNumberOfTargets;
if (!player.choose(new CardsImpl(Zone.LIBRARY, player.getLibrary().getCards(game)), this, game)) {
if (!player.choose(outcome, new CardsImpl(Zone.LIBRARY, player.getLibrary().getCards(game)), this, game)) {
return chosen;
}
chosen = targets.size() >= minNumberOfTargets;
}
while (!doneChosing()) {
if (!player.choose(new CardsImpl(Zone.LIBRARY, player.getLibrary().getCards(game)), this, game)) {
if (!player.choose(outcome, new CardsImpl(Zone.LIBRARY, player.getLibrary().getCards(game)), this, game)) {
break;
}
}