frankkarsten

MTG Optimal Deck for Ball Lightning format

Sep 23rd, 2013
170
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. package balllightninggoldfish;
  2.  
  3. import java.util.Arrays.*;
  4. import java.util.Random;
  5.  
  6. public class BallLightningGoldfish {
  7.  
  8.     public static void main(String[] args) {
  9.        
  10.         //Note: Three-drop means Ball Lightning!!!
  11.  
  12.         Deck deck=new Deck();
  13.         boolean[][][][][][] KeepOpeningHand = new boolean[8][8][8][8][8][8];
  14.         boolean TakeTimeToFindOptimalMulliganStrategy = true;
  15.         if (TakeTimeToFindOptimalMulliganStrategy==false) {KeepOpeningHand=GiveLooseMulliganStrategy();}
  16.         int NumberOfSimulationsPerDeck=2000;
  17.         double FastestTurn=50;
  18.         double KillTurn;
  19.         int OptimalOneDrops=0;
  20.         int OptimalTwoDrops=0;
  21.         int OptimalThreeDrops=0;
  22.         int OptimalBolts=0;
  23.         int OptimalLands=0;
  24.  
  25.         for (int TripleOneDropCount=0; TripleOneDropCount<=10; TripleOneDropCount++){
  26.             for (int TripleTwoDropCount=0; TripleTwoDropCount<=10; TripleTwoDropCount++){
  27.                 for (int TripleThreeDropCount=0; TripleThreeDropCount<=20; TripleThreeDropCount++){
  28.                     for (int TripleBoltCount=0; TripleBoltCount<=10; TripleBoltCount++){
  29.                         int TripleLandCount=20-TripleOneDropCount-TripleTwoDropCount-TripleThreeDropCount-TripleBoltCount;
  30.                         if (TripleLandCount>=0 && TripleLandCount<=20) {
  31.                             deck.SetDeck(3*TripleOneDropCount,3*TripleTwoDropCount,3*TripleThreeDropCount,3*TripleBoltCount,3*TripleLandCount);
  32.                             deck.PrintDeckBrief();
  33.                             KillTurn=AverageKillTurnForRandomHand(deck,7,KeepOpeningHand,NumberOfSimulationsPerDeck);
  34.                             System.out.println(" "+KillTurn);
  35.                             if (KillTurn<FastestTurn){
  36.                                 FastestTurn=KillTurn;
  37.                                 OptimalOneDrops=3*TripleOneDropCount;
  38.                                 OptimalTwoDrops=3*TripleTwoDropCount;
  39.                                 OptimalThreeDrops=3*TripleThreeDropCount;
  40.                                 OptimalBolts=3*TripleBoltCount;
  41.                                 OptimalLands=3*TripleLandCount;
  42.                             }
  43.                         }
  44.                     }
  45.                 }
  46.             }
  47.         }
  48.        
  49.         System.out.println("----------------");
  50.         System.out.print("The optimal deck after the grid-enumeration at a small number of simulations per deck was:");
  51.         deck.SetDeck(OptimalOneDrops,OptimalTwoDrops,OptimalThreeDrops,OptimalBolts,OptimalLands);
  52.         deck.PrintDeckBrief();
  53.         System.out.println();
  54.         System.out.println("----------------");
  55.        
  56.         NumberOfSimulationsPerDeck=10000;
  57.         int NewOptimalOneDrops=0;
  58.         int NewOptimalTwoDrops=0;
  59.         int NewOptimalThreeDrops=0;
  60.         int NewOptimalBolts=0;
  61.         int NewOptimalLands=0;
  62.         boolean ContinueLocalSearch=true;
  63.        
  64.         do {
  65.             FastestTurn=50;
  66.             for (int OneDropCount=Math.max(0,OptimalOneDrops-4); OneDropCount<=Math.min(60,OptimalOneDrops+4); OneDropCount++){
  67.                 for (int TwoDropCount=Math.max(0,OptimalTwoDrops-4); TwoDropCount<=Math.min(60,OptimalTwoDrops+4); TwoDropCount++){
  68.                     for (int ThreeDropCount=Math.max(0,OptimalThreeDrops-4); ThreeDropCount<=Math.min(60,OptimalThreeDrops+4); ThreeDropCount++){
  69.                         for (int BoltCount=Math.max(0,OptimalBolts-4); BoltCount<=Math.min(60,OptimalBolts+4); BoltCount++){
  70.                            int LandCount=60-OneDropCount-TwoDropCount-ThreeDropCount-BoltCount;
  71.                            if (LandCount>=Math.max(0,OptimalLands-3) && LandCount<=Math.min(60,OptimalLands+3)) {
  72.                                 deck.SetDeck(OneDropCount,TwoDropCount,ThreeDropCount,BoltCount,LandCount);
  73.                                 deck.PrintDeckBrief();
  74.                                 KillTurn=AverageKillTurnForRandomHand(deck,7,KeepOpeningHand,NumberOfSimulationsPerDeck);
  75.                                 System.out.println(" "+KillTurn);
  76.                                 if (KillTurn<FastestTurn){
  77.                                     FastestTurn=KillTurn;
  78.                                     NewOptimalOneDrops=OneDropCount;
  79.                                     NewOptimalTwoDrops=TwoDropCount;
  80.                                     NewOptimalThreeDrops=ThreeDropCount;
  81.                                     NewOptimalBolts=BoltCount;
  82.                                     NewOptimalLands=LandCount;
  83.                                 }
  84.                             }
  85.                         }
  86.                     }
  87.                 }
  88.             }
  89.             if (Math.abs(NewOptimalOneDrops-OptimalOneDrops)+Math.abs(NewOptimalTwoDrops-OptimalTwoDrops)+Math.abs(NewOptimalThreeDrops-OptimalThreeDrops)+Math.abs(NewOptimalBolts-OptimalBolts)+Math.abs(NewOptimalLands-OptimalLands)<=2) {ContinueLocalSearch=false;}
  90.             OptimalOneDrops=NewOptimalOneDrops;
  91.             OptimalTwoDrops=NewOptimalTwoDrops;
  92.             OptimalThreeDrops=NewOptimalThreeDrops;
  93.             OptimalBolts=NewOptimalBolts;
  94.             OptimalLands=NewOptimalLands;
  95.             System.out.println("----------------");
  96.             System.out.print("The optimal deck after the local search was:");
  97.             deck.SetDeck(OptimalOneDrops,OptimalTwoDrops,OptimalThreeDrops,OptimalBolts,OptimalLands);
  98.             deck.PrintDeckBrief();
  99.             System.out.println();
  100.             System.out.println("----------------");
  101.         } while (ContinueLocalSearch);
  102.        
  103.         TakeTimeToFindOptimalMulliganStrategy=true;
  104.         NumberOfSimulationsPerDeck=50000;
  105.         ContinueLocalSearch=true;
  106.        
  107.         do {
  108.             FastestTurn=50;
  109.             for (int OneDropCount=Math.max(0,OptimalOneDrops-2); OneDropCount<=Math.min(60,OptimalOneDrops+2); OneDropCount++){
  110.                 for (int TwoDropCount=Math.max(0,OptimalTwoDrops-2); TwoDropCount<=Math.min(60,OptimalTwoDrops+2); TwoDropCount++){
  111.                     for (int ThreeDropCount=Math.max(0,OptimalThreeDrops-2); ThreeDropCount<=Math.min(60,OptimalThreeDrops+2); ThreeDropCount++){
  112.                         for (int BoltCount=Math.max(0,OptimalBolts-2); BoltCount<=Math.min(60,OptimalBolts+2); BoltCount++){
  113.                             int LandCount=60-OneDropCount-TwoDropCount-ThreeDropCount-BoltCount;
  114.                             if (LandCount>=Math.max(0,OptimalLands-2) && LandCount<=Math.min(60,OptimalLands+2)) {
  115.                                 deck.SetDeck(OneDropCount,TwoDropCount,ThreeDropCount,BoltCount,LandCount);
  116.                                 deck.PrintDeckBrief();
  117.                                 if (TakeTimeToFindOptimalMulliganStrategy==true) {KeepOpeningHand=GiveOptimalMulliganStrategy(deck);}
  118.                                 KillTurn=AverageKillTurnForRandomHand(deck,7,KeepOpeningHand,NumberOfSimulationsPerDeck);
  119.                                 System.out.println(" "+KillTurn);
  120.                                 if (KillTurn<FastestTurn){
  121.                                     FastestTurn=KillTurn;
  122.                                     NewOptimalOneDrops=OneDropCount;
  123.                                     NewOptimalTwoDrops=TwoDropCount;
  124.                                     NewOptimalThreeDrops=ThreeDropCount;
  125.                                     NewOptimalBolts=BoltCount;
  126.                                     NewOptimalLands=LandCount;
  127.                                 }
  128.                             }
  129.                         }
  130.                     }
  131.                 }
  132.             }
  133.             if (Math.abs(NewOptimalOneDrops-OptimalOneDrops)+Math.abs(NewOptimalTwoDrops-OptimalTwoDrops)+Math.abs(NewOptimalThreeDrops-OptimalThreeDrops)+Math.abs(NewOptimalBolts-OptimalBolts)+Math.abs(NewOptimalLands-OptimalLands)==0) {ContinueLocalSearch=false;}
  134.             OptimalOneDrops=NewOptimalOneDrops;
  135.             OptimalTwoDrops=NewOptimalTwoDrops;
  136.             OptimalThreeDrops=NewOptimalThreeDrops;
  137.             OptimalBolts=NewOptimalBolts;
  138.             OptimalLands=NewOptimalLands;
  139.             System.out.println("----------------");
  140.             System.out.print("The final optimal deck:");
  141.             deck.SetDeck(OptimalOneDrops,OptimalTwoDrops,OptimalThreeDrops,OptimalBolts,OptimalLands);
  142.             deck.PrintDeckBrief();
  143.             System.out.println();
  144.             System.out.println("----------------");
  145.         } while (ContinueLocalSearch);
  146.     }//end of main
  147.  
  148.     static boolean[][][][][][] GiveOptimalMulliganStrategy(Deck deck) {
  149.         boolean[][][][][][] KeepOpeningHand = new boolean[8][8][8][8][8][8];
  150.         OpeningHand openinghand=new OpeningHand();
  151.         int NumberOfSimulationsPerOpeningHandSize=1000;
  152.         int OriginalNr1Cost=deck.NumberOf1Cost;
  153.         int OriginalNr2Cost=deck.NumberOf2Cost;
  154.         int OriginalNr3Cost=deck.NumberOf3Cost;
  155.         int OriginalNrBolts=deck.NumberOfBolts;
  156.         int OriginalNrLands=deck.NumberOfLands;
  157.         double CutOffTurn = AverageKillTurnForRandomHand(deck,1,KeepOpeningHand,NumberOfSimulationsPerOpeningHandSize);
  158.         for (int StartingCards=2; StartingCards<=7; StartingCards++){
  159.             System.out.print(".");
  160.             for (int OneDropCount=0; OneDropCount<=OriginalNr1Cost && OneDropCount<=StartingCards; OneDropCount++){
  161.                 for (int TwoDropCount=0; TwoDropCount<=OriginalNr2Cost && TwoDropCount+OneDropCount<=StartingCards; TwoDropCount++){
  162.                     for  (int ThreeDropCount=0; ThreeDropCount<=OriginalNr3Cost && ThreeDropCount+TwoDropCount+OneDropCount<=StartingCards; ThreeDropCount++){
  163.                         for (int BoltCount=0; BoltCount<=OriginalNrBolts && BoltCount+ThreeDropCount+TwoDropCount+OneDropCount<=StartingCards; BoltCount++){
  164.                             int LandCount=StartingCards-OneDropCount-TwoDropCount-ThreeDropCount-BoltCount;
  165.                             if (LandCount<=OriginalNrLands){
  166.                                 openinghand.SetHand(OneDropCount, TwoDropCount, ThreeDropCount, BoltCount, LandCount);
  167.                                 deck.SetDeck(OriginalNr1Cost,OriginalNr2Cost,OriginalNr3Cost,OriginalNrBolts,OriginalNrLands);
  168.                                 double AvgKillTurn=AverageKillTurnForSpecificHand(deck,openinghand);
  169.                                 if (AvgKillTurn<=CutOffTurn) { KeepOpeningHand[StartingCards][OneDropCount][TwoDropCount][ThreeDropCount][BoltCount][LandCount]=true; }
  170.                                 if (AvgKillTurn>CutOffTurn) { KeepOpeningHand[StartingCards][OneDropCount][TwoDropCount][ThreeDropCount][BoltCount][LandCount]=false; }
  171.                                 }
  172.                             }
  173.                         }
  174.                     }
  175.                 }
  176.             deck.SetDeck(OriginalNr1Cost,OriginalNr2Cost,OriginalNr3Cost,OriginalNrBolts,OriginalNrLands);
  177.             if (StartingCards<7) {CutOffTurn=AverageKillTurnForRandomHand(deck,StartingCards,KeepOpeningHand,NumberOfSimulationsPerOpeningHandSize);}
  178.         }
  179.         return KeepOpeningHand;
  180.     }
  181.  
  182.     static boolean[][][][][][] GiveLooseMulliganStrategy() {
  183.         boolean[][][][][][] KeepOpeningHand = new boolean[8][8][8][8][8][8];
  184.         for (int StartingCards=2; StartingCards<=7; StartingCards++){
  185.             for (int OneDropCount=0; OneDropCount<=StartingCards; OneDropCount++){
  186.                 for (int TwoDropCount=0; TwoDropCount+OneDropCount<=StartingCards; TwoDropCount++){
  187.                     for  (int ThreeDropCount=0; ThreeDropCount+TwoDropCount+OneDropCount<=StartingCards; ThreeDropCount++){
  188.                         for (int BoltCount=0; BoltCount+ThreeDropCount+TwoDropCount+OneDropCount<=StartingCards; BoltCount++){
  189.                             int LandCount=StartingCards-OneDropCount-TwoDropCount-ThreeDropCount-BoltCount;
  190.                             KeepOpeningHand[StartingCards][OneDropCount][TwoDropCount][ThreeDropCount][BoltCount][LandCount]=false;
  191.                             if (LandCount>=1 && LandCount<=3) {KeepOpeningHand[StartingCards][OneDropCount][TwoDropCount][ThreeDropCount][BoltCount][LandCount]=true;}
  192.                             if (ThreeDropCount>=5) {KeepOpeningHand[StartingCards][OneDropCount][TwoDropCount][ThreeDropCount][BoltCount][LandCount]=true;}
  193.                         }
  194.                     }
  195.                 }
  196.             }
  197.         }
  198.         return KeepOpeningHand;
  199.     }
  200.    
  201.     static double AverageKillTurnForSpecificHand(Deck deck, OpeningHand openinghand){
  202.         int NumberOfIterations=200;
  203.         Deck remainingdeck=new Deck();
  204.         double AverageKillTurn=0;
  205.         for (int IterationCounter=1; IterationCounter<=NumberOfIterations; IterationCounter++){
  206.             remainingdeck.SetDeck(deck.NumberOf1Cost-openinghand.NumberOf1Cost,deck.NumberOf2Cost-openinghand.NumberOf2Cost,deck.NumberOf3Cost-openinghand.NumberOf3Cost,deck.NumberOfBolts-openinghand.NumberOfBolts,deck.NumberOfLands-openinghand.NumberOfLands);
  207.             AverageKillTurn=AverageKillTurn+TurnKill(remainingdeck,openinghand);
  208.         }
  209.         return (AverageKillTurn/(NumberOfIterations+0.0));
  210.     }//end of AverageKillTurnForSpecificHand
  211.  
  212.     static double AverageKillTurnForRandomHand(Deck deck, int StartingCards, boolean[][][][][][] KeepOpeningHand, int NumberOfIterations){
  213.         Deck remainingdeck=new Deck();
  214.         double AverageKillTurn=0;
  215.         for (int IterationCounter=1; IterationCounter<=NumberOfIterations; IterationCounter++){
  216.             OpeningHand openinghand=GiveOpeningHandAfterMulls(deck, StartingCards, KeepOpeningHand);
  217.             remainingdeck.SetDeck(deck.NumberOf1Cost-openinghand.NumberOf1Cost,deck.NumberOf2Cost-openinghand.NumberOf2Cost,deck.NumberOf3Cost-openinghand.NumberOf3Cost,deck.NumberOfBolts-openinghand.NumberOfBolts,deck.NumberOfLands-openinghand.NumberOfLands);
  218.             AverageKillTurn=AverageKillTurn+TurnKill(remainingdeck,openinghand);
  219.             if ( IterationCounter % 200000 == 0) {System.out.print(".");}
  220.         }
  221.         return AverageKillTurn/(NumberOfIterations+0.0);
  222.     }//end of AverageKillTurnForRandomHand
  223.    
  224.     static OpeningHand GiveOpeningHandAfterMulls (Deck deck, int StartingCards, boolean[][][][][][] KeepOpeningHand) {
  225.        
  226.         Deck remainingdeck=new Deck();
  227.         OpeningHand openinghand=new OpeningHand();
  228.         int TypeOfCardDrawn;
  229.         boolean KeepHand=false;
  230.        
  231.         for (int OpeningHandSize=7; OpeningHandSize>=1; OpeningHandSize--){
  232.             if (KeepHand==false && StartingCards>=OpeningHandSize){
  233.                 openinghand.ResetHand();
  234.                 remainingdeck.SetDeck(deck.NumberOf1Cost,deck.NumberOf2Cost,deck.NumberOf3Cost,deck.NumberOfBolts,deck.NumberOfLands);
  235.                 for (int CardsDrawn=0; CardsDrawn<OpeningHandSize; CardsDrawn++){
  236.                     TypeOfCardDrawn=remainingdeck.DrawCard();
  237.                     if (TypeOfCardDrawn==1) {openinghand.NumberOf1Cost++;}
  238.                     if (TypeOfCardDrawn==2) {openinghand.NumberOf2Cost++;}
  239.                     if (TypeOfCardDrawn==3) {openinghand.NumberOf3Cost++;}
  240.                     if (TypeOfCardDrawn==4) {openinghand.NumberOfBolts++;}
  241.                     if (TypeOfCardDrawn==5) {openinghand.NumberOfLands++;}
  242.                 }
  243.                 KeepHand=true;
  244.                 if (OpeningHandSize>1) {
  245.                     if (KeepOpeningHand[OpeningHandSize][openinghand.NumberOf1Cost][openinghand.NumberOf2Cost][openinghand.NumberOf3Cost][openinghand.NumberOfBolts][openinghand.NumberOfLands]==false) {KeepHand=false;}
  246.                 }
  247.             }
  248.         }
  249.        
  250.         return openinghand;
  251.     }//end of GiveOpeningHandAfterMulls
  252.    
  253.   static int TurnKill(Deck remainingdeck, OpeningHand openinghand) {
  254.        
  255.         int OneCostPower=2;
  256.         int TwoCostPower=4;
  257.         int ThreeCostPower=6;
  258.         int BoltDamage=3;
  259.        
  260.         int Turn=0;
  261.         int OppLife=20;
  262.         int ManaLeft;
  263.         int TypeOfCardDrawn;
  264.    
  265.         int OneDropsInPlay=0;
  266.         int TwoDropsInPlay=0;
  267.         int LandsInPlay=0;
  268.        
  269.         int OneDropsInHand=openinghand.NumberOf1Cost;
  270.         int TwoDropsInHand=openinghand.NumberOf2Cost;
  271.         int ThreeDropsInHand=openinghand.NumberOf3Cost;
  272.         int BoltsInHand=openinghand.NumberOfBolts;
  273.         int LandsInHand=openinghand.NumberOfLands;
  274.        
  275.         do {
  276.            
  277.             Turn++;
  278.            
  279.             if (Turn==1) {
  280.                
  281.                 if (LandsInHand>=1) {LandsInPlay++; LandsInHand--;}
  282.                 ManaLeft=LandsInPlay;
  283.                 if (OneDropsInHand>=1 && ManaLeft==1) {OneDropsInPlay++; ManaLeft--; OneDropsInHand--;}
  284.                 if (BoltsInHand>=1 && ManaLeft==1) {OppLife=OppLife-BoltDamage; ManaLeft--; BoltsInHand--;}
  285.                
  286.             } //end of the first turn
  287.            
  288.             if (Turn>1) {
  289.  
  290.                 TypeOfCardDrawn=remainingdeck.DrawCard();
  291.                 if (TypeOfCardDrawn==1) {OneDropsInHand++;}
  292.                 if (TypeOfCardDrawn==2) {TwoDropsInHand++;}
  293.                 if (TypeOfCardDrawn==3) {ThreeDropsInHand++;}
  294.                 if (TypeOfCardDrawn==4) {BoltsInHand++;}
  295.                 if (TypeOfCardDrawn==5) {LandsInHand++;}
  296.  
  297.                 if (LandsInHand>=1) {LandsInPlay++; LandsInHand--;}
  298.                 ManaLeft=LandsInPlay;
  299.                 OppLife=OppLife-OneCostPower*OneDropsInPlay;
  300.                 OppLife=OppLife-TwoCostPower*TwoDropsInPlay;
  301.                
  302.                 if (ManaLeft==1) {
  303.                     int CastableBolts=Math.min(BoltsInHand, ManaLeft);
  304.                     if (OppLife<=CastableBolts*BoltDamage) {OppLife=OppLife-CastableBolts*BoltDamage; ManaLeft=ManaLeft-CastableBolts; BoltsInHand=BoltsInHand-CastableBolts;}
  305.                     if (OneDropsInHand>=1 && ManaLeft==1) {OneDropsInPlay++; ManaLeft--; OneDropsInHand--;}
  306.                     if (BoltsInHand>=1 && ManaLeft==1) {OppLife=OppLife-BoltDamage; ManaLeft--; BoltsInHand--;}
  307.                 }
  308.                
  309.                 if (ManaLeft==2) {
  310.                     int CastableBolts=Math.min(BoltsInHand, ManaLeft);
  311.                     if (OppLife<=CastableBolts*BoltDamage) {OppLife=OppLife-CastableBolts*BoltDamage; ManaLeft=ManaLeft-CastableBolts; BoltsInHand=BoltsInHand-CastableBolts;}
  312.                     if (TwoDropsInHand>=1 && ManaLeft==2) {TwoDropsInPlay++; ManaLeft=ManaLeft-2; TwoDropsInHand--;}
  313.                     int CastableOneDrops=Math.min(OneDropsInHand, ManaLeft);
  314.                     if (CastableOneDrops>=1) {OneDropsInPlay=OneDropsInPlay+CastableOneDrops; ManaLeft=ManaLeft-CastableOneDrops; OneDropsInHand=OneDropsInHand-CastableOneDrops;}
  315.                     CastableBolts=Math.min(BoltsInHand, ManaLeft);
  316.                     if (CastableBolts>=1) {OppLife=OppLife-CastableBolts*BoltDamage; ManaLeft=ManaLeft-CastableBolts; BoltsInHand=BoltsInHand-CastableBolts;}
  317.                 }
  318.  
  319.                 if (ManaLeft==3) {
  320.                     int CastableBolts=Math.min(BoltsInHand, ManaLeft);
  321.                     if (OppLife<=CastableBolts*BoltDamage) {OppLife=OppLife-CastableBolts*BoltDamage; ManaLeft=ManaLeft-CastableBolts; BoltsInHand=BoltsInHand-CastableBolts;}
  322.                     if (ThreeDropsInHand>=1 && ManaLeft==3) {OppLife=OppLife-ThreeCostPower; ManaLeft=ManaLeft-3; ThreeDropsInHand--;}
  323.                     if (TwoDropsInHand>=1 && ManaLeft>=2) {TwoDropsInPlay++; ManaLeft=ManaLeft-2; TwoDropsInHand--;}
  324.                     int CastableOneDrops=Math.min(OneDropsInHand, ManaLeft);
  325.                     if (CastableOneDrops>=1) {OneDropsInPlay=OneDropsInPlay+CastableOneDrops; ManaLeft=ManaLeft-CastableOneDrops; OneDropsInHand=OneDropsInHand-CastableOneDrops;}
  326.                     CastableBolts=Math.min(BoltsInHand, ManaLeft);
  327.                     if (CastableBolts>=1) {OppLife=OppLife-CastableBolts*BoltDamage; ManaLeft=ManaLeft-CastableBolts; BoltsInHand=BoltsInHand-CastableBolts;}
  328.                 }
  329.                
  330.                 if (ManaLeft==4) {
  331.                     int CastableBolts=Math.min(BoltsInHand, ManaLeft);
  332.                     if (OppLife<=CastableBolts*BoltDamage) {OppLife=OppLife-CastableBolts*BoltDamage; ManaLeft=ManaLeft-CastableBolts; BoltsInHand=BoltsInHand-CastableBolts;}
  333.                     if (ThreeDropsInHand>=1 && ManaLeft>=3) {OppLife=OppLife-ThreeCostPower; ManaLeft=ManaLeft-3; ThreeDropsInHand--;}
  334.                     int CastableTwoDrops=Math.min(TwoDropsInHand, ManaLeft/2);
  335.                     if (CastableTwoDrops==2) {TwoDropsInPlay=TwoDropsInPlay+2; ManaLeft=ManaLeft-4; TwoDropsInHand=TwoDropsInHand-2;}
  336.                     if (TwoDropsInHand>=1 && ManaLeft>=2) {TwoDropsInPlay++; ManaLeft=ManaLeft-2; TwoDropsInHand--;}
  337.                     int CastableOneDrops=Math.min(OneDropsInHand, ManaLeft);
  338.                     if (CastableOneDrops>=1) {OneDropsInPlay=OneDropsInPlay+CastableOneDrops; ManaLeft=ManaLeft-CastableOneDrops; OneDropsInHand=OneDropsInHand-CastableOneDrops;}
  339.                     CastableBolts=Math.min(BoltsInHand, ManaLeft);
  340.                     if (CastableBolts>=1) {OppLife=OppLife-CastableBolts*BoltDamage; ManaLeft=ManaLeft-CastableBolts; BoltsInHand=BoltsInHand-CastableBolts;}
  341.                 }
  342.                        
  343.                 if (ManaLeft>=5) {
  344.                     int CastableBolts=Math.min(BoltsInHand, ManaLeft);
  345.                     if (OppLife<=CastableBolts*BoltDamage) {OppLife=OppLife-CastableBolts*BoltDamage; ManaLeft=ManaLeft-CastableBolts; BoltsInHand=BoltsInHand-CastableBolts;}
  346.                     int CastableThreeDrops=Math.min(ThreeDropsInHand, ManaLeft/3);
  347.                     if (CastableThreeDrops>=1) {OppLife=OppLife-ThreeCostPower*CastableThreeDrops; ManaLeft=ManaLeft-3*CastableThreeDrops; ThreeDropsInHand=ThreeDropsInHand-CastableThreeDrops;}
  348.                     int CastableTwoDrops=Math.min(TwoDropsInHand, ManaLeft/2);
  349.                     if (CastableTwoDrops>=1) {TwoDropsInPlay=TwoDropsInPlay+CastableTwoDrops; ManaLeft=ManaLeft-2*CastableTwoDrops; TwoDropsInHand=TwoDropsInHand-CastableTwoDrops;}
  350.                     int CastableOneDrops=Math.min(OneDropsInHand, ManaLeft);
  351.                     if (CastableOneDrops>=1) {OneDropsInPlay=OneDropsInPlay+CastableOneDrops; ManaLeft=ManaLeft-CastableOneDrops; OneDropsInHand=OneDropsInHand-CastableOneDrops;}
  352.                     CastableBolts=Math.min(BoltsInHand, ManaLeft);
  353.                     if (CastableBolts>=1) {OppLife=OppLife-CastableBolts*BoltDamage; ManaLeft=ManaLeft-CastableBolts; BoltsInHand=BoltsInHand-CastableBolts;}
  354.                 }
  355.                
  356.             } //end of a turn in which we drew a card and attacked
  357.  
  358.         } while (OppLife>0 &&Turn<=50);
  359.        
  360.         return Turn;
  361.     }//end of TurnKill
  362.    
  363.    
  364. }//end of OptimalAggroGoldfishDeck
  365.  
  366. class OpeningHand {
  367.     int NumberOf1Cost;
  368.     int NumberOf2Cost;
  369.     int NumberOf3Cost;
  370.     int NumberOfBolts;
  371.     int NumberOfLands;
  372.  
  373.     void ResetHand(){
  374.         NumberOf1Cost=0;
  375.         NumberOf2Cost=0;
  376.         NumberOf3Cost=0;
  377.         NumberOfBolts=0;
  378.         NumberOfLands=0;
  379.     }
  380.            
  381.     void SetHand (int Nr1Cost, int Nr2Cost, int Nr3Cost, int NrBolts, int NrLands) {
  382.         NumberOf1Cost=Nr1Cost;
  383.         NumberOf2Cost=Nr2Cost;
  384.         NumberOf3Cost=Nr3Cost;
  385.         NumberOfBolts=NrBolts;
  386.         NumberOfLands=NrLands;
  387.     }
  388.  
  389. }//end of OpeningHand
  390.  
  391. class Deck {
  392.     int NumberOf1Cost;
  393.     int NumberOf2Cost;
  394.     int NumberOf3Cost;
  395.     int NumberOfBolts;
  396.     int NumberOfLands;
  397.  
  398.     void PrintDeckBrief () {
  399.         if(NumberOf1Cost<10) {System.out.print("0");}
  400.         System.out.print(NumberOf1Cost+" ");
  401.         if(NumberOf2Cost<10) {System.out.print("0");}
  402.         System.out.print(NumberOf2Cost+" ");
  403.         if(NumberOf3Cost<10) {System.out.print("0");}
  404.         System.out.print(NumberOf3Cost+" ");
  405.         if(NumberOfBolts<10) {System.out.print("0");}
  406.         System.out.print(NumberOfBolts+" ");
  407.         if(NumberOfLands<10) {System.out.print("0");}
  408.         System.out.print(NumberOfLands);
  409.         System.out.print(" ");
  410.     }
  411.  
  412.     void SetDeck (int Nr1Cost, int Nr2Cost, int Nr3Cost, int NrBolts, int NrLands) {
  413.         NumberOf1Cost=Nr1Cost;
  414.         NumberOf2Cost=Nr2Cost;
  415.         NumberOf3Cost=Nr3Cost;
  416.         NumberOfBolts=NrBolts;
  417.         NumberOfLands=NrLands;
  418.     }
  419.    
  420.     int NrOfCards(){
  421.         return NumberOf1Cost+NumberOf2Cost+NumberOf3Cost+NumberOfBolts+NumberOfLands;
  422.     }
  423.    
  424.     int DrawCard (){
  425.             Random generator = new Random();
  426.             int RandomIntegerBetweenOneAndDeckSize=generator.nextInt( this.NrOfCards() )+1;
  427.             int CardType=0;
  428.             int OneCostCutoff=NumberOf1Cost;
  429.             int TwoCostCutoff=OneCostCutoff+NumberOf2Cost;
  430.             int ThreeCostCutoff=TwoCostCutoff+NumberOf3Cost;
  431.             int BoltCutoff=ThreeCostCutoff+NumberOfBolts;
  432.             int LandCutoff=BoltCutoff+NumberOfLands;
  433.            
  434.             if (RandomIntegerBetweenOneAndDeckSize<=OneCostCutoff) {CardType=1; this.NumberOf1Cost--;}
  435.             if (RandomIntegerBetweenOneAndDeckSize>OneCostCutoff && RandomIntegerBetweenOneAndDeckSize<=TwoCostCutoff) {CardType=2; this.NumberOf2Cost--;}
  436.             if (RandomIntegerBetweenOneAndDeckSize>TwoCostCutoff && RandomIntegerBetweenOneAndDeckSize<=ThreeCostCutoff) {CardType=3; this.NumberOf3Cost--;}
  437.             if (RandomIntegerBetweenOneAndDeckSize>ThreeCostCutoff && RandomIntegerBetweenOneAndDeckSize<=BoltCutoff) {CardType=4; this.NumberOfBolts--;}
  438.             if (RandomIntegerBetweenOneAndDeckSize>BoltCutoff && RandomIntegerBetweenOneAndDeckSize<=LandCutoff) {CardType=5; this.NumberOfLands--;}
  439.             return CardType;
  440.     }
  441.    
  442. }//end of Deck
RAW Paste Data