Short Exercises #4¶
Due: Sunday, Nov 8 at 3pm CST
The following short exercises are intended to help you practice some of the programming concepts introduced in the first four weeks of the quarter. These exercises should not take more than 1-2 hours in total to complete.
Tic-tac-toe (also known as “noughts and crosses” or “Xs and Os”) is a game for two players who take turns marking cells in a 3 by 3 grid. One player marks cells with an “X” and the other marks cells with an “O”. The first player who places three marks in a row horiztonally, vertially, or diagonally is the winner. You can read more about tic-tac-toe here or play a few games against Google here.
In the following exercises, you will complete the implementation of a two player
terminal-based tic-tac-toe game. We have provided a Player
class which encapsulates
information about a tic-tac-toe player and a Game
class which runs the game.
You will implement a Board
class, which Game
utilizes.
Our game runs from the command line. The first two turns will look like this:
$ python3 se4.py
Ready to play tic-tac-toe?
Player 1: Enter your name and pick your symbol: C-3PO X
Player 2: Enter your name and pick your symbol: R2-D2 O
Enter your move C-3PO: 1 2
| | | |
--+-+--
| | |X|
--+-+--
| | | |
Enter your move R2-D2: 2 0
| | | |
--+-+--
| | |X|
--+-+--
|O| | |
The Player
class encapsulates information about a
tic-tac-toe player and has the the following attributes.
name
(string): the name of the playersymbol
(string): the player’s one character symbol
In [1]: from se4 import Player
In [2]: p1 = Player("C-3PO", "X")
In [3]: p1.name
Out[3]: 'C-3PO'
In [4]: p1.symbol
Out[4]: 'X'
In [5]: p2 = Player("R2-D2", "O")
In [5]: p2.name
Out[5]: 'R2-D2'
In [6]: p2.symbol
Out[6]: 'O'
The Game
class starts the game, repeately asks players for their next
move, and plays each move in turn. Please read through the Game
class.
It is okay if you don’t understand every detail, but reading the code will help
you understand how Game
interacts with Player
and Board
.
We will make the following simplifying assumptions for our game:
A player’s name contains no spaces.
A player’s symbol is a one character string (“X” or “O”).
During a turn, a player will enter two integers in (row then column) to indicate which cell on the board they want to mark.
Exercises¶
The Board
class encapsulates information about the 3 by 3
tic-tac-toe board and contains methods for interacting with the
board. In these exercises, you will implement the Board
class.
Important: The Game
class and our tests access attributes and
call methods of your Board
class. Therefore, it is very important that you follow
the attribute names and method parameter order exactly as shown below.
Magic numbers: Near the top of se4.py
, you will see the global constant
SIZE = 3
. You should use this constant in your implementation to avoid the use
of the “magic number” 3 throughout your code. We’ve used it in Game
, too.
Implement a
Board
class with the following attribute.board
(list of list of string): the 3 by 3 tic-tac-toe board
We will represent the board as a nested list of strings where each element is a one character string (
" "
,"X"
, or"O"
). Upon construction, the board should be empty. We will use a blank space (" "
) to indicate an empty cell.In [7]: from se4 import Board In [8]: b1 = Board() In [9]: len(b1.board) # Number of rows Out[9]: 3 In [10]: len(b1.board[0]) # Number of columns Out[10]: 3 In [11]: b1.board[0][0] Out[11]: ' '
Implement the
__repr__
method.__repr__
should return a useful string representation of the board. The design is up to you, it does not need to match ours.In [12]: b1 Out[12]: | | | | --+-+-- | | | | --+-+-- | | | |
Implement the method
valid_move
, which takes two integer parametersrow
andcol
and returnsTrue
if the move is valid, andFalse
otherwise. Recally that during a turn, a player will enter two integers to indicate which cell they want to mark. A move to any unoccupied cell on the board is valid.In [18]: b1 Out[18]: | | | | --+-+-- | |X|O| --+-+-- | | | | In [19]: b1.valid_move(1, 1) Out[19]: False In [20]: b1.valid_move(1, 2) Out[20]: False In [21]: b1.valid_move(1, 4) Out[21]: False In [22]: b1.valid_move(-1, 0) Out[22]: False In [23]: b1.valid_move(0, 0) Out[23]: True In [24]: b1.valid_move(0, 1) Out[24]: True
Implement the method
move
, which takes the following three parameters.row
(int): rowcol
(int): columnplayer
(Player): the player who is moving
move
updates the board at the indicated location with the player’s symbol. You can assume that this method is only called when the move is valid.In [25]: b1 Out[25]: | | | | --+-+-- | |X|O| --+-+-- | | | | In [26]: b1.move(2, 2, p1) In [27]: b1 Out[27]: | | | | --+-+-- | |X|O| --+-+-- | | |X| In [28]: b1.move(0, 0, p2) In [29]: b1 Out[29]: |O| | | --+-+-- | |X|O| --+-+-- | | |X|
Implement the method
winner
, which takes aPlayer
object as a parameter and returnsTrue
if the player is a winner, andFalse
otherwise. A player wins tic-tac-toe if they place three marks in a row horiztonally, vertially, or diagonally.In [32]: p1.symbol Out[32]: 'X' In [33]: p2.symbol Out[33]: 'O' In [34]: b2 Out[34]: | |O|X| --+-+-- |O|X| | --+-+-- |X| |O| In [35]: b2.winner(p1) Out[35]: True In [36]: b2.winner(p2) Out[36]: False In [41]: b3 Out[41]: | |X|O| --+-+-- |X|X|X| --+-+-- |O|O|O| In [42]: b3.winner(p1) Out[42]: True In [43]: b3.winner(p2) Out[43]: True In [46]: b4 Out[46]: |X|O|X| --+-+-- |O|X|O| --+-+-- |O|X|O| In [47]: b4.winner(p1) Out[47]: False In [48]: b4.winner(p2) Out[48]: False
Testing and Submitting your Solutions¶
Like the previous short exercises, you will need to pull some instructor files to your repository, and then add your code to one of those files. You can find detailed instructions on how to do this in our Coursework Basics page. For instructions on how to test your code, please see our Testing Your Code.
Once you’ve completed the exercises, you must submit your work through Gradescope (linked from our Canvas site). In the “Short Exercises #4” assignment, simply upload the file se4.py
(do not upload any other file!). Please note:
You are allowed to make as many submissions as you want before the deadline.
There are no extensions for the short exercises. The two free extensions you get for the programming assignments cannot be applied towards the short exercises. Please note that, if you need an extension due to extraordinary circumstances, you should alert us via a private message on Piazza.
Your score on the short exercises is determined solely based on the automated tests, but we may adjust your score if you attempt to pass tests by rote (e.g., by writing code that hard-codes the expected output for each possible test input).
Gradescope will report the test score it obtains when running your code. If there is a discrepancy between the score you get when running our grader script, and the score reported by Gradescope, please let us know so we can take a look at it.