Assigned Date: Friday, Apr. 17, 2015
Due Date: Friday, May 1, 2015
Due Time: 12:20pm
Last modified on April 28, 2015, at 07:56 PM (see updates)
Write a program that simulates a game of Tic-Tac-Toe. In our version of the game, two players, human and computer, play in turns, placing X's and O's, respectively, on the 3x3 square board. The human player always goes first. The game goes on until either there is a winner (3 X's or 3 O's in a vertical, horizontal, or diagonal line), or the game is a draw (all squares are occupied and no one has won).
The program should create a GUI display with the Tic-Tac-Toe board (via the GUI library) and update it after each move., e.g.,
The human player always goes first. The program should be as robust as possible. When the game is over it should output a message describing the outcome.
This is a solo assignment (you must work alone).
input() to get the human move (1-9). If the user makes a mistake (i.e., selects a non-empty or an out-of-range (1-9) square), they should be prompted again (and again) until they get it right. Every proper human move you should update the board (by placing an 'X' at the corresponding square).
Each proper human move should be followed by the computer move (e.g., "Computer moves to square 3!" - shown on a label on the display), which should also update the board (by placing an 'O' at the corresponding square).
When a player wins, a colored line (thick enough) should show the winning combination.
Also, when the game is over, a "Game Over" label (or icon) should appear.
To simplify testing, for now, the computer should choose the next available (non-empty) square starting from 1. Also, print (via print statement) each player and move made, and the outcome of the game.
Soon we will use some Artificial Intelligence (AI) code to make the game more interesting.
Your program should consist of the following classes:
Board– this class encapsulates the game board
__init__()- builds a board of nine squares
clear()– initializes the board to empty squares
positionis an integer - returns the corresponding square's value as a string (i.e., "X", "O", or " ")
setSquare(position, value), where
positionis an integer and
valueis a string
isEmpty()- returns True or False indicating if the board is empty or not
isFull()- returns True or False indicating if the board is full or not
isWin()- returns True or False indicating if the board contains a wining configuration (either player)
Square– this class encapsulates a single square
__init__()- builds an empty square
getValue()- returns the square value as a string (i.e., "X", "O", or " ")
setValue(value)- sets the square contents, where
valueis a string (i.e., "X", "O", or " ")
__repr__()- returns a string representation of a square (its contents as a single character - a string)
HumanPlayer– encapsulates the human player
__init__()- initializes a human player
getMove(board)- returns the move selected by the human - for now, in order to simplify things, use
input()to get the move (1-9). If the user makes a mistake, they should be prompted again (and again) until they get it right.
ComputerPlayer– encapsulates the computer player
__init__()- initializes a computer player
getMove(board)- returns the move selected by the computer - for now, in order to simplify things, pick the next empty square (starting from 1).
playTicTacToe()– this function declares instances of above classes and uses their functions to implement the game
The user should be able to click on the square they wish to play. (Hint: There are different ways to make this happen - think before you code!)
Modify the above design (maintaining classes
Square) so that the input to the program is the human player's moves - one at a time - capturing a mouse click on the board. If the user makes mistakes (i.e., clicks outside of a free/available square), you should ignore it. Every proper human move you should update the board (by placing an 'X' at the corresponding square).
In general, you should comment any class, function, variable, obscure statement, block of code, etc. you create. Functions should be documented using Python docstrings.
Your comments should reflect the "what" something does, as opposed to the "how" it does it. The "how" is reflected in the code. The "what" usually comes from the thought you had, as to what you need to do, before you wrote the corresponding Python code.
So, since that info is in your head first (i.e., before you write the code), it is much easier to type it in your program (before you figure out the corresponding code that does what needs to be done).
Conversely, once you have already written the code, it is very hard to go back and recreate the original thought (thus comments written after the code tend to focus on the "how" something is being done, and not the "why" - the latter being what we need.)
The goal of comments is to gently introduce someone accurately into the big picture of our code - the forest view - while the code itself represents the tree view.
Additionally, your code should always have header documentation that explains what the program does, in general terms.
Follow the documentation instructions from Homework 1.
You will submit your assignment via OAKS. Your submission consists of:
Your grade will be based on how well you followed the above instructions.