Tic-Tac-Toe Game in Python

Introduction

This Python program is an implementation of the classic Tic-Tac-Toe game for two players. The game is played on a 3×3 grid, where players take turns marking a cell with their respective symbols (‘O’ or ‘X’). The winner is the first player to align three of their symbols horizontally, vertically, or diagonally.

Prerequisites

  • Basic understanding of Python programming.
  • Familiarity with functions, global variables, and control structures in Python.
  • Python environment (like IDLE, Jupyter Notebook, or any IDE supporting Python).

Learning Objectives

  • Implementing a two-player game logic using Python.
  • Understanding the use of functions, global variables, and conditional statements.
  • Handling user inputs and validating them.

Installation Guide

No additional installation is required if Python is already installed. This game can be run in any Python environment.

Project Steps

  1. Initialization: Set up the game board and global variables.
  2. User Input: Prompt players to input their choices in each turn.
  3. Game Logic: Implement functions to update the board, check for a win or tie, and determine the game’s outcome.
  4. Gameplay Loop: Run the game in a loop until a player wins or the game ends in a tie.

Code

				
					l = [['1','2','3'],
     ['4','5','6'],
     ['7','8','9']]

def replaceUser(u,sign):
    if   u == 1 : l[0][0] = sign
    elif u == 2 : l[0][1] = sign
    elif u == 3 : l[0][2] = sign
    elif u == 4 : l[1][0] = sign
    elif u == 5 : l[1][1] = sign
    elif u == 6 : l[1][2] = sign
    elif u == 7 : l[2][0] = sign
    elif u == 8 : l[2][1] = sign
    elif u == 9 : l[2][2] = sign

def horizontalcheck():
    if 'O' == l[0][0] == l[0][1] == l[0][2] or 'O' == l[1][0] == l[1][1] == l[1][2] or 'O' == l[2][0] == l[2][1] == l[2][2] :
        return True
    elif 'X' == l[0][0] == l[0][1] == l[0][2] or 'X' == l[1][0] == l[1][1] == l[1][2] or 'X' == l[2][0] == l[2][1] == l[2][2] :
        return True

def verticlecheck():
    if 'O' == l[0][0] == l[1][0] == l[2][0] or 'O' == l[0][1] == l[1][1] == l[2][1] or 'O' == l[0][2] == l[1][2] == l[2][2]:
        return True
    elif 'X' == l[0][0] == l[1][0] == l[2][0] or 'X' == l[0][1] == l[1][1] == l[2][1] or 'X' == l[0][2] == l[1][2] == l[2][2]: 
        return True

def diagonalcheck():
    if 'O' == l[0][0] == l[1][1] == l[2][2] or 'O' == l[0][2] == l[1][1] == l[2][0]:
        return True
    elif 'X' == l[0][0] == l[1][1] == l[2][2] or 'X' == l[0][2] == l[1][1] == l[2][0]:         
        return True

def printMatrix():
    print(l[0])
    print(l[1])
    print(l[2])

def resetdb():
    global l 
    l = [['1','2','3'],
         ['4','5','6'],
         ['7','8','9']]

print("User 1 represents O")
print("User 2 represents X")
resetdb()
nl = []
flagu1= True
flagu2 = True
while True:
    if len(nl) == 9: 
        print("Match Tie")
        break
    if flagu1:
        u1 = int(input("User O Chance : enter 1 to 9 : ", ))
        if u1 not in nl:
            nl.append(u1)
            replaceUser(u1,'O')
            printMatrix()
            flagu2 = True
            if horizontalcheck() or verticlecheck() or diagonalcheck() :
                print("User 1 wins")
                break
        else : 
            print("Position already filled")
            flagu2 = False
    if len(nl) == 9: 
        print("Match Tie")
        break
    if flagu2:
        u2 = int(input("User X Chance : enter 1 to 9 : ", ))
        if u2 not in nl :
            nl.append(u2)
            replaceUser(u2,'X')
            printMatrix()
            flagu1 = True
            if horizontalcheck() or verticlecheck() or diagonalcheck() :
                print("User 2 wins")
                break
        else :
            print("Position already filled")
            flagu1 = False
				
			

Code

				
					l = [['1','2','3'],
     ['4','5','6'],
     ['7','8','9']]

