Modelling Tic-Tac-Toe in Python

A simple coding activity that creates a virtual tic-tac-toe board with pieces.

Programming a computer game lets you create your own world with your own rules. And if you break everything down and tackle each piece one at a time, even the most complex games can be simple to write. Let’s start with a classic: tic-tac-toe.

Step 1: Brainstorming

Before we pull up the code editor, let’s think about the design of our tic-tac-toe board. In a professional setting you’d look at different graphics packages, colours, animations. For now let’s stick with something simple and text based. A good tic-tac-toe board could be:

_ | _ | _
_ | _ | _
_ | _ | _

Where Xs and Os are added like so:

X | _ | O
_ | X | _
_ | _ | _

Step 2: Open the Code Editor

1. Fire up your browser and navigate to

2. In the ‘Search for a Language’ box, type ‘Python3’ (Don’t forget the ‘3’!)

3. Select ‘Python3’. Your webpage should look like this:

Step 3: Modelling

There are two parts to creating a virtual game board. First, you have to decide how the information on the board is stored in your program. We call this the model. The code for the model is meant to be short and sweet. It usually doesn’t look like the real game because the computer doesn’t care about presentation — just facts.

Users, on the other hand, care a lot about presentation, so you need a way to display the model’s information in a pretty, visual way. We call this the view. Here’s some sample code:

board = ['_'] * 9
def print_board():
  print(board[0] + '|' + board[1] + '|' + board[2])
  print(board[3] + '|' + board[4] + '|' + board[5])
  print(board[6] + '|' + board[7] + '|' + board[8])

When you hit the run button you should see the blank board displayed in the console:

Code in Depth:

We create the model in a single line: board = [ ‘_’ ] * 9.

The square brackets signify that we’re creating a list. Since we multiply the list by 9, we get a list of 9 identical items. In this case, each item in the list is the underscore symbol: “_”. These are the values contained in the tic-tac-toe board: all empty for now.

Next, we create a function to display the board in the console (lines 3-6). In most programming languages, lists start at “0”, so the 1st item in a list is actually the ‘0th’ item! When creating our view, we assign each position in the list to a specific board tile. In this code we go horizontally, but we could have gone vertically as well. The computer doesn’t care. As long as you connect your model and your view properly it won’t matter!

0th | 1st | 2nd
3rd | 4th | 5th
6th | 7th | 8th


0th | 3rd | 6th
1st | 4th | 7th
2nd | 5th | 8th

Now, whenever we call the ‘display_board’ function, the program displays a representation of the the board onscreen.

Step 4: User Input

Next, we need to let the user place pieces on the board. Add the following code to your editor:

while True:
  x = input('Pick a number from 0-8')
  x = int(x)
  board[x] = 'X'

In line 11 we ask the user to pick one of the tiles by specifying a number. Then we transform their input into a number (line 12) and change the appropriate item in the list to the ‘X’ symbol (line 13). When you display the board it now contains the user’s piece:

Since lines 11-13 are inside an infinite ‘While loop’, the program keeps prompting the user until we manually stop it.

Step 5: What Comes Next?

We’ve finished creating our basic model and view! But there’s still lots to do to make this into a working tic-tac-toe game. If you’ve worked with Python before and you’re up for a challenge, see if you can figure out how to add one or more of the following:

  1. There’s only nine spots on the board. What if the user types in ’11’, or ‘-1’, or ‘nachos’? How can we prevent these errors from happening?
  2. In fact, getting a user to pick a tile by number isn’t a great system. Can you think of a better one?
  3. We need to add player turns to the game. If the first piece is an X, then the second should be an O, and then an X, and on and on.
  4. What if there’s already an X or an O on the tile chosen by the user? Should the program exit, give the user another chance, or skip their turn?
  5. If three Xs or three Os are in a row, the game should declare the winner. If the board is filled, the game should declare a tie, and end.

Even if you don’t feel like tackling the code solo, think about potential solutions to these problems — that’s the important part of coding. Once you know what you want to do, the rest is just learning the right syntax!

Learn More

Lists and Arrays


User Input


  • Patricia Foster

    Patricia Foster is a computer science student at Carleton University. In addition to working professionally as a software developer, she spends her time reading and writing.

Also In The February 2018 Issue

In an era before telephones, a clever code was created to send messages by telegraph.

A simple coding activity that creates a virtual tic-tac-toe board with pieces.

Seven days to design, code, and debug a program with PyGame. What could go wrong?

Play with your friends or connect to Minecraft servers all around the world.

Turning scientific data into music can lead to new insights and new solutions.

Tools to help you design and print your own jewelry. Who says geeks can’t be fashionable?

Say hello to your new favorite robot: spherical, programmable, and durable. It can even swim!

The perfect language to help you transition into a new way of coding.

Create a new and improved variation of the classic 1960s board game with micro:bit.

Learn about the origin of Unix time, the calendar system used by digital devices.

Could a human brain be simulated by a computer? Would it think and feel like we do?

Links from the bottom of all the February 2018 articles, collected in one place for you to print, share, or bookmark.

Interesting stories about computer science, software programming, and technology for February 2018.

Interested but not ready to subscribe? Sign-up for our free monthly email newsletter with curated site content and a new issue email announcement that we send every two months.

No, thanks!