New 2 Color Deck Generator
Post MTG Forge Related Programming Questions Here
Moderators: timmermac, Blacksmith, KrazyTheFox, Agetian, friarsol, CCGHQ Admins
18 posts
• Page 1 of 2 • 1, 2
New 2 Color Deck Generator
by Rob Cashwalker » 30 Sep 2010, 11:56
I just added a new random deck generator. It allows the user to specify the colors.
At the moment it doesn't handle dual lands, nor does it add any artifacts.
It attempts to promote a slight mana curve, and most cards should not be singleton.
At the moment it doesn't handle dual lands, nor does it add any artifacts.
It attempts to promote a slight mana curve, and most cards should not be singleton.
- Code: Select all
package forge;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import forge.error.ErrorViewer;
public class Generate2ColorDeck
{
private String color1 = "";
private String color2 = "";
private Random r = null;
private Map<String,String> ClrMap = null;
private ArrayList<String> notColors = null;
public Generate2ColorDeck(String Clr1, String Clr2)
{
r = new Random();
ClrMap = new HashMap<String,String>();
ClrMap.put("White", "W");
ClrMap.put("Blue", "U");
ClrMap.put("Black", "B");
ClrMap.put("Red", "R");
ClrMap.put("Green", "G");
notColors = new ArrayList<String>();
notColors.add("White");
notColors.add("Blue");
notColors.add("Black");
notColors.add("Red");
notColors.add("Green");
if (Clr1.equals("AI"))
{
// choose first color
color1 = notColors.get(r.nextInt(5));
// choose second color
String c2 = notColors.get(r.nextInt(5));
while (c2.equals(color1))
c2 = notColors.get(r.nextInt(5));
color2 = c2;
}
else
{
color1 = Clr1;
color2 = Clr2;
}
notColors.remove(color1);
notColors.remove(color2);
}
public CardList get2ColorDeck(int Size)
{
String tmpDeck = "";
CardList tDeck = new CardList();
Map<String, Integer> CardCounts = new HashMap<String, Integer>();
int LandsPercentage = 42;
int CreatPercentage = 34;
int SpellPercentage = 24;
// start with all cards
CardList AllCards = AllZone.CardFactory.getAllCards();
// remove cards that generated decks don't like
AllCards = AllCards.filter(new CardListFilter(){
public boolean addCard(Card c){
return (!c.getSVar("RemAIDeck").equals("True"));
}
});
// reduce to cards that match the colors
CardList CL1 = AllCards.getColor(ClrMap.get(color1));
CardList CL2 = AllCards.getColor(ClrMap.get(color2));
// remove multicolor cards that don't match the colors
CardListFilter clrF = new CardListFilter(){
public boolean addCard(Card c){
for (int i=0; i<notColors.size(); i++)
{
if (c.getManaCost().contains(ClrMap.get(notColors.get(i))))
return false;
}
return true;
}
};
CL1 = CL1.filter(clrF);
CL2 = CL2.filter(clrF);
// build subsets based on type
CardList Cr1 = CL1.getType("Creature");
CardList Cr2 = CL2.getType("Creature");
String ISE[] = {"Instant", "Sorcery", "Enchantment", "Planeswalker"};
CardList Sp1 = CL1.getValidCards(ISE);
CardList Sp2 = CL2.getValidCards(ISE);
// final card pools
CardList Cr12 = new CardList();
CardList Sp12 = new CardList();
// used for mana curve in the card pool
final int MinCMC[] = {1}, MaxCMC[] = {2};
CardListFilter cmcF = new CardListFilter(){
public boolean addCard(Card c){
int cCMC = c.getCMC();
return (cCMC >= MinCMC[0]) && (cCMC <= MaxCMC[0]);
}
};
// select cards to build card pools using a mana curve
for (int i=4; i>0; i--)
{
CardList Cr1CMC = Cr1.filter(cmcF);
CardList Cr2CMC = Cr2.filter(cmcF);
CardList Sp1CMC = Sp1.filter(cmcF);
CardList Sp2CMC = Sp2.filter(cmcF);
for (int j=0; j<i; j++)
{
Card c = Cr1CMC.get(r.nextInt(Cr1CMC.size()));
Cr12.add(c);
CardCounts.put(c.getName(), 0);
c = Cr2CMC.get(r.nextInt(Cr2CMC.size()));
Cr12.add(c);
CardCounts.put(c.getName(), 0);
c = Sp1CMC.get(r.nextInt(Sp1CMC.size()));
Sp12.add(c);
CardCounts.put(c.getName(), 0);
c = Sp2CMC.get(r.nextInt(Sp2CMC.size()));
Sp12.add(c);
CardCounts.put(c.getName(), 0);
}
MinCMC[0] += 2; MaxCMC[0] +=2;
// resulting mana curve of the card pool
//16x 1 - 2
//12x 3 - 4
//8x 5 - 6
//4x 7 - 8
//=40x - card pool could support up to a 275 card deck (all 4-ofs plus basic lands)
}
// shuffle card pools
Cr12.shuffle();
Sp12.shuffle();
// calculate card counts
float p = (float) ((float)CreatPercentage * .01);
int CreatCnt = (int)(p * (float)Size);
tmpDeck += "Creature Count:" + CreatCnt + "\n";
p = (float) ((float)SpellPercentage * .01);
int SpellCnt = (int)(p * (float)Size);
tmpDeck += "Spell Count:" + SpellCnt + "\n";
// build deck from the card pools
for (int i=0; i<CreatCnt; i++)
{
Card c = Cr12.get(r.nextInt(Cr12.size()));
while (CardCounts.get(c.getName()) > 3)
c = Cr12.get(r.nextInt(Cr12.size()));
tDeck.add(AllZone.CardFactory.getCard(c.getName(), Constant.Player.Computer));
int n = CardCounts.get(c.getName());
CardCounts.put(c.getName(), n + 1);
tmpDeck += c.getName() + " " + c.getManaCost() + "\n";
}
for (int i=0; i<SpellCnt; i++)
{
Card c = Sp12.get(r.nextInt(Sp12.size()));
while (CardCounts.get(c.getName()) > 3)
c = Sp12.get(r.nextInt(Sp12.size()));
tDeck.add(AllZone.CardFactory.getCard(c.getName(), Constant.Player.Computer));
int n = CardCounts.get(c.getName());
CardCounts.put(c.getName(), n + 1);
tmpDeck += c.getName() + " " + c.getManaCost() + "\n";
}
// Add basic lands
// TODO: dual lands?
int numBLands = 0;
if (LandsPercentage > 0)
{
p = (float)((float)LandsPercentage * .01);
numBLands = (int)(p * (float)Size);
}
else // otherwise, just fill in the rest of the deck with basic lands
numBLands = Size - tDeck.size();
tmpDeck += "numBLands:" + numBLands + "\n";
if (numBLands > 0) // attempt to optimize basic land counts according to color representation
{
CCnt ClrCnts[] = {new CCnt("Plains", 0),
new CCnt("Island", 0),
new CCnt("Swamp", 0),
new CCnt("Mountain", 0),
new CCnt("Forest", 0)};
// count each card color using mana costs
// TODO: count hybrid mana differently?
// TODO: count all color letters? ie: 2 W W counts as 2
for (int i=0;i<tDeck.size(); i++)
{
Card c = tDeck.get(i);
String mc = c.getManaCost();
if (mc.contains("W"))
ClrCnts[0].Count++;
if (mc.contains("U"))
ClrCnts[1].Count++;
if (mc.contains("B"))
ClrCnts[2].Count++;
if (mc.contains("R"))
ClrCnts[3].Count++;
if (mc.contains("G"))
ClrCnts[4].Count++;
}
// total of all ClrCnts
int totalColor = 0;
for (int i=0;i<5; i++)
{
totalColor += ClrCnts[i].Count;
tmpDeck += ClrCnts[i].Color + ":" + ClrCnts[i].Count + "\n";
}
tmpDeck += "totalColor:" + totalColor + "\n";
for (int i=0; i<5; i++)
{
if (ClrCnts[i].Count > 0)
{ // calculate number of lands for each color
p = (float)ClrCnts[i].Count / (float)totalColor;
int nLand = (int)((float)numBLands * p);
tmpDeck += "numLand-" + ClrCnts[i].Color + ":" + nLand + "\n";
// just to prevent a null exception by the deck size fixing code
CardCounts.put(ClrCnts[i].Color, nLand);
for (int j=0; j<=nLand; j++)
tDeck.add(AllZone.CardFactory.getCard(ClrCnts[i].Color, Constant.Player.Computer));
}
}
}
tmpDeck += "DeckSize:" + tDeck.size() + "\n";
// fix under-sized or over-sized decks, due to integer arithmetic
if (tDeck.size() < Size)
{
int diff = Size - tDeck.size();
for (int i=0; i<diff; i++)
{
Card c = tDeck.get(r.nextInt(tDeck.size()));
while (CardCounts.get(c.getName()) >= 4)
c = tDeck.get(r.nextInt(tDeck.size()));
int n = CardCounts.get(c.getName());
tDeck.add(AllZone.CardFactory.getCard(c.getName(), Constant.Player.Computer));
CardCounts.put(c.getName(), n + 1);
tmpDeck += "Added:" + c.getName() + "\n";
}
}
else if (tDeck.size() > Size)
{
int diff = tDeck.size() - Size;
for (int i=0; i<diff; i++)
{
Card c = tDeck.get(r.nextInt(tDeck.size()));
while (c.getType().contains("Basic")) // don't remove basic lands
c = tDeck.get(r.nextInt(tDeck.size()));
tDeck.remove(c);
tmpDeck += "Removed:" + c.getName() + "\n";
}
}
tmpDeck += "DeckSize:" + tDeck.size() + "\n";
//ErrorViewer.showError(tmpDeck);
return tDeck;
}
class CCnt
{
public String Color;
public int Count;
public CCnt(String clr, int cnt)
{
Color = clr;
Count = cnt;
}
}
}
The Force will be with you, Always.
-
Rob Cashwalker - Programmer
- Posts: 2167
- Joined: 09 Sep 2008, 15:09
- Location: New York
- Has thanked: 5 times
- Been thanked: 40 times
Re: New 2 Color Deck Generator
by mtgrares » 30 Sep 2010, 17:19
A better random deck generator sounds great. Sometimes the current deck generator (which I wrote) is too random since it doesn't consider a mana curve at all. (I think the old deck generator did create decks with at least 12 creatures.)
Thanks of the update because I enjoy using and playing against generated decks. (I turn on the AI Land Stack option in order to make it more challenging.)
Thanks of the update because I enjoy using and playing against generated decks. (I turn on the AI Land Stack option in order to make it more challenging.)
- mtgrares
- DEVELOPER
- Posts: 1352
- Joined: 08 Sep 2008, 22:10
- Has thanked: 3 times
- Been thanked: 12 times
Re: New 2 Color Deck Generator
by Rob Cashwalker » 04 Oct 2010, 03:37
Made some changes this weekend.
First off, I added support for dual lands in the 2-color generator.
Then I changed how both the them deck generator and the 2-color generator count mana colors for the ratio of lands. It now counts each mana symbol.
I also changed the NewGame screen. Instead of listing all the different deck generators, I left only one "Generate Deck". It then presents a list dialog with the different generators.
Finally, I added a property to enable/disable the display of the 2-color deck list. "showdeck/2color=true"
First off, I added support for dual lands in the 2-color generator.
Then I changed how both the them deck generator and the 2-color generator count mana colors for the ratio of lands. It now counts each mana symbol.
I also changed the NewGame screen. Instead of listing all the different deck generators, I left only one "Generate Deck". It then presents a list dialog with the different generators.
Finally, I added a property to enable/disable the display of the 2-color deck list. "showdeck/2color=true"
The Force will be with you, Always.
-
Rob Cashwalker - Programmer
- Posts: 2167
- Joined: 09 Sep 2008, 15:09
- Location: New York
- Has thanked: 5 times
- Been thanked: 40 times
Re: New 2 Color Deck Generator
by friarsol » 04 Oct 2010, 13:58
For Hybrid Mana do those count as half mana or full mana?Rob Cashwalker wrote:Then I changed how both the them deck generator and the 2-color generator count mana colors for the ratio of lands. It now counts each mana symbol.
- friarsol
- Global Moderator
- Posts: 7593
- Joined: 15 May 2010, 04:20
- Has thanked: 243 times
- Been thanked: 965 times
Re: New 2 Color Deck Generator
by Rob Cashwalker » 04 Oct 2010, 16:13
Alas, I still haven't decided how those should count. For now, they count full.
The Force will be with you, Always.
-
Rob Cashwalker - Programmer
- Posts: 2167
- Joined: 09 Sep 2008, 15:09
- Location: New York
- Has thanked: 5 times
- Been thanked: 40 times
Re: New 2 Color Deck Generator
by friarsol » 04 Oct 2010, 18:22
How about this?Rob Cashwalker wrote:Alas, I still haven't decided how those should count. For now, they count full.
2/R counts as a full.
R/G in a red/green deck count as a half each.
R/G in a red/black deck counts as a full.
- friarsol
- Global Moderator
- Posts: 7593
- Joined: 15 May 2010, 04:20
- Has thanked: 243 times
- Been thanked: 965 times
Re: New 2 Color Deck Generator
by Rob Cashwalker » 04 Oct 2010, 18:55
R/G in a R-B THEME deck, I guess... but how to know that the deck is supposed to be R-B, when there's G in a mana cost..?
R/G in a R-B GENERATED deck, will never occur, because of the color-selection filter - it removes any card that has a mana symbol outside of the decks two chosen colors.
In the long run I don't think it makes a huge difference:
given the mana costs for a simple R/G deck:
R
1 R
R R
2 R
G
1 G
G G
2 G
R/G
1 R/G
R/G R/G
2 R/G
colors always count as full: 10R + 10G = 20total (50%R 50%G)
hybrids count as half: 7.5R + 7.5G = 15total (50%R 50%G)
R/G in a R-B GENERATED deck, will never occur, because of the color-selection filter - it removes any card that has a mana symbol outside of the decks two chosen colors.
In the long run I don't think it makes a huge difference:
given the mana costs for a simple R/G deck:
R
1 R
R R
2 R
G
1 G
G G
2 G
R/G
1 R/G
R/G R/G
2 R/G
colors always count as full: 10R + 10G = 20total (50%R 50%G)
hybrids count as half: 7.5R + 7.5G = 15total (50%R 50%G)
The Force will be with you, Always.
-
Rob Cashwalker - Programmer
- Posts: 2167
- Joined: 09 Sep 2008, 15:09
- Location: New York
- Has thanked: 5 times
- Been thanked: 40 times
Re: New 2 Color Deck Generator
by Bog Wraith » 05 Oct 2010, 16:17
Since the 1002 release I find myself, when not questing, playing allot of the 2 colour generated deck mode. I really like it & it seems very well balanced.
Just saw that dual lands are now included. Is there a way to eventually get a smattering of Artifacts in the mix too? Maybe colour specific Arty's like Scepter of Fugue when playing Black as one of your colours as an example. Would Arty's with a specific mana colour cost make it easier for them to be included and for randomization of those picks as well?
In any event, I really like the balance I've seen with this so far Rob, thanks very much for all the work!
Just saw that dual lands are now included. Is there a way to eventually get a smattering of Artifacts in the mix too? Maybe colour specific Arty's like Scepter of Fugue when playing Black as one of your colours as an example. Would Arty's with a specific mana colour cost make it easier for them to be included and for randomization of those picks as well?
In any event, I really like the balance I've seen with this so far Rob, thanks very much for all the work!

