Advertisement
Guest User

Monte Carlo Search Tree Tic-Tac-Toe In Python

a guest
Aug 16th, 2020
3,684
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.85 KB | None | 0 0
  1. ### The Monte Carlo Search Tree AI
  2.  
  3. ### 1 - It takes the current game state
  4.  
  5. ### 2 - It runs multiple random game simulations starting from this game state
  6.  
  7. ### 3 - For each simulation, the final state is evaluated by a score (higher score = better outcome)
  8.  
  9. ### 4 - It only remembers the next move of each simulation and accumulates the scores for that move
  10.  
  11. ### 5 - Finally, it returns the next move with the highest score
  12.  
  13. import random
  14. import ast
  15.  
  16. userPlayer = 'O'
  17. boardSize = 3
  18. numberOfSimulations = 200
  19.  
  20. board = [
  21.     list('...'),
  22.     list('...'),
  23.     list('...')
  24. ]
  25.  
  26. startingPlayer = 'X'
  27. currentPlayer = startingPlayer
  28.  
  29. def getBoardCopy(board):
  30.     boardCopy = []
  31.    
  32.     for row in board:
  33.         boardCopy.append( row.copy() )
  34.    
  35.     return boardCopy
  36.  
  37. def hasMovesLeft(board):
  38.     for y in range(boardSize):
  39.         for x in range(boardSize):
  40.             if board[y][x] == '.':
  41.                 return True
  42.    
  43.     return False
  44.  
  45. def getNextMoves(currentBoard, player):
  46.     nextMoves = []
  47.    
  48.     for y in range(boardSize):
  49.         for x in range(boardSize):
  50.             if currentBoard[y][x] == '.':
  51.                 boardCopy = getBoardCopy(currentBoard)
  52.                 boardCopy[y][x] = player
  53.                 nextMoves.append(boardCopy)
  54.    
  55.     return nextMoves
  56.  
  57. def hasWon(currentBoard, player):
  58.     winningSet = [player for _ in range(boardSize)]
  59.    
  60.     for row in currentBoard:
  61.         if row == winningSet:
  62.             return True
  63.    
  64.     for y in range(len(currentBoard)):
  65.         column = [currentBoard[index][y] for index in range(boardSize)]
  66.        
  67.         if column == winningSet:
  68.             return True
  69.    
  70.     diagonal1 = []
  71.     diagonal2 = []
  72.     for index in range(len(currentBoard)):
  73.         diagonal1.append(currentBoard[index][index])
  74.         diagonal2.append(currentBoard[index][boardSize - index - 1])
  75.    
  76.     if diagonal1 == winningSet or diagonal2 == winningSet:
  77.         return True
  78.    
  79.     return False
  80.  
  81. def getNextPlayer(currentPlayer):
  82.     if currentPlayer == 'X':
  83.         return 'O'
  84.    
  85.     return 'X'
  86.  
  87. def getBestNextMove(currentBoard, currentPlayer):
  88.     evaluations = {}
  89.    
  90.     for generation in range(numberOfSimulations):
  91.         player = currentPlayer
  92.         boardCopy = getBoardCopy(currentBoard)
  93.        
  94.         simulationMoves = []
  95.         nextMoves = getNextMoves(boardCopy, player)
  96.        
  97.         score = boardSize * boardSize
  98.        
  99.         while nextMoves != []:
  100.             roll = random.randint(1, len(nextMoves)) - 1
  101.             boardCopy = nextMoves[roll]
  102.            
  103.             simulationMoves.append(boardCopy)
  104.            
  105.             if hasWon(boardCopy, player):
  106.                 break
  107.            
  108.             score -= 1
  109.            
  110.             player = getNextPlayer(player)
  111.             nextMoves = getNextMoves(boardCopy, player)
  112.        
  113.         firstMove = simulationMoves[0]
  114.         lastMove = simulationMoves[-1]
  115.        
  116.         firstMoveKey = repr(firstMove)
  117.        
  118.         if player == userPlayer and hasWon(boardCopy, player):
  119.             score *= -1
  120.        
  121.         if firstMoveKey in evaluations:
  122.             evaluations[firstMoveKey] += score
  123.         else:
  124.             evaluations[firstMoveKey] = score
  125.    
  126.     bestMove = []
  127.     highestScore = 0
  128.     firstRound = True
  129.    
  130.     for move, score in evaluations.items():
  131.         if firstRound or score > highestScore:
  132.             highestScore = score
  133.             bestMove = ast.literal_eval(move)
  134.             firstRound = False
  135.    
  136.     return bestMove
  137.  
  138. def printBoard(board):
  139.     firstRow = True
  140.    
  141.     for index in range(boardSize):
  142.         if firstRow:
  143.             print('  012')
  144.             firstRow = False
  145.            
  146.         print( str(index) + ' ' + ''.join(board[index]) )
  147.  
  148. def getPlayerMove(board, currentPlayer):
  149.     isMoveValid = False
  150.     while isMoveValid == False:
  151.         print('')
  152.         userMove = input('X,Y? ')
  153.         userX, userY = map(int, userMove.split(','))
  154.        
  155.         if board[userY][userX] == '.':
  156.             isMoveValid = True
  157.    
  158.     board[userY][userX] = currentPlayer
  159.     return board
  160.  
  161. printBoard(board)
  162.  
  163. while hasMovesLeft(board):
  164.     if currentPlayer == userPlayer:
  165.         board = getPlayerMove(board, currentPlayer)
  166.     else :
  167.         board = getBestNextMove(board, currentPlayer)
  168.    
  169.     print('')
  170.     printBoard(board)
  171.    
  172.     if hasWon(board, currentPlayer):
  173.         print('Player ' + currentPlayer + ' has won!')
  174.         break
  175.    
  176.     currentPlayer = getNextPlayer(currentPlayer)
  177.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement