We'll start by importing two libraries: `pgzrun` to help run the game and `random` to make unpredictable choices for the computer.
import pgzrun
import random
Next, we decide the size of our game window. The game will be 300 pixels wide and tall. Each square (or tile) of our Tic Tac Toe board is one-third of the game window's width.
WIDTH = 300
HEIGHT = 300
TILE_SIZE = WIDTH // 3
We'll construct a class named Game. This class is like the game's control center. When we make a new "instance" of this class, we initiate a new game.
class Game:
def __init__(self):
self.board = [['' for _ in range(3)] for _ in range(3)]
self.player = 'X'
self.ai = 'O'
self.current_turn = 'X'
This section dictates how the player places an "X" on the board.
def player_move(self, x, y):
if self.board[y][x] == '':
self.board[y][x] = self.player
if not self.is_game_over():
self.current_turn = self.ai
self.ai_move()
The computer uses this part to decide where to place an "O" on the board. It selects randomly from the available spots.
def ai_move(self):
available_moves = [(x, y) for y in range(3) for x in range(3) if self.board[y][x] == '']
if available_moves:
x, y = random.choice(available_moves)
self.board[y][x] = self.ai
if not self.is_game_over():
self.current_turn = self.player
This section determines if someone (player or AI) has won, or if the board is filled up resulting in a tie.
def is_game_over(self):
for i in range(3):
if self.board[i][0] == self.board[i][1] == self.board[i][2] != '':
return True
if self.board[0][0] == self.board[1][1] == self.board[2][2] != '' or self.board[0][2] == self.board[1][1] == self.board[2][0] != '':
return True
if all(cell != '' for row in self.board for cell in row):
return True
return False
We create a fresh instance of our Game class, which represents a new game where nobody has made any moves yet.
game = Game()
The draw function displays the game board and the moves of both the player and the AI on the screen.
def draw():
screen.clear()
for x in range(1, 3):
screen.draw.line((TILE_SIZE * x, 0), (TILE_SIZE * x, HEIGHT), 'white')
screen.draw.line((0, TILE_SIZE * x), (WIDTH, TILE_SIZE * x), 'white')
for y in range(3):
for x in range(3):
if game.board[y][x] == 'X':
draw_x(x, y)
elif game.board[y][x] == 'O':
draw_o(x, y)
This function draws an "X" on the Tic Tac Toe board.
Parameters: It takes in x
and y
which indicate the column and row numbers of the cell where the "X" should be drawn.
Functionality: The function utilizes the screen.draw.line
method twice to create two lines in the shape of an "X". These lines stretch diagonally from one corner of the cell to its opposite counterpart.
def draw_x(x, y):
screen.draw.line((x * TILE_SIZE, y * TILE_SIZE),
((x + 1) * TILE_SIZE, (y + 1) * TILE_SIZE), 'red')
screen.draw.line(((x + 1) * TILE_SIZE, y * TILE_SIZE),
(x * TILE_SIZE, (y + 1) * TILE_SIZE), 'red')
This function is designated for drawing an "O" on the Tic Tac Toe board.
Parameters: Similar to draw_x
, it requires x
and y
, which specify the column and row of the cell where the "O" should be positioned.
Functionality: The function harnesses the screen.draw.circle
method to design a circle in the center of the designated cell, symbolizing the "O". The circle's radius is set to be one-third of the tile's size, ensuring it snugly fits within the cell, avoiding the edges.
def draw_o(x, y):
screen.draw.circle((x * TILE_SIZE + TILE_SIZE // 2, y * TILE_SIZE + TILE_SIZE // 2),
TILE_SIZE // 3, 'blue')
When the player clicks on a spot, this function determines where they clicked and registers the move for them.
def on_mouse_down(pos):
if game.current_turn == game.player:
x, y = pos[0] // TILE_SIZE, pos[1] // TILE_SIZE
game.player_move(x, y)
To kick off our game, we'll use the pgzrun.go() function.
pgzrun.go()
Copyright © KX Technology Group, LLC. All Rights Reserved.