frankkarsten

Should you play tapped duals in two-color Limited decks?

Mar 26th, 2018
393
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. package optimalnrtapduals;
  2.  
  3. import java.util.Arrays.*;
  4. import java.util.Random;
  5.  
  6. public class OptimalNrTapDuals {
  7.  
  8.     public static void main(String[] args) {
  9.        
  10.         Deck deck=new Deck();
  11.  
  12.         //CardType 1 is Crested Herdcaller: 6 power for 3GG
  13.         //CardType 2 is Wind Strider: 3 power for 4U
  14.         //CardType 3 is Ripjaw Raptor: 4 power for 2GG
  15.         //CardType 4 is Jade Guardian: 3 power for 3G
  16.         //CardType 5 is Deadeye Rig Hauler: 3 power for 3U
  17.         //CardType 6 is Swift Warden: 3 power for 1GG
  18.         //CardType 7 is Jungleborn Pioneer: 3 power for 2G
  19.         //CardType 8 is Watertrap Weaver: 2 power for 2U
  20.         //CardType 9 is Deeproot Warrior: 2 power for 1G
  21.         //CardType 10 is Shaper Apprentice: 2 power for 1U
  22.         //CardType 11 is Jungle Delver: 1 power for G
  23.         //CardType 12 is Mist-Cloaked Herald: 1 power for U
  24.         //And finally we have Forest, Island, and Woodland Stream (U/G tap-dual)
  25.        
  26.         for (int NrForest=7; NrForest<=11; NrForest++){
  27.             for (int NrIsland=4; NrIsland<=8; NrIsland++){
  28.                 if (NrForest+NrIsland>=12 && NrForest+NrIsland<=17){
  29.                     deck.SetDeck(1,2,1,2,3,1,4,2,3,2,1,1,NrForest,NrIsland,17-NrForest-NrIsland);
  30.                     double ExpKillTurn=Math.round(KillTurnForRandomHand(deck,7,10000000)*10000)/10000.0;
  31.                     System.out.println("For the deck with "+NrForest+" Forests, "+NrIsland+" Islands, "+(17-NrForest-NrIsland)+" Duals, the expected kill-turn is: "+ ExpKillTurn);
  32.                 }
  33.             }
  34.         }
  35.     }//end of main
  36.  
  37.     public static double KillTurnForRandomHand(Deck deck, int StartingCards, int NumberOfIterations){
  38.         Deck remainingdeck=new Deck();
  39.         int SumOfKillTurns=0;
  40.         for (int IterationCounter=1; IterationCounter<=NumberOfIterations; IterationCounter++){
  41.             OpeningHand openinghand=GiveOpeningHandAfterMulls(deck, StartingCards);
  42.             remainingdeck.SetDeck(deck.NumberOfCardType1-openinghand.NumberOfCardType1,deck.NumberOfCardType2-openinghand.NumberOfCardType2,deck.NumberOfCardType3-openinghand.NumberOfCardType3,deck.NumberOfCardType4-openinghand.NumberOfCardType4,deck.NumberOfCardType5-openinghand.NumberOfCardType5,deck.NumberOfCardType6-openinghand.NumberOfCardType6,deck.NumberOfCardType7-openinghand.NumberOfCardType7,deck.NumberOfCardType8-openinghand.NumberOfCardType8,deck.NumberOfCardType9-openinghand.NumberOfCardType9,deck.NumberOfCardType10-openinghand.NumberOfCardType10,deck.NumberOfCardType11-openinghand.NumberOfCardType11,deck.NumberOfCardType12-openinghand.NumberOfCardType12,deck.NumberOfForest-openinghand.NumberOfForest,deck.NumberOfIsland-openinghand.NumberOfIsland,deck.NumberOfDuals-openinghand.NumberOfDuals);
  43.             SumOfKillTurns=SumOfKillTurns+SimulateGame(remainingdeck,openinghand);
  44.         }
  45.         return SumOfKillTurns/(NumberOfIterations+0.0);
  46.     }//end of AverageKillTurnForRandomHand
  47.    
  48.     static OpeningHand GiveOpeningHandAfterMulls (Deck deck, int StartingCards) {
  49.        
  50.         Deck remainingdeck=new Deck();
  51.         OpeningHand openinghand=new OpeningHand();
  52.         int TypeOfCardDrawn;
  53.         boolean KeepHand=false;
  54.        
  55.         for (int OpeningHandSize=7; OpeningHandSize>=1; OpeningHandSize--){
  56.             if (KeepHand==false){
  57.                 int NrLands=0;
  58.                 openinghand.SetHand(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
  59.                 remainingdeck.SetDeck(deck.NumberOfCardType1,deck.NumberOfCardType2,deck.NumberOfCardType3,deck.NumberOfCardType4,deck.NumberOfCardType5,deck.NumberOfCardType6,deck.NumberOfCardType7,deck.NumberOfCardType8,deck.NumberOfCardType9,deck.NumberOfCardType10,deck.NumberOfCardType11,deck.NumberOfCardType12,deck.NumberOfForest-openinghand.NumberOfForest,deck.NumberOfIsland-openinghand.NumberOfIsland,deck.NumberOfDuals-openinghand.NumberOfDuals);
  60.                 for (int CardsDrawn=0; CardsDrawn<OpeningHandSize; CardsDrawn++){
  61.                     TypeOfCardDrawn=remainingdeck.DrawCard();
  62.                     if (TypeOfCardDrawn==1) {openinghand.NumberOfCardType1++;}
  63.                     if (TypeOfCardDrawn==2) {openinghand.NumberOfCardType2++;}
  64.                     if (TypeOfCardDrawn==3) {openinghand.NumberOfCardType3++;}
  65.                     if (TypeOfCardDrawn==4) {openinghand.NumberOfCardType4++;}
  66.                     if (TypeOfCardDrawn==5) {openinghand.NumberOfCardType5++;}
  67.                     if (TypeOfCardDrawn==6) {openinghand.NumberOfCardType6++;}
  68.                     if (TypeOfCardDrawn==7) {openinghand.NumberOfCardType7++;}
  69.                     if (TypeOfCardDrawn==8) {openinghand.NumberOfCardType8++;}
  70.                     if (TypeOfCardDrawn==9) {openinghand.NumberOfCardType9++;}
  71.                     if (TypeOfCardDrawn==10) {openinghand.NumberOfCardType10++;}
  72.                     if (TypeOfCardDrawn==11) {openinghand.NumberOfCardType11++;}
  73.                     if (TypeOfCardDrawn==12) {openinghand.NumberOfCardType12++;}
  74.                     if (TypeOfCardDrawn==20) {openinghand.NumberOfForest++; NrLands++;}
  75.                     if (TypeOfCardDrawn==21) {openinghand.NumberOfIsland++; NrLands++;}
  76.                     if (TypeOfCardDrawn==22) {openinghand.NumberOfDuals++; NrLands++;}
  77.                    
  78.                 }
  79.                 //Keep any hand that has 3 or 4 lands with at least one card that can be cast with those lands. Keep any hand that has 5 lands with both colors of mana. Keep any hand with 2 lands with both colors of mana or at least one card that can be cast with those lands. Keep every 4-card opening hand; we have to stop somewhere. Mulligan the rest.
  80.                 boolean AtLeastOneCastableSpell=false;
  81.                 int NrGreenSources=openinghand.NumberOfDuals+openinghand.NumberOfForest;
  82.                 int NrBlueSources=openinghand.NumberOfDuals+openinghand.NumberOfIsland;
  83.                 if (openinghand.NumberOfCardType1>=1 && NrGreenSources>=2 && NrLands>=5) {AtLeastOneCastableSpell=true;}
  84.                 if (openinghand.NumberOfCardType2>=1 && NrBlueSources>=1 && NrLands>=5) {AtLeastOneCastableSpell=true;}
  85.                 if (openinghand.NumberOfCardType3>=1 && NrGreenSources>=2 && NrLands>=4) {AtLeastOneCastableSpell=true;}
  86.                 if (openinghand.NumberOfCardType4>=1 && NrGreenSources>=1 && NrLands>=4) {AtLeastOneCastableSpell=true;}
  87.                 if (openinghand.NumberOfCardType5>=1 && NrBlueSources>=1 && NrLands>=4) {AtLeastOneCastableSpell=true;}
  88.                 if (openinghand.NumberOfCardType6>=1 && NrGreenSources>=2 && NrLands>=3) {AtLeastOneCastableSpell=true;}
  89.                 if (openinghand.NumberOfCardType7>=1 && NrGreenSources>=1 && NrLands>=3) {AtLeastOneCastableSpell=true;}
  90.                 if (openinghand.NumberOfCardType8>=1 && NrBlueSources>=1 && NrLands>=3) {AtLeastOneCastableSpell=true;}
  91.                 if (openinghand.NumberOfCardType9>=1 && NrGreenSources>=1 && NrLands>=2) {AtLeastOneCastableSpell=true;}
  92.                 if (openinghand.NumberOfCardType10>=1 && NrBlueSources>=1 && NrLands>=2) {AtLeastOneCastableSpell=true;}
  93.                 if (openinghand.NumberOfCardType11>=1 && NrGreenSources>=1 && NrLands>=1) {AtLeastOneCastableSpell=true;}
  94.                 if (openinghand.NumberOfCardType12>=1 && NrBlueSources>=1 && NrLands>=1) {AtLeastOneCastableSpell=true;}
  95.                
  96.                 if ( (NrLands==3 || NrLands==4) && AtLeastOneCastableSpell) {KeepHand=true;}
  97.                 if (NrLands==5 && NrGreenSources>=1 && NrBlueSources>=1) {KeepHand=true;}
  98.                 if (NrLands==2 && ( (NrGreenSources>=1 && NrBlueSources>=1) || AtLeastOneCastableSpell) )  {KeepHand=true;}
  99.                 if (OpeningHandSize<=4) {KeepHand=true;}
  100.             }
  101.         }
  102.        
  103.         return openinghand;
  104.     }//end of GiveOpeningHandAfterMulls
  105.    
  106.     static int SimulateGame(Deck remainingdeck, OpeningHand openinghand) {
  107.        
  108.         //Initializing
  109.         int TypeOfCardDrawn=0;
  110.         int Turn=0;
  111.         int OppLife=20;
  112.         int PowerInPlay=0;
  113.         int ForestInPlay=0;
  114.         int IslandInPlay=0;
  115.         int DualInPlay=0;
  116.         int NrCountersThatOurOpponentStillHas=2;
  117.         boolean DebugMode=false;
  118.        
  119.         //Better late than never: an array to keep track of this nonsense
  120.         int[] CardsInHand = new int[23];
  121.         CardsInHand[1]=openinghand.NumberOfCardType1;
  122.         CardsInHand[2]=openinghand.NumberOfCardType2;
  123.         CardsInHand[3]=openinghand.NumberOfCardType3;
  124.         CardsInHand[4]=openinghand.NumberOfCardType4;
  125.         CardsInHand[5]=openinghand.NumberOfCardType5;
  126.         CardsInHand[6]=openinghand.NumberOfCardType6;
  127.         CardsInHand[7]=openinghand.NumberOfCardType7;
  128.         CardsInHand[8]=openinghand.NumberOfCardType8;
  129.         CardsInHand[9]=openinghand.NumberOfCardType9;
  130.         CardsInHand[10]=openinghand.NumberOfCardType10;
  131.         CardsInHand[11]=openinghand.NumberOfCardType11;
  132.         CardsInHand[12]=openinghand.NumberOfCardType12;
  133.         CardsInHand[20]=openinghand.NumberOfForest;
  134.         CardsInHand[21]=openinghand.NumberOfIsland;
  135.         CardsInHand[22]=openinghand.NumberOfDuals;
  136.        
  137.         do {
  138.            
  139.             Turn++;
  140.            
  141.             //Draw step: Draw a card
  142.             if (Turn>1) {
  143.                 TypeOfCardDrawn=remainingdeck.DrawCard();
  144.                 CardsInHand[TypeOfCardDrawn]++;
  145.             }
  146.            
  147.             //Combat step: Attack!
  148.             OppLife=OppLife-PowerInPlay;
  149.  
  150.             if (DebugMode) {System.out.print("TURN "+ Turn +": Our hand is ");}
  151.             if (CardsInHand[1]>0) {if (DebugMode) {System.out.print(CardsInHand[1]+" 3GG, ");}}
  152.             if (CardsInHand[2]>0) {if (DebugMode) {System.out.print(CardsInHand[2]+" 4U, ");}}
  153.             if (CardsInHand[3]>0) {if (DebugMode) {System.out.print(CardsInHand[3]+" 2GG, ");}}
  154.             if (CardsInHand[4]>0) {if (DebugMode) {System.out.print(CardsInHand[4]+" 3G, ");}}
  155.             if (CardsInHand[5]>0) {if (DebugMode) {System.out.print(CardsInHand[5]+" 3U, ");}}
  156.             if (CardsInHand[6]>0) {if (DebugMode) {System.out.print(CardsInHand[6]+" 1GG, ");}}
  157.             if (CardsInHand[7]>0) {if (DebugMode) {System.out.print(CardsInHand[7]+" 2G, ");}}
  158.             if (CardsInHand[8]>0) {if (DebugMode) {System.out.print(CardsInHand[8]+" 2U, ");}}
  159.             if (CardsInHand[9]>0) {if (DebugMode) {System.out.print(CardsInHand[9]+" 1G, ");}}
  160.             if (CardsInHand[10]>0) {if (DebugMode) {System.out.print(CardsInHand[10]+" 1U, ");}}
  161.             if (CardsInHand[11]>0) {if (DebugMode) {System.out.print(CardsInHand[11]+" G, ");}}
  162.             if (CardsInHand[12]>0) {if (DebugMode) {System.out.print(CardsInHand[12]+" U, ");}}
  163.             if (CardsInHand[20]>0) {if (DebugMode) {System.out.print(" "+CardsInHand[20]+" For");}}
  164.             if (CardsInHand[21]>0) {if (DebugMode) {System.out.print(" "+CardsInHand[21]+" Isl");}}
  165.             if (CardsInHand[22]>0) {if (DebugMode) {System.out.print(" "+CardsInHand[22]+" Dual");}}
  166.             if (DebugMode) {System.out.print(". We own "+ForestInPlay+" For, "+IslandInPlay+" Isl, "+DualInPlay+" Dual, and "+PowerInPlay+" power. Opp at "+OppLife+" and "+ NrCountersThatOurOpponentStillHas+" counters. ");}
  167.             if (DebugMode) {System.out.print("Land drop is ");}
  168.  
  169.             //Second main phase: Let's figure out which land and spells to play
  170.             LandDropAndPlayRecommendation Recommendation = new LandDropAndPlayRecommendation();
  171.             Recommendation = WhichLandAndSpellsToPlay(CardsInHand, ForestInPlay, IslandInPlay, DualInPlay);
  172.             if (Recommendation.LandTypeDrop==0) {if (DebugMode) {System.out.print("N/A.");}}
  173.             if (Recommendation.LandTypeDrop==1) {ForestInPlay++; CardsInHand[20]--; if (DebugMode) {System.out.print("Forest.");}}
  174.             if (Recommendation.LandTypeDrop==2) {IslandInPlay++; CardsInHand[21]--; if (DebugMode) {System.out.print("Island.");}}
  175.             if (Recommendation.LandTypeDrop==3) {DualInPlay++; CardsInHand[22]--; if (DebugMode) {System.out.print("Dual.");}}
  176.            
  177.             for (int CardType=1; CardType<=12; CardType++){
  178.                 CardsInHand[CardType]=CardsInHand[CardType]-Recommendation.NumberToPlayOfThisCardType[CardType];
  179.                 for (int NumberOfCasts=1; NumberOfCasts<=Recommendation.NumberToPlayOfThisCardType[CardType]; NumberOfCasts++){
  180.                     if (DebugMode) {
  181.                         System.out.print(" We cast");
  182.                         if (CardType==1) {System.out.print(" 3GG.");}
  183.                         if (CardType==2) {System.out.print(" 4U. ");}
  184.                         if (CardType==3) {System.out.print(" 2GG. ");}
  185.                         if (CardType==4) {System.out.print(" 3G. ");}
  186.                         if (CardType==5) {System.out.print(" 3U. ");}
  187.                         if (CardType==6) {System.out.print(" 1GG. ");}
  188.                         if (CardType==7) {System.out.print(" 2G. ");}
  189.                         if (CardType==8) {System.out.print(" 2U. ");}
  190.                         if (CardType==9) {System.out.print(" 1G. ");}
  191.                         if (CardType==10) {System.out.print(" 1U. ");}
  192.                         if (CardType==11) {System.out.print(" G. ");}
  193.                         if (CardType==12) {System.out.print(" U. ");}
  194.                     }
  195.                     if (NrCountersThatOurOpponentStillHas==0 || TotalCost(CardType)==1) {PowerInPlay=PowerInPlay+Recommendation.NumberToPlayOfThisCardType[CardType]*Power(CardType);}
  196.                     if (NrCountersThatOurOpponentStillHas>0 && TotalCost(CardType)>1) {NrCountersThatOurOpponentStillHas--;}
  197.                 }
  198.             }
  199.             if (DebugMode) {System.out.println(); }
  200.         } while (OppLife>0);
  201.  
  202.         return Turn;
  203.        
  204.     }//end of SimulateGame
  205.    
  206.     static int GreenCost(int CardType){
  207.         int Outcome=0;
  208.         if (CardType==1) {Outcome=2;}
  209.         if (CardType==2) {Outcome=0;}
  210.         if (CardType==3) {Outcome=2;}
  211.         if (CardType==4) {Outcome=1;}
  212.         if (CardType==5) {Outcome=0;}
  213.         if (CardType==6) {Outcome=2;}
  214.         if (CardType==7) {Outcome=1;}
  215.         if (CardType==8) {Outcome=0;}
  216.         if (CardType==9) {Outcome=1;}
  217.         if (CardType==10) {Outcome=0;}
  218.         if (CardType==11) {Outcome=1;}
  219.         if (CardType==12) {Outcome=0;}
  220.         return Outcome;
  221.     }
  222.    
  223.     static int BlueCost(int CardType){
  224.         int Outcome=0;
  225.         if (CardType==1) {Outcome=0;}
  226.         if (CardType==2) {Outcome=1;}
  227.         if (CardType==3) {Outcome=0;}
  228.         if (CardType==4) {Outcome=0;}
  229.         if (CardType==5) {Outcome=1;}
  230.         if (CardType==6) {Outcome=0;}
  231.         if (CardType==7) {Outcome=0;}
  232.         if (CardType==8) {Outcome=1;}
  233.         if (CardType==9) {Outcome=0;}
  234.         if (CardType==10) {Outcome=1;}
  235.         if (CardType==11) {Outcome=0;}
  236.         if (CardType==12) {Outcome=1;}
  237.         return Outcome;
  238.     }
  239.        
  240.     static int TotalCost(int CardType){
  241.         int Outcome=0;
  242.         if (CardType==1) {Outcome=5;}
  243.         if (CardType==2) {Outcome=5;}
  244.         if (CardType==3) {Outcome=4;}
  245.         if (CardType==4) {Outcome=4;}
  246.         if (CardType==5) {Outcome=4;}
  247.         if (CardType==6) {Outcome=3;}
  248.         if (CardType==7) {Outcome=3;}
  249.         if (CardType==8) {Outcome=3;}
  250.         if (CardType==9) {Outcome=2;}
  251.         if (CardType==10) {Outcome=2;}
  252.         if (CardType==11) {Outcome=1;}
  253.         if (CardType==12) {Outcome=1;}
  254.         return Outcome;
  255.     }
  256.    
  257.     static int Power(int CardType){
  258.         int Outcome=0;
  259.         if (CardType==1) {Outcome=6;}
  260.         if (CardType==2) {Outcome=3;}
  261.         if (CardType==3) {Outcome=4;}
  262.         if (CardType==4) {Outcome=3;}
  263.         if (CardType==5) {Outcome=3;}
  264.         if (CardType==6) {Outcome=3;}
  265.         if (CardType==7) {Outcome=3;}
  266.         if (CardType==8) {Outcome=2;}
  267.         if (CardType==9) {Outcome=2;}
  268.         if (CardType==10) {Outcome=2;}
  269.         if (CardType==11) {Outcome=1;}
  270.         if (CardType==12) {Outcome=1;}
  271.         return Outcome;
  272.     }
  273.    
  274.     static LandDropAndPlayRecommendation WhichLandAndSpellsToPlay(int[] CardsInHand, int ForestInPlay, int IslandInPlay, int DualInPlay){
  275.  
  276.         int LandsInHand=CardsInHand[20]+CardsInHand[21]+CardsInHand[22];
  277.         LandDropAndPlayRecommendation Outcome=new LandDropAndPlayRecommendation();
  278.         Outcome.NumberToPlayOfThisCardType=new int[23];
  279.         if (LandsInHand==0) {
  280.             PlayRecommendation WithNoLand=new PlayRecommendation();
  281.             WithNoLand=GiveRecommendation(CardsInHand,ForestInPlay,IslandInPlay,DualInPlay);
  282.             Outcome.LandTypeDrop=0;
  283.             Outcome.NumberToPlayOfThisCardType=WithNoLand.NumberToPlayOfThisCardType;
  284.         }
  285.         if (LandsInHand>=1) {
  286.             int TotalManaSpentWithForest = -1;
  287.             int TotalManaSpentWithIsland = -1;
  288.             int TotalManaSpentWithDual = -1;
  289.             if (CardsInHand[20]>=1){
  290.                 PlayRecommendation WithForest=new PlayRecommendation();
  291.                 WithForest=GiveRecommendation(CardsInHand,ForestInPlay+1,IslandInPlay,DualInPlay);
  292.                 TotalManaSpentWithForest = WithForest.TotalManaSpentThisTurn;
  293.                 Outcome.LandTypeDrop=1;
  294.                 Outcome.NumberToPlayOfThisCardType=WithForest.NumberToPlayOfThisCardType;
  295.             }
  296.             if (CardsInHand[21]>=1){
  297.                 PlayRecommendation WithIsland=new PlayRecommendation();
  298.                 WithIsland=GiveRecommendation(CardsInHand,ForestInPlay,IslandInPlay+1,DualInPlay);
  299.                 TotalManaSpentWithIsland = WithIsland.TotalManaSpentThisTurn;
  300.                 if (TotalManaSpentWithIsland>TotalManaSpentWithForest || (TotalManaSpentWithIsland==TotalManaSpentWithForest && ForestInPlay>IslandInPlay) ) {
  301.                     Outcome.LandTypeDrop=2;
  302.                     Outcome.NumberToPlayOfThisCardType=WithIsland.NumberToPlayOfThisCardType;
  303.                 }
  304.             }
  305.             if (CardsInHand[22]>=1){
  306.                 PlayRecommendation WithDual=new PlayRecommendation();
  307.                 WithDual=GiveRecommendation(CardsInHand,ForestInPlay,IslandInPlay,DualInPlay);
  308.                 TotalManaSpentWithDual = WithDual.TotalManaSpentThisTurn;
  309.                 if (TotalManaSpentWithDual>=Math.max(TotalManaSpentWithForest,TotalManaSpentWithIsland)) {
  310.                     Outcome.LandTypeDrop=3;
  311.                     Outcome.NumberToPlayOfThisCardType=WithDual.NumberToPlayOfThisCardType;
  312.                 }
  313.             }
  314.         }
  315.        
  316.         return Outcome;
  317.     }
  318.    
  319.     static PlayRecommendation GiveRecommendation(int[] CardsInHand, int ForestInPlay, int IslandInPlay, int DualInPlay){
  320.         PlayRecommendation Outcome = new PlayRecommendation();
  321.         Outcome.NumberToPlayOfThisCardType = new int[23];
  322.         //We'll iterate over all 3-card combinations that we might play and pick the one. In case of a tie, we take the combination that lexicographically minimizes (CardType 1, CardType 2, CardType 3).
  323.         int BestCardType1=0;
  324.         int BestCardType2=0;
  325.         int BestCardType3=0;
  326.         int BestTotalManaSpent=0;
  327.         int GreenManaToPay; int BlueManaToPay; int ColorlessManaToPay; int GreenManaFromForest; int BlueManaFromIsland;
  328.         for (int CardType1=1; CardType1<=12; CardType1++){
  329.             int TappedForest=0;
  330.             int TappedIsland=0;
  331.             int TappedDual=0;
  332.             int AvailableTotalMana=ForestInPlay+IslandInPlay+DualInPlay;
  333.             int AvailableGreenMana=ForestInPlay+DualInPlay;
  334.             int AvailableBlueMana=IslandInPlay+DualInPlay;
  335.             if (CardsInHand[CardType1]>0 && GreenCost(CardType1)<=AvailableGreenMana && BlueCost(CardType1)<=AvailableBlueMana && TotalCost(CardType1)<=AvailableTotalMana) {
  336.                 //Start of the auto-tapping mana logic for the first card
  337.                 GreenManaToPay=GreenCost(CardType1);
  338.                 BlueManaToPay=BlueCost(CardType1);
  339.                 ColorlessManaToPay=TotalCost(CardType1)-GreenCost(CardType1)-BlueCost(CardType1);
  340.                 GreenManaFromForest=Math.min(GreenManaToPay,ForestInPlay-TappedForest);
  341.                 TappedForest=TappedForest+GreenManaFromForest;
  342.                 GreenManaToPay=GreenManaToPay-GreenManaFromForest;
  343.                 TappedDual=TappedDual+Math.min(GreenManaToPay,DualInPlay-TappedDual);
  344.                 BlueManaFromIsland=Math.min(BlueManaToPay,IslandInPlay-TappedIsland);
  345.                 TappedIsland=TappedIsland+BlueManaFromIsland;
  346.                 BlueManaToPay=BlueManaToPay-BlueManaFromIsland;
  347.                 TappedDual=TappedDual+Math.min(BlueManaToPay,DualInPlay-TappedDual);
  348.                 do {
  349.                     if ( ( (ForestInPlay-TappedForest)==(IslandInPlay-TappedIsland) )&& ColorlessManaToPay>=2 && (ForestInPlay-TappedForest)>0 && (IslandInPlay-TappedIsland)>0) {
  350.                         TappedForest++; TappedIsland++;
  351.                         ColorlessManaToPay--; ColorlessManaToPay--;
  352.                     }
  353.                    
  354.                     if ( ( (ForestInPlay-TappedForest)>(IslandInPlay-TappedIsland))&& ColorlessManaToPay>=1 ) {
  355.                         TappedForest++;
  356.                         ColorlessManaToPay--;
  357.                     }
  358.                     if ( ( (IslandInPlay-TappedIsland)>(ForestInPlay-TappedForest))&& ColorlessManaToPay>=1 ) {
  359.                         TappedIsland++;
  360.                         ColorlessManaToPay--;
  361.                     }
  362.                    
  363.                     if ( ( (ForestInPlay-TappedForest)==(IslandInPlay-TappedIsland) )&& ColorlessManaToPay==1 && (ForestInPlay-TappedForest)>0 && (IslandInPlay-TappedIsland)>0) {
  364.                         boolean TapForest=false;
  365.                         if (CardsInHand[12]>0) {TapForest=true;}
  366.                         if (TapForest) {
  367.                             TappedForest++; ColorlessManaToPay--;
  368.                         }
  369.                         else {
  370.                             TappedIsland++; ColorlessManaToPay--;
  371.                         }
  372.                     }
  373.                    
  374.                     if ( ForestInPlay==TappedForest && IslandInPlay==TappedIsland && ColorlessManaToPay>0 ) {
  375.                         TappedDual++;
  376.                         ColorlessManaToPay--;
  377.                     }
  378.                    
  379.                 } while (ColorlessManaToPay>0);
  380.                 if (TotalCost(CardType1)>BestTotalManaSpent){
  381.                     BestTotalManaSpent=TotalCost(CardType1);
  382.                     BestCardType1=CardType1;
  383.                 }
  384.                 //We have now cast the first card
  385.                 for (int CardType2=1; CardType2<=12; CardType2++){
  386.                     AvailableTotalMana=ForestInPlay-TappedForest+IslandInPlay-TappedIsland+DualInPlay-TappedDual;
  387.                     AvailableGreenMana=ForestInPlay-TappedForest+DualInPlay-TappedDual;
  388.                     AvailableBlueMana=IslandInPlay-TappedIsland+DualInPlay-TappedDual;
  389.                     boolean WeCastASecondSpell=false;
  390.                     int NrRemainingCardsOfThisTypeInHand=CardsInHand[CardType2];
  391.                     if (CardType2==CardType1) {NrRemainingCardsOfThisTypeInHand--;}
  392.                     if (!WeCastASecondSpell && NrRemainingCardsOfThisTypeInHand>0 && GreenCost(CardType2)<=AvailableGreenMana && BlueCost(CardType2)<=AvailableBlueMana && TotalCost(CardType2)<=AvailableTotalMana) {
  393.                         //Start of the auto-tapping mana logic for the second card. It's a copy-paste of the same logic as before except now all referring to CardType2
  394.                         GreenManaToPay=GreenCost(CardType2);
  395.                         BlueManaToPay=BlueCost(CardType2);
  396.                         ColorlessManaToPay=TotalCost(CardType2)-GreenCost(CardType2)-BlueCost(CardType2);
  397.                         GreenManaFromForest=Math.min(GreenManaToPay,ForestInPlay-TappedForest);
  398.                         TappedForest=TappedForest+GreenManaFromForest;
  399.                         GreenManaToPay=GreenManaToPay-GreenManaFromForest;
  400.                         TappedDual=TappedDual+Math.min(GreenManaToPay,DualInPlay-TappedDual);
  401.                         BlueManaFromIsland=Math.min(BlueManaToPay,IslandInPlay-TappedIsland);
  402.                         TappedIsland=TappedIsland+BlueManaFromIsland;
  403.                         BlueManaToPay=BlueManaToPay-BlueManaFromIsland;
  404.                         TappedDual=TappedDual+Math.min(BlueManaToPay,DualInPlay-TappedDual);
  405.                         do {
  406.                             if ( ( (ForestInPlay-TappedForest)==(IslandInPlay-TappedIsland) )&& ColorlessManaToPay>=2 && (ForestInPlay-TappedForest)>0 && (IslandInPlay-TappedIsland)>0) {
  407.                                 TappedForest++; TappedIsland++;
  408.                                 ColorlessManaToPay--; ColorlessManaToPay--;
  409.                             }
  410.  
  411.                             if ( ( (ForestInPlay-TappedForest)>(IslandInPlay-TappedIsland))&& ColorlessManaToPay>=1 ) {
  412.                                 TappedForest++;
  413.                                 ColorlessManaToPay--;
  414.                             }
  415.                             if ( ( (IslandInPlay-TappedIsland)>(ForestInPlay-TappedForest))&& ColorlessManaToPay>=1 ) {
  416.                                 TappedIsland++;
  417.                                 ColorlessManaToPay--;
  418.                             }
  419.  
  420.                             if ( ( (ForestInPlay-TappedForest)==(IslandInPlay-TappedIsland) )&& ColorlessManaToPay==1 && (ForestInPlay-TappedForest)>0 && (IslandInPlay-TappedIsland)>0) {
  421.                                 boolean TapForest=false;
  422.                                 if (CardsInHand[12]>0) {TapForest=true;}
  423.                                 if (TapForest) {
  424.                                     TappedForest++; ColorlessManaToPay--;
  425.                                 }
  426.                                 else {
  427.                                     TappedIsland++; ColorlessManaToPay--;
  428.                                 }
  429.                             }
  430.  
  431.                             if ( ForestInPlay==TappedForest && IslandInPlay==TappedIsland && ColorlessManaToPay>0 ) {
  432.                                 TappedDual++;
  433.                                 ColorlessManaToPay--;
  434.                             }
  435.  
  436.                         } while (ColorlessManaToPay>0);
  437.                         //We have now cast the second card
  438.                         WeCastASecondSpell=true;
  439.                         if (TotalCost(CardType1)+TotalCost(CardType2)>BestTotalManaSpent){
  440.                             BestTotalManaSpent=TotalCost(CardType1)+TotalCost(CardType2);
  441.                             BestCardType1=CardType1;
  442.                             BestCardType2=CardType2;
  443.                         }
  444.                         for (int CardType3=1; CardType3<=12; CardType3++){
  445.                             AvailableTotalMana=ForestInPlay-TappedForest+IslandInPlay-TappedIsland+DualInPlay-TappedDual;
  446.                             AvailableGreenMana=ForestInPlay-TappedForest+DualInPlay-TappedDual;
  447.                             AvailableBlueMana=IslandInPlay-TappedIsland+DualInPlay-TappedDual;
  448.                             boolean WeCastAThirdSpell=false;
  449.                             int NrRemainingCardsOfThisFinalTypeInHand=CardsInHand[CardType3];
  450.                             if (CardType3==CardType1) {NrRemainingCardsOfThisFinalTypeInHand--;}
  451.                             if (CardType3==CardType2) {NrRemainingCardsOfThisFinalTypeInHand--;}
  452.                             if (!WeCastAThirdSpell && NrRemainingCardsOfThisFinalTypeInHand>0 && GreenCost(CardType3)<=AvailableGreenMana && BlueCost(CardType3)<=AvailableBlueMana && TotalCost(CardType3)<=AvailableTotalMana) {
  453.                                 //Start of the auto-tapping mana logic for the third card. It's a copy-paste of the same logic as before except now all referring to CardType3
  454.                                 GreenManaToPay=GreenCost(CardType3);
  455.                                 BlueManaToPay=BlueCost(CardType3);
  456.                                 ColorlessManaToPay=TotalCost(CardType3)-GreenCost(CardType3)-BlueCost(CardType3);
  457.                                 GreenManaFromForest=Math.min(GreenManaToPay,ForestInPlay-TappedForest);
  458.                                 TappedForest=TappedForest+GreenManaFromForest;
  459.                                 GreenManaToPay=GreenManaToPay-GreenManaFromForest;
  460.                                 TappedDual=TappedDual+Math.min(GreenManaToPay,DualInPlay-TappedDual);
  461.                                 BlueManaFromIsland=Math.min(BlueManaToPay,IslandInPlay-TappedIsland);
  462.                                 TappedIsland=TappedIsland+BlueManaFromIsland;
  463.                                 BlueManaToPay=BlueManaToPay-BlueManaFromIsland;
  464.                                 TappedDual=TappedDual+Math.min(BlueManaToPay,DualInPlay-TappedDual);
  465.                                 do {
  466.                                     if ( ( (ForestInPlay-TappedForest)==(IslandInPlay-TappedIsland) )&& ColorlessManaToPay>=2 && (ForestInPlay-TappedForest)>0 && (IslandInPlay-TappedIsland)>0) {
  467.                                         TappedForest++; TappedIsland++;
  468.                                         ColorlessManaToPay--; ColorlessManaToPay--;
  469.                                     }
  470.  
  471.                                     if ( ( (ForestInPlay-TappedForest)>(IslandInPlay-TappedIsland))&& ColorlessManaToPay>=1 ) {
  472.                                         TappedForest++;
  473.                                         ColorlessManaToPay--;
  474.                                     }
  475.                                     if ( ( (IslandInPlay-TappedIsland)>(ForestInPlay-TappedForest))&& ColorlessManaToPay>=1 ) {
  476.                                         TappedIsland++;
  477.                                         ColorlessManaToPay--;
  478.                                     }
  479.  
  480.                                     if ( ( (ForestInPlay-TappedForest)==(IslandInPlay-TappedIsland) )&& ColorlessManaToPay==1 && (ForestInPlay-TappedForest)>0 && (IslandInPlay-TappedIsland)>0) {
  481.                                         boolean TapForest=false;
  482.                                         if (CardsInHand[12]>0) {TapForest=true;}
  483.                                         if (TapForest) {
  484.                                             TappedForest++; ColorlessManaToPay--;
  485.                                         }
  486.                                         else {
  487.                                             TappedIsland++; ColorlessManaToPay--;
  488.                                         }
  489.                                     }
  490.  
  491.                                     if ( ForestInPlay==TappedForest && IslandInPlay==TappedIsland && ColorlessManaToPay>0 ) {
  492.                                         TappedDual++;
  493.                                         ColorlessManaToPay--;
  494.                                     }
  495.  
  496.                                 } while (ColorlessManaToPay>0);
  497.                                 //We have now cast the third card
  498.                                 WeCastAThirdSpell=true;
  499.                                 if (TotalCost(CardType1)+TotalCost(CardType2)+TotalCost(CardType3)>BestTotalManaSpent){
  500.                                     BestTotalManaSpent=TotalCost(CardType1)+TotalCost(CardType2)+TotalCost(CardType3);
  501.                                     BestCardType1=CardType1;
  502.                                     BestCardType2=CardType2;
  503.                                     BestCardType3=CardType3;
  504.                                 }
  505.                             }
  506.                         }
  507.                     }
  508.                 }
  509.             }
  510.         }
  511.         //We have now determined the combination of at most 3 cards that maximize our mana usage.
  512.         if (BestCardType1>0) {Outcome.NumberToPlayOfThisCardType[BestCardType1]++;}
  513.         if (BestCardType2>0) {Outcome.NumberToPlayOfThisCardType[BestCardType2]++;}
  514.         if (BestCardType3>0) {Outcome.NumberToPlayOfThisCardType[BestCardType3]++;}
  515.         Outcome.TotalManaSpentThisTurn=BestTotalManaSpent;
  516.         return Outcome;
  517.     }
  518.    
  519. }
  520.  
  521. class PlayRecommendation {
  522.     int[] NumberToPlayOfThisCardType;
  523.     int TotalManaSpentThisTurn;
  524. }
  525.  
  526. class LandDropAndPlayRecommendation {
  527.     int[] NumberToPlayOfThisCardType;
  528.     int LandTypeDrop;
  529. }
  530.  
  531. class OpeningHand {
  532.     int NumberOfCardType1;
  533.     int NumberOfCardType2;
  534.     int NumberOfCardType3;
  535.     int NumberOfCardType4;
  536.     int NumberOfCardType5;
  537.     int NumberOfCardType6;
  538.     int NumberOfCardType7;
  539.     int NumberOfCardType8;
  540.     int NumberOfCardType9;
  541.     int NumberOfCardType10;
  542.     int NumberOfCardType11;
  543.     int NumberOfCardType12;
  544.     int NumberOfForest;
  545.     int NumberOfIsland;
  546.     int NumberOfDuals;
  547.     //I really should've used arrays here, lol
  548.  
  549.     int NrOfCards(){
  550.         return NumberOfCardType1+NumberOfCardType2+NumberOfCardType3+NumberOfCardType4+NumberOfCardType5+NumberOfCardType6+NumberOfCardType7+NumberOfCardType8+NumberOfCardType9+NumberOfCardType10+NumberOfCardType11+NumberOfCardType12+NumberOfForest+NumberOfIsland+NumberOfDuals;
  551.     }
  552.  
  553.     void SetHand (int Nr1, int Nr2, int Nr3, int Nr4, int Nr5, int Nr6, int Nr7, int Nr8, int Nr9, int Nr10, int Nr11, int Nr12, int NrForest, int NrIsland, int NrDuals) {
  554.         NumberOfCardType1=Nr1;
  555.         NumberOfCardType2=Nr2;
  556.         NumberOfCardType3=Nr3;
  557.         NumberOfCardType4=Nr4;
  558.         NumberOfCardType5=Nr5;
  559.         NumberOfCardType6=Nr6;
  560.         NumberOfCardType7=Nr7;
  561.         NumberOfCardType8=Nr8;
  562.         NumberOfCardType9=Nr9;
  563.         NumberOfCardType10=Nr10;
  564.         NumberOfCardType11=Nr11;
  565.         NumberOfCardType11=Nr12;
  566.         NumberOfForest=NrForest;
  567.         NumberOfIsland=NrIsland;
  568.         NumberOfDuals=NrDuals;
  569.     }
  570.  
  571. }//end of OpeningHand
  572.  
  573. class Deck {
  574.     int NumberOfCardType1;
  575.     int NumberOfCardType2;
  576.     int NumberOfCardType3;
  577.     int NumberOfCardType4;
  578.     int NumberOfCardType5;
  579.     int NumberOfCardType6;
  580.     int NumberOfCardType7;
  581.     int NumberOfCardType8;
  582.     int NumberOfCardType9;
  583.     int NumberOfCardType10;
  584.     int NumberOfCardType11;
  585.     int NumberOfCardType12;
  586.     int NumberOfForest;
  587.     int NumberOfIsland;
  588.     int NumberOfDuals;
  589.     //I really should've used arrays here, lol
  590.  
  591.     void SetDeck (int Nr1, int Nr2, int Nr3, int Nr4, int Nr5, int Nr6, int Nr7, int Nr8, int Nr9, int Nr10, int Nr11, int Nr12, int NrForest, int NrIsland, int NrDuals) {
  592.         NumberOfCardType1=Nr1;
  593.         NumberOfCardType2=Nr2;
  594.         NumberOfCardType3=Nr3;
  595.         NumberOfCardType4=Nr4;
  596.         NumberOfCardType5=Nr5;
  597.         NumberOfCardType6=Nr6;
  598.         NumberOfCardType7=Nr7;
  599.         NumberOfCardType8=Nr8;
  600.         NumberOfCardType9=Nr9;
  601.         NumberOfCardType10=Nr10;
  602.         NumberOfCardType11=Nr11;
  603.         NumberOfCardType12=Nr12;
  604.         NumberOfForest=NrForest;
  605.         NumberOfIsland=NrIsland;
  606.         NumberOfDuals=NrDuals;
  607.     }
  608.    
  609.     int NrOfCards(){
  610.         return NumberOfCardType1+NumberOfCardType2+NumberOfCardType3+NumberOfCardType4+NumberOfCardType5+NumberOfCardType6+NumberOfCardType7+NumberOfCardType8+NumberOfCardType9+NumberOfCardType10+NumberOfCardType11+NumberOfCardType12+NumberOfForest+NumberOfIsland+NumberOfDuals;
  611.     }
  612.    
  613.     int DrawCard (){
  614.         Random generator = new Random();
  615.         int CardType=0;
  616.         int RandomIntegerBetweenOneAndDeckSize=generator.nextInt( this.NrOfCards() )+1;
  617.         int OneCutoff=NumberOfCardType1;
  618.         int TwoCutoff=OneCutoff+NumberOfCardType2;
  619.         int ThreeCutoff=TwoCutoff+NumberOfCardType3;
  620.         int FourCutoff=ThreeCutoff+NumberOfCardType4;
  621.         int FiveCutoff=FourCutoff+NumberOfCardType5;
  622.         int SixCutoff=FiveCutoff+NumberOfCardType6;
  623.         int SevenCutoff=SixCutoff+NumberOfCardType7;
  624.         int EightCutoff=SevenCutoff+NumberOfCardType8;
  625.         int NineCutoff=EightCutoff+NumberOfCardType9;
  626.         int TenCutoff=NineCutoff+NumberOfCardType10;
  627.         int ElevenCutoff=TenCutoff+NumberOfCardType11;
  628.         int TwelveCutoff=ElevenCutoff+NumberOfCardType12;
  629.         int ForestCutoff=TwelveCutoff+NumberOfForest;
  630.         int IslandCutoff=ForestCutoff+NumberOfIsland;
  631.         int DualCutoff=IslandCutoff+NumberOfDuals;
  632.        
  633.         if (RandomIntegerBetweenOneAndDeckSize>0 && RandomIntegerBetweenOneAndDeckSize<=OneCutoff) {CardType=1; this.NumberOfCardType1--;}
  634.         if (RandomIntegerBetweenOneAndDeckSize>OneCutoff && RandomIntegerBetweenOneAndDeckSize<=TwoCutoff) {CardType=2; this.NumberOfCardType2--;}
  635.         if (RandomIntegerBetweenOneAndDeckSize>TwoCutoff && RandomIntegerBetweenOneAndDeckSize<=ThreeCutoff) {CardType=3; this.NumberOfCardType3--;}
  636.         if (RandomIntegerBetweenOneAndDeckSize>ThreeCutoff && RandomIntegerBetweenOneAndDeckSize<=FourCutoff) {CardType=4; this.NumberOfCardType4--;}
  637.         if (RandomIntegerBetweenOneAndDeckSize>FourCutoff && RandomIntegerBetweenOneAndDeckSize<=FiveCutoff) {CardType=5; this.NumberOfCardType5--;}
  638.         if (RandomIntegerBetweenOneAndDeckSize>FiveCutoff && RandomIntegerBetweenOneAndDeckSize<=SixCutoff) {CardType=6; this.NumberOfCardType6--;}
  639.         if (RandomIntegerBetweenOneAndDeckSize>SixCutoff && RandomIntegerBetweenOneAndDeckSize<=SevenCutoff) {CardType=7; this.NumberOfCardType7--;}
  640.         if (RandomIntegerBetweenOneAndDeckSize>SevenCutoff && RandomIntegerBetweenOneAndDeckSize<=EightCutoff) {CardType=8; this.NumberOfCardType8--;}
  641.         if (RandomIntegerBetweenOneAndDeckSize>EightCutoff && RandomIntegerBetweenOneAndDeckSize<=NineCutoff) {CardType=9; this.NumberOfCardType9--;}
  642.         if (RandomIntegerBetweenOneAndDeckSize>NineCutoff && RandomIntegerBetweenOneAndDeckSize<=TenCutoff) {CardType=10; this.NumberOfCardType10--;}
  643.         if (RandomIntegerBetweenOneAndDeckSize>TenCutoff && RandomIntegerBetweenOneAndDeckSize<=ElevenCutoff) {CardType=11; this.NumberOfCardType11--;}
  644.         if (RandomIntegerBetweenOneAndDeckSize>ElevenCutoff && RandomIntegerBetweenOneAndDeckSize<=TwelveCutoff) {CardType=12; this.NumberOfCardType12--;}
  645.         if (RandomIntegerBetweenOneAndDeckSize>TwelveCutoff && RandomIntegerBetweenOneAndDeckSize<=ForestCutoff) {CardType=20; this.NumberOfForest--;}
  646.         if (RandomIntegerBetweenOneAndDeckSize>ForestCutoff && RandomIntegerBetweenOneAndDeckSize<=IslandCutoff) {CardType=21; this.NumberOfIsland--;}
  647.         if (RandomIntegerBetweenOneAndDeckSize>IslandCutoff && RandomIntegerBetweenOneAndDeckSize<=DualCutoff) {CardType=22; this.NumberOfDuals--;}
  648.  
  649.         return CardType;
  650.     }
  651.    
  652. }//end of Deck
RAW Paste Data