Advertisement
Guest User

Untitled

a guest
Nov 18th, 2019
117
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.05 KB | None | 0 0
  1. import java.util.Collections;
  2. import java.util.Comparator;
  3. import java.util.LinkedList;
  4.  
  5. class Gamestate {
  6. // P1: current score of P1
  7. // P2: current score of P2
  8. // lastTaken: amount of coins taken during last move
  9. // P1touched: boolean list, which stacks has P1 interacted with
  10. // P2touched: boolean list, which stacks has P2 interacted with
  11. // coins: integer list of coins left on stacks
  12. // turn: either "P1" or "P2"
  13. // next: list of Gamestates
  14.  
  15. private int P1;
  16. private int P2;
  17. private int lastTaken;
  18. private LinkedList<Boolean> P1touched; // we can't use primitive types like "boolean" in LinkedList
  19. private LinkedList<Boolean> P2touched;
  20. private LinkedList<Integer> coins;
  21. private String turn;
  22. private LinkedList<Gamestate> next;
  23.  
  24. // creates initial game start node
  25. // it was makeInitState
  26. Gamestate(LinkedList<Integer> coins) {
  27. this.P1 = 0;
  28. this.P2 = 0;
  29. this.lastTaken = 0;
  30. this.P1touched = new LinkedList<>();
  31. this.P2touched = new LinkedList<>();
  32. this.coins = coins;
  33. this.turn = "P1";
  34. this.next = new LinkedList<>();
  35.  
  36. for (int i = 0; i < coins.size(); i++) {
  37. P1touched.add(Boolean.FALSE);
  38. P2touched.add(Boolean.FALSE);
  39. }
  40. }
  41.  
  42. // i removed parent since you weren't using it
  43. public Gamestate(int P1, int P2, String turn, int lastTaken, LinkedList<Boolean> P1touched, LinkedList<Boolean> P2touched, LinkedList<Integer> coins) {
  44. this.P1 = P1;
  45. this.P2 = P2;
  46. this.lastTaken = lastTaken;
  47. this.P1touched = P1touched;
  48. this.P2touched = P2touched;
  49. this.coins = coins;
  50. this.turn = turn;
  51. this.next = new LinkedList<>();
  52. }
  53.  
  54. static Gamestate minmaxTree(Gamestate tree) {
  55. // if leaf, return self
  56. if (tree.next.size() == 0) {
  57. return tree;
  58. }
  59. // if not leaf, agregate minmaxTree results from all possible moves
  60. LinkedList<Gamestate> choices = new LinkedList<>();
  61. for (Gamestate move : tree.next) {
  62. choices.add(minmaxTree(move));
  63. }
  64.  
  65. // if P1 choose best minmax for P1 from choices
  66. Gamestate result;
  67. if (tree.turn.equals("P1")) {
  68. result = Collections.max(choices, Comparator.comparing(g -> (g.P1 - g.P2)));
  69. }
  70. // if P2 choose worst minmax for P1 from choices
  71. else {
  72. result = Collections.min(choices, Comparator.comparing(g -> (g.P1 - g.P2)));
  73. }
  74. return result;
  75. }
  76.  
  77. // it overrides toString method in Object (parent of every object)
  78. public String toString() {
  79. return "P1:" + P1 + ", P2:" + P2 + ", coins" + coins.toString();
  80. }
  81.  
  82. // turns whole tree into string with indents
  83. static String strFromTree(Gamestate tree, int depth) {
  84. // StringBuilder is faster than String when object is frequently modified
  85. // Strings are immutable which means that whenever we're adding some new letters to existing String, program will have to create new object and delete existing one
  86. StringBuilder s = new StringBuilder();
  87.  
  88. for (int i=0; i<depth; i++){
  89. s.append(" ");
  90. }
  91.  
  92. s.append(tree.toString()).append("\n");
  93. for (Gamestate subtree : tree.next) {
  94. s.append(strFromTree(subtree, depth + 1));
  95. }
  96. return s.toString();
  97. }
  98.  
  99. String nextTurn() {
  100. if (turn.equals("P1")) // == is for checking address comparison, .equals(...) is for content comparison
  101. {
  102. return "P2";
  103. } else {
  104. return "P1";
  105. }
  106. }
  107.  
  108. // return list with possible amounts of coins to take from given stack
  109. LinkedList<Integer> possibleTakes(int stack_num) {
  110. LinkedList<Integer> result = new LinkedList<>();
  111. if (coins.get(stack_num) == 0) {
  112. return result;
  113. }
  114. if (lastTaken == 0 && coins.get(stack_num) >= 1) {
  115. result.add(1);
  116. return result;
  117. }
  118. int j = 1;
  119. while (j <= coins.get(stack_num) && j <= lastTaken * 2) {
  120. result.add(j);
  121. j++;
  122. }
  123. return result;
  124. }
  125.  
  126. void addSubstates(LinkedList<Gamestate> substates) {
  127. next.addAll(substates);
  128. }
  129.  
  130. // creates all valid moves
  131. void genPossibleSubstates() {
  132. LinkedList<Gamestate> result = new LinkedList<>();
  133. int n = coins.size();
  134.  
  135. String currMove = turn;
  136. String nextMove = nextTurn();
  137.  
  138. // consider which stacks can current player interact with
  139. LinkedList<Boolean> consideredTouches;
  140. if (currMove.equals("P1")) {
  141. consideredTouches = new LinkedList<>(P1touched); // this constructor will copy list
  142. } else {
  143. consideredTouches = new LinkedList<>(P2touched);
  144. }
  145.  
  146. boolean madeMove = false;
  147. for (int i = 0; i < n; i++) {
  148. // if stack touched, skip
  149. if (consideredTouches.get(i) == Boolean.TRUE) {
  150. continue;
  151. }
  152.  
  153. LinkedList<Integer> takes = possibleTakes(i);
  154.  
  155. // many lines were duplicated and i have removed them
  156. // for each stack player can interact with, generate branch for each possible amount taken
  157. for (Integer takevalue : takes) {
  158. LinkedList<Boolean> newTouchP1 = new LinkedList<>(P1touched);
  159. LinkedList<Boolean> newTouchP2 = new LinkedList<>(P2touched);
  160. LinkedList<Integer> newCoin = new LinkedList<>(coins);
  161. newCoin.set(i, newCoin.get(i) - takevalue);
  162. int newP1 = P1;
  163. int newP2 = P2;
  164. madeMove = true;
  165.  
  166. if (currMove.equals("P1")) {
  167. newTouchP1.set(i, Boolean.TRUE);
  168. newP1 += takevalue;
  169. } else {
  170. newTouchP2.set(i, Boolean.TRUE);
  171. newP2 += takevalue;
  172. }
  173. result.add(new Gamestate(newP1, newP2, nextMove, takevalue, newTouchP1, newTouchP2, newCoin));
  174. }
  175. }
  176.  
  177. // if moves couldn't be generated for current player, check if there exist any valid moves
  178. if (!madeMove) {
  179. boolean gameOver = true;
  180. for (int i = 0; i < coins.size(); i++) {
  181. if (coins.get(i) != 0 && (!P1touched.get(i) || !P2touched.get(i))) {
  182. gameOver = false;
  183. break;
  184. }
  185. }
  186. if (!gameOver) {
  187. result.add(new Gamestate(P1, P2, nextMove, lastTaken,
  188. new LinkedList<>(P1touched), new LinkedList<>(P2touched), new LinkedList<>(coins)));
  189. }
  190. }
  191. addSubstates(result);
  192. }
  193.  
  194. void makeTree() {
  195. genPossibleSubstates();
  196. for (Gamestate gamestate : next) {
  197. gamestate.makeTree();
  198. }
  199. }
  200. }
  201.  
  202. // there can be only one public class in java file and it has to match filename
  203. //public class Coins {
  204. // public static void main(String[] args) {
  205. // LinkedList<Integer> coins;
  206. // Gamestate gameTree;
  207. // Gamestate result;
  208. //
  209. // // ========================
  210. // coins = new LinkedList<>();
  211. // coins.add(2);
  212. // coins.add(2);
  213. // coins.add(2); // it would look better as an array instead of list but in Python everything is list so i made it that way
  214. // gameTree = new Gamestate(coins);
  215. // gameTree.makeTree();
  216. // result = Gamestate.minmaxTree(gameTree);
  217. //
  218. // System.out.println(Gamestate.strFromTree(gameTree, 0));
  219. //
  220. // System.out.println("===========");
  221. // System.out.println("game: " + coins.toString());
  222. // System.out.println("minmax game outcome:");
  223. // System.out.println(result.toString());
  224. // System.out.println("----------");
  225. //
  226. // // ========================
  227. // coins = new LinkedList<>();
  228. // coins.add(3);
  229. // coins.add(3);
  230. // coins.add(3);
  231. // gameTree = new Gamestate(coins);
  232. // gameTree.makeTree();
  233. //
  234. // result = Gamestate.minmaxTree(gameTree);
  235. //
  236. // System.out.println("===========");
  237. // System.out.println("game: " + coins.toString());
  238. // System.out.println("minmax game outcome:");
  239. // System.out.println(result.toString());
  240. // System.out.println("----------");
  241. //
  242. // // ========================
  243. // coins = new LinkedList<>();
  244. // coins.add(1);
  245. // coins.add(2);
  246. // coins.add(6);
  247. // gameTree = new Gamestate(coins);
  248. // gameTree.makeTree();
  249. //
  250. // result = Gamestate.minmaxTree(gameTree);
  251. //
  252. // System.out.println("===========");
  253. // System.out.println("game: " + coins.toString());
  254. // System.out.println("minmax game outcome:");
  255. // System.out.println(result.toString());
  256. // System.out.println("----------");
  257. // }
  258. //}
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement