Advertisement
Guest User

Untitled

a guest
Mar 29th, 2020
108
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.97 KB | None | 0 0
  1. def minmax_decision(state):
  2.     def max_value(state):
  3.         if is_terminal(state):
  4.             return utility_of(state)
  5.         v = -infinity
  6.         for (a, s) in successors_of(state):
  7.             v = max(v, min_value(s))
  8.         print('V: ' + str(v))
  9.         return v
  10.  
  11.     def min_value(state):
  12.         if is_terminal(state):
  13.             return utility_of(state)
  14.         v = infinity
  15.         for (a, s) in successors_of(state):
  16.             v = min(v, max_value(s))
  17.         return v
  18.  
  19.     infinity = float('inf')
  20.     action, state = argmax(successors_of(state), lambda a: min_value(a[1]))
  21.     return action
  22.  
  23.  
  24. def is_terminal(state):
  25.     no_options = True
  26.     for entry in state:
  27.         if entry > 2:  # hvis bunken er større end 2, kan man stadig dele bunken.
  28.             no_options = False
  29.             break
  30.  
  31.     if no_options:
  32.         return True
  33.  
  34.     utility = utility_of(state)
  35.     if utility == 0 or utility == 1:
  36.         return True
  37.     else:
  38.         return False
  39.  
  40.  
  41. def utility_of(state):
  42.     '''
  43.   Checks who wins. if 0 min if 1 max
  44.   the check works, because we are sorting the state space to have the biggest number first.
  45.   If the first number in the state space is two, we cannot split the pile anymore.
  46.  
  47.   If the entry is 2 and modulo is 1, we are on a minimum level,
  48.   minimum cannot divide the piles anymore, and max wins.
  49.   '''
  50.     for entry in state:
  51.         if state[0] == 2 and len(state) % 2 == 1:
  52.             return 1
  53.         elif state[0] == 2 and len(state) % 2 == 0:
  54.             return 0
  55.  
  56.     return -1
  57.  
  58.  
  59. def successors_of(state):
  60.     """
  61.   The successor seems to create the correct tree
  62.   """
  63.  
  64.     # Generate valid moves
  65.     valid_moves = []
  66.     for i in range(len(state)):
  67.         if state[i] == 1 or state[i] == 2:
  68.             continue
  69.         count = 1
  70.         while count < state[i] / 2:
  71.             new_state = state.copy()
  72.             new_state[i] = new_state[i] - count
  73.             new_state.append(count)
  74.             new_state.sort(reverse=True)
  75.             valid_moves.append((count, new_state))
  76.             count += 1
  77.  
  78.     print(valid_moves)
  79.  
  80.     return valid_moves
  81.  
  82.  
  83. def display(state):
  84.     print("-----")
  85.     print(state)
  86.     '''
  87.   for c in [0, 3, 6]:
  88.       print(state[c + 0], state[c + 1], state[c + 2])
  89.   '''
  90.  
  91.  
  92. def main():
  93.     board = [15]
  94.     while not is_terminal(board):
  95.         board = user_select_pile(board)
  96.         if not is_terminal(board):
  97.             display(board)
  98.             board = computer_select_pile(board)
  99.     print("    Final state is {}".format(board))
  100.  
  101.  
  102. def argmax(iterable, func):
  103.     return max(iterable, key=func)
  104.  
  105.  
  106. def computer_select_pile(state):
  107.     new_state = minmax_decision(state)
  108.     return new_state
  109.  
  110.  
  111. def user_select_pile(list_of_piles):
  112.     '''
  113.    Given a list of piles, asks the user to select a pile and then a split.
  114.    Then returns the new list of piles.
  115.    '''
  116.     print("\n    Current piles: {}".format(list_of_piles))
  117.  
  118.     i = -1
  119.     while i < 0 or i >= len(list_of_piles) or list_of_piles[i] < 3:
  120.         print("Which pile (from 1 to {}, must be > 2)?".format(len(list_of_piles)))
  121.         i = -1 + int(input())
  122.  
  123.     print("Selected pile {}".format(list_of_piles[i]))
  124.  
  125.     max_split = list_of_piles[i] - 1
  126.  
  127.     j = 0
  128.     while j < 1 or j > max_split or j == list_of_piles[i] - j:
  129.         if list_of_piles[i] % 2 == 0:
  130.             print(
  131.                 'How much is the first split (from 1 to {}, but not {})?'.format(
  132.                     max_split,
  133.                     list_of_piles[i] // 2
  134.                 )
  135.             )
  136.         else:
  137.             print(
  138.                 'How much is the first split (from 1 to {})?'.format(max_split)
  139.             )
  140.         j = int(input())
  141.  
  142.     k = list_of_piles[i] - j
  143.  
  144.     new_list_of_piles = list_of_piles[:i] + [j, k] + list_of_piles[i + 1:]
  145.  
  146.     print("    New piles: {}".format(new_list_of_piles))
  147.  
  148.     return new_list_of_piles
  149.  
  150.  
  151. if __name__ == '__main__':
  152.     main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement