mirror of
https://github.com/correl/mage.git
synced 2024-12-24 11:50:45 +00:00
improved AI targetting
This commit is contained in:
parent
6ea73a6726
commit
aed200bc11
13 changed files with 129 additions and 105 deletions
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue