#tic-tac-toe "TIC TAC TOE (an impossible game)"
********** files included ********** -board.py -tictactoe.py
****** HOW TO RUN THE PROGRAM ****** -Run tictactoe.py -choose a player and who goes first -play tictactoe
*********** tictactoe.py *********** This file is where the front-end is written for the GUI. For this, we used tkinter. We used the button feature of tkinter to make the board: We used 9 buttons in total, one for each node (move). Additional buttons were used: 'Quit', ends the game; and 'New Game' resets the board. We also used radio buttons for the user to choose the symbol it's gonna play with ("X" or "O") and who goes first (the user or the computer). Initially, the 9 buttons are disabled and will only be enabled once the player has chosen the options. While playing, the radio buttons are then disabled so that the user can't change it in the middle of the game.
****** board.py ****** this file is where the back-end of the program is written. In the Board class, the board is initialized by making a list with size 9. If it is printed (using __repr(self) ), it is printed in the terminal as follows: 0 | 1 | 2 3 | 4 | 5 6 | 7 | 8 The numbers 0-8 represents the node which are the moves available for the board. The functions for this class are (arguments are described in the comments in board.py): - check_win : checks if the player won - check_draw : checks if the generated temporary board** results a draw - check_full_draw: checks if the game results in a draw - is_empty : checks if the node is empty - empty_moves : returns a list of all empty nodes - move : places a move on the permanent board* - temp_move : places a move on the temorary board** - copy_temp : copies the contents of the permanent board to a buffer board - del_move : removes the content of a node in the board (only for temporary board**) - clearBoard : clears the permanent board - minimax : generates the next move by the computer (explained in a different section below)
- Permanent board is the board that is displayed on the GUI ** Temporary board is the board generated by the algorithm when it is in "thinking mode". The purpose of this is to not affect the permanent board when the program is trying to generate a move. This is also the board used when using the minimax function
THE MINIMAX ALGORITHM: This is the algorithm used to determine which move the computer should make. It is sort of a depth first search in a way that it checks one empty node, and then it checks all the possible outcomes of that node before switching to the next. Minimax works as follows:
- The input arguments are: . the node that was last played by the other player. . the current player
- helper functions: . getmaxscore : inputs a list of tuples: (node, score) then it returns the tuple with the highest score. This function is used in max_val . getminscore : inputs a list of tuples: (node, score) then it returns the tuple with the lowest score. This function is used in min_val . max_val : it inputs 6 arguments (explained in the comments in board.py). This function is for checking the highest score generated. The scoring is as follows: if the computer won, the score is 10 - depth (accounts for depth because the closer it is to the node, the better the move is); if the generated move results in a draw, the socre is 0 (only cheks this if the generated move is tha last one among the empty moves; if that move did not resut in a win, or the end of generating moves is not reached yet, it calls the min_val. this function returns the tuple with the best score that was obtained thuogh getmaxscore. . min_val : it inputs 6 arguments (explained in the comments in board.py). This function is for checking the lowest score generated. The scoring is as follows: if the user won, the score is depth - 10; if the generated move results in a draw, the socre is 0 (only cheks this if the generated move is tha last one among the empty moves; if that move did not resut in a win, or the end of generating moves is not reached yet, it calls the max_val. this function returns the tuple with the best score that was obtained thuogh getmaxscore.
essentially with minimax, it keeps make recursive calls and alternating between max_val and min_val depending on the currentplayer (max_val for the computer, min_val for the user). Since minimax is only called after the user makes its move, max_vals is called first.