SHARE
TWEET

Optimal Mana Curve

frankkarsten Jul 24th, 2014 4,374 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. package optimalmanacurve;
  2.  
  3. import java.util.Arrays.*;
  4. import java.util.Random;
  5.  
  6.  
  7. public class OptimalManaCurve {
  8.  
  9.     public static void main(String[] args) {
  10.        
  11.         Deck deck=new Deck();
  12.         boolean[][][][][][][][] KeepOpeningHand = new boolean[8][8][8][8][8][8][8][8];
  13.         KeepOpeningHand=GiveLooseMulliganStrategy();
  14.         int NumberOfSimulationsPerDeck=2500;
  15.         double TotalManaSpent;
  16.         double MostManaSpent=1;
  17.         int OptimalOneDrops=0;
  18.         int OptimalTwoDrops=0;
  19.         int OptimalThreeDrops=0;
  20.         int OptimalFourDrops=0;
  21.         int OptimalFiveDrops=0;
  22.         int OptimalSixDrops=0;
  23.         int OptimalLands=0;
  24.         int NumberOfCardsInDeck=40;
  25.        
  26.         //Doing a grid search (increasing each card by 3) to quickly zoom in on, hopefully, the optimal configuration)
  27.  
  28.         for (int TripleOneDropCount=0; TripleOneDropCount<=10; TripleOneDropCount++){
  29.             for (int TripleTwoDropCount=0; TripleTwoDropCount<=10; TripleTwoDropCount++){
  30.                 for (int TripleThreeDropCount=0; TripleThreeDropCount<=7; TripleThreeDropCount++){
  31.                     for (int TripleFourDropCount=0; TripleFourDropCount<=4; TripleFourDropCount++){
  32.                         for (int TripleFiveDropCount=0; TripleFiveDropCount<=3; TripleFiveDropCount++){
  33.                             for (int TripleSixDropCount=0; TripleSixDropCount<=2; TripleSixDropCount++){
  34.                                     int LandCount=NumberOfCardsInDeck-3*TripleOneDropCount-3*TripleTwoDropCount-3*TripleThreeDropCount-3*TripleFourDropCount-3*TripleFiveDropCount-3*TripleSixDropCount;
  35.                                     if (LandCount>=13 && LandCount<=32) {
  36.                                         deck.SetDeck(3*TripleOneDropCount,3*TripleTwoDropCount,3*TripleThreeDropCount,3*TripleFourDropCount,3*TripleFiveDropCount,3*TripleSixDropCount,LandCount);
  37.                                         deck.PrintDeckBrief();
  38.                                         TotalManaSpent=AverageManaSpentForRandomHand(deck,7,KeepOpeningHand,NumberOfSimulationsPerDeck);
  39.                                         System.out.println(" "+TotalManaSpent);
  40.                                         if (TotalManaSpent>MostManaSpent){
  41.                                             MostManaSpent=TotalManaSpent;
  42.                                             OptimalOneDrops=3*TripleOneDropCount;
  43.                                             OptimalTwoDrops=3*TripleTwoDropCount;
  44.                                             OptimalThreeDrops=3*TripleThreeDropCount;
  45.                                             OptimalFourDrops=3*TripleFourDropCount;
  46.                                             OptimalFiveDrops=3*TripleFiveDropCount;
  47.                                             OptimalSixDrops=3*TripleSixDropCount;
  48.                                             OptimalLands=LandCount;
  49.                                         }
  50.                                     }
  51.                                 //Seven drops are no longer considered due to the curse of dimensionality
  52.                             }
  53.                         }
  54.                     }
  55.                 }
  56.             }
  57.         }
  58.        
  59.         System.out.println("----------------");
  60.         System.out.print("The optimal deck after the grid-enumeration at a small number of simulations per deck was:");
  61.         deck.SetDeck(OptimalOneDrops,OptimalTwoDrops,OptimalThreeDrops,OptimalFourDrops,OptimalFiveDrops,OptimalSixDrops,OptimalLands);
  62.         deck.PrintDeckBrief();
  63.         System.out.println();
  64.         System.out.println("The expected mana spent for this deck:"+MostManaSpent);
  65.         System.out.println("----------------");
  66.        
  67.         NumberOfSimulationsPerDeck=10000;
  68.         int NewOptimalOneDrops=OptimalOneDrops;
  69.         int NewOptimalTwoDrops=OptimalTwoDrops;
  70.         int NewOptimalThreeDrops=OptimalThreeDrops;
  71.         int NewOptimalFourDrops=OptimalFourDrops;
  72.         int NewOptimalFiveDrops=OptimalFiveDrops;
  73.         int NewOptimalSixDrops=OptimalSixDrops;
  74.         int NewOptimalLands=OptimalLands;
  75.         boolean ContinueLocalSearch=true;
  76.        
  77.         //Doing a local search, starting with the best deck from the previous step, all with a loose mulligan strategy under a reasonable number of simulations per deck
  78.        
  79.         do {
  80.             MostManaSpent=1;
  81.             for (int OneDropCount=Math.max(0,OptimalOneDrops-2); OneDropCount<=Math.min(NumberOfCardsInDeck,OptimalOneDrops+2); OneDropCount++){
  82.                 for (int TwoDropCount=Math.max(0,OptimalTwoDrops-2); TwoDropCount<=Math.min(NumberOfCardsInDeck,OptimalTwoDrops+2); TwoDropCount++){
  83.                     for (int ThreeDropCount=Math.max(0,OptimalThreeDrops-2); ThreeDropCount<=Math.min(NumberOfCardsInDeck,OptimalThreeDrops+2); ThreeDropCount++){
  84.                         for (int FourDropCount=Math.max(0,OptimalFourDrops-2); FourDropCount<=Math.min(NumberOfCardsInDeck,OptimalFourDrops+2); FourDropCount++){
  85.                             for (int FiveDropCount=Math.max(0,OptimalFiveDrops-2); FiveDropCount<=Math.min(NumberOfCardsInDeck,OptimalFiveDrops+2); FiveDropCount++){
  86.                                 for (int SixDropCount=Math.max(0,OptimalSixDrops-2); SixDropCount<=Math.min(NumberOfCardsInDeck,OptimalSixDrops+2); SixDropCount++){
  87.                                         int LandCount=NumberOfCardsInDeck-OneDropCount-TwoDropCount-ThreeDropCount-FourDropCount-FiveDropCount-SixDropCount;
  88.                                         if (LandCount>=Math.max(0,OptimalLands-2) && LandCount<=Math.min(NumberOfCardsInDeck,OptimalLands+2)) {
  89.                                             deck.SetDeck(OneDropCount,TwoDropCount,ThreeDropCount,FourDropCount,FiveDropCount,SixDropCount,LandCount);
  90.                                             deck.PrintDeckBrief();
  91.                                             TotalManaSpent=AverageManaSpentForRandomHand(deck,7,KeepOpeningHand,NumberOfSimulationsPerDeck);
  92.                                             System.out.println(" "+TotalManaSpent);
  93.                                             if (TotalManaSpent>MostManaSpent){
  94.                                                 MostManaSpent=TotalManaSpent;
  95.                                                 NewOptimalOneDrops=OneDropCount;
  96.                                                 NewOptimalTwoDrops=TwoDropCount;
  97.                                                 NewOptimalThreeDrops=ThreeDropCount;
  98.                                                 NewOptimalFourDrops=FourDropCount;
  99.                                                 NewOptimalFiveDrops=FiveDropCount;
  100.                                                 NewOptimalSixDrops=SixDropCount;
  101.                                                 OptimalLands=LandCount;
  102.                                             }
  103.                                         }
  104.                                     //Seven drops are no longer considered due to the curse of dimensionality
  105.                                 }
  106.                             }
  107.                         }
  108.                     }
  109.                 }
  110.             }
  111.             if (Math.abs(NewOptimalOneDrops-OptimalOneDrops)+Math.abs(NewOptimalTwoDrops-OptimalTwoDrops)+Math.abs(NewOptimalThreeDrops-OptimalThreeDrops)+Math.abs(NewOptimalFourDrops-OptimalFourDrops)+Math.abs(NewOptimalFiveDrops-OptimalFiveDrops)+Math.abs(NewOptimalSixDrops-OptimalSixDrops)+Math.abs(NewOptimalLands-OptimalLands)<=2) {ContinueLocalSearch=false;}
  112.             OptimalOneDrops=NewOptimalOneDrops;
  113.             OptimalTwoDrops=NewOptimalTwoDrops;
  114.             OptimalThreeDrops=NewOptimalThreeDrops;
  115.             OptimalFourDrops=NewOptimalFourDrops;
  116.             OptimalFiveDrops=NewOptimalFiveDrops;
  117.             OptimalSixDrops=NewOptimalSixDrops;
  118.             OptimalLands=NewOptimalLands;
  119.             System.out.println("----------------");
  120.             System.out.print("The optimal deck after the local search was:");
  121.             deck.SetDeck(OptimalOneDrops,OptimalTwoDrops,OptimalThreeDrops,OptimalFourDrops,OptimalFiveDrops,OptimalSixDrops,OptimalLands);
  122.             deck.PrintDeckBrief();
  123.             System.out.println();
  124.             System.out.println("The expected mana spent for this deck:"+MostManaSpent);
  125.             System.out.println("----------------");
  126.         } while (ContinueLocalSearch);
  127.        
  128.         NumberOfSimulationsPerDeck=200000;
  129.         ContinueLocalSearch=true;
  130.        
  131.         //Doing another local search, starting with the best deck from the previous step, but more fine-grained and with the optimal mulligan strategy
  132.        
  133.         do {
  134.             MostManaSpent=1;
  135.             for (int OneDropCount=Math.max(0,OptimalOneDrops-1); OneDropCount<=Math.min(NumberOfCardsInDeck,OptimalOneDrops+1); OneDropCount++){
  136.                 for (int TwoDropCount=Math.max(0,OptimalTwoDrops-1); TwoDropCount<=Math.min(NumberOfCardsInDeck,OptimalTwoDrops+1); TwoDropCount++){
  137.                     for (int ThreeDropCount=Math.max(0,OptimalThreeDrops-1); ThreeDropCount<=Math.min(NumberOfCardsInDeck,OptimalThreeDrops+1); ThreeDropCount++){
  138.                         for (int FourDropCount=Math.max(0,OptimalFourDrops-1); FourDropCount<=Math.min(NumberOfCardsInDeck,OptimalFourDrops+1); FourDropCount++){
  139.                             for (int FiveDropCount=Math.max(0,OptimalFiveDrops-1); FiveDropCount<=Math.min(NumberOfCardsInDeck,OptimalFiveDrops+1); FiveDropCount++){
  140.                                 for (int SixDropCount=Math.max(0,OptimalSixDrops-1); SixDropCount<=Math.min(NumberOfCardsInDeck,OptimalSixDrops+1); SixDropCount++){
  141.                                         int LandCount=NumberOfCardsInDeck-OneDropCount-TwoDropCount-ThreeDropCount-FourDropCount-FiveDropCount-SixDropCount;
  142.                                         if (LandCount>=Math.max(0,OptimalLands-1) && LandCount<=Math.min(NumberOfCardsInDeck,OptimalLands+1)) {
  143.                                             deck.SetDeck(OneDropCount,TwoDropCount,ThreeDropCount,FourDropCount,FiveDropCount,SixDropCount,LandCount);
  144.                                             //deck.PrintDeckBrief();
  145.                                             KeepOpeningHand=GiveOptimalMulliganStrategy(deck);
  146.                                             TotalManaSpent=AverageManaSpentForRandomHand(deck,7,KeepOpeningHand,NumberOfSimulationsPerDeck);
  147.                                             //System.out.println(" "+TotalManaSpent);
  148.                                             if (TotalManaSpent>MostManaSpent){
  149.                                                 MostManaSpent=TotalManaSpent;
  150.                                                 NewOptimalOneDrops=OneDropCount;
  151.                                                 NewOptimalTwoDrops=TwoDropCount;
  152.                                                 NewOptimalThreeDrops=ThreeDropCount;
  153.                                                 NewOptimalFourDrops=FourDropCount;
  154.                                                 NewOptimalFiveDrops=FiveDropCount;
  155.                                                 NewOptimalSixDrops=SixDropCount;
  156.                                                 NewOptimalLands=LandCount;
  157.                                             }
  158.                                         }
  159.                                     }
  160.                                 }
  161.                             }
  162.                         }
  163.                     }
  164.                 System.out.println();
  165.                 }
  166.             if (Math.abs(NewOptimalOneDrops-OptimalOneDrops)+Math.abs(NewOptimalTwoDrops-OptimalTwoDrops)+Math.abs(NewOptimalThreeDrops-OptimalThreeDrops)+Math.abs(NewOptimalFourDrops-OptimalFourDrops)+Math.abs(NewOptimalFiveDrops-OptimalFiveDrops)+Math.abs(NewOptimalSixDrops-OptimalSixDrops)+Math.abs(NewOptimalLands-OptimalLands)==0) {ContinueLocalSearch=false;}
  167.             OptimalOneDrops=NewOptimalOneDrops;
  168.             OptimalTwoDrops=NewOptimalTwoDrops;
  169.             OptimalThreeDrops=NewOptimalThreeDrops;
  170.             OptimalFourDrops=NewOptimalFourDrops;
  171.             OptimalFiveDrops=NewOptimalFiveDrops;
  172.             OptimalSixDrops=NewOptimalSixDrops;
  173.             OptimalLands=NewOptimalLands;
  174.  
  175.             System.out.println("----------------");
  176.             System.out.print("Found a better deck:");
  177.             deck.SetDeck(OptimalOneDrops,OptimalTwoDrops,OptimalThreeDrops,OptimalFourDrops,OptimalFiveDrops,OptimalSixDrops,OptimalLands);
  178.             deck.PrintDeckBrief();
  179.             System.out.println();
  180.             System.out.println("The expected mana spent for this deck:"+MostManaSpent);
  181.             System.out.println("----------------");
  182.            
  183.         } while (ContinueLocalSearch);
  184.    
  185.     System.out.println("----------------");
  186.     System.out.print("The final optimal deck:");
  187.     deck.SetDeck(OptimalOneDrops,OptimalTwoDrops,OptimalThreeDrops,OptimalFourDrops,OptimalFiveDrops,OptimalSixDrops,OptimalLands);
  188.     deck.PrintDeckBrief();
  189.     System.out.println();
  190.     System.out.println("The expected mana spent for this deck:"+MostManaSpent);
  191.     System.out.println("----------------");
  192.    
  193.     }//end of main
  194.  
  195.     public static boolean[][][][][][][][] GiveOptimalMulliganStrategy(Deck deck) {
  196.         boolean[][][][][][][][] KeepOpeningHand = new boolean[8][8][8][8][8][8][8][8];
  197.         OpeningHand openinghand=new OpeningHand();
  198.         int NumberOfSimulationsPerOpeningHandSize=1000;
  199.         int OriginalNr1Cost=deck.NumberOf1Cost;
  200.         int OriginalNr2Cost=deck.NumberOf2Cost;
  201.         int OriginalNr3Cost=deck.NumberOf3Cost;
  202.         int OriginalNr4Cost=deck.NumberOf4Cost;
  203.         int OriginalNr5Cost=deck.NumberOf5Cost;
  204.         int OriginalNr6Cost=deck.NumberOf6Cost;
  205.         int OriginalNrLands=deck.NumberOfLands;
  206.         double CutOffManaSpent = 1;
  207.         //Let's just keep every 2-card hand. That simplifies things.
  208.         for (int StartingCards=2; StartingCards<=7; StartingCards++){
  209.             //System.out.print(".");
  210.             for (int OneDropCount=0; OneDropCount<=StartingCards; OneDropCount++){
  211.                 for (int TwoDropCount=0; TwoDropCount+OneDropCount<=StartingCards; TwoDropCount++){
  212.                     for  (int ThreeDropCount=0; ThreeDropCount+TwoDropCount+OneDropCount<=StartingCards; ThreeDropCount++){
  213.                         for  (int FourDropCount=0; FourDropCount+ThreeDropCount+TwoDropCount+OneDropCount<=StartingCards; FourDropCount++){
  214.                             for  (int FiveDropCount=0; FiveDropCount+FourDropCount+ThreeDropCount+TwoDropCount+OneDropCount<=StartingCards; FiveDropCount++){
  215.                                 for  (int SixDropCount=0; SixDropCount+FiveDropCount+FourDropCount+ThreeDropCount+TwoDropCount+OneDropCount<=StartingCards; SixDropCount++){
  216.                                     int LandCount=StartingCards-OneDropCount-TwoDropCount-ThreeDropCount-FourDropCount-FiveDropCount-SixDropCount;
  217.                                     if (OneDropCount<=OriginalNr1Cost && TwoDropCount<=OriginalNr2Cost && ThreeDropCount<=OriginalNr3Cost && FourDropCount<=OriginalNr4Cost && FiveDropCount<=OriginalNr5Cost && SixDropCount<=OriginalNr6Cost && LandCount<=OriginalNrLands){
  218.                                         openinghand.SetHand(OneDropCount, TwoDropCount, ThreeDropCount, FourDropCount, FiveDropCount, SixDropCount, LandCount);
  219.                                         deck.SetDeck(OriginalNr1Cost,OriginalNr2Cost,OriginalNr3Cost,OriginalNr4Cost,OriginalNr5Cost,OriginalNr6Cost,OriginalNrLands);
  220.                                         double AvgManaSpent=AverageManaSpentForSpecificHand(deck,openinghand);
  221.                                         if (AvgManaSpent>CutOffManaSpent) { KeepOpeningHand[StartingCards][OneDropCount][TwoDropCount][ThreeDropCount][FourDropCount][FiveDropCount][SixDropCount][LandCount]=true;}
  222.                                         if (AvgManaSpent<=CutOffManaSpent) { KeepOpeningHand[StartingCards][OneDropCount][TwoDropCount][ThreeDropCount][FourDropCount][FiveDropCount][SixDropCount][LandCount]=false;}
  223.                                         if (StartingCards==2) {KeepOpeningHand[StartingCards][OneDropCount][TwoDropCount][ThreeDropCount][FourDropCount][FiveDropCount][SixDropCount][LandCount]=true;}
  224.                                     }
  225.                                 }
  226.                             }
  227.                         }
  228.                     }
  229.                 }
  230.             }
  231.             deck.SetDeck(OriginalNr1Cost,OriginalNr2Cost,OriginalNr3Cost,OriginalNr4Cost,OriginalNr5Cost,OriginalNr6Cost,OriginalNrLands);
  232.             if (StartingCards<7) {CutOffManaSpent=AverageManaSpentForRandomHand(deck,StartingCards,KeepOpeningHand,NumberOfSimulationsPerOpeningHandSize);}
  233.         }
  234.         return KeepOpeningHand;
  235.     }
  236.  
  237.     public static boolean[][][][][][][][] GiveLooseMulliganStrategy() {
  238.         boolean[][][][][][][][] KeepOpeningHand = new boolean[8][8][8][8][8][8][8][8];
  239.         for (int StartingCards=2; StartingCards<=7; StartingCards++){
  240.             for (int OneDropCount=0; OneDropCount<=StartingCards; OneDropCount++){
  241.                 for (int TwoDropCount=0; TwoDropCount+OneDropCount<=StartingCards; TwoDropCount++){
  242.                     for  (int ThreeDropCount=0; ThreeDropCount+TwoDropCount+OneDropCount<=StartingCards; ThreeDropCount++){
  243.                         for  (int FourDropCount=0; FourDropCount+ThreeDropCount+TwoDropCount+OneDropCount<=StartingCards; FourDropCount++){
  244.                             for  (int FiveDropCount=0; FiveDropCount+FourDropCount+ThreeDropCount+TwoDropCount+OneDropCount<=StartingCards; FiveDropCount++){
  245.                                 for  (int SixDropCount=0; SixDropCount+FiveDropCount+FourDropCount+ThreeDropCount+TwoDropCount+OneDropCount<=StartingCards; SixDropCount++){
  246.                                     int LandCount=StartingCards-OneDropCount-TwoDropCount-ThreeDropCount-FourDropCount-FiveDropCount-SixDropCount;
  247.                                     KeepOpeningHand[StartingCards][OneDropCount][TwoDropCount][ThreeDropCount][FourDropCount][FiveDropCount][SixDropCount][LandCount]=false;
  248.                                     //The simple idea is that we're keeping a hand if it contains between 2 and 5 lands and at least one spell of 3 mana or less. Also, keep any 2-card hand.
  249.                                     if (LandCount>=2 && LandCount<=5 && (OneDropCount+TwoDropCount+ThreeDropCount)>=1) {KeepOpeningHand[StartingCards][OneDropCount][TwoDropCount][ThreeDropCount][FourDropCount][FiveDropCount][SixDropCount][LandCount]=true;}
  250.                                     if (StartingCards<=2) {KeepOpeningHand[StartingCards][OneDropCount][TwoDropCount][ThreeDropCount][FourDropCount][FiveDropCount][SixDropCount][LandCount]=true;}
  251.                                 }
  252.                             }
  253.                         }
  254.                     }
  255.                 }
  256.             }
  257.         }
  258.         return KeepOpeningHand;
  259.     }
  260.    
  261.     public static double AverageManaSpentForSpecificHand(Deck deck, OpeningHand openinghand){
  262.         int NumberOfIterations=250;
  263.         Deck remainingdeck=new Deck();
  264.         double TotalManaSpent=0;
  265.         for (int IterationCounter=1; IterationCounter<=NumberOfIterations; IterationCounter++){
  266.             remainingdeck.SetDeck(deck.NumberOf1Cost-openinghand.NumberOf1Cost,deck.NumberOf2Cost-openinghand.NumberOf2Cost,deck.NumberOf3Cost-openinghand.NumberOf3Cost,deck.NumberOf4Cost-openinghand.NumberOf4Cost,deck.NumberOf5Cost-openinghand.NumberOf5Cost,deck.NumberOf6Cost-openinghand.NumberOf6Cost,deck.NumberOfLands-openinghand.NumberOfLands);
  267.             TotalManaSpent=TotalManaSpent+ManaSpent(remainingdeck,openinghand);
  268.         }
  269.         return (TotalManaSpent/(NumberOfIterations+0.0));
  270.     }//end of AverageManaSpentForSpecificHand
  271.  
  272.     public static double AverageManaSpentForRandomHand(Deck deck, int StartingCards, boolean[][][][][][][][] KeepOpeningHand, int NumberOfIterations){
  273.         Deck remainingdeck=new Deck();
  274.         double TotalManaSpent=0;
  275.         for (int IterationCounter=1; IterationCounter<=NumberOfIterations; IterationCounter++){
  276.             OpeningHand openinghand=GiveOpeningHandAfterMulls(deck, StartingCards, KeepOpeningHand);
  277.             remainingdeck.SetDeck(deck.NumberOf1Cost-openinghand.NumberOf1Cost,deck.NumberOf2Cost-openinghand.NumberOf2Cost,deck.NumberOf3Cost-openinghand.NumberOf3Cost,deck.NumberOf4Cost-openinghand.NumberOf4Cost,deck.NumberOf5Cost-openinghand.NumberOf5Cost,deck.NumberOf6Cost-openinghand.NumberOf6Cost,deck.NumberOfLands-openinghand.NumberOfLands);
  278.             TotalManaSpent=TotalManaSpent+ManaSpent(remainingdeck,openinghand);
  279.             if ( IterationCounter % 10000 == 0) {System.out.print(".");}
  280.         }
  281.         return TotalManaSpent/(NumberOfIterations+0.0);
  282.     }//end of AverageManaSpentForRandomHand
  283.    
  284.     static OpeningHand GiveOpeningHandAfterMulls (Deck deck, int StartingCards, boolean[][][][][][][][] KeepOpeningHand) {
  285.        
  286.         Deck remainingdeck=new Deck();
  287.         OpeningHand openinghand=new OpeningHand();
  288.         int TypeOfCardDrawn;
  289.         boolean KeepHand=false;
  290.        
  291.         for (int OpeningHandSize=7; OpeningHandSize>=1; OpeningHandSize--){
  292.             if (KeepHand==false && StartingCards>=OpeningHandSize){
  293.                 openinghand.ResetHand();
  294.                 remainingdeck.SetDeck(deck.NumberOf1Cost,deck.NumberOf2Cost,deck.NumberOf3Cost,deck.NumberOf4Cost,deck.NumberOf5Cost,deck.NumberOf6Cost,deck.NumberOfLands);
  295.                 for (int CardsDrawn=0; CardsDrawn<OpeningHandSize; CardsDrawn++){
  296.                     TypeOfCardDrawn=remainingdeck.DrawCard();
  297.                     if (TypeOfCardDrawn==1) {openinghand.NumberOf1Cost++;}
  298.                     if (TypeOfCardDrawn==2) {openinghand.NumberOf2Cost++;}
  299.                     if (TypeOfCardDrawn==3) {openinghand.NumberOf3Cost++;}
  300.                     if (TypeOfCardDrawn==4) {openinghand.NumberOf4Cost++;}
  301.                     if (TypeOfCardDrawn==5) {openinghand.NumberOf5Cost++;}
  302.                     if (TypeOfCardDrawn==6) {openinghand.NumberOf6Cost++;}
  303.                     if (TypeOfCardDrawn==9) {openinghand.NumberOfLands++;}
  304.                 }
  305.                 KeepHand=true;
  306.                 if (OpeningHandSize>1) {
  307.                     if (KeepOpeningHand[OpeningHandSize][openinghand.NumberOf1Cost][openinghand.NumberOf2Cost][openinghand.NumberOf3Cost][openinghand.NumberOf4Cost][openinghand.NumberOf5Cost][openinghand.NumberOf6Cost][openinghand.NumberOfLands]==false) {KeepHand=false;}
  308.                 }
  309.             }
  310.         }
  311.        
  312.         return openinghand;
  313.     }//end of GiveOpeningHandAfterMulls
  314.    
  315.     static int ManaSpent(Deck remainingdeck, OpeningHand openinghand) {
  316.        
  317.         int TotalManaSpent=0;
  318.         //Here we put in the speed of the format
  319.         int FinalTurn=7;
  320.        
  321.             int Turn=0;
  322.             int ManaLeft;
  323.             int TypeOfCardDrawn;
  324.    
  325.             int LandsInPlay=0;
  326.            
  327.             /*This is old code when the final turn was random, and we took the average of one turn slower, the expected game-over turn, and one turn faster, which all happen with equal probability  
  328.             OpeningHand openinghand=new OpeningHand();
  329.             openinghand.NumberOf1Cost=openinghandOrig.NumberOf1Cost;
  330.             openinghand.NumberOf2Cost=openinghandOrig.NumberOf2Cost;
  331.             openinghand.NumberOf3Cost=openinghandOrig.NumberOf3Cost;
  332.             openinghand.NumberOf4Cost=openinghandOrig.NumberOf4Cost;
  333.             openinghand.NumberOf5Cost=openinghandOrig.NumberOf5Cost;
  334.             openinghand.NumberOf6Cost=openinghandOrig.NumberOf6Cost;
  335.             openinghand.NumberOfLands=openinghandOrig.NumberOfLands;
  336.             Deck remainingdeck=new Deck();
  337.             remainingdeck.NumberOf1Cost=remainingdeckOrig.NumberOf1Cost;
  338.             remainingdeck.NumberOf2Cost=remainingdeckOrig.NumberOf2Cost;
  339.             remainingdeck.NumberOf3Cost=remainingdeckOrig.NumberOf3Cost;
  340.             remainingdeck.NumberOf4Cost=remainingdeckOrig.NumberOf4Cost;
  341.             remainingdeck.NumberOf5Cost=remainingdeckOrig.NumberOf5Cost;
  342.             remainingdeck.NumberOf6Cost=remainingdeckOrig.NumberOf6Cost;
  343.             remainingdeck.NumberOfLands=remainingdeckOrig.NumberOfLands;
  344.             */
  345.             int OneDropsInHand=openinghand.NumberOf1Cost;
  346.             int TwoDropsInHand=openinghand.NumberOf2Cost;
  347.             int ThreeDropsInHand=openinghand.NumberOf3Cost;
  348.             int FourDropsInHand=openinghand.NumberOf4Cost;
  349.             int FiveDropsInHand=openinghand.NumberOf5Cost;
  350.             int SixDropsInHand=openinghand.NumberOf6Cost;
  351.             int LandsInHand=openinghand.NumberOfLands;
  352.        
  353.            
  354.             do {
  355.                
  356.                 Turn++;
  357.                
  358.                 if (Turn==1) {
  359.                     if (LandsInHand>=1) {LandsInPlay++; LandsInHand--;}
  360.                     ManaLeft=LandsInPlay;
  361.                     if (OneDropsInHand>=1 && ManaLeft==1) {TotalManaSpent++; ManaLeft--; OneDropsInHand--;}
  362.                     //TotalManaSpent=TotalManaSpent+(LandsInPlay-ManaLeft)*0.5;
  363.                 } //end of the first turn
  364.                
  365.                 if (Turn>1) {
  366.  
  367.                     TypeOfCardDrawn=remainingdeck.DrawCard();
  368.                     if (TypeOfCardDrawn==1) {OneDropsInHand++;}
  369.                     if (TypeOfCardDrawn==2) {TwoDropsInHand++;}
  370.                     if (TypeOfCardDrawn==3) {ThreeDropsInHand++;}
  371.                     if (TypeOfCardDrawn==4) {FourDropsInHand++;}
  372.                     if (TypeOfCardDrawn==5) {FiveDropsInHand++;}
  373.                     if (TypeOfCardDrawn==6) {SixDropsInHand++;}                
  374.                     if (TypeOfCardDrawn==9) {LandsInHand++;}
  375.  
  376.                     if (LandsInHand>=1) {LandsInPlay++; LandsInHand--;}
  377.                     ManaLeft=LandsInPlay;
  378.                
  379.                     int CastableSixDrops=Math.min(SixDropsInHand, ManaLeft/6);
  380.                     if (CastableSixDrops>=1) {TotalManaSpent=TotalManaSpent+6*CastableSixDrops; ManaLeft=ManaLeft-6*CastableSixDrops; SixDropsInHand=SixDropsInHand-CastableSixDrops;}
  381.                
  382.                     int CastableFiveDrops=Math.min(FiveDropsInHand, ManaLeft/5);
  383.                     if (CastableFiveDrops>=1) {TotalManaSpent=TotalManaSpent+5*CastableFiveDrops; ManaLeft=ManaLeft-5*CastableFiveDrops; FiveDropsInHand=FiveDropsInHand-CastableFiveDrops;}
  384.                
  385.                     int CastableFourDrops=Math.min(FourDropsInHand, ManaLeft/4);
  386.                     if (CastableFourDrops>=1) {TotalManaSpent=TotalManaSpent+4*CastableFourDrops; ManaLeft=ManaLeft-4*CastableFourDrops; FourDropsInHand=FourDropsInHand-CastableFourDrops;}
  387.                
  388.                     int CastableThreeDrops=Math.min(ThreeDropsInHand, ManaLeft/3);
  389.                     if (CastableThreeDrops>=1) {TotalManaSpent=TotalManaSpent+3*CastableThreeDrops; ManaLeft=ManaLeft-3*CastableThreeDrops; ThreeDropsInHand=ThreeDropsInHand-CastableThreeDrops;}
  390.                
  391.                     int CastableTwoDrops=Math.min(TwoDropsInHand, ManaLeft/2);
  392.                     if (CastableTwoDrops>=1) {TotalManaSpent=TotalManaSpent+2*CastableTwoDrops; ManaLeft=ManaLeft-2*CastableTwoDrops; TwoDropsInHand=TwoDropsInHand-CastableTwoDrops;}
  393.                
  394.                     int CastableOneDrops=Math.min(OneDropsInHand, ManaLeft);
  395.                     if (CastableOneDrops>=1) {TotalManaSpent=TotalManaSpent+CastableOneDrops; ManaLeft=ManaLeft-CastableOneDrops; OneDropsInHand=OneDropsInHand-CastableOneDrops;}
  396.                    
  397.              
  398.                 } //end of a turn in which we drew a card and attacked
  399.             } while (Turn<FinalTurn);
  400.        
  401.         return TotalManaSpent;
  402.     }//end of TurnKill
  403.  
  404. }//end of OptimalAggroGoldfishDeck
  405.  
  406. class OpeningHand {
  407.     int NumberOf1Cost;
  408.     int NumberOf2Cost;
  409.     int NumberOf3Cost;
  410.     int NumberOf4Cost;
  411.     int NumberOf5Cost;
  412.     int NumberOf6Cost;
  413.     int NumberOfLands;
  414.    
  415.     void ResetHand(){
  416.         NumberOf1Cost=0;
  417.         NumberOf2Cost=0;
  418.         NumberOf3Cost=0;
  419.         NumberOf4Cost=0;
  420.         NumberOf5Cost=0;
  421.         NumberOf6Cost=0;
  422.         NumberOfLands=0;
  423.     }
  424.            
  425.     void SetHand (int Nr1Cost, int Nr2Cost, int Nr3Cost, int Nr4Cost, int Nr5Cost, int Nr6Cost, int NrLands) {
  426.         NumberOf1Cost=Nr1Cost;
  427.         NumberOf2Cost=Nr2Cost;
  428.         NumberOf3Cost=Nr3Cost;
  429.         NumberOf4Cost=Nr4Cost;
  430.         NumberOf5Cost=Nr5Cost;
  431.         NumberOf6Cost=Nr6Cost;
  432.         NumberOfLands=NrLands;
  433.     }
  434.  
  435. }//end of OpeningHand
  436.  
  437. class Deck {
  438.     int NumberOf1Cost;
  439.     int NumberOf2Cost;
  440.     int NumberOf3Cost;
  441.     int NumberOf4Cost;
  442.     int NumberOf5Cost;
  443.     int NumberOf6Cost;
  444.     int NumberOfLands;
  445.  
  446.     void PrintDeckBrief () {
  447.         if(NumberOf1Cost<10) {System.out.print("0");}
  448.         System.out.print(NumberOf1Cost+" ");
  449.         if(NumberOf2Cost<10) {System.out.print("0");}
  450.         System.out.print(NumberOf2Cost+" ");
  451.         if(NumberOf3Cost<10) {System.out.print("0");}
  452.         System.out.print(NumberOf3Cost+" ");
  453.         if(NumberOf4Cost<10) {System.out.print("0");}
  454.         System.out.print(NumberOf4Cost+" ");
  455.         if(NumberOf5Cost<10) {System.out.print("0");}
  456.         System.out.print(NumberOf5Cost+" ");
  457.         if(NumberOf6Cost<10) {System.out.print("0");}
  458.         System.out.print(NumberOf6Cost+" ");
  459.         if(NumberOfLands<10) {System.out.print("0");}
  460.         System.out.print(NumberOfLands);
  461.         System.out.print(" ");
  462.     }
  463.  
  464.     void SetDeck (int Nr1Cost, int Nr2Cost, int Nr3Cost, int Nr4Cost, int Nr5Cost, int Nr6Cost, int NrLands) {
  465.         NumberOf1Cost=Nr1Cost;
  466.         NumberOf2Cost=Nr2Cost;
  467.         NumberOf3Cost=Nr3Cost;
  468.         NumberOf4Cost=Nr4Cost;
  469.         NumberOf5Cost=Nr5Cost;
  470.         NumberOf6Cost=Nr6Cost;
  471.         NumberOfLands=NrLands;
  472.     }
  473.    
  474.     int NrOfCards(){
  475.         return NumberOf1Cost+NumberOf2Cost+NumberOf3Cost+NumberOf4Cost+NumberOf5Cost+NumberOf6Cost+NumberOfLands;
  476.     }
  477.    
  478.     int DrawCard (){
  479.             Random generator = new Random();
  480.             int RandomIntegerBetweenOneAndDeckSize=generator.nextInt( this.NrOfCards() )+1;
  481.             int CardType=0;
  482.             int OneCostCutoff=NumberOf1Cost;
  483.             int TwoCostCutoff=OneCostCutoff+NumberOf2Cost;
  484.             int ThreeCostCutoff=TwoCostCutoff+NumberOf3Cost;
  485.             int FourCostCutoff=ThreeCostCutoff+NumberOf4Cost;
  486.             int FiveCostCutoff=FourCostCutoff+NumberOf5Cost;
  487.             int SixCostCutoff=FiveCostCutoff+NumberOf6Cost;
  488.             int LandCutoff=SixCostCutoff+NumberOfLands;
  489.            
  490.             if (RandomIntegerBetweenOneAndDeckSize<=OneCostCutoff) {CardType=1; this.NumberOf1Cost--;}
  491.             if (RandomIntegerBetweenOneAndDeckSize>OneCostCutoff && RandomIntegerBetweenOneAndDeckSize<=TwoCostCutoff) {CardType=2; this.NumberOf2Cost--;}
  492.             if (RandomIntegerBetweenOneAndDeckSize>TwoCostCutoff && RandomIntegerBetweenOneAndDeckSize<=ThreeCostCutoff) {CardType=3; this.NumberOf3Cost--;}
  493.             if (RandomIntegerBetweenOneAndDeckSize>ThreeCostCutoff && RandomIntegerBetweenOneAndDeckSize<=FourCostCutoff) {CardType=4; this.NumberOf4Cost--;}
  494.             if (RandomIntegerBetweenOneAndDeckSize>FourCostCutoff && RandomIntegerBetweenOneAndDeckSize<=FiveCostCutoff) {CardType=5; this.NumberOf5Cost--;}
  495.             if (RandomIntegerBetweenOneAndDeckSize>FiveCostCutoff && RandomIntegerBetweenOneAndDeckSize<=SixCostCutoff) {CardType=6; this.NumberOf6Cost--;}
  496.             if (RandomIntegerBetweenOneAndDeckSize>SixCostCutoff && RandomIntegerBetweenOneAndDeckSize<=LandCutoff) {CardType=9; this.NumberOfLands--;}
  497.            
  498.             return CardType;
  499.     }
  500.    
  501. }//end of Deck
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top