You may know one of the most popular games that we used to play in childhood. All it needs is a pen and a paper (or maybe someone’s hand) to play.
So to bring you the same game, here I am presenting a regular ‘tic-tac-toe’ game made on python.

Before you try to run the main code on your Python IDE, please ensure that you have installed pygame libraries on you system. If you haven’t , head to this link: Pygame lib. download
When you have installed pygame on your computer, copy this code in your Python IDE script mode and save it in some folder.
import pygame as py
import gamefunctions as gf
import buttons as but
import txt
import st
def run_game():
py.init()
surf = py.display.set_mode((500,500))
surf_rect = surf.get_rect()
gf.start(surf)
buttons = []
pos = [(90,40),(215,40),(350,40),(90,170),(215,170),(350,170),(90,295),(215,295),(350,295)]
for i in pos:
bt = but.Button(surf,'', i, (200,200,200),(80,80))
bt.state = False
buttons.append(bt)
CMP = but.Button(surf, 'COMP',(surf_rect.right -160,365),(200,200,200),(150,30), margin_color = (0,250,250), b_clr = (230,230,230))
P2 = but.Button(surf, '2 PLAYERS',(surf_rect.right -160,405),(200,200,200),(150,30), margin_color = (0,250,250), b_clr = (230,230,230))
EXIT = but.Button(surf, 'X',(surf_rect.right -60,5),(200,200,200),(55,30), margin_color = (250,0,0))
ABOUT = but.Button(surf, 'ABOUT',(surf_rect.right -110,445),(200,200,200),(100,30), margin_color = (250,0,255))
for i in [CMP, P2, ABOUT, EXIT]:
buttons.append(i)
board = ['','','','','','','','','']
texts = []
var = st.Var()
for i in range(0,len(board)):
tx = txt.Text(surf)
texts.append(tx)
while True:
gf.update_screen(surf,buttons,board, texts, var)
run_game()
Don’t forget to copy the codes of files it uses. Save them in the same folder as directed on the comment on first line of the code:
# save this as gamefunctions.py
import pygame as py
import random as ran
import buttons as but
from time import sleep
import sys
import txt
import logics as lg
def start(surf):
'''Start of the game'''
surf.fill((150,150,150))
py.display.set_caption('Tic Tac Toe')
surf_trans1 = surf.convert_alpha()
surf_trans2 = surf.convert_alpha()
for i in range(200):
py.draw.rect(surf_trans1,(250,i,i,i), py.Rect(0,i*500//200,500,5))
for i in range(200):
py.draw.rect(surf_trans2,(i,250,i,i), py.Rect(i*500//200,0,5,500))
surf.blit(surf_trans1,py.Rect(0,0,0,0))
surf.blit(surf_trans2,py.Rect(0,0,0,0))
# Vertical lines
py.draw.rect(surf, (230,230,230), py.Rect(180,35, 15,340))
py.draw.rect(surf, (230,230,230), py.Rect(320,35, 15,340))
# Horizontal lines
py.draw.rect(surf, (230,230,230), py.Rect(85,130,340, 15))
py.draw.rect(surf, (230,230,230), py.Rect(85,270,340, 15))
def update_screen(surf,buttons, board, texts,var):
'''Updates the screen every moment'''
check_events(surf, buttons, board, texts,var)
start(surf)
for i in buttons:
i.update_me()
pos = [(90,40),(215,40),(350,40),(90,170),(215,170),(350,170),(90,295),(215,295),(350,295)]
for i in range(0, len(texts)):
texts[i].text(board[i],(100,100,100),(pos[i][0]+20,pos[i][1]+15), size = 50)
play_comp_hard(surf,buttons, board, var.cmp)
check_seq(surf, board)
py.display.flip()
def check_events(surf,buttons, board, texts,var):
'''Checks the mouse and keyboard events'''
for event in py.event.get():
if event.type == py.QUIT:
py.quit()
sys.exit()
if event.type == py.MOUSEBUTTONDOWN:
click_down(surf,buttons, board, texts,var)
if event.type == py.MOUSEBUTTONUP:
click_up()
def click_down(surf,buttons,board, texts,var):
'''On click down'''
if 1 == py.mouse.get_pressed()[2]:
py.mouse.set_cursor(*py.cursors.diamond)
if 1 == py.mouse.get_pressed()[0]:
py.mouse.set_cursor(*py.cursors.ball)
if buttons[-1].mouseover == True:
commands(surf,'EXIT')
elif buttons[-2].mouseover == True and buttons[-2].state == True:
buttons[-2].deactivate()
commands(surf,'ABOUT')
sleep(2)
buttons[-2].state = True
if buttons[-3].mouseover == True and buttons[-3].state == True:
buttons[-3].deactivate()
buttons[-4].deactivate()
for i in range(0,9):
buttons[i].state = True
elif buttons[-4].mouseover == True and buttons[-4].state == True:
buttons[-3].deactivate()
buttons[-4].deactivate()
var.cmp = True
pla(surf, board, var.cmp)
for i in range(0,9):
buttons[i].state = True
for i in range(0,9):
if buttons[i].mouseover == True and buttons[i].state == True:
buttons[i].deactivate() # ---------mysy means player turn here: Odd-1st and Even-2nd
count = 0
for j in board:
if j == '+' or j == 'o':
count += 1
if count %2 == 0:
board[i] = '+'
elif count %2 == 1:
board[i] = 'o'
def click_up():
'''On click down'''
if 0 == py.mouse.get_pressed()[0] and 0 == py.mouse.get_pressed()[1] and 0 == py.mouse.get_pressed()[2] :
py.mouse.set_cursor(*py.cursors.arrow)
def commands(surf, cmd):
'''Gives appropriate commands on appropriate events'''
import txt
if cmd == 'END1':
win = txt.Text(surf)
win.text('Player 1 \'+\' has won',(0,150,250),(50,410), size = 40 ,font = 'Comic Sans MS')
py.display.flip()
sleep(3)
cmd = 'EXIT'
elif cmd == 'END2':
win = txt.Text(surf)
win.text('Player 2 \'o\' has won',(0,250,150),(50,410), size = 40 ,font = 'Comic Sans MS')
py.display.flip()
sleep(3)
cmd = 'EXIT'
elif cmd == 'DRAW':
draw = txt.Text(surf)
draw.text('It is a Draw',(150,250,0),(50,410), size = 40 ,font = 'Comic Sans MS')
py.display.flip()
sleep(3)
cmd = 'EXIT'
if cmd == 'EXIT':
py.quit()
sys.exit()
elif cmd == 'ABOUT':
about = txt.Text(surf)
about.text('TIC-TAC-TOE created by :',(150,0,250),(50,380), size = 20 ,font = 'Comic Sans MS')
about.text('----------------------------',(160,125,205),(50,390), size = 25 ,font = 'Comic Sans MS')
about.text('Prashant Rawat',(0,150,250),(50,410), size = 25 ,font = 'Comic Sans MS')
about.text('Class - XI',(0,200,150),(50,440), size = 20 ,font = 'Comic Sans MS')
about.text('Dec. 2018',(50,120,150),(250,440), size = 20 ,font = 'Comic Sans MS')
py.display.flip()
def check_seq(surf, board):
'''Checks the position of X's and O's on the board'''
b = board
if (b[0]==b[1]==b[2]):
if b[0] == '+':
commands(surf, 'END1')
elif b[0] == 'o':
commands(surf, 'END2')
if (b[0]==b[3]==b[6]):
if b[0] == '+':
commands(surf, 'END1')
elif b[0] == 'o':
commands(surf, 'END2')
if (b[0]==b[4]==b[8]):
if b[0] == '+':
commands(surf, 'END1')
elif b[0] == 'o':
commands(surf, 'END2')
if (b[1]==b[4]==b[7]):
if b[1] == '+':
commands(surf, 'END1')
elif b[1] == 'o':
commands(surf, 'END2')
if (b[2]==b[4]==b[6]):
if b[2] == '+':
commands(surf, 'END1')
elif b[2] == 'o':
commands(surf, 'END2')
if (b[2]==b[5]==b[8]):
if b[2] == '+':
commands(surf, 'END1')
elif b[2] == 'o':
commands(surf, 'END2')
if (b[3]==b[4]==b[5]):
if b[3] == '+':
commands(surf, 'END1')
elif b[3] == 'o':
commands(surf, 'END2')
if (b[6]==b[7]==b[8]):
if b[6] == '+':
commands(surf, 'END1')
elif b[6] == 'o':
commands(surf, 'END2')
if '' not in b:
commands(surf, 'DRAW')
def play_comp_easy(surf,buttons,board, cmp = False):
'''Play with computer attempting randomly'''
if cmp == True:
count = 0
num = []
for j in range(0, len(board)):
if board[j] == '+' or board[j] == 'o':
count += 1
num.append(j)
if count %2 == 1:
l = list(set(list(range(0,9)))-set(num))
if len(l)>0:
p = ran.choice([x for x in l])
buttons[p].deactivate()
board[p] = 'o'
# save this as st.py
class Var():
def __init__(self):
self.cmp = False
# save this as txt.py
import pygame
from time import sleep
from pygame.sprite import Sprite
from pygame.sprite import Group
class Text(Sprite):
'''Class to display text'''
def __init__(self,screen):
super().__init__()
self.screen = screen
self.comments = []
def text(self,msg , color , co, size = 20,font = 'Arial'):
'''Displays the text on the screen\n(msg = \'String\' , color , co-ordinates, size = 20 ,font = \'Arial\''''
pygame.font.init()
myfont = pygame.font.SysFont(font,size)
textsurface = myfont.render(msg, False, color)
self.screen.blit(textsurface, co)
def c_k(self,comment):
l = list(range(0,len(comment)))
f,j,n = 0,0,0
for i in l:
if comment[0] != '&' :
n += 1
self.text(comment[0],(250,250,250),(20+i*30 - f ,20+j),40,'Aerial')
sleep(0.02)
comment.pop(0)
else:
j += 40
comment.remove('&')
f = (n+1)*30
n += 1
del i
pygame.display.flip()
# save this as buttons.py
'''A class for buttons'''
import pygame
class Button():
'''An object for a button'''
def __init__(self, surf,message, position, color, size, margin_color = (0,250,0), b_clr = (0,0,0)):
self.surf = surf
from txt import Text
self.txt = Text(self.surf)
self.message = message
self.color = color
self.state = True
self.b_clr = b_clr
self.margin_color = margin_color
self.x, self.y = position[0], position[1]
self.width , self.height = size[0], size[1]
self.rect = pygame.Rect(self.x, self.y, self.width, self.height)
self.mouseover = False
def draw(self):
'''Displaying the button on the screen'''
if self.margin_color != (0,250,0):
pygame.draw.rect(self.surf,self.margin_color ,pygame.Rect(self.x, self.y, self.width+1, self.height+1 ))
else:
pygame.draw.rect(self.surf,self.margin_color ,pygame.Rect(self.x, self.y, self.width+1, self.height+1 ))
pygame.draw.rect(self.surf,self.color,self.rect)
self.txt.text(self.message, self.b_clr,(self.x+23,self.y+2))
def update_me(self):
'''Updating the buttons on mouse events'''
if self.state == True:
self.draw()
self.check_mouse_over()
def check_mouse_over(self):
'''Does these when mouse is over the button'''
if self.state == True:
if pygame.mouse.get_pos()[0] >= self.x and pygame.mouse.get_pos()[0] <= self.x + self.width and pygame.mouse.get_pos()[1] >= self.y and pygame.mouse.get_pos()[1] <= self.y + self.height:
self.color = (250,250,250)
self.mouseover = True
else:
self.color = (200,200,200)
self.mouseover = False
def deactivate(self):
'''Deactivates the button after click'''
self.state = False
