frankkarsten

MTG Optimal Deck for Burning-Tree Emissary format

Sep 23rd, 2013
245
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. package btegoldfish;
  2.  
  3. import java.util.Arrays.*;
  4. import java.util.Random;
  5.  
  6. public class BTEGoldfish {
  7.  
  8. public static void main(String[] args) {
  9.  
  10. //Note: Three-drop means BTE!!!
  11.  
  12. Deck deck=new Deck();
  13. boolean[][][][][][] KeepOpeningHand = new boolean[8][8][8][8][8][8];
  14. boolean TakeTimeToFindOptimalMulliganStrategy = false;
  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<=14; TripleOneDropCount++){
  26. for (int TripleTwoDropCount=0; TripleTwoDropCount<=14; TripleTwoDropCount++){
  27. for (int TripleThreeDropCount=0; TripleThreeDropCount<=14; TripleThreeDropCount++){
  28. for (int TripleBoltCount=0; TripleBoltCount<=14; TripleBoltCount++){
  29. int TripleLandCount=20-TripleOneDropCount-TripleTwoDropCount-TripleThreeDropCount-TripleBoltCount;
  30. if (TripleLandCount>=0 && TripleLandCount<=8) {
  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-3); OneDropCount<=Math.min(60,OptimalOneDrops+3); OneDropCount++){
  67. for (int TwoDropCount=Math.max(0,OptimalTwoDrops-3); TwoDropCount<=Math.min(60,OptimalTwoDrops+3); TwoDropCount++){
  68. for (int ThreeDropCount=Math.max(0,OptimalThreeDrops-3); ThreeDropCount<=Math.min(60,OptimalThreeDrops+3); ThreeDropCount++){
  69. for (int BoltCount=Math.max(0,OptimalBolts-3); BoltCount<=Math.min(60,OptimalBolts+3); 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. FastestTurn=50;
  106. ContinueLocalSearch=true;
  107.  
  108. do {
  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. public 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. public 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<=4) {KeepOpeningHand[StartingCards][OneDropCount][TwoDropCount][ThreeDropCount][BoltCount][LandCount]=true;}
  192. }
  193. }
  194. }
  195. }
  196. }
  197. return KeepOpeningHand;
  198. }
  199.  
  200. public static double AverageKillTurnForSpecificHand(Deck deck, OpeningHand openinghand){
  201. int NumberOfIterations=200;
  202. Deck remainingdeck=new Deck();
  203. double AverageKillTurn=0;
  204. for (int IterationCounter=1; IterationCounter<=NumberOfIterations; IterationCounter++){
  205. remainingdeck.SetDeck(deck.NumberOf1Cost-openinghand.NumberOf1Cost,deck.NumberOf2Cost-openinghand.NumberOf2Cost,deck.NumberOf3Cost-openinghand.NumberOf3Cost,deck.NumberOfBolts-openinghand.NumberOfBolts,deck.NumberOfLands-openinghand.NumberOfLands);
  206. AverageKillTurn=AverageKillTurn+TurnKill(remainingdeck,openinghand);
  207. }
  208. return (AverageKillTurn/(NumberOfIterations+0.0));
  209. }//end of AverageKillTurnForSpecificHand
  210.  
  211. public static double AverageKillTurnForRandomHand(Deck deck, int StartingCards, boolean[][][][][][] KeepOpeningHand, int NumberOfIterations){
  212. Deck remainingdeck=new Deck();
  213. double AverageKillTurn=0;
  214. for (int IterationCounter=1; IterationCounter<=NumberOfIterations; IterationCounter++){
  215. OpeningHand openinghand=GiveOpeningHandAfterMulls(deck, StartingCards, KeepOpeningHand);
  216. remainingdeck.SetDeck(deck.NumberOf1Cost-openinghand.NumberOf1Cost,deck.NumberOf2Cost-openinghand.NumberOf2Cost,deck.NumberOf3Cost-openinghand.NumberOf3Cost,deck.NumberOfBolts-openinghand.NumberOfBolts,deck.NumberOfLands-openinghand.NumberOfLands);
  217. AverageKillTurn=AverageKillTurn+TurnKill(remainingdeck,openinghand);
  218. if ( IterationCounter % 200000 == 0) {System.out.print(".");}
  219. }
  220. return AverageKillTurn/(NumberOfIterations+0.0);
  221. }//end of AverageKillTurnForRandomHand
  222.  
  223. static OpeningHand GiveOpeningHandAfterMulls (Deck deck, int StartingCards, boolean[][][][][][] KeepOpeningHand) {
  224.  
  225. Deck remainingdeck=new Deck();
  226. OpeningHand openinghand=new OpeningHand();
  227. int TypeOfCardDrawn;
  228. boolean KeepHand=false;
  229.  
  230. for (int OpeningHandSize=7; OpeningHandSize>=1; OpeningHandSize--){
  231. if (KeepHand==false && StartingCards>=OpeningHandSize){
  232. openinghand.ResetHand();
  233. remainingdeck.SetDeck(deck.NumberOf1Cost,deck.NumberOf2Cost,deck.NumberOf3Cost,deck.NumberOfBolts,deck.NumberOfLands);
  234. for (int CardsDrawn=0; CardsDrawn<OpeningHandSize; CardsDrawn++){
  235. TypeOfCardDrawn=remainingdeck.DrawCard();
  236. if (TypeOfCardDrawn==1) {openinghand.NumberOf1Cost++;}
  237. if (TypeOfCardDrawn==2) {openinghand.NumberOf2Cost++;}
  238. if (TypeOfCardDrawn==3) {openinghand.NumberOf3Cost++;}
  239. if (TypeOfCardDrawn==4) {openinghand.NumberOfBolts++;}
  240. if (TypeOfCardDrawn==5) {openinghand.NumberOfLands++;}
  241. }
  242. KeepHand=true;
  243. if (OpeningHandSize>1) {
  244. if (KeepOpeningHand[OpeningHandSize][openinghand.NumberOf1Cost][openinghand.NumberOf2Cost][openinghand.NumberOf3Cost][openinghand.NumberOfBolts][openinghand.NumberOfLands]==false) {KeepHand=false;}
  245. }
  246. }
  247. }
  248.  
  249. return openinghand;
  250. }//end of GiveOpeningHandAfterMulls
  251.  
  252. static int TurnKill(Deck remainingdeck, OpeningHand openinghand) {
  253.  
  254. int OneCostPower=2;
  255. int TwoCostPower=4;
  256. int BTEPower=2;
  257. int BoltDamage=3;
  258.  
  259. int Turn=0;
  260. int OppLife=20;
  261. int ManaLeft;
  262. int TypeOfCardDrawn;
  263.  
  264. int OneDropsInPlay=0;
  265. int TwoDropsInPlay=0;
  266. int BTEInPlay=0;
  267. int LandsInPlay=0;
  268.  
  269. int OneDropsInHand=openinghand.NumberOf1Cost;
  270. int TwoDropsInHand=openinghand.NumberOf2Cost;
  271. int BTEInHand=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) {BTEInHand++;}
  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. OppLife=OppLife-BTEPower*BTEInPlay;
  302.  
  303. if (ManaLeft==1) {
  304. int CastableBolts=Math.min(BoltsInHand, ManaLeft);
  305. if (OppLife<=CastableBolts*BoltDamage) {OppLife=OppLife-CastableBolts*BoltDamage; ManaLeft=ManaLeft-CastableBolts; BoltsInHand=BoltsInHand-CastableBolts;}
  306. if (OneDropsInHand>=1 && ManaLeft==1) {OneDropsInPlay++; ManaLeft--; OneDropsInHand--;}
  307. if (BoltsInHand>=1 && ManaLeft==1) {OppLife=OppLife-BoltDamage; ManaLeft--; BoltsInHand--;}
  308. }
  309.  
  310. if (ManaLeft==2) {
  311. BTEInPlay=BTEInPlay+BTEInHand;
  312. BTEInHand=0;
  313. int CastableBolts=Math.min(BoltsInHand, ManaLeft);
  314. if (OppLife<=CastableBolts*BoltDamage) {OppLife=OppLife-CastableBolts*BoltDamage; ManaLeft=ManaLeft-CastableBolts; BoltsInHand=BoltsInHand-CastableBolts;}
  315. if (TwoDropsInHand>=1 && ManaLeft==2) {TwoDropsInPlay++; ManaLeft=ManaLeft-2; TwoDropsInHand--;}
  316. int CastableOneDrops=Math.min(OneDropsInHand, ManaLeft);
  317. if (CastableOneDrops>=1) {OneDropsInPlay=OneDropsInPlay+CastableOneDrops; ManaLeft=ManaLeft-CastableOneDrops; OneDropsInHand=OneDropsInHand-CastableOneDrops;}
  318. CastableBolts=Math.min(BoltsInHand, ManaLeft);
  319. if (CastableBolts>=1) {OppLife=OppLife-CastableBolts*BoltDamage; ManaLeft=ManaLeft-CastableBolts; BoltsInHand=BoltsInHand-CastableBolts;}
  320. }
  321.  
  322. if (ManaLeft==3) {
  323. BTEInPlay=BTEInPlay+BTEInHand;
  324. BTEInHand=0;
  325. int CastableBolts=Math.min(BoltsInHand, ManaLeft);
  326. if (OppLife<=CastableBolts*BoltDamage) {OppLife=OppLife-CastableBolts*BoltDamage; ManaLeft=ManaLeft-CastableBolts; BoltsInHand=BoltsInHand-CastableBolts;}
  327. if (TwoDropsInHand>=1 && ManaLeft>=2) {TwoDropsInPlay++; ManaLeft=ManaLeft-2; TwoDropsInHand--;}
  328. int CastableOneDrops=Math.min(OneDropsInHand, ManaLeft);
  329. if (CastableOneDrops>=1) {OneDropsInPlay=OneDropsInPlay+CastableOneDrops; ManaLeft=ManaLeft-CastableOneDrops; OneDropsInHand=OneDropsInHand-CastableOneDrops;}
  330. CastableBolts=Math.min(BoltsInHand, ManaLeft);
  331. if (CastableBolts>=1) {OppLife=OppLife-CastableBolts*BoltDamage; ManaLeft=ManaLeft-CastableBolts; BoltsInHand=BoltsInHand-CastableBolts;}
  332. }
  333.  
  334. if (ManaLeft==4) {
  335. BTEInPlay=BTEInPlay+BTEInHand;
  336. BTEInHand=0;
  337. int CastableBolts=Math.min(BoltsInHand, ManaLeft);
  338. if (OppLife<=CastableBolts*BoltDamage) {OppLife=OppLife-CastableBolts*BoltDamage; ManaLeft=ManaLeft-CastableBolts; BoltsInHand=BoltsInHand-CastableBolts;}
  339. int CastableTwoDrops=Math.min(TwoDropsInHand, ManaLeft/2);
  340. if (CastableTwoDrops==2) {TwoDropsInPlay=TwoDropsInPlay+2; ManaLeft=ManaLeft-4; TwoDropsInHand=TwoDropsInHand-2;}
  341. if (TwoDropsInHand>=1 && ManaLeft>=2) {TwoDropsInPlay++; ManaLeft=ManaLeft-2; TwoDropsInHand--;}
  342. int CastableOneDrops=Math.min(OneDropsInHand, ManaLeft);
  343. if (CastableOneDrops>=1) {OneDropsInPlay=OneDropsInPlay+CastableOneDrops; ManaLeft=ManaLeft-CastableOneDrops; OneDropsInHand=OneDropsInHand-CastableOneDrops;}
  344. CastableBolts=Math.min(BoltsInHand, ManaLeft);
  345. if (CastableBolts>=1) {OppLife=OppLife-CastableBolts*BoltDamage; ManaLeft=ManaLeft-CastableBolts; BoltsInHand=BoltsInHand-CastableBolts;}
  346. }
  347.  
  348. if (ManaLeft>=5) {
  349. BTEInPlay=BTEInPlay+BTEInHand;
  350. BTEInHand=0;
  351. int CastableBolts=Math.min(BoltsInHand, ManaLeft);
  352. if (OppLife<=CastableBolts*BoltDamage) {OppLife=OppLife-CastableBolts*BoltDamage; ManaLeft=ManaLeft-CastableBolts; BoltsInHand=BoltsInHand-CastableBolts;}
  353. int CastableTwoDrops=Math.min(TwoDropsInHand, ManaLeft/2);
  354. if (CastableTwoDrops>=1) {TwoDropsInPlay=TwoDropsInPlay+CastableTwoDrops; ManaLeft=ManaLeft-2*CastableTwoDrops; TwoDropsInHand=TwoDropsInHand-CastableTwoDrops;}
  355. int CastableOneDrops=Math.min(OneDropsInHand, ManaLeft);
  356. if (CastableOneDrops>=1) {OneDropsInPlay=OneDropsInPlay+CastableOneDrops; ManaLeft=ManaLeft-CastableOneDrops; OneDropsInHand=OneDropsInHand-CastableOneDrops;}
  357. CastableBolts=Math.min(BoltsInHand, ManaLeft);
  358. if (CastableBolts>=1) {OppLife=OppLife-CastableBolts*BoltDamage; ManaLeft=ManaLeft-CastableBolts; BoltsInHand=BoltsInHand-CastableBolts;}
  359. }
  360.  
  361. } //end of a turn in which we drew a card and attacked
  362.  
  363. //System.out.println("At the end of Turn "+Turn+" with the opponent at "+OppLife+" life, the situation is as follows:");
  364. //System.out.println("Hand: "+OneDropsInHand+ " one-drops, "+TwoDropsInHand+" two-drops, "+BTEInHand+" BTEs, "+BoltsInHand+" Bolts, and "+LandsInHand+" lands.");
  365. //System.out.println("Board: "+OneDropsInPlay+ " one-drops, "+TwoDropsInPlay+" two-drops, "+BTEInPlay+" BTEs, and "+LandsInPlay+" lands.");
  366.  
  367.  
  368. } while (OppLife>0 &&Turn<=50);
  369.  
  370. return Turn;
  371. }//end of TurnKill
  372.  
  373. }//end of OptimalAggroGoldfishDeck
  374.  
  375. class OpeningHand {
  376. int NumberOf1Cost;
  377. int NumberOf2Cost;
  378. int NumberOf3Cost;
  379. int NumberOfBolts;
  380. int NumberOfLands;
  381.  
  382. void ResetHand(){
  383. NumberOf1Cost=0;
  384. NumberOf2Cost=0;
  385. NumberOf3Cost=0;
  386. NumberOfBolts=0;
  387. NumberOfLands=0;
  388. }
  389.  
  390. void SetHand (int Nr1Cost, int Nr2Cost, int Nr3Cost, int NrBolts, int NrLands) {
  391. NumberOf1Cost=Nr1Cost;
  392. NumberOf2Cost=Nr2Cost;
  393. NumberOf3Cost=Nr3Cost;
  394. NumberOfBolts=NrBolts;
  395. NumberOfLands=NrLands;
  396. }
  397.  
  398. }//end of OpeningHand
  399.  
  400. class Deck {
  401. int NumberOf1Cost;
  402. int NumberOf2Cost;
  403. int NumberOf3Cost;
  404. int NumberOfBolts;
  405. int NumberOfLands;
  406.  
  407. void PrintDeckBrief () {
  408. if(NumberOf1Cost<10) {System.out.print("0");}
  409. System.out.print(NumberOf1Cost+" ");
  410. if(NumberOf2Cost<10) {System.out.print("0");}
  411. System.out.print(NumberOf2Cost+" ");
  412. if(NumberOf3Cost<10) {System.out.print("0");}
  413. System.out.print(NumberOf3Cost+" ");
  414. if(NumberOfBolts<10) {System.out.print("0");}
  415. System.out.print(NumberOfBolts+" ");
  416. if(NumberOfLands<10) {System.out.print("0");}
  417. System.out.print(NumberOfLands);
  418. System.out.print(" ");
  419. }
  420.  
  421. void SetDeck (int Nr1Cost, int Nr2Cost, int Nr3Cost, int NrBolts, int NrLands) {
  422. NumberOf1Cost=Nr1Cost;
  423. NumberOf2Cost=Nr2Cost;
  424. NumberOf3Cost=Nr3Cost;
  425. NumberOfBolts=NrBolts;
  426. NumberOfLands=NrLands;
  427. }
  428.  
  429. int NrOfCards(){
  430. return NumberOf1Cost+NumberOf2Cost+NumberOf3Cost+NumberOfBolts+NumberOfLands;
  431. }
  432.  
  433. int DrawCard (){
  434. Random generator = new Random();
  435. int RandomIntegerBetweenOneAndDeckSize=generator.nextInt( this.NrOfCards() )+1;
  436. int CardType=0;
  437. int OneCostCutoff=NumberOf1Cost;
  438. int TwoCostCutoff=OneCostCutoff+NumberOf2Cost;
  439. int ThreeCostCutoff=TwoCostCutoff+NumberOf3Cost;
  440. int BoltCutoff=ThreeCostCutoff+NumberOfBolts;
  441. int LandCutoff=BoltCutoff+NumberOfLands;
  442.  
  443. if (RandomIntegerBetweenOneAndDeckSize<=OneCostCutoff) {CardType=1; this.NumberOf1Cost--;}
  444. if (RandomIntegerBetweenOneAndDeckSize>OneCostCutoff && RandomIntegerBetweenOneAndDeckSize<=TwoCostCutoff) {CardType=2; this.NumberOf2Cost--;}
  445. if (RandomIntegerBetweenOneAndDeckSize>TwoCostCutoff && RandomIntegerBetweenOneAndDeckSize<=ThreeCostCutoff) {CardType=3; this.NumberOf3Cost--;}
  446. if (RandomIntegerBetweenOneAndDeckSize>ThreeCostCutoff && RandomIntegerBetweenOneAndDeckSize<=BoltCutoff) {CardType=4; this.NumberOfBolts--;}
  447. if (RandomIntegerBetweenOneAndDeckSize>BoltCutoff && RandomIntegerBetweenOneAndDeckSize<=LandCutoff) {CardType=5; this.NumberOfLands--;}
  448. return CardType;
  449. }
  450.  
  451. }//end of Deck
RAW Paste Data