Tic-Tac-Toe

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
   

Leave a Reply

Create your own website, free on WordPress.com.Create your own website.
Start free