Advertisement
RokettoJanpu

Tic Tac Toe Game Constructor

May 10th, 2019
228
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.54 KB | None | 0 0
  1. class Game:
  2.     def __init__(self, boardSize):
  3.         self.boardSize = boardSize  # Holds the size of the board
  4.         self.marks = np.empty((boardSize, boardSize),dtype='str')  # Holds the mark for each position
  5.         self.marks[:,:] = ' '
  6.    
  7.     # Prints the game board using current marks
  8.     def printBoard(self):
  9.         # Prthe column numbers
  10.         print(' ',end='')
  11.         for j in range(self.boardSize):
  12.             print(" "+str(j+1), end='')
  13.        
  14.        
  15.         # Prthe rows with marks
  16.         print("")
  17.         for i in range(self.boardSize):
  18.             # Prthe line separating the row
  19.             print(" ",end='')
  20.             for j in range(self.boardSize):
  21.                 print("--",end='')
  22.            
  23.             print("-")
  24.  
  25.             # Prthe row number
  26.             print(i+1,end='')
  27.            
  28.             # Prthe marks on self row
  29.             for j in range(self.boardSize):
  30.                 print("|"+self.marks[i][j],end='')
  31.            
  32.             print("|")
  33.                
  34.        
  35.         # Prthe line separating the last row
  36.         print(" ",end='')
  37.         for j in range(self.boardSize):
  38.             print("--",end='')
  39.        
  40.         print("-")
  41.    
  42.     # Attempts to make a move given the row,col and mark
  43.     # If move cannot be made, returns False and prints a message if mark is 'X'
  44.     # Otherwise, returns True
  45.     def makeMove(self, row, col, mark):
  46.         if(0<=row<self.boardSize and 0<=col<self.boardSize and self.marks[row][col] == ' '):
  47.             self.marks[row][col] = mark
  48.             return True
  49.         else:
  50.             return False
  51.     def checkWin(self, mark):
  52.         for i in range(self.boardSize):
  53.             hasWon = True
  54.             for j in range(self.boardSize):
  55.                 if(self.marks[i][j] != mark):
  56.                     hasWon = False
  57.             if(hasWon):
  58.                 return True
  59.             hasWon = True
  60.             for j in range(self.boardSize):
  61.                 if(self.marks[j][i] != mark):
  62.                     hasWon = False
  63.             if(hasWon):
  64.                 return True
  65.         hasWon = True
  66.         for i in range(self.boardSize):
  67.                
  68.                 if self.marks[i][i] != mark:
  69.                     hasWon = False
  70.         if(hasWon):
  71.             return True
  72.         hasWon = True
  73.         for i in range(self.boardSize):
  74.  
  75.                 if(self.marks[self.boardSize-1-i][i] != mark):
  76.                     hasWon = False
  77.         if(hasWon):
  78.             return True
  79.     def noMoreMoves(self):
  80.         return not(game.marks == ' ').any()
  81.    
  82.     # This method should run minimax to determine the value of each move
  83.     # Then make best move for the computer by placing the mark in the best spot
  84.     def makeCompMove(self):
  85.         # Depth limit of 5
  86.         v, best_action = self.max_value(5)
  87.         (row,col)=best_action
  88.         self.makeMove(row, col, 'O')
  89.        
  90.     # return utility to computer player
  91.     def utility(self):
  92.         if self.checkWin('O'):
  93.             return 1000
  94.         elif self.checkWin('X'):
  95.             return -1000
  96.         #simplified version for now:
  97.         else:
  98.             return 0
  99.        
  100.     #return possible moves
  101.     def possibleMoves(self):
  102.         possible=[]
  103.         for i in range(self.boardSize):
  104.             for j in range(self.boardSize):
  105.                 if (self.marks[i][j]==' '):
  106.                     possible.append((i,j))
  107.         return possible
  108.    
  109.     def max_value(self, depth):
  110.         # if current board is in game ending state, return the utility to computer player
  111.         if self.checkWin('O'):
  112.             return 999, None
  113.         elif self.checkWin('X'):
  114.             return -999, None
  115.         elif self.noMoreMoves():
  116.             return 0,None
  117.         if depth<0:
  118.             return self.utility(), None
  119.  
  120.         v = -math.inf
  121.         best_action = None
  122.         # go through all possible marks that can be made (i.e. move = possible coordinate of mark)
  123.         for (row,col) in self.possibleMoves():
  124.             #It’s easiest to use the backtracking method. That is, instead of generating
  125.             #hypothetical states, just apply the moves to the game board,
  126.             #compute the utility, and then backtrack the move. This requires
  127.             #that you save the current board configuration before trying each move,
  128.             #so you can backtrack it later
  129.  
  130.             #save current board
  131.             savedboard=self.marks.copy()
  132.            
  133.             # make current move (mark) on board
  134.             self.makeMove(row, col, 'O')
  135.            
  136.             min_val, act = self.min_value(depth-1)
  137.             if (min_val > v):
  138.                 v = min_val
  139.                 best_action = (row,col)
  140.                
  141.             # backtrack to prior state: make ' ' mark at same coordinate
  142.             self.marks=savedboard
  143.    
  144.         return v, best_action
  145.                
  146.     def min_value(self, alpha, beta, depth):
  147.         # if current board is in game ending state, return the utility to computer player
  148.         if self.checkWin('O'):
  149.             return 999, None
  150.         elif self.checkWin('X'):
  151.             return -999, None
  152.         elif self.noMoreMoves():
  153.             return 0,None
  154.         if depth<0:
  155.             return self.utility(), None
  156.  
  157.  
  158.         v = math.inf
  159.         best_action = None
  160.         # go through all possible marks that can be made (i.e. move = possible coordinate of mark)
  161.         for (row,col) in self.possibleMoves():
  162.             #It’s easiest to use the backtracking method. That is, instead of generating
  163.             #hypothetical states, just apply the moves to the game board,
  164.             #compute the utility, and then backtrack the move. This requires
  165.             #that you save the current board configuration before trying each move,
  166.             #so you can backtrack it later
  167.  
  168.             #save current board
  169.             savedboard=self.marks.copy()
  170.            
  171.             # make current move (mark) on board
  172.             self.makeMove(row, col, 'X')
  173.            
  174.             # update alpha beta
  175.             max_val, act = self.max_value(alpha, beta,depth-1)
  176.             if (max_val < v):
  177.                 v = max_val
  178.                 best_action = (row,col)
  179.            
  180.             # backtrack to prior state: make ' ' mark at same coordinate
  181.             self.marks=savedboard
  182.  
  183.             # break early
  184.             if v <= alpha:
  185.                 return v, best_action
  186.                
  187.             beta = min(beta, v)
  188.            
  189.         return v, best_action
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement