5 - Tic-Tak-Toe
5 - Tic-Tak-Toe
Practical 5: Tic-Tac-Toe
Aim: Write a program to implement the Tic-Tac-Toe game.
Theory:
Tic-Tac-Toe, also known as Noughts and Crosses, is a classic two-player board game that serves as an
important problem in the field of artificial intelligence. The objective of the game is for two players
to take turns marking empty cells on a 3x3 grid with their respective symbols, typically "X" and "O,"
with the goal of achieving a winning combination or forcing a draw. This problem involves creating
an AI agent capable of playing Tic-Tac-Toe optimally.
Problem Components:
1. Game Board: The game is played on a 3x3 grid, resulting in a total of 9 cells. Players take turns
selecting an empty cell to place their symbol on.
2. Players: There are two players, often represented as "X" and "O," who alternate turns.
3. Winning Condition: A player wins the game if they are the first to form a line of their symbol
(horizontally, vertically, or diagonally) on the board. The game ends, and that player is declared the
winner.
4. Draw Condition: If all cells on the board are filled, and no player has won, the game ends in a
draw.
5. Player Actions: Players take turns choosing an empty cell to place their symbol. The AI agent must
determine the best move at each turn based on the current state of the board.
6. AI Strategy: The AI's objective is to maximize its chances of winning or forcing a draw. It needs to
evaluate the current board state, anticipate future moves, and make decisions accordingly.
Problem Formulation:
Given a 3x3 Tic-Tac-Toe board with the current positions of "X" and "O" symbols, the AI agent's task
is to decide the optimal move to make on its turn. This decision should be based on a strategy that
maximizes the AI's chances of winning or achieving a draw.
Objective:
The primary objective of the AI in Tic-Tac-Toe is to:
1. Find the best move that will lead to a win if possible.
2. Block the opponent from winning if they are one move away from a victory.
3. Otherwise, choose a move that maximizes the AI's chances of winning in the future or achieving a
draw if victory is not possible.
Challenges:
The Tic-Tac-Toe problem in AI presents several challenges, including:
1. Game Tree Complexity: As the game progresses, the number of possible board configurations
increases, leading to a complex branching game tree.
2. Optimal Decision-Making: Designing an AI strategy that can evaluate the board state effectively
and make optimal decisions is crucial.
3. Opponent Modeling: The AI may need to anticipate the opponent's moves and respond
accordingly.
4. Efficiency: Efficient algorithms and heuristics are needed to search the game tree effectively,
especially in more complex variants of Tic-Tac-Toe.
Tic-Tac-Toe serves as a fundamental problem in AI, illustrating concepts of search, decision-making,
and adversarial game playing. Solving this problem can also serve as a foundation for more advanced
AI techniques applied to games like chess and Go.
Python Code:
#!/usr/bin/env python3
from math import inf as infinity
from random import choice
import platform
import time
from os import system
HUMAN = -1
COMP = +1
board = [
[0, 0, 0],
[0, 0, 0],
[0, 0, 0],
]
def evaluate(state):
"""
Function to heuristic evaluation of state.
:param state: the state of the current board
:return: +1 if the computer wins; -1 if the human
wins; 0 draw
"""
if wins(state, COMP):
score = +1
elif wins(state, HUMAN):
score = -1
else:
score = 0
return score
return True
else:
return False
def game_over(state):
"""
This function test if the human or computer wins
:param state: the state of the current board
:return: True if the human or computer wins
"""
return wins(state, HUMAN) or wins(state, COMP)
def empty_cells(state):
"""
Each empty cell will be added into cells' list
:param state: the state of the current board
:return: a list of empty cells
"""
cells = []
return cells
"""
AI function that choice the best move
:param state: current state of the board
:param depth: node index in the tree (0 <= depth <=
9),
but never nine in this case (see iaturn() function)
:param player: an human or a computer
:return: a list with [the best row, best col, best
score]
"""
if player == COMP:
best = [-1, -1, -infinity]
else:
best = [-1, -1, +infinity]
if depth == 0 or game_over(state):
score = evaluate(state)
return [-1, -1, score]
if player == COMP:
if score[2] > best[2]:
best = score # max value
else:
if score[2] < best[2]:
best = score # min value
return best
def clean():
"""
Clears the console
"""
os_name = platform.system().lower()
if 'windows' in os_name:
system('cls')
else:
system('clear')
chars = {
-1: h_choice,
+1: c_choice,
0: ' '
}
str_line = '---------------'
print('\n' + str_line)
for row in state:
for cell in row:
symbol = chars[cell]
print(f'| {symbol} |', end='')
print('\n' + str_line)
clean()
print(f'Computer turn [{c_choice}]')
render(board, c_choice, h_choice)
if depth == 9:
x = choice([0, 1, 2])
y = choice([0, 1, 2])
else:
move = minimax(board, depth, COMP)
x, y = move[0], move[1]
set_move(x, y, COMP)
time.sleep(1)
clean()
print(f'Human turn [{h_choice}]')
if not can_move:
print('Bad move')
move = -1
except (EOFError, KeyboardInterrupt):
print('Bye')
exit()
except (KeyError, ValueError):
print('Bad choice')
def main():
"""
Main function that calls all functions
"""
clean()
h_choice = '' # X or O
c_choice = '' # X or O
first = '' # if human is the first
human_turn(c_choice, h_choice)
ai_turn(c_choice, h_choice)
exit()
if __name__ == '__main__':
main()
Output:
https://youtu.be/uKps1rM7neQ