diff --git a/.gitattributes b/.gitattributes index 3b4f6b5ab31..197012f729a 100644 --- a/.gitattributes +++ b/.gitattributes @@ -9822,6 +9822,7 @@ src/main/java/forge/game/limited/BoosterDraft.java svneol=native#text/plain src/main/java/forge/game/limited/BoosterDraftAI.java svneol=native#text/plain src/main/java/forge/game/limited/BoosterDraft_1.java svneol=native#text/plain src/main/java/forge/game/limited/CCnt.java svneol=native#text/plain +src/main/java/forge/game/limited/CardPoolLimitation.java -text src/main/java/forge/game/limited/CustomLimited.java svneol=native#text/plain src/main/java/forge/game/limited/DeckColors.java svneol=native#text/plain src/main/java/forge/game/limited/SealedDeck.java svneol=native#text/plain diff --git a/src/main/java/forge/card/BoosterGenerator.java b/src/main/java/forge/card/BoosterGenerator.java index 16dd4657410..40f51e9c042 100644 --- a/src/main/java/forge/card/BoosterGenerator.java +++ b/src/main/java/forge/card/BoosterGenerator.java @@ -215,15 +215,6 @@ public class BoosterGenerator { return temp; } - /** - *

getBoosterPackSize.

- * - * @return a int. - */ - public final int getBoosterPackSize() { - return numCommons + numUncommons + numRareSlots + numSpecials; - } - private void addToRarity(final CardPrinted c) { switch(c.getRarity()) { case Common: commons.add(c); break; diff --git a/src/main/java/forge/game/limited/BoosterDraft.java b/src/main/java/forge/game/limited/BoosterDraft.java index 0882cb00c08..5c41b6d5294 100644 --- a/src/main/java/forge/game/limited/BoosterDraft.java +++ b/src/main/java/forge/game/limited/BoosterDraft.java @@ -4,9 +4,6 @@ import forge.deck.Deck; import forge.item.CardPrinted; import forge.item.ItemPoolView; -import java.util.Map; -import java.util.TreeMap; - /** *

BoosterDraft interface.

* @@ -44,12 +41,12 @@ public interface BoosterDraft { /** Constant LandSetCode="{}". */ public String LandSetCode[] = {""}; + + /** + * Called when drafting is over - to upload picks. + */ + void finishedDrafting(); - /** Constant draftFormat="{}". */ - public String draftFormat[] = {""}; - - /** Constant draftPicks="{}". */ - public Map draftPicks = new TreeMap(); } diff --git a/src/main/java/forge/game/limited/BoosterDraft_1.java b/src/main/java/forge/game/limited/BoosterDraft_1.java index 55e50678678..2303114cbc1 100644 --- a/src/main/java/forge/game/limited/BoosterDraft_1.java +++ b/src/main/java/forge/game/limited/BoosterDraft_1.java @@ -5,6 +5,7 @@ import forge.Card; import forge.CardList; import forge.Constant; import forge.FileUtil; +import forge.HttpUtil; import forge.SetUtils; import forge.card.BoosterGenerator; import forge.card.CardBlock; @@ -20,9 +21,14 @@ import forge.item.ItemPoolView; import java.io.File; import java.util.ArrayList; import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.TreeMap; import javax.swing.JOptionPane; +import org.apache.commons.lang3.ArrayUtils; + import net.slightlymagic.braids.util.lambda.Lambda1; import net.slightlymagic.maxmtg.Closure1; @@ -31,113 +37,96 @@ import net.slightlymagic.maxmtg.Closure1; * TODO Write javadoc for this type. * */ -public class BoosterDraft_1 implements BoosterDraft { +public final class BoosterDraft_1 implements BoosterDraft { private final BoosterDraftAI draftAI = new BoosterDraftAI(); private static final int nPlayers = 8; - //private static int boosterPackSize = 14; // 10 com + 3 unc + 1 rare/myth - private static int stopCount = 42; //boosterPackSize * 3;//should total of 42 - because you don't draft lands - private int currentCount = 0; + private int nextBoosterGroup = 0; + private int currentBoosterSize = 0; + private int currentBoosterPick = 0; private List> pack; //size 8 - //private BoosterGenerator packs[] = {new BoosterGenerator(), new BoosterGenerator(), new BoosterGenerator()}; + + public Map draftPicks = new TreeMap(); + private CardPoolLimitation draftFormat; + private ArrayList, BoosterGenerator>> packs = new ArrayList, BoosterGenerator>>(); - private int currentBoosterPack = 0; - - //helps the computer choose which booster packs to pick from - //the first row says "pick from boosters 1-7, skip 0" since the players picks from 0 - //the second row says "pick from 0 and 2-7 boosters, skip 1" - player chooses from 1 - private final int[][] computerChoose = { - {1, 2, 3, 4, 5, 6, 7}, - {0, 2, 3, 4, 5, 6, 7}, - {0, 1, 3, 4, 5, 6, 7}, - {0, 1, 2, 4, 5, 6, 7}, - {0, 1, 2, 3, 5, 6, 7}, - {0, 1, 2, 3, 4, 6, 7}, - {0, 1, 2, 3, 4, 5, 7}, - {0, 1, 2, 3, 4, 5, 6} - }; - - /** - * - * TODO Write javadoc for Constructor. - */ - public BoosterDraft_1() { - pack = get8BoosterPack(); - } /** *

Constructor for BoosterDraft_1.

* * @param draftType a {@link java.lang.String} object. */ - public BoosterDraft_1(String draftType) { + public BoosterDraft_1(CardPoolLimitation draftType) { draftAI.bd = this; - draftFormat[0] = draftType; + draftFormat = draftType; - if (draftType.equals("Full")) { // Draft from all cards in Forge - BoosterGenerator bpFull = new BoosterGenerator(CardDb.instance().getAllUniqueCards()); - Closure1, BoosterGenerator> picker = BoosterGenerator.getSimplePicker(bpFull); - for (int i = 0; i < 3; i++) { - packs.add(picker); - } - - LandSetCode[0] = AllZone.getCardFactory().getCard("Plains", AllZone.getHumanPlayer()).getMostRecentSet(); - } else if (draftType.equals("Block")) { // Draft from cards by block or set - List blocks = SetUtils.getBlocks(); - - Object o = GuiUtils.getChoice("Choose Block", blocks.toArray()); - CardBlock block = (CardBlock) o; - - CardSet[] cardSets = block.getSets(); - String[] sets = new String[cardSets.length]; - for (int k = cardSets.length - 1; k >= 0 ; --k) { sets[k] = cardSets[k].getCode();} - - int nPacks = block.getCntBoostersDraft(); - - ArrayList setCombos = new ArrayList(); - if (sets.length >= 2) { - setCombos.add(String.format("%s/%s/%s", sets[0], sets[0], sets[0])); - setCombos.add(String.format("%s/%s/%s", sets[1], sets[0], sets[0])); - setCombos.add(String.format("%s/%s/%s", sets[1], sets[1], sets[0])); - setCombos.add(String.format("%s/%s/%s", sets[1], sets[1], sets[1])); - } - if (sets.length >= 3) { - setCombos.add(String.format("%s/%s/%s", sets[2], sets[1], sets[0])); - setCombos.add(String.format("%s/%s/%s", sets[2], sets[2], sets[0])); - setCombos.add(String.format("%s/%s/%s", sets[2], sets[2], sets[1])); - setCombos.add(String.format("%s/%s/%s", sets[2], sets[2], sets[2])); - } - - int sumCards = 0; - if (sets.length > 1) { - Object p = GuiUtils.getChoice("Choose Set Combination", setCombos.toArray()); - String[] pp = p.toString().split("/"); - for (int i = 0; i < nPacks; i++) { - BoosterGenerator bpMulti = new BoosterGenerator(pp[i]); - Closure1, BoosterGenerator> picker = BoosterGenerator.getSimplePicker(bpMulti); + switch (draftType) { + case Full: // Draft from all cards in Forge + BoosterGenerator bpFull = new BoosterGenerator(CardDb.instance().getAllUniqueCards()); + Closure1, BoosterGenerator> picker = BoosterGenerator.getSimplePicker(bpFull); + for (int i = 0; i < 3; i++) { packs.add(picker); - sumCards += bpMulti.getBoosterPackSize(); } - } else { - BoosterGenerator bpOne = new BoosterGenerator(sets[0]); - Closure1, BoosterGenerator> picker = BoosterGenerator.getSimplePicker(bpOne); - for (int i = 0; i < nPacks; i++) { - packs.add(picker); - sumCards += bpOne.getBoosterPackSize(); + + LandSetCode[0] = CardDb.instance().getCard("Plains").getSet(); + break; + + case Block: // Draft from cards by block or set + List blocks = SetUtils.getBlocks(); + + Object o = GuiUtils.getChoice("Choose Block", blocks.toArray()); + CardBlock block = (CardBlock) o; + + CardSet[] cardSets = block.getSets(); + String[] sets = new String[cardSets.length]; + for (int k = cardSets.length - 1; k >= 0 ; --k) { sets[k] = cardSets[k].getCode();} + + int nPacks = block.getCntBoostersDraft(); + + ArrayList setCombos = new ArrayList(); + if (sets.length >= 2) { + setCombos.add(String.format("%s/%s/%s", sets[0], sets[0], sets[0])); + setCombos.add(String.format("%s/%s/%s", sets[1], sets[0], sets[0])); + setCombos.add(String.format("%s/%s/%s", sets[1], sets[1], sets[0])); + setCombos.add(String.format("%s/%s/%s", sets[1], sets[1], sets[1])); } - } - stopCount = sumCards; - LandSetCode[0] = block.getLandSet().getCode(); - - } else if (draftType.equals("Custom")) { // Draft from user-defined cardpools - List myDrafts = loadCustomDrafts("res/draft/", ".draft"); - - if (myDrafts.size() < 1) { - JOptionPane.showMessageDialog(null, "No custom draft files found.", "", JOptionPane.INFORMATION_MESSAGE); - } else { - CustomLimited draft = (CustomLimited) GuiUtils.getChoice("Choose Custom Draft", myDrafts.toArray()); - setupCustomDraft(draft); - } + if (sets.length >= 3) { + setCombos.add(String.format("%s/%s/%s", sets[2], sets[1], sets[0])); + setCombos.add(String.format("%s/%s/%s", sets[2], sets[2], sets[0])); + setCombos.add(String.format("%s/%s/%s", sets[2], sets[2], sets[1])); + setCombos.add(String.format("%s/%s/%s", sets[2], sets[2], sets[2])); + } + + + if (sets.length > 1) { + Object p = GuiUtils.getChoice("Choose Set Combination", setCombos.toArray()); + String[] pp = p.toString().split("/"); + for (int i = 0; i < nPacks; i++) { + BoosterGenerator bpMulti = new BoosterGenerator(pp[i]); + packs.add(BoosterGenerator.getSimplePicker(bpMulti)); + } + + } else { + BoosterGenerator bpOne = new BoosterGenerator(sets[0]); + Closure1, BoosterGenerator> pick1 = BoosterGenerator.getSimplePicker(bpOne); + for (int i = 0; i < nPacks; i++) { packs.add(pick1); } + } + + LandSetCode[0] = block.getLandSet().getCode(); + break; + + case Custom: + List myDrafts = loadCustomDrafts("res/draft/", ".draft"); + + if (myDrafts.size() < 1) { + JOptionPane.showMessageDialog(null, "No custom draft files found.", "", JOptionPane.INFORMATION_MESSAGE); + } else { + CustomLimited draft = (CustomLimited) GuiUtils.getChoice("Choose Custom Draft", myDrafts.toArray()); + setupCustomDraft(draft); + } + break; + default: + throw new NoSuchElementException("Draft for mode " + draftType + " has not been set up!"); } pack = get8BoosterPack(); @@ -162,13 +151,7 @@ public class BoosterDraft_1 implements BoosterDraft { }; Closure1, BoosterGenerator> picker = new Closure1, BoosterGenerator>(fnPick, bpCustom); - - int n = 0; - for (int i = 0; i < draft.NumPacks; i++) { - packs.add(picker); - n += draft.NumCards; //bpCustom.getBoosterPackSize(); - } - stopCount = n; + for (int i = 0; i < draft.NumPacks; i++) { packs.add(picker); } LandSetCode[0] = draft.LandSetCode; } @@ -206,7 +189,7 @@ public class BoosterDraft_1 implements BoosterDraft { * * @return a {@link forge.CardList} object. */ - public final ItemPoolView nextChoice() { + public ItemPoolView nextChoice() { if (pack.get(getCurrentBoosterIndex()).size() == 0) { pack = get8BoosterPack(); } @@ -220,19 +203,17 @@ public class BoosterDraft_1 implements BoosterDraft { * * @return an array of {@link forge.CardList} objects. */ - public final List> get8BoosterPack() { + public List> get8BoosterPack() { + if (nextBoosterGroup >= packs.size()) { return null; } + List> list = new ArrayList>(); - - if (currentBoosterPack < packs.size()) { - for (int i = 0; i < 8; i++) { - list.add(packs.get(currentBoosterPack).apply()); - } - } - - currentBoosterPack++; - + for (int i = 0; i < 8; i++) { list.add(packs.get(nextBoosterGroup).apply()); } + + nextBoosterGroup++; + currentBoosterSize = list.get(0).size(); + currentBoosterPick = 0; return list; - } //get8BoosterPack() + } //size 7, all the computers decks @@ -241,21 +222,24 @@ public class BoosterDraft_1 implements BoosterDraft { * * @return an array of {@link forge.deck.Deck} objects. */ - public final Deck[] getDecks() { + public Deck[] getDecks() { return draftAI.getDecks(); } private void computerChoose() { - int[] row = computerChoose[getCurrentBoosterIndex()]; - for (int i = 0; i < row.length; i++) { + int iHumansBooster = getCurrentBoosterIndex(); + int iPlayer = 0; + for (int i = 0; i < pack.size(); i++) { + if (iHumansBooster == i) { continue; } // don't touch player's booster + CardList forAi = new CardList(); - List booster = pack.get(row[i]); + List booster = pack.get(i); for (CardPrinted cr : booster) { forAi.add(cr.toForgeCard()); } - // TODO Please write this drafting code to work without heavy cards - Card aiPick = draftAI.choose(forAi, i); + // TODO: Please write this drafting code to work without heavy card objects + Card aiPick = draftAI.choose(forAi, iPlayer++); String pickedName = aiPick.getName(); for (int pick = booster.size() - 1; pick >= 0; pick--) { @@ -269,7 +253,7 @@ public class BoosterDraft_1 implements BoosterDraft { } //computerChoose() private int getCurrentBoosterIndex() { - return currentCount % nPlayers; + return currentBoosterPick % nPlayers; } /** @@ -277,12 +261,15 @@ public class BoosterDraft_1 implements BoosterDraft { * * @return a boolean. */ - public final boolean hasNextChoice() { - return currentCount < stopCount; + public boolean hasNextChoice() { + boolean isLastGroup = nextBoosterGroup >= packs.size(); + boolean isBoosterDepleted = currentBoosterPick >= currentBoosterSize; + boolean noMoreCards = isLastGroup && isBoosterDepleted; + return !noMoreCards; } /** {@inheritDoc} */ - public final void setChoice(final CardPrinted c) { + public void setChoice(final CardPrinted c) { List thisBooster = pack.get(getCurrentBoosterIndex()); if (!thisBooster.contains(c)) { @@ -296,7 +283,7 @@ public class BoosterDraft_1 implements BoosterDraft { float pickValue = 0; if (cc.equals(c)) { - pickValue = thisBooster.size() * (1f - ((float) currentCount) / stopCount) * 2f; + pickValue = thisBooster.size() * (1f - ((float) currentBoosterPick / currentBoosterSize) * 2f); } else { pickValue = 0; } @@ -312,6 +299,26 @@ public class BoosterDraft_1 implements BoosterDraft { } thisBooster.remove(c); - currentCount++; + currentBoosterPick++; } //setChoice() + + /** This will upload drafting picks to cardforge HQ */ + @Override public void finishedDrafting() { + if (Constant.Runtime.UpldDrft[0]) { + if (draftPicks.size() > 1) { + ArrayList outDraftData = new ArrayList(); + + String[] keys = draftPicks.keySet().toArray(ArrayUtils.EMPTY_STRING_ARRAY); + + for (int i = 0; i < keys.length; i++) { + outDraftData.add(keys[i] + "|" + draftPicks.get(keys[i])); + } + + FileUtil.writeFile("res/draft/tmpDraftData.txt", outDraftData); + + HttpUtil poster = new HttpUtil(); + poster.upload("http://cardforge.org/draftAI/submitDraftData.php?fmt=" + draftFormat, "res/draft/tmpDraftData.txt"); + } + } + } } diff --git a/src/main/java/forge/game/limited/CardPoolLimitation.java b/src/main/java/forge/game/limited/CardPoolLimitation.java new file mode 100644 index 00000000000..3317da3160a --- /dev/null +++ b/src/main/java/forge/game/limited/CardPoolLimitation.java @@ -0,0 +1,11 @@ +package forge.game.limited; + +/** + * TODO: Write javadoc for this type. + * + */ +public enum CardPoolLimitation { + Full, + Block, + Custom +} diff --git a/src/main/java/forge/gui/deckeditor/DeckEditorDraft.java b/src/main/java/forge/gui/deckeditor/DeckEditorDraft.java index b5cf7079de8..35ed80f928f 100644 --- a/src/main/java/forge/gui/deckeditor/DeckEditorDraft.java +++ b/src/main/java/forge/gui/deckeditor/DeckEditorDraft.java @@ -2,8 +2,6 @@ package forge.gui.deckeditor; import forge.AllZone; import forge.Constant; -import forge.FileUtil; -import forge.HttpUtil; import forge.deck.Deck; import forge.deck.DeckManager; import forge.error.ErrorViewer; @@ -19,17 +17,26 @@ import forge.properties.ForgeProps; import forge.properties.NewConstants; import forge.view.swing.OldGuiNewGame; -import javax.swing.*; - -import org.apache.commons.lang3.ArrayUtils; - import net.slightlymagic.maxmtg.Predicate; -import java.awt.*; -import java.awt.event.*; +import java.awt.Rectangle; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.InputEvent; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; import java.util.ArrayList; import java.util.List; +import javax.swing.JButton; +import javax.swing.JOptionPane; +import javax.swing.JTable; + /** *

Gui_BoosterDraft class.

@@ -169,7 +176,7 @@ public class DeckEditorDraft extends DeckEditorBase implements NewConstants, New jButtonPick.setBounds(new Rectangle(238, 418, 147, 44)); jButtonPick.setFont(new java.awt.Font("Dialog", 0, 16)); jButtonPick.setText("Choose Card"); - jButtonPick.addActionListener(new java.awt.event.ActionListener() { + jButtonPick.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { jButtonPickClicked(e); } @@ -200,22 +207,7 @@ public class DeckEditorDraft extends DeckEditorBase implements NewConstants, New if (boosterDraft.hasNextChoice()) { showChoices(boosterDraft.nextChoice()); } else { - if (Constant.Runtime.UpldDrft[0]) { - if (BoosterDraft.draftPicks.size() > 1) { - ArrayList outDraftData = new ArrayList(); - - String[] keys = BoosterDraft.draftPicks.keySet().toArray(ArrayUtils.EMPTY_STRING_ARRAY); - - for (int i = 0; i < keys.length; i++) { - outDraftData.add(keys[i] + "|" + BoosterDraft.draftPicks.get(keys[i])); - } - - FileUtil.writeFile("res/draft/tmpDraftData.txt", outDraftData); - - HttpUtil poster = new HttpUtil(); - poster.upload("http://cardforge.org/draftAI/submitDraftData.php?fmt=" + BoosterDraft.draftFormat[0], "res/draft/tmpDraftData.txt"); - } - } + boosterDraft.finishedDrafting(); //quit saveDraft(); diff --git a/src/main/java/forge/view/swing/OldGuiNewGame.java b/src/main/java/forge/view/swing/OldGuiNewGame.java index 4e87b21e799..50816ec2704 100644 --- a/src/main/java/forge/view/swing/OldGuiNewGame.java +++ b/src/main/java/forge/view/swing/OldGuiNewGame.java @@ -10,6 +10,7 @@ import forge.error.BugzReporter; import forge.error.ErrorViewer; import forge.game.GameType; import forge.game.limited.BoosterDraft_1; +import forge.game.limited.CardPoolLimitation; import forge.game.limited.SealedDeck; import forge.gui.GuiUtils; import forge.gui.ListChooser; @@ -392,15 +393,15 @@ public class OldGuiNewGame extends JFrame implements NewConstants, NewConstants. Object o = GuiUtils.getChoice(prompt, draftTypes.toArray()); if (o.toString().equals(draftTypes.get(0))) { - draft.showGui(new BoosterDraft_1("Full")); + draft.showGui(new BoosterDraft_1(CardPoolLimitation.Full)); } else if (o.toString().equals(draftTypes.get(1))) { - draft.showGui(new BoosterDraft_1("Block")); + draft.showGui(new BoosterDraft_1(CardPoolLimitation.Block)); } else if (o.toString().equals(draftTypes.get(2))) { - draft.showGui(new BoosterDraft_1("Custom")); + draft.showGui(new BoosterDraft_1(CardPoolLimitation.Custom)); } } diff --git a/src/test/java/forge/BoosterDraftTest.java b/src/test/java/forge/BoosterDraftTest.java index 0af98ddda51..67722ad39d9 100644 --- a/src/test/java/forge/BoosterDraftTest.java +++ b/src/test/java/forge/BoosterDraftTest.java @@ -72,4 +72,9 @@ public class BoosterDraftTest implements BoosterDraft { public CardList getUnchosenCards() { return null; } + + @Override + public void finishedDrafting() { + + } } diff --git a/src/test/java/forge/BoosterDraft_1Test.java b/src/test/java/forge/BoosterDraft_1Test.java index 14bf609d3db..bbeb48133ad 100644 --- a/src/test/java/forge/BoosterDraft_1Test.java +++ b/src/test/java/forge/BoosterDraft_1Test.java @@ -4,6 +4,7 @@ import org.testng.annotations.Test; import forge.game.limited.BoosterDraft_1; +import forge.game.limited.CardPoolLimitation; import forge.item.CardPrinted; import forge.item.ItemPoolView; @@ -19,7 +20,7 @@ public class BoosterDraft_1Test { */ @Test(groups = {"UnitTest", "fast"}, timeOut = 1000) public void BoosterDraft_1Test1() throws Exception { - BoosterDraft_1 draft = new BoosterDraft_1(); + BoosterDraft_1 draft = new BoosterDraft_1(CardPoolLimitation.Full); while (draft.hasNextChoice()) { ItemPoolView list = draft.nextChoice(); System.out.println(list.countAll()); diff --git a/src/test/java/forge/GuiBoosterDraftTest.java b/src/test/java/forge/GuiBoosterDraftTest.java index 07fb1b7bca3..7b2c2c06f51 100644 --- a/src/test/java/forge/GuiBoosterDraftTest.java +++ b/src/test/java/forge/GuiBoosterDraftTest.java @@ -3,6 +3,7 @@ package forge; import forge.deck.Deck; import forge.game.GameType; import forge.game.limited.BoosterDraft_1; +import forge.game.limited.CardPoolLimitation; import forge.gui.deckeditor.DeckEditorDraft; import org.testng.Assert; @@ -25,7 +26,7 @@ public class GuiBoosterDraftTest { Constant.Runtime.HumanDeck[0] = new Deck(GameType.Sealed); DeckEditorDraft g = new DeckEditorDraft(); - g.showGui(new BoosterDraft_1()); + g.showGui(new BoosterDraft_1(CardPoolLimitation.Full)); Assert.assertNotNull(g); g.dispose(); }