# 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 player`symbol`

(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 parameters`row`

and`col`

and returns`True`

if the move is valid, and`False`

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): row`col`

(int): column`player`

(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 a`Player`

object as a parameter and returns`True`

if the player is a winner, and`False`

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.