Advertisement
Guest User

Untitled

a guest
Nov 17th, 2019
120
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.94 KB | None | 0 0
  1. # -*- coding: utf-8 -*-
  2. """
  3. Created on Wed Nov 6 09:02:28 2019
  4.  
  5. @author: Gloomy
  6. """
  7.  
  8.  
  9. class Gamestate:
  10. def __init__(self, P1, P2, turn, lastTaken, P1touched, P2touched, coins, parent):
  11. # P1: current score of P1
  12. # P2: current score of P2
  13. # lastTaken: amount of coins taken during last move
  14. # P1touched: boolean list, which stacks has P1 interacted with
  15. # P2touched: boolean list, which stacks has P2 interacted with
  16. # coins: integer list of coins left on stacks
  17. # turn: either "P1" or "P2"
  18. # next: list of Gamestates
  19.  
  20. self.P1 = P1
  21. self.P2 = P2
  22. self.lastTaken = lastTaken
  23. self.P1touched = P1touched
  24. self.P2touched = P2touched
  25. self.coins = coins
  26. self.turn = turn
  27. self.next = []
  28.  
  29.  
  30. def nextTurn(self):
  31. if self.turn == "P1":
  32. return "P2"
  33. else:
  34. return "P1"
  35.  
  36. # return list with possible amounts of coins to take from given stack
  37. def possibleTakes(self, stack_num):
  38. if self.coins[stack_num] == 0:
  39. return []
  40. if self.lastTaken == 0 and self.coins[stack_num] >= 1:
  41. return [1]
  42. result = []
  43. j = 1
  44. while j <= self.coins[stack_num] and j <= self.lastTaken * 2:
  45. result.append(j)
  46. j += 1
  47. return result
  48.  
  49. def addSubstates(self, substates):
  50. self.next = self.next + substates
  51.  
  52. # creates all valid moves
  53. def genPossibleSubstates(self):
  54. result = []
  55. n = len(self.coins)
  56. currMove = self.turn
  57. nextMove = self.nextTurn()
  58.  
  59. # consider which stacks can current player interact with
  60. if currMove == "P1":
  61. consideredTouches = self.P1touched
  62. else:
  63. consideredTouches = self.P2touched
  64.  
  65. madeMove = False
  66. for i in range(n):
  67. # if stack touched, skip
  68. if consideredTouches[i] == True:
  69. continue
  70.  
  71. takes = self.possibleTakes(i)
  72.  
  73. # for each stack player can interact with, generate branch for each possible amount taken
  74. for takevalue in takes:
  75. if currMove == "P1":
  76. newTouchP1 = self.P1touched.copy()
  77. newTouchP1[i] = True
  78.  
  79. newTouchP2 = self.P2touched.copy()
  80.  
  81. newCoin = self.coins.copy()
  82. newCoin[i] -= takevalue
  83.  
  84. newP1 = self.P1 + takevalue
  85.  
  86. result.append(Gamestate(newP1, self.P2, nextMove, takevalue, newTouchP1, newTouchP2, newCoin, self))
  87. madeMove = True
  88. else:
  89. newTouchP1 = self.P1touched.copy()
  90.  
  91. newTouchP2 = self.P2touched.copy()
  92. newTouchP2[i] = True
  93.  
  94. newCoin = self.coins.copy()
  95. newCoin[i] -= takevalue
  96.  
  97. newP2 = self.P2 + takevalue
  98.  
  99. result.append(Gamestate(self.P1, newP2, nextMove, takevalue, newTouchP1, newTouchP2, newCoin, self))
  100. madeMove = True
  101.  
  102. # if moves couldn't be generated for current player, check if there exist any valid moves
  103. if not madeMove:
  104.  
  105. gameOver = True
  106.  
  107. for i in range(len(self.coins)):
  108. if self.coins[i] != 0 and (self.P1touched[i] == False or self.P2touched[i] == False):
  109. gameOver = False
  110. break
  111. if not gameOver:
  112. result.append(
  113. Gamestate(self.P1, self.P2, nextMove, self.lastTaken, self.P1touched.copy(), self.P2touched.copy(),
  114. self.coins.copy(), self))
  115. self.addSubstates(result)
  116.  
  117. def makeTree(self):
  118. self.genPossibleSubstates()
  119. for state in self.next:
  120. state.makeTree()
  121.  
  122. def __repr__(self):
  123. return "P1:{0}, P2:{1}, coins{2}".format(self.P1, self.P2, self.coins)
  124.  
  125.  
  126.  
  127. # creates initial game start node
  128. def makeInitState(coins):
  129. P1touched = []
  130. P2touched = []
  131. for i in range(len(coins)):
  132. P1touched.append(False)
  133. P2touched.append(False)
  134. return Gamestate(0, 0, "P1", 0, P1touched, P2touched, coins, None)
  135.  
  136.  
  137. def minmaxTree(tree: Gamestate):
  138. # if leaf, return self
  139. if len(tree.next) == 0:
  140. return tree
  141. # if not leaf, agregate minmaxTree results from all possible moves
  142. choices = []
  143. for move in tree.next:
  144. choices = choices + [minmaxTree(move)]
  145.  
  146. # if P1 choose best minmax for P1 from choices
  147. if tree.turn == "P1":
  148. result = max(choices, key=(lambda x: x.P1 - x.P2))
  149. # if P2 choose worst minmax for P1 from choices
  150. else:
  151. result = min(choices, key=(lambda x: x.P1 - x.P2))
  152.  
  153. return result
  154.  
  155.  
  156. # turns whole tree into string with indents
  157. def strFromTree(tree: Gamestate, depth):
  158. s = ""
  159. for i in range(depth):
  160. s = s + " "
  161. s = s + str(tree) + "\n"
  162. for subtree in tree.next:
  163. s = s + strFromTree(subtree, depth + 1)
  164.  
  165. return s
  166.  
  167.  
  168. # ========================
  169. coins = [2, 2, 2]
  170. gameTree = makeInitState(coins)
  171. gameTree.makeTree()
  172.  
  173. result = minmaxTree(gameTree)
  174.  
  175. # print(strFromTree(gameTree,0))
  176.  
  177. print("===========")
  178. print("game: {0}".format(coins))
  179. print("minmax game outcome:")
  180. print(str(result))
  181. print("----------")
  182.  
  183. # ========================
  184. coins = [3, 3, 3]
  185. gameTree = makeInitState(coins)
  186. gameTree.makeTree()
  187.  
  188. result = minmaxTree(gameTree)
  189.  
  190. print("===========")
  191. print("game: {0}".format(coins))
  192. print("minmax game outcome:")
  193. print(str(result))
  194. print("----------")
  195.  
  196. # ========================
  197. coins = [1, 2, 6]
  198. gameTree = makeInitState(coins)
  199. gameTree.makeTree()
  200.  
  201. result = minmaxTree(gameTree)
  202.  
  203. print("===========")
  204. print("game: {0}".format(coins))
  205. print("minmax game outcome:")
  206. print(str(result))
  207. print("----------")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement