import numpy as np import random class Brain(object): def __init__(self): self.inputLayerSize = 9 self.outputLayerSize = 1 self.hiddenLayerSize = 14 self.alpha = 0.05 self.W1 = np.random.randn(self.inputLayerSize, self.hiddenLayerSize) self.W2 = np.random.randn(self.hiddenLayerSize, self.outputLayerSize) self.winchance = 0 def forward(self, X): self.z2 = np.dot(X, self.W1) self.a2 = self.sigmoid(self.z2) print(self.a2.shape) self.z3 = np.dot(self.a2, self.W2) yhat = self.sigmoid(self.z3) return yhat def sigmoid(self, z): return 1/(1+np.exp(-z)) def possiblemoves(self, X): iX = np.full((9), 3) np.copyto(iX, X) possibilities = {} if playerturn == 2: iX[iX == 1] = 2 iX[iX == 0] = 1 iX[iX == 2] = 0 iX = iX.tolist() iterations = 1 for cell in range(0,len(iX)): if iX[cell] == 3: newmove = list(iX) newmove[cell] = 0 newmove = np.asarray(newmove) newwinchance = self.forward(newmove)[0] newmove = newmove.tolist() possibilities[iterations] = [newwinchance, newmove] iterations = iterations + 1 return possibilities def backpropogate(self): self.W1 = (self.alpha * (self.target - self.winchance) * self.winchance * (1 - self.winchance) * self.W2 * self.a2 * (1 - self.a2) * self.lastinput) + self.W2 self.W2 = (self.alpha * (self.target - self.winchance) * self.winchance * (1 - self.winchance) * self.a2) + self.W2 def initialize(): global gameboard gameboard = np.full((9), 3) def displayboard(): global gameboard boardisplay = np.full((9), 0).astype('object') np.copyto(boardisplay, gameboard) boardisplay[boardisplay == 3] = ' ' boardisplay[boardisplay == 1] = 'X' boardisplay[boardisplay == 0] = 'O' boardisplay = boardisplay.tolist() print(''' {} | {} | {} ---+---+--- {} | {} | {} ---+---+--- {} | {} | {} '''.format(*boardisplay)) def p1turn(): global playerturn global gameboard global firstturn playerbrain.target = playerbrain.forward(gameboard) if firstturn == 0: print('trying to backprop') playerbrain.backpropogate() print("backprop success!") playerbrain.lastinput = gameboard moves = playerbrain.possiblemoves(gameboard) gameboard = gameboard.tolist() bestmove = max(moves, key=moves.get) gameboard = moves[bestmove][1] print(gameboard) firstturn = 0 gameboard = np.asarray(gameboard) playerturn = 2 def p2turn(): global playerturn global gameboard gameboard = gameboard.tolist() rand = random.randint(0, 8) if gameboard[rand] == 3: gameboard[rand] = 1 gameboard = np.asarray(gameboard) playerturn = 1 else: gameboard = np.asarray(gameboard) def checkwin(): global gameboard checkboard = gameboard.reshape((3, 3)) if np.all(checkboard[0, :] == 1): return 2 elif np.all(checkboard[1, :] == 1): return 2 elif np.all(checkboard[2, :] == 1): return 2 elif np.all(checkboard[:, 0] == 1): return 2 elif np.all(checkboard[:, 1] == 1): return 2 elif np.all(checkboard[:, 2] == 1): return 2 elif np.all(np.diag(checkboard) == 1): return 2 elif np.all(np.diag(np.fliplr(checkboard)) == 1): return 2 elif np.all(checkboard[0, :] == 0): return 1 elif np.all(checkboard[1, :] == 0): return 1 elif np.all(checkboard[2, :] == 0): return 1 elif np.all(checkboard[:, 0] == 0): return 1 elif np.all(checkboard[:, 1] == 0): return 1 elif np.all(checkboard[:, 2] == 0): return 1 elif np.all(np.diag(checkboard) == 0): return 1 elif np.all(np.diag(np.fliplr(checkboard)) == 0): return 1 else: return 0 def gameloop(): global checkwn global firstturn global playerturn initialize() checkwn = 0 playerturn = 1 firstturn = 1 while checkwn == 0: if 3 in gameboard: if playerturn == 1: p1turn() checkwn = checkwin() elif playerturn == 2: p2turn() checkwn = checkwin() else: checkwn = 4 if checkwn == 4: playerbrain.target = 0 playerbrain.backpropogate() print("The game was a tie") elif checkwn == 1: playerbrain.target = 1 playerbrain.backpropogate() print("Player {} has won the game".format(checkwn)) else: print("Player {} has won the game".format(checkwn)) playerbrain = Brain() for x in range(1, 500): gameloop()