'Twas in the bogs of Cannelbrae
My mate did meet an early grave
'Twas nothing left for us to save
In the peat-filled bogs of Cannelbrae.
My mate did meet an early grave
'Twas nothing left for us to save
In the peat-filled bogs of Cannelbrae.
-
Bog Wraith - Global Mod 1 (Ret)
- Posts: 1108
- Joined: 28 May 2008, 22:40
- Location: Shandalar
- Has thanked: 425 times
- Been thanked: 153 times
Re: New 2 Color Deck Generator
by Rob Cashwalker » 05 Oct 2010, 18:00
I think if artifacts came into the mix, then it would end up diluting the colored cards.... This generator tries to promote card multiples.
I was also trying to think of an easy way to eliminate on-color cards with off-color activations, and I couldn't think of a simple, universal way, since not all abilities provide the activation cost, and not all cards include them in the card text.... Plus, how to differentiate "W" as a mana cost and not as a character in the word "Whenever".
Definitely something to look at at some point.
I played a number of matches with both players using these 2 color decks, and the computer was doing a kick-ass job, much better win % than the original generator.
I'm going to add a color option to the color list - "Random".
I was also trying to think of an easy way to eliminate on-color cards with off-color activations, and I couldn't think of a simple, universal way, since not all abilities provide the activation cost, and not all cards include them in the card text.... Plus, how to differentiate "W" as a mana cost and not as a character in the word "Whenever".
Definitely something to look at at some point.
I played a number of matches with both players using these 2 color decks, and the computer was doing a kick-ass job, much better win % than the original generator.
I'm going to add a color option to the color list - "Random".
The Force will be with you, Always.
-
Rob Cashwalker - Programmer
- Posts: 2167
- Joined: 09 Sep 2008, 15:09
- Location: New York
- Has thanked: 5 times
- Been thanked: 40 times
Re: New 2 Color Deck Generator
by Bog Wraith » 05 Oct 2010, 19:31
I get what you mean about artifacts & it's no big deal not to have them.
I too have noticed that the AI is performing at a higher level then before. I find the games closer and the AI making more logical choices with the cards in hand vs what is already played to the table. I also find that the deck compositions are well balanced and that the randomization of the cards in the decks in multiple replays are very fair and playable.
As I said earlier, I find myself playing this more & more & enjoying it immensely!
I too have noticed that the AI is performing at a higher level then before. I find the games closer and the AI making more logical choices with the cards in hand vs what is already played to the table. I also find that the deck compositions are well balanced and that the randomization of the cards in the decks in multiple replays are very fair and playable.
As I said earlier, I find myself playing this more & more & enjoying it immensely!

'Twas in the bogs of Cannelbrae
My mate did meet an early grave
'Twas nothing left for us to save
In the peat-filled bogs of Cannelbrae.
My mate did meet an early grave
'Twas nothing left for us to save
In the peat-filled bogs of Cannelbrae.
-
Bog Wraith - Global Mod 1 (Ret)
- Posts: 1108
- Joined: 28 May 2008, 22:40
- Location: Shandalar
- Has thanked: 425 times
- Been thanked: 153 times
Re: New 2 Color Deck Generator
by zerker2000 » 05 Oct 2010, 21:44
Uh, they don't? Since when is getManaCost() depreciated?Rob Cashwalker wrote:I was also trying to think of an easy way to eliminate on-color cards with off-color activations, and I couldn't think of a simple, universal way, since not all abilities provide the activation cost
O forest, hold thy wand'ring son
Though fears assail the door.
O foliage, cloak thy ravaged one
In vestments cut for war.
--Eladamri, the Seed of Freyalise
Though fears assail the door.
O foliage, cloak thy ravaged one
In vestments cut for war.
--Eladamri, the Seed of Freyalise
- zerker2000
- Programmer
- Posts: 569
- Joined: 09 May 2009, 21:40
- Location: South Pasadena, CA
- Has thanked: 0 time
- Been thanked: 0 time
Re: New 2 Color Deck Generator
by Rob Cashwalker » 06 Oct 2010, 03:26
Heh... you know, I was so busy working at this from the card level, I didn't really think about the SpellAbility.getManaCost(). On the other hand, some abilities (and most future ones) use the Ability_Cost, maybe the mana portion is copied to the SpellAbility?
The Force will be with you, Always.
-
Rob Cashwalker - Programmer
- Posts: 2167
- Joined: 09 Sep 2008, 15:09
- Location: New York
- Has thanked: 5 times
- Been thanked: 40 times
Re: New 2 Color Deck Generator
by friarsol » 06 Oct 2010, 04:45
Ability_Cost sets the ManaCost during creation of an ability.
- Code: Select all
public Ability_Activated(Card sourceCard, Ability_Cost abCost, Target tgt) {
super(SpellAbility.Ability, sourceCard);
setManaCost(abCost.getMana());
setPayCosts(abCost);
if (tgt != null && tgt.doesTarget())
setTarget(tgt);
}
- friarsol
- Global Moderator
- Posts: 7593
- Joined: 15 May 2010, 04:20
- Has thanked: 243 times
- Been thanked: 965 times
Re: New 2 Color Deck Generator
by slapshot5 » 06 Oct 2010, 14:35
I am getting an exception generating a 5 color deck:
-slapshot5
- Code: Select all
An error has occured. You can copy/paste this message or save it to a file.
Please report this, plus what you tried to do, to:
http://www.slightlymagic.net/forum/viewforum.php?f=26
If you don't want to register an account, you can mail it directly to
mtgerror@yahoo.com
GenerateConstructedDeck() : generateDeck() error, deck size it not 60, deck size is 29
Version:
Forge -- official beta: $Date: 2010-09-14 07:34:27 -0500 (Tue, 14 Sep 2010) $, SVN revision: $Revision: 2039 $
OS: Windows XP Version: 5.1 Architecture: x86
Java Version: 1.6.0_21 Vendor: Sun Microsystems Inc.
Detailed error trace:
java.lang.RuntimeException: GenerateConstructedDeck() : generateDeck() error, deck size it not 60, deck size is 29
at forge.GenerateConstructedMultiColorDeck.generate5ColorDeck(GenerateConstructedMultiColorDeck.java:96)
at forge.Gui_NewGame.generateConstructed5ColorDeck(Gui_NewGame.java:659)
at forge.Gui_NewGame.genDecks(Gui_NewGame.java:625)
at forge.Gui_NewGame.startButton_actionPerformed(Gui_NewGame.java:554)
at forge.Gui_NewGame$11.actionPerformed(Gui_NewGame.java:420)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
-slapshot5
- slapshot5
- Programmer
- Posts: 1391
- Joined: 03 Jan 2010, 17:47
- Location: Mac OS X
- Has thanked: 25 times
- Been thanked: 68 times
Re: New 2 Color Deck Generator
by Rob Cashwalker » 06 Oct 2010, 17:04
I'm getting that too, on my work pc that hasn't been updated in a couple weeks, since before my updates. I didn't make any changes to the 5 color generator.
I'm suspecting it might be due to the changes involving card color.
I'm suspecting it might be due to the changes involving card color.
The Force will be with you, Always.
-
Rob Cashwalker - Programmer
- Posts: 2167
- Joined: 09 Sep 2008, 15:09
- Location: New York
- Has thanked: 5 times
- Been thanked: 40 times
18 posts
• Page 1 of 2 • 1, 2
Who is online
Users browsing this forum: No registered users and 51 guests