import os import sys import random import numpy as np class TicTacToe: def __init__(self, board_size): self.board_size = board_size # set the board size zeroList = [0 for _ in range(self.board_size)] self.board_matrix = [list(zeroList) for _ in range(self.board_size)] # generate a matrix for board and initialize as 0, 1 is for player 1 (Use X), 2 is for player 2(Use O). Here we use list copy, otherwise you will have trouble self.printBoard() # this function will load the board_matrix and print the board for current state def printBoard(self): print " ", for index in range(self.board_size): print " "+str(index)+" ", # print the index so it will be easier for player to pick location print "" for index in range(self.board_size): print " ", print(" --- " * self.board_size) # first print the horiz line print index, for col in range(self.board_size): symbol = " " # by default you use empty space if(self.board_matrix[index][col] == 1): symbol = "X" elif(self.board_matrix[index][col] == 2): symbol = "O" print "| "+symbol+" ", print("|") print(" --- " * self.board_size) # print the ending horiz line def verifyMove(self,move): try: x = (int)(move[0]) y = (int)(move[1]) if x >=0 and x < self.board_size and y>=0 and y < self.board_size and self.board_matrix[x][y]==0: return (x,y) else: return (-1,-1) except: return (-1,-1) def moveOneStep(self,movex,movey,current_player): #print self.board_matrix self.board_matrix[movex][movey] = current_player #print self.board_matrix """ This function will check row by row for player and return player number if any row has the same player value, otherwise return 0 """ def checkRow(self): npArray = np.rot90(np.array(self.board_matrix)) # rotate them, now it will be check row for row in range(len(npArray)): if npArray[row][0]!=0 and len(np.unique(npArray[row])) == 1: return npArray[row][0] # this is the value you want to return return 0 """ This function will check column by column for player and return player number if any column has the same player value, otherwise return 0 """ def checkColumn(self): npArray = np.array(self.board_matrix) # similar to checkrow, you just don't need to rotate it for row in range(len(npArray)): if npArray[row][0]!=0 and len(np.unique(npArray[row])) == 1: return npArray[row][0] # this is the value you want to return return 0 """ This function will check diagonal for player and return player number if the diagonal has the same player value, otherwise return 0 """ def checkDiagonal(self): dia = np.diagonal(np.array(self.board_matrix)) # first get the diagonal array if len(np.unique(dia)) == 1 and dia[0] != 0: # you get more than one element same as the first diagonal element return dia[0] dia2 = np.diagonal(np.rot90(np.array(self.board_matrix))) # second check another diagonal array if len(np.unique(dia2)) == 1 and dia2[0] != 0: # you get more than one element same as the first diagonal element return dia2[0] return 0 def checkWinner(self): checkMe = self.checkRow() if checkMe!=0: print("Win from the same row value in the board matrix") return checkMe checkMe = self.checkColumn() if checkMe!=0: print("Win from the same column value in the board matrix") return checkMe checkMe = self.checkDiagonal() if checkMe!=0: print("Win from the same diagonal in the board matrix") return checkMe if np.count_nonzero(np.array(self.board_matrix)) >= self.board_size * self.board_size: return 0 # a tier happens since it's full now return -1 # the game continue if __name__ == "__main__": try: board_size = int(input("What size of game board? ")) while(board_size < 1 or board_size > 50): print("The board size "+ board_size + "is not a good number, could you please try it again with number in [1,50]?") board_size = int(input("What size of game board? ")) except: print("Something happened, re-run the program, please make sure you put number for the size! ") sys.exit(0) mytictactoe = TicTacToe(board_size) print("now randomly select user 1 or user 2 to start the game ...") current_player = random.sample([1,2],1)[0] # random start print("player " + str(current_player) + " is randomly selected to start the game") while True: move = input(str(current_player)+": Please enter the x,y cooordinate (e.g, you could input 0,0 if you want to mark the top left block)\n") (movex,movey) = mytictactoe.verifyMove(move) # it's going to verify the movement, if it is not valid, it will return -1,-1, otherwise, it will return x and y cooordinate for that movement. while(movex == -1): move = input(str(current_player)+": Wrong input "+str(move)+" , please enter x,y again, make sure the block is empty and it should have a format like: 0,0\n") (movex,movey) = mytictactoe.verifyMove(move) mytictactoe.moveOneStep(movex,movey,current_player) mytictactoe.printBoard() # now print the new board current_player = 3 - current_player # switch the play now winner = mytictactoe.checkWinner() # this function will check the winnder: 0 means it filled out and a tie, -1 means game continue, 1 means winner is player 1, 2 means winner is player 2 if winner == 0: print "A tier happened, game finished, please try it again!" break elif winner == 1: print "Winner is Player 1 (Use X), congratulations!" break elif winner == 2: print "Winner is Player 2 (Use O), congratulations!" break