def replaceUser(u,sign):
    if   u == 1 : l[0][0] = sign
    elif u == 2 : l[0][1] = sign
    elif u == 3 : l[0][2] = sign
    elif u == 4 : l[1][0] = sign
    elif u == 5 : l[1][1] = sign
    elif u == 6 : l[1][2] = sign
    elif u == 7 : l[2][0] = sign
    elif u == 8 : l[2][1] = sign
    elif u == 9 : l[2][2] = sign

def horizontalcheck():
    if 'O' == l[0][0] == l[0][1] == l[0][2] or 'O' == l[1][0] == l[1][1] == l[1][2] or 'O' == l[2][0] == l[2][1] == l[2][2] :
        return True
    elif 'X' == l[0][0] == l[0][1] == l[0][2] or 'X' == l[1][0] == l[1][1] == l[1][2] or 'X' == l[2][0] == l[2][1] == l[2][2] :
        return True

def verticlecheck():
    if 'O' == l[0][0] == l[1][0] == l[2][0] or 'O' == l[0][1] == l[1][1] == l[2][1] or 'O' == l[0][2] == l[1][2] == l[2][2]:
        return True
    elif 'X' == l[0][0] == l[1][0] == l[2][0] or 'X' == l[0][1] == l[1][1] == l[2][1] or 'X' == l[0][2] == l[1][2] == l[2][2]: 
        return True

def diagonalcheck():
    if 'O' == l[0][0] == l[1][1] == l[2][2] or 'O' == l[0][2] == l[1][1] == l[2][0]:
        return True
    elif 'X' == l[0][0] == l[1][1] == l[2][2] or 'X' == l[0][2] == l[1][1] == l[2][0]:         
        return True

def printMatrix():
    print(l[0])
    print(l[1])
    print(l[2])

def resetdb():
    global l 
    l = [['1','2','3'],
         ['4','5','6'],
         ['7','8','9']]

print("User 1 represents O")
print("User 2 represents X")
resetdb()
nl = []
flagu1= True
flagu2 = True
while True:
    if len(nl) == 9: 
        print("Match Tie")
        break
    if flagu1:
        u1 = int(input("User O Chance : enter 1 to 9 : ", ))
        if u1 not in nl:
            nl.append(u1)
            replaceUser(u1,'O')
            printMatrix()
            flagu2 = True
            if horizontalcheck() or verticlecheck() or diagonalcheck() :
                print("User 1 wins")
                break
        else : 
            print("Position already filled")
            flagu2 = False
    if len(nl) == 9: 
        print("Match Tie")
        break
    if flagu2:
        u2 = int(input("User X Chance : enter 1 to 9 : ", ))
        if u2 not in nl :
            nl.append(u2)
            replaceUser(u2,'X')
            printMatrix()
            flagu1 = True
            if horizontalcheck() or verticlecheck() or diagonalcheck() :
                print("User 2 wins")
                break
        else :
            print("Position already filled")
            flagu1 = False
				
			

Code Explanation

  1. Global Variables: l for the game board, p1c and p2c for player scores.
  2. Functions:
    • replaceUser(u, sign): Updates the game board based on the player’s choice.
    • horizontalcheck(): Checks for a horizontal win condition.
    • verticlecheck(): Checks for a vertical win condition.
    • diagonalcheck(): Checks for a diagonal win condition.
    • printMatrix(): Prints the current state of the game board.
    • resetdb(): Resets the game board to its initial state.

Flow Chart

TicTac Toe - flowchart

Pseudo Code

				
					Initialize the game board
Set player symbols as 'O' and 'X'

While the game is not over:
    Get Player 1's choice
    Update the board and check for a win or tie
    Get Player 2's choice
    Update the board and check for a win or tie

If a player wins or the game ties:
    Declare the result
    Reset the board for a new game

				
			

Challenges and Solutions

  • Challenge: Ensuring that players do not overwrite each other’s moves.
  • Solution: Validate each move to ensure the chosen cell is not already occupied.

Testing

  • Test the game with various inputs to ensure all possible game scenarios are handled correctly.
  • Verify that the game correctly identifies win conditions and ties.

Additional Resources

FAQs

  1. Can the game be played with more than two players?
    The program will display an error message and will not include it in the bill or points calculation.

  2. How is the game board reset for a new game?
    Points are calculated based on the total bill. One point is earned for every 100 units of currency in the bill.

Project by Nimisha Agrawal, Team edSlash.