It seems like many people enjoy tutorials about making games. Well, let me make one too! Today we are going to be implementing the *legendary* "Noughts and Crosses" game in 69 lines of Python code! I am not going to overcomplicate matters with OOP and all that... a few functions will do.

First, let's create 2 global variables:

```
# GLOBAL VARIABLES
M = [
['_','_','_'],
['_','_','_'],
['_','_','_']
]
S = True
C = 0
```

`M`

stores our game's 3 x 3 field. Classic. It is a 2D matrix, so I called it `M`

. `S`

holds the side: when `S = True`

, it's X's turn and vice versa. `C`

holds the number of moves made.

Now, let's write the main function. I called it `xo()`

for simplicity. It has to:

- Show an empty board
- Start a
`while`

loop that will repeat itself until`C == 9`

- Inside the loop, it has to
- Ask user to make a move
- Check if either of the two players won and if yes,
`break`

itself

- If the
`while`

loop doesn't encounter a`break`

on its way, it means that the 9 moves are made, yet no one won, so it must be a tie!

```
# MAIN
def xo():
board_show() # FUNCTION NOT YET IMPLEMENTED!
while C < 9:
turn() # FUNCTION NOT YET IMPLEMENTED!
if big_check(): # FUNCTION NOT YET IMPLEMENTED!
print(f"{'X' if not S else 'O'} wins!", end="\n\n")
break
else: # if break not encountered, it must be a tie!
print("It's a tie!", end="\n\n")
```

The easiest function to implement is `board_show()`

. Just print out our little matrix `M`

. Don't forget to put some empty `print`

s for spacing purposes!

```
def board_show():
print()
for y in range(3):
print(" ", end="")
for x in range(3):
print(M[y][x], end=" ")
print()
print()
```

Now, the `turn()`

function is a bit trickier, yet not too complicated either. We want to:

- Ask player where he/she wants to place his/her mark
- Check if the selected square is free, and if it is, put X or O into it, change the
`S`

tate, and`board_show()`

to demonstrate the result - If it's not empty, we want to let the user know that the move was invalid and make him repeat it

```
def turn():
global S, C # allows us to reference S that is not assigned in this scope
pos = [ ( int(i) - 1 ) for i in input("Your move: ").split() ]
# this produces a list of two int values X and Y
# it reduces each one by 1 since computer (unlike human) starts counting from 0
x, y = pos[0], pos[1] # save x and y separately for clearance
if M[y][x] == '_':
M[y][x] = 'X' if S else 'O'
S = not S
C += 1 # increment move counter C by 1 only if the move is valid
board_show()
else:
print("Invalid move!")
```

Now that we have our `turn()`

function nice and shining, we only need the `big_check()`

function, only it's not so easy. The `big_check()`

isn't called big for no reason -- it consists of three other functions:

`check_hr(y)`

check`y`

th row`check_vr(x)`

check`x`

th column`check_dig()`

check both diagonals

But these are fairly simple and you will see why in a second. The only thing we need to do is to check whether all three positions have the same `chr`

in them that is not `'_'`

the default one.

```
def check_hr(y):
return M[y][0] == M[y][1] == M[y][2] != '_'
def check_vr(x):
return M[0][x] == M[1][x] == M[2][x] != '_'
def check_dig():
return M[0][0] == M[1][1] == M[2][2] != '_' or \
M[0][2] == M[1][1] == M[2][0] != '_'
```

Now, let's get to the `big_check()`

. What it does essentially is it checks every row, column, and diagonal using the functions we've just written and if at least one of those function returns `True`

, the whole `big_check()`

function must return `True`

!

```
def big_check():
win = False
for i in range(3):
if check_hr(i) or check_vr(i):
win = True
if check_dig():
win = True
return win
```

"Now we have everything! It's complete!" -- a newbie would say, but no, it's actually not. There is one last bit to it that will finally make it work -- the 69th line:

`xo() # invoke the xo() function`

Great visuals - thanks for making this!

@timmy_i_chen In my repls I now have Noughts & Crosses (Web) repo in which you'll find the same game but in HTML format. No need to calculate coordinates! Go check it out.