What's up HIVE Community, 👋👋 For quite some time now I have been procrastinating getting started with sharing some different beginner programming projects.
I decided to start with sharing this small Python Project I was working on yesterday. It is pretty straightforward, probably some of you have tried the implementing the game out in different programming languages.
I will provide the image files at the end of the post for anyone interested in aggregating the different code blocks and giving the game a try.
I am currently working on my Python skills, will be sharing more projects in the community for anyone also learning Python.
pygame and time library.import pygame as pg,sys
from pygame.locals import *
import time
time library provides us with the time.sleep() method to pause the game.Global Variables to be used in the reset of the code.#initialize the global variables
XO = 'x'
winner = None
draw = False
width = 400
height = 400
white = (255, 255, 255)
line_color = (10,10,10)
#TicTacToe 3x3 board
TTT = [[None]*3,[None]*3,[None]*3]
pygame to initialize a new window on where to play the game.pg.init()
fps = 30
CLOCK = pg.time.Clock()
pg.display.set_mode() initializes the display, reference it with thescreen = pg.display.set_mode((width, height+100),0,32)
pg.display.set_caption() method is used to set a name that will appear atpg.display.set_caption("Tic Tac Toe")
The game requires 3 Images:
#Loading the Images
opening = pg.image.load('opening.png')
x_img = pg.image.load('x.png')
o_img = pg.image.load('o.png')
The images have to be resized to fit in the display window previously initialized.
#Resizing images
x_img = pg.transform.scale(x_img, (80,80))
o_img = pg.transform.scale(o_img, (80,80))
opening = pg.transform.scale(opening, (width, height+100))
game_opening() Function that Starts and Restarts the gamepygame provides the function blit() which allows drawing an image on top of another image.
Draw the opening image, after which the display has to be always updated using pg.display.update()
Using time.sleep(1) wait for 1 second and fill the screen with white color
To make the 3x3 grid, draw 2 horizonatal and vertical lines on the white background.
# Function that starts and restarts the game
def game_opening():
screen.blit(opening,(0,0))
pg.display.update()
time.sleep(1)
screen.fill(white)
# Drawing vertical lines
pg.draw.line(screen,line_color,(width/3,0),(width/3, height),7)
pg.draw.line(screen,line_color,(width/3*2,0),(width/3*2, height),7)
# Drawing horizontal lines
pg.draw.line(screen,line_color,(0,height/3),(width, height/3),7)
pg.draw.line(screen,line_color,(0,height/3*2),(width, height/3*2),7)
draw_status()
draw_status() Functiondef draw_status():
global draw
if winner is None:
message = XO.upper() + "'s Turn"
else:
message = winner.upper() + " won!"
if draw:
message = 'Game Draw!'
font = pg.font.Font(None, 30)
text = font.render(message, 1, (255, 255, 255))
# copy the rendered message onto the board
screen.fill ((0, 0, 0), (0, 400, 500, 100))
text_rect = text.get_rect(center=(width/2, 500-50))
screen.blit(text, text_rect)
pg.display.update()
check_win() Functiondef check_win():
global TTT, winner,draw
# check for winning rows
for row in range (0,3):
if ((TTT [row][0] == TTT[row][1] == TTT[row][2]) and(TTT [row][0] is not None)):
# this row won
winner = TTT[row][0]
pg.draw.line(screen, (250,0,0), (0, (row + 1)*height/3 -height/6),\
(width, (row + 1)*height/3 - height/6 ), 4)
break
# check for winning columns
for col in range (0, 3):
if (TTT[0][col] == TTT[1][col] == TTT[2][col]) and (TTT[0][col] is not None):
# this column won
winner = TTT[0][col]
#draw winning line
pg.draw.line (screen, (250,0,0),((col + 1)* width/3 - width/6, 0),\
((col + 1)* width/3 - width/6, height), 4)
break
# check for diagonal winners
if (TTT[0][0] == TTT[1][1] == TTT[2][2]) and (TTT[0][0] is not None):
# game won diagonally left to right
winner = TTT[0][0]
pg.draw.line (screen, (250,70,70), (50, 50), (350, 350), 4)
if (TTT[0][2] == TTT[1][1] == TTT[2][0]) and (TTT[0][2] is not None):
# game won diagonally right to left
winner = TTT[0][2]
pg.draw.line (screen, (250,70,70), (350, 50), (50, 350), 4)
if(all([all(row) for row in TTT]) and winner is None ):
draw = True
draw_status()
drawXO(row, col) Functiondef drawXO(row, col):
global TTT, XO
if row == 1:
posx = 30
if row == 2:
posx = width/3 + 30
if row == 3:
posx = width/3*2 + 30
if col == 1:
posy = 30
if col == 2:
posy = height/3 + 30
if col == 3:
posy = height/3*2 + 30
TTT[row-1][col-1] = XO
if (XO == 'x'):
screen.blit(x_img,(posy, posx))
XO = 'o'
else:
screen.blit(o_img,(posy, posx))
XO = 'x'
pg.display.update()
userClick() Functiondef userClick():
# Get coordinates of mouse click
x,y = pg.mouse.get_pos()
# Get column of mouse click
if (x < width / 3):
col = 1
elif (x < width/3 * 2 ):
col = 2
elif (x < width):
col = 3
else:
col = None
# Get row of mouse click
if (y < height/3):
row = 1
elif (y < height / 3 * 2):
row = 2
elif (y < height):
row = 3
else:
row = None
# Print row and col
if (row and col and TTT [row-1][col-1] is None):
global XO
# Draw the X or O on screen
drawXO(row, col)
check_win()
reset_game() FunctionThe function restarts the game and also
resets all the variables to the beginning of the game.
def reset_game():
global TTT, winner, XO, draw
time.sleep(3)
XO = 'x'
draw = False
game_opening()
winner = None
TTT = [[None] * 3, [None] * 3, [None] * 3]
game_opening()
To start the game, invoke game_opening() function.
Then, run an infinite loop and continuously check for any event made by the user.
MOUSEBUTTONDOWN event will be captured and then trigger the userClick() function.reset_game() function.In each iteration the display is updated, having set the frames per second to 30.
while(True):
for event in pg.event.get():
if event.type == QUIT:
pg.quit()
sys.exit()
elif event.type == MOUSEBUTTONDOWN:
# the user clicked; place an X or O
userClick()
if (winner or draw):
reset_game()
pg.display.update()
CLOCK.tick(fps)
As promised here are the image files necessary for successful running of the game. 👇👇
Inspiration and Image files from Tech Vidvan
See you in my next update! Cheers ✌️