mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-18 19:58:00 +00:00
- Rewriting Booster Draft to be a bit more capable of handling Draft Matters cards
This commit is contained in:
2
.gitattributes
vendored
2
.gitattributes
vendored
@@ -19750,6 +19750,8 @@ forge-gui/src/main/java/forge/limited/DraftRankCache.java -text
|
||||
forge-gui/src/main/java/forge/limited/GauntletMini.java -text
|
||||
forge-gui/src/main/java/forge/limited/IBoosterDraft.java svneol=native#text/plain
|
||||
forge-gui/src/main/java/forge/limited/LimitedDeckBuilder.java -text
|
||||
forge-gui/src/main/java/forge/limited/LimitedPlayer.java -text
|
||||
forge-gui/src/main/java/forge/limited/LimitedPlayerAI.java -text
|
||||
forge-gui/src/main/java/forge/limited/LimitedPoolType.java -text
|
||||
forge-gui/src/main/java/forge/limited/LimitedWinLoseController.java -text
|
||||
forge-gui/src/main/java/forge/limited/ReadDraftRankings.java -text
|
||||
|
||||
@@ -7,6 +7,7 @@ import forge.game.card.Card;
|
||||
import forge.item.PaperCard;
|
||||
import forge.item.SealedProduct;
|
||||
import forge.limited.IBoosterDraft;
|
||||
import forge.limited.LimitedPlayer;
|
||||
import forge.model.FModel;
|
||||
|
||||
import org.testng.annotations.Test;
|
||||
@@ -24,29 +25,14 @@ import java.util.List;
|
||||
@Test(groups = { "UnitTest" }, timeOut = 1000, enabled = false)
|
||||
public class BoosterDraftTest implements IBoosterDraft {
|
||||
|
||||
/** The n. */
|
||||
private int n = 3;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* getDecks.
|
||||
* </p>
|
||||
*
|
||||
* @return an array of {@link forge.deck.Deck} objects.
|
||||
*/
|
||||
@Override
|
||||
@Test(timeOut = 1000)
|
||||
public Deck[] getDecks() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* nextChoice.
|
||||
* </p>
|
||||
*
|
||||
* @return a {@link forge.CardList} object.
|
||||
*/
|
||||
@Override
|
||||
public CardPool nextChoice() {
|
||||
this.n--;
|
||||
@@ -62,13 +48,6 @@ public class BoosterDraftTest implements IBoosterDraft {
|
||||
System.out.println(c.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* hasNextChoice.
|
||||
* </p>
|
||||
*
|
||||
* @return a boolean.
|
||||
*/
|
||||
@Override
|
||||
public boolean hasNextChoice() {
|
||||
return this.n > 0;
|
||||
@@ -79,24 +58,10 @@ public class BoosterDraftTest implements IBoosterDraft {
|
||||
return hasNextChoice();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* getChosenCards.
|
||||
* </p>
|
||||
*
|
||||
* @return a {@link forge.CardList} object.
|
||||
*/
|
||||
public List<Card> getChosenCards() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* getUnchosenCards.
|
||||
* </p>
|
||||
*
|
||||
* @return a {@link forge.CardList} object.
|
||||
*/
|
||||
public List<Card> getUnchosenCards() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -43,18 +43,16 @@ import java.util.*;
|
||||
* Booster Draft Format.
|
||||
*/
|
||||
public class BoosterDraft implements IBoosterDraft {
|
||||
private final BoosterDraftAI draftAI = new BoosterDraftAI();
|
||||
private static final int N_PLAYERS = 8;
|
||||
public static final String FILE_EXT = ".draft";
|
||||
private final List<LimitedPlayer> players = new ArrayList<>();
|
||||
private LimitedPlayer localPlayer;
|
||||
|
||||
protected int nextBoosterGroup = 0;
|
||||
private int currentBoosterSize = 0;
|
||||
private int currentBoosterPick = 0;
|
||||
private int[] draftingBooster;
|
||||
private int packsInDraft;
|
||||
|
||||
private List<List<PaperCard>> pack; // size 8
|
||||
|
||||
/** The draft picks. */
|
||||
private final Map<String, Float> draftPicks = new TreeMap<>();
|
||||
protected LimitedPoolType draftFormat;
|
||||
|
||||
@@ -63,6 +61,7 @@ public class BoosterDraft implements IBoosterDraft {
|
||||
public static BoosterDraft createDraft(final LimitedPoolType draftType) {
|
||||
final BoosterDraft draft = new BoosterDraft(draftType);
|
||||
if (!draft.generateProduct()) { return null; }
|
||||
draft.initializeBoosters();
|
||||
return draft;
|
||||
}
|
||||
|
||||
@@ -115,7 +114,7 @@ public class BoosterDraft implements IBoosterDraft {
|
||||
|
||||
if (sets.size() > 1) {
|
||||
Object p;
|
||||
if (nPacks == 3) {
|
||||
if (nPacks == 3 && sets.size() < 4) {
|
||||
p = SGuiChoose.oneOrNone("Choose Set Combination", getSetCombos(sets));
|
||||
} else {
|
||||
p = choosePackByPack(sets, nPacks);
|
||||
@@ -158,7 +157,6 @@ public class BoosterDraft implements IBoosterDraft {
|
||||
throw new NoSuchElementException("Draft for mode " + this.draftFormat + " has not been set up!");
|
||||
}
|
||||
|
||||
this.pack = this.get8BoosterPack();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -172,16 +170,26 @@ public class BoosterDraft implements IBoosterDraft {
|
||||
IBoosterDraft.LAND_SET_CODE[0] = block.getLandSet();
|
||||
IBoosterDraft.CUSTOM_RANKINGS_FILE[0] = null;
|
||||
|
||||
draft.pack = draft.get8BoosterPack();
|
||||
draft.initializeBoosters();
|
||||
return draft;
|
||||
}
|
||||
|
||||
protected BoosterDraft() {
|
||||
this.draftFormat = LimitedPoolType.Full;
|
||||
this(LimitedPoolType.Full);
|
||||
}
|
||||
protected BoosterDraft(final LimitedPoolType draftType) {
|
||||
this.draftAI.setBd(this);
|
||||
this.draftFormat = draftType;
|
||||
|
||||
localPlayer = new LimitedPlayer(0);
|
||||
players.add(localPlayer);
|
||||
for(int i = 1; i < N_PLAYERS; i++) {
|
||||
players.add(new LimitedPlayerAI(i));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPileDraft() {
|
||||
return false;
|
||||
}
|
||||
|
||||
private void setupCustomDraft(final CustomLimited draft) {
|
||||
@@ -228,19 +236,12 @@ public class BoosterDraft implements IBoosterDraft {
|
||||
return customs;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* nextChoice.
|
||||
* </p>
|
||||
*
|
||||
* @return a {@link forge.deck.CardPool} object.
|
||||
*/
|
||||
@Override
|
||||
public CardPool nextChoice() {
|
||||
// Primary draft loop - Computer Chooses from their packs, you choose form your packs
|
||||
if (this.isRoundOver()) {
|
||||
// If all packs are depleted crack 8 new packs
|
||||
this.pack = this.get8BoosterPack();
|
||||
if (this.pack == null) {
|
||||
// If this round is over, try to start the next round
|
||||
if (!startRound()) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -248,7 +249,7 @@ public class BoosterDraft implements IBoosterDraft {
|
||||
this.computerChoose();
|
||||
|
||||
final CardPool result = new CardPool();
|
||||
result.addAllFlat(this.pack.get(this.getCurrentBoosterIndex()));
|
||||
result.addAllFlat(localPlayer.nextChoice());
|
||||
|
||||
if (result.isEmpty()) {
|
||||
// Can't set a card, since none are available. Just pass "empty" packs.
|
||||
@@ -260,129 +261,95 @@ public class BoosterDraft implements IBoosterDraft {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* get8BoosterPack.
|
||||
* </p>
|
||||
*
|
||||
* @return an array of {@link forge.deck.CardPool} objects.
|
||||
*/
|
||||
public List<List<PaperCard>> get8BoosterPack() {
|
||||
if (this.nextBoosterGroup >= this.product.size()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final List<List<PaperCard>> list = new ArrayList<>();
|
||||
for (int i = 0; i < 8; i++) {
|
||||
list.add(this.product.get(this.nextBoosterGroup).get());
|
||||
public void initializeBoosters() {
|
||||
for(Supplier<List<PaperCard>> boosterRound : this.product) {
|
||||
for (int i = 0; i < N_PLAYERS; i++) {
|
||||
this.players.get(i).receiveUnopenedPack(boosterRound.get());
|
||||
}
|
||||
}
|
||||
startRound();
|
||||
}
|
||||
|
||||
public boolean startRound() {
|
||||
this.nextBoosterGroup++;
|
||||
this.currentBoosterSize = list.get(0).size();
|
||||
this.currentBoosterPick = 0;
|
||||
draftingBooster = new int[]{0, 1, 2, 3, 4, 5, 6, 7};
|
||||
return list;
|
||||
packsInDraft = this.players.size();
|
||||
LimitedPlayer firstPlayer = this.players.get(0);
|
||||
if (firstPlayer.unopenedPacks.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for(LimitedPlayer pl : this.players) {
|
||||
pl.newPack();
|
||||
}
|
||||
this.currentBoosterSize = firstPlayer.packQueue.peek().size();
|
||||
return true;
|
||||
}
|
||||
|
||||
public void addSingleBoosterPack(int player, boolean random) {
|
||||
// TODO Lore Seeker
|
||||
}
|
||||
|
||||
// size 7, all the computers decks
|
||||
@Override
|
||||
public Deck[] getDecks() {
|
||||
return this.draftAI.getDecks();
|
||||
Deck decks[] = new Deck[7];
|
||||
for (int i = 1; i < N_PLAYERS; i++) {
|
||||
decks[i-1] = ((LimitedPlayerAI)this.players.get(i)).buildDeck();
|
||||
}
|
||||
return decks;
|
||||
}
|
||||
|
||||
public void passPacks() {
|
||||
// Alternate direction of pack passing
|
||||
int adjust = this.nextBoosterGroup % 2 == 1 ? 1 : -1;
|
||||
for(int i = 0; i < N_PLAYERS; i++) {
|
||||
draftingBooster[i] = (draftingBooster[i] + adjust + pack.size()) % pack.size();
|
||||
List<PaperCard> passingPack = this.players.get(i).passPack();
|
||||
|
||||
if (!passingPack.isEmpty()) {
|
||||
// TODO Canal Dredger for passing a pack with a single card in it
|
||||
|
||||
int passTo = (i + adjust + N_PLAYERS) % N_PLAYERS;
|
||||
this.players.get(passTo).receiveOpenedPack(passingPack);
|
||||
this.players.get(passTo).adjustPackNumber(adjust, packsInDraft);
|
||||
} else {
|
||||
packsInDraft--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void computerChoose() {
|
||||
// Loop through players 1-7 to draft their current pack
|
||||
for (int i = 1; i < N_PLAYERS; i++) {
|
||||
final List<PaperCard> booster = this.pack.get(this.draftingBooster[i]);
|
||||
|
||||
// Empty boosters can happen in a Conspiracy draft
|
||||
if (!booster.isEmpty()) {
|
||||
booster.remove(this.draftAI.choose(booster, i-1));
|
||||
}
|
||||
LimitedPlayer pl = this.players.get(i);
|
||||
pl.draftCard(pl.chooseCard());
|
||||
}
|
||||
} // computerChoose()
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Get the current booster index for the Human
|
||||
* @return int
|
||||
*/
|
||||
public int getCurrentBoosterIndex() {
|
||||
return this.draftingBooster[0];
|
||||
return localPlayer.currentPack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRoundOver() {
|
||||
for(List<PaperCard> singlePack : this.pack) {
|
||||
if (!singlePack.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return packsInDraft == 0;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean hasNextChoice() {
|
||||
return this.nextBoosterGroup < this.product.size() || !this.isRoundOver();
|
||||
return !this.isRoundOver() || !this.localPlayer.unopenedPacks.isEmpty();
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public void setChoice(final PaperCard c) {
|
||||
final List<PaperCard> thisBooster = this.pack.get(this.getCurrentBoosterIndex());
|
||||
final List<PaperCard> thisBooster = this.localPlayer.nextChoice();
|
||||
|
||||
if (!thisBooster.contains(c)) {
|
||||
throw new RuntimeException("BoosterDraft : setChoice() error - card not found - " + c
|
||||
+ " - booster pack = " + thisBooster);
|
||||
}
|
||||
|
||||
if (ForgePreferences.UPLOAD_DRAFT) {
|
||||
for (int i = 0; i < thisBooster.size(); i++) {
|
||||
final PaperCard cc = thisBooster.get(i);
|
||||
final String cnBk = cc.getName() + "|" + cc.getEdition();
|
||||
recordDraftPick(thisBooster, c);
|
||||
|
||||
float pickValue;
|
||||
if (cc.equals(c)) {
|
||||
pickValue = thisBooster.size()
|
||||
* (1f - (((float) this.currentBoosterPick / this.currentBoosterSize) * 2f));
|
||||
}
|
||||
else {
|
||||
pickValue = 0;
|
||||
}
|
||||
|
||||
if (!this.draftPicks.containsKey(cnBk)) {
|
||||
this.draftPicks.put(cnBk, pickValue);
|
||||
}
|
||||
else {
|
||||
final float curValue = this.draftPicks.get(cnBk);
|
||||
final float newValue = (curValue + pickValue) / 2;
|
||||
this.draftPicks.put(cnBk, newValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
thisBooster.remove(c);
|
||||
this.localPlayer.draftCard(c);
|
||||
this.currentBoosterPick++;
|
||||
this.passPacks();
|
||||
} // setChoice()
|
||||
|
||||
@Override
|
||||
public boolean isPileDraft() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -403,7 +370,6 @@ public class BoosterDraft implements IBoosterDraft {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
private static List<String> getSetCombos(final List<String> setz) {
|
||||
final String[] sets = setz.toArray(ArrayUtils.EMPTY_STRING_ARRAY);
|
||||
final List<String> setCombos = new ArrayList<>();
|
||||
@@ -466,4 +432,31 @@ public class BoosterDraft implements IBoosterDraft {
|
||||
}
|
||||
return setCombos;
|
||||
}
|
||||
|
||||
private void recordDraftPick(final List<PaperCard> thisBooster, PaperCard c) {
|
||||
if (ForgePreferences.UPLOAD_DRAFT) {
|
||||
for (int i = 0; i < thisBooster.size(); i++) {
|
||||
final PaperCard cc = thisBooster.get(i);
|
||||
final String cnBk = cc.getName() + "|" + cc.getEdition();
|
||||
|
||||
float pickValue;
|
||||
if (cc.equals(c)) {
|
||||
pickValue = thisBooster.size()
|
||||
* (1f - (((float) this.currentBoosterPick / this.currentBoosterSize) * 2f));
|
||||
}
|
||||
else {
|
||||
pickValue = 0;
|
||||
}
|
||||
|
||||
if (!this.draftPicks.containsKey(cnBk)) {
|
||||
this.draftPicks.put(cnBk, pickValue);
|
||||
}
|
||||
else {
|
||||
final float curValue = this.draftPicks.get(cnBk);
|
||||
final float newValue = (curValue + pickValue) / 2;
|
||||
this.draftPicks.put(cnBk, newValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,12 +35,8 @@ import forge.properties.ForgePreferences;
|
||||
*/
|
||||
public class BoosterDraftAI {
|
||||
|
||||
/** The bd. */
|
||||
// TODO When WinstonDraft gets related changes that BoosterDraft gets, this can be deleted
|
||||
private IBoosterDraft bd = null;
|
||||
|
||||
/**
|
||||
* Constant <code>nDecks=7.</code>
|
||||
*/
|
||||
protected static final int N_DECKS = 7;
|
||||
|
||||
// holds all the cards for each of the computer's decks
|
||||
@@ -83,13 +79,6 @@ public class BoosterDraftAI {
|
||||
return bestPick;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* getDecks.
|
||||
* </p>
|
||||
*
|
||||
* @return an array of {@link forge.deck.Deck} objects.
|
||||
*/
|
||||
public Deck[] getDecks() {
|
||||
final Deck[] out = new Deck[this.decks.size()];
|
||||
|
||||
@@ -103,11 +92,6 @@ public class BoosterDraftAI {
|
||||
return out;
|
||||
} // getDecks()
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Constructor for BoosterDraftAI.
|
||||
* </p>
|
||||
*/
|
||||
public BoosterDraftAI() {
|
||||
// Initialize deck array and playerColors list
|
||||
for (int i = 0; i < N_DECKS; i++) {
|
||||
@@ -116,21 +100,9 @@ public class BoosterDraftAI {
|
||||
}
|
||||
} // BoosterDraftAI()
|
||||
|
||||
/**
|
||||
* Gets the bd.
|
||||
*
|
||||
* @return the bd
|
||||
*/
|
||||
public IBoosterDraft getBd() {
|
||||
return this.bd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the bd.
|
||||
*
|
||||
* @param bd0
|
||||
* the bd to set
|
||||
*/
|
||||
public void setBd(final IBoosterDraft bd0) {
|
||||
this.bd = bd0;
|
||||
}
|
||||
|
||||
@@ -31,49 +31,15 @@ import forge.item.PaperCard;
|
||||
* @version $Id$
|
||||
*/
|
||||
public interface IBoosterDraft {
|
||||
/**
|
||||
* <p>
|
||||
* nextChoice.
|
||||
* </p>
|
||||
*
|
||||
* @return a {@link CardPool} object.
|
||||
*/
|
||||
|
||||
CardPool nextChoice();
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* setChoice.
|
||||
* </p>
|
||||
*
|
||||
* @param c
|
||||
* a {@link forge.game.card.Card} object.
|
||||
*/
|
||||
void setChoice(PaperCard c);
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* hasNextChoice.
|
||||
* </p>
|
||||
*
|
||||
* @return a boolean.
|
||||
*/
|
||||
boolean hasNextChoice();
|
||||
boolean isRoundOver();
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* getDecks.
|
||||
* </p>
|
||||
*
|
||||
* @return an array of {@link forge.deck.Deck} objects.
|
||||
*/
|
||||
Deck[] getDecks(); // size 7, all the computers decks
|
||||
|
||||
/** Constant <code>LandSetCode="{}"</code>. */
|
||||
CardEdition[] LAND_SET_CODE = { null };
|
||||
|
||||
String[] CUSTOM_RANKINGS_FILE = { null };
|
||||
|
||||
boolean isPileDraft();
|
||||
|
||||
}
|
||||
|
||||
148
forge-gui/src/main/java/forge/limited/LimitedPlayer.java
Normal file
148
forge-gui/src/main/java/forge/limited/LimitedPlayer.java
Normal file
@@ -0,0 +1,148 @@
|
||||
package forge.limited;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import forge.deck.CardPool;
|
||||
import forge.deck.Deck;
|
||||
import forge.deck.DeckSection;
|
||||
import forge.item.PaperCard;
|
||||
import forge.limited.powers.DraftPower;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class LimitedPlayer {
|
||||
// A Player class for inside some type of limited environment, like Draft.
|
||||
final protected int order;
|
||||
protected int currentPack;
|
||||
protected int draftedThisRound;
|
||||
protected Deck deck;
|
||||
|
||||
protected Queue<List<PaperCard>> packQueue;
|
||||
protected Queue<List<PaperCard>> unopenedPacks;
|
||||
|
||||
// WIP - Draft Matters cards
|
||||
/*
|
||||
private static int CantDraftThisRound = 1,
|
||||
SpyNextCardDrafted = 1 << 1,
|
||||
ReceiveLastCard = 1 << 2,
|
||||
CanRemoveAfterDraft = 1 << 3,
|
||||
CanTradeAfterDraft = 1 << 4;
|
||||
|
||||
private static int MAXFLAGS = CantDraftThisRound | ReceiveLastCard | CanRemoveAfterDraft | SpyNextCardDrafted
|
||||
| CanTradeAfterDraft;
|
||||
|
||||
|
||||
private int playerFlags = 0;
|
||||
|
||||
private List<PaperCard> revealed = Lists.newArrayList();
|
||||
private Map<String, List<Object>> noted = new HashMap<>();
|
||||
private Map<DraftPower, Integer> powers = new HashMap<>();
|
||||
*/
|
||||
|
||||
public LimitedPlayer(int seatingOrder) {
|
||||
order = seatingOrder;
|
||||
deck = new Deck();
|
||||
|
||||
packQueue = new LinkedList<>();
|
||||
unopenedPacks = new LinkedList<>();
|
||||
}
|
||||
|
||||
public PaperCard chooseCard() {
|
||||
// A basic LimitedPlayer chooses cards via the UI instead of this function
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean draftCard(PaperCard bestPick) {
|
||||
return draftCard(bestPick, DeckSection.Sideboard);
|
||||
}
|
||||
public boolean draftCard(PaperCard bestPick, DeckSection section) {
|
||||
if (bestPick == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
List<PaperCard> chooseFrom = packQueue.peek();
|
||||
if (chooseFrom == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
chooseFrom.remove(bestPick);
|
||||
|
||||
|
||||
|
||||
CardPool pool = deck.getOrCreate(section);
|
||||
pool.add(bestPick);
|
||||
draftedThisRound++;
|
||||
|
||||
// TODO Note Lurking Automaton
|
||||
// TODO Note Paliano, the High City
|
||||
// TODO Note Aether Searcher
|
||||
// TODO Note Custodi Peacepeeper
|
||||
// TODO Note Paliano Vanguard
|
||||
// TODO Note Garbage Fire
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public List<PaperCard> nextChoice() {
|
||||
return packQueue.peek();
|
||||
}
|
||||
|
||||
public void newPack() {
|
||||
currentPack = order;
|
||||
draftedThisRound = 0;
|
||||
packQueue.add(unopenedPacks.poll());
|
||||
}
|
||||
public void adjustPackNumber(int adjust, int numPacks) {
|
||||
currentPack = (currentPack + adjust + numPacks) % numPacks;
|
||||
}
|
||||
|
||||
public List<PaperCard> passPack() {
|
||||
return packQueue.poll();
|
||||
}
|
||||
|
||||
public void receiveUnopenedPack(List<PaperCard> pack) {
|
||||
unopenedPacks.add(pack);
|
||||
}
|
||||
|
||||
public void receiveOpenedPack(List<PaperCard> pack) {
|
||||
packQueue.add(pack);
|
||||
}
|
||||
|
||||
/*
|
||||
public void addSingleBoosterPack(boolean random) {
|
||||
// TODO Lore Seeker
|
||||
// Generate booster pack then, "receive" that pack
|
||||
}
|
||||
|
||||
public boolean activatePower(DraftPower power) {
|
||||
if (!powers.containsKey(power)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int i = (int)powers.get(power);
|
||||
if (i == 1) {
|
||||
powers.remove(power);
|
||||
} else {
|
||||
powers.put(power, i-1);
|
||||
}
|
||||
|
||||
power.activate(this);
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean noteObject(String cardName, Object notedObj) {
|
||||
// Returns boolean based on creation of new mapped param
|
||||
boolean alreadyContained = noted.containsKey(cardName);
|
||||
|
||||
if (alreadyContained) {
|
||||
noted.get(cardName).add(notedObj);
|
||||
} else {
|
||||
noted.put(cardName, Lists.newArrayList(notedObj));
|
||||
}
|
||||
|
||||
return !alreadyContained;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
58
forge-gui/src/main/java/forge/limited/LimitedPlayerAI.java
Normal file
58
forge-gui/src/main/java/forge/limited/LimitedPlayerAI.java
Normal file
@@ -0,0 +1,58 @@
|
||||
package forge.limited;
|
||||
|
||||
import forge.card.ColorSet;
|
||||
import forge.deck.CardPool;
|
||||
import forge.deck.Deck;
|
||||
import forge.deck.DeckSection;
|
||||
import forge.item.PaperCard;
|
||||
import forge.properties.ForgePreferences;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class LimitedPlayerAI extends LimitedPlayer {
|
||||
protected DeckColors deckCols;
|
||||
|
||||
public LimitedPlayerAI(int seatingOrder) {
|
||||
super(seatingOrder);
|
||||
deckCols = new DeckColors();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public PaperCard chooseCard() {
|
||||
if (packQueue.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
List<PaperCard> chooseFrom = packQueue.peek();
|
||||
if (chooseFrom.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
CardPool pool = deck.getOrCreate(DeckSection.Sideboard);
|
||||
if (ForgePreferences.DEV_MODE) {
|
||||
System.out.println("Player[" + order + "] pack: " + chooseFrom.toString());
|
||||
}
|
||||
|
||||
final ColorSet chosenColors = deckCols.getChosenColors();
|
||||
final boolean canAddMoreColors = deckCols.canChoseMoreColors();
|
||||
|
||||
List<PaperCard> rankedCards = CardRanker.rankCardsInPack(chooseFrom, pool.toFlatList(), chosenColors, canAddMoreColors);
|
||||
PaperCard bestPick = rankedCards.get(0);
|
||||
|
||||
if (canAddMoreColors) {
|
||||
deckCols.addColorsOf(bestPick);
|
||||
}
|
||||
|
||||
if (ForgePreferences.DEV_MODE) {
|
||||
System.out.println("Player[" + order + "] picked: " + bestPick);
|
||||
}
|
||||
|
||||
return bestPick;
|
||||
}
|
||||
|
||||
public Deck buildDeck() {
|
||||
CardPool section = deck.getOrCreate(DeckSection.Sideboard);
|
||||
return new BoosterDeckBuilder(section.toFlatList(), deckCols).buildDeck();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user