0% found this document useful (0 votes)
29 views33 pages

Ai Lab

ai lab

Uploaded by

anjalimaurya2801
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
29 views33 pages

Ai Lab

ai lab

Uploaded by

anjalimaurya2801
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 33

DR.

APJ ABDUL KALAM TECHNICAL


UNIVERSITY LUCKNOW

RAM CHAMELI CHADHA VISHWAS GIRLS COLLEGE

SESSION 2023-24
PROJECT FILE
ARITIFICIAL INTELLIGENCE LAB

SUBMITTED BY: SUBMITTED TO:


ANJALI MAURYA MRS. YASHI TYAGI MAM
MCA 2ND YR
ROLL NO: 2301170140003
INDEX

S.No. TOPICS Teacher’s


Signature

1. STUDY OF PROLOG AND LISP

2. WRITE SIMPLE FACTS FOR THE STATEMENT USING


PROLOG

3. WRITE PROGRAM TO IMPLEMENT UNIFORM


SEARCHING ALGORITHMS

4. WRITE PROGRAM TO SOLVE THE MONKEY


BANANA PROBLEM

5. WRITE PROGRAM IN PROLOG FOR MEDICAL


SCIENCES

6. WRITE PROBLEM TO SOLVE MATHEMATICAL


PROBLEM SUCH AS CALCULATE FACTORIAL,
GENERATE FABONACCI SERIES, ETC

7. WRITE PROGRAM TO SOLVE 4-QUEEN/8-QUEEN


PROBLEM

8. WRITE A PROGRAM TO SOLVE TRAVELLING


SALESMAN PROBLEM

9. WRITE PROGRAM TO SOLVE WATER JUG


PROBLEM
10.
WRITE PROGRAM TO SOLVE TIC-TAC TOE
PROBLEM
1. STUDY OF PROLOG AND LISP

Prolog and Lisp are two founda onal programming languages that are
widely studied in the fields of ar ficial intelligence (AI), computer science,
and logic programming. Both languages have dis nct paradigms and were
developed for different purposes, but they have influenced the
development of many other languages and concepts in the compu ng
world. Below is an overview of each language and its characteris cs:

Prolog (Programming in Logic)

Overview:
 Developed by: Alain Colmerauer and Philippe Roussel in the early 1970s.
 Paradigm: Logic programming language.
 Key Feature: Based on formal logic and uses rules and facts to infer
answers.
 Primary Use: Knowledge representa on, natural language processing,
expert systems, and AI.

Core Concepts:
1. Facts:
o Represent basic asser ons about the world. For example:
o parent(john, mary).
o parent(mary, susan).
These facts state that John is a parent of Mary and Mary is a parent of
Susan.
2. Rules:
o Define rela onships between facts. For example:
o grandparent(X, Y) :- parent(X, Z), parent(Z, Y).
This rule states that X is a grandparent of Y if X is a parent of Z and Z is a
parent of Y.
3. Queries:
o Used to ask Prolog ques ons. For example:
o ?- grandparent(john, susan).
Prolog tries to find a solu on based on the facts and rules defined.
4. Backtracking:
o Prolog uses backtracking to explore different possible solu ons. If
a solu on is not found, it backtracks to previous decisions to try
alterna ve paths.
5. Unifica on:
o A process of making two terms iden cal by finding a common
subs tu on. For example:
o parent(X, Y).
Prolog would try to unify X and Y with the exis ng facts in the database.
Strengths of Prolog:
 Declara ve Language: You describe what you want, not how to achieve
it.
 Expressiveness: Ideal for problems involving complex rela onships and
logical reasoning.
 Backtracking and pa ern matching allow elegant solu ons to problems
like puzzles, planning, and search.

Applica ons of Prolog:


 Expert systems
 Natural language processing (NLP)
 Theorem proving
 Problem-solving in AI
 Knowledge-based systems

Lisp (LISt Processing)

Overview:
 Developed by: John McCarthy in 1958.
 Paradigm: Func onal programming language, with symbolic expression
manipula on.
 Key Feature: Manipula on of lists and recursive func ons.
 Primary Use: AI, symbolic processing, and general-purpose
programming.
Core Concepts:
1. Symbolic Expressions (S-expressions):
o Lisp uses S-expressions to represent both code and data. An S-
expression is a list, typically wri en in parentheses. For example:
o (+ 2 3)
This expression represents the addi on of 2 and 3. The operator (+) and
operands (2 and 3) are all part of a list.
2. Recursive Func ons:
o Lisp relies heavily on recursion as a fundamental programming
technique. A func on in Lisp can call itself as part of its execu on.
3. First-Class Func ons:
o Func ons are first-class ci zens in Lisp, meaning they can be
passed as arguments to other func ons, returned as values, and
stored in variables.
4. Dynamic Typing:
o Lisp is dynamically typed, meaning that variables do not have fixed
types at compile me. The type of a variable is determined at
run me.
5. Macros:
o Lisp allows for powerful metaprogramming via macros, which can
transform code at compile me, enabling the crea on of new
control structures.
6. Garbage Collec on:
o Lisp has built-in automa c memory management via garbage
collec on, which reclaims memory used by objects that are no
longer in use.

Strengths of Lisp:
 Flexibility: Lisp’s homoiconicity (code as data) allows for a high degree of
flexibility and metaprogramming.
 Extensibility: Lisp allows users to define new language constructs and
create domain-specific languages.
 Support for recursion and symbolic manipula on makes it ideal for AI
research and symbolic computa on.
Applica ons of Lisp:
 Ar ficial intelligence
 Expert systems
 Symbolic mathema cal computa on
 Computer science research
 Robo cs and natural language processing

Comparison of Prolog and Lisp

Feature Prolog Lisp

Paradigm Logic programming Func onal and symbolic


programming

Core Approach Declara ve (describes Impera ve and


facts and rules) declara ve
(manipulates data)
Type System Implicitly typed Dynamically typed
(variable types inferred)
Programming Style Rule-based, logical Func onal, symbolic
inference computa on

Backtracking Supports backtracking Does not have built-in


for search and pa ern backtracking; focuses on
matching recursion

Symbol Manipula on Limited (mainly for Extensive (symbolic


logical facts and expressions and
rela onships) recursion)

Memory Management Implicitly handled Automa c garbage


(based on logic) collec on

Key Applica ons Expert systems, AI AI, symbolic


reasoning, natural computa on,
language processing metaprogramming
When to Use Prolog vs Lisp:

 Prolog is more suitable when solving problems that involve formal logic,
rule-based reasoning, and complex search spaces, such as in knowledge
representa on, natural language processing, or AI decision-making
systems.
 Lisp is ideal for tasks that require symbolic manipula on, complex
recursive algorithms, and metaprogramming. It's o en used in AI
research, computer science theory, and systems that need extensive
customiza on or flexibility.

Conclusion:
Prolog and Lisp represent two important paradigms in computer science:
logic programming and symbolic func onal programming, respec vely.
Prolog excels in tasks that require logical reasoning and problem-solving
based on facts and rules, while Lisp's flexibility and powerful support for
recursion and symbolic processing make it a valuable tool in AI and
research. Both languages have had a las ng impact on AI and programming
language design.
2. WRITE SIMPLE FACTS FOR THE STATEMENT USING PROLOG

To write simple facts in Prolog based on a statement, we break the


statement down into logical facts (asser ons) that Prolog can use. Below, I'll
create some simple examples of facts that correspond to statements in
Prolog.

Example Statement 1: "John is the father of Mary."


Prolog Fact:
father(john, mary).

Example Statement 2: "Mary is the mother of Susan."


Prolog Fact:
mother(mary, susan).

Example Statement 3: "John is a parent of Mary."


Prolog Fact:
parent(john, mary).

Example Statement 4: "Alice is a teacher."


Prolog Fact:
teacher(alice).

Example Statement 5: "Bob works as an engineer."


Prolog Fact:
works_as(bob, engineer).

Example Statement 6: "John is older than Mary."


Prolog Fact:
older_than(john, mary).

Example Statement 7: "Susan likes chocolate."


Prolog Fact:
likes(susan, chocolate).
Example Statement 8: "Mary is married to John."
Prolog Fact:
married(mary, john).

Example Statement 9: "Peter is a student."


Prolog Fact:
student(peter).

Example Statement 10: "The sky is blue."


Prolog Fact:
sky_is_blue.

In these Prolog facts, the predicate represents the rela onship, and the
arguments provide the en es involved in the rela onship. Prolog allows
you to define such facts to represent knowledge about the world, and then
use queries to retrieve informa on based on these facts.

Example Queries

1. Query to find a parent:


2. ?- parent(john, mary).
This query would return true because the fact parent(john, mary). is
defined.
3. Query to check if someone is a teacher:
4. ?- teacher(alice).
This would return true because teacher(alice). is a fact.
5. Query to find who likes chocolate:
6. ?- likes(susan, chocolate).
This would return true because likes(susan, chocolate). is a fact.
By wri ng such simple facts in Prolog, you can build a knowledge base and
use Prolog’s inference mechanisms to query and derive new knowledge.
3. WRITE PROGRAM TO IMPLEMENT UNIFORM SEARCHING
ALGORITHMS

import heapq
# Node class to represent each state in the search problem
class Node:
def __init__(self, state, parent=None, ac on=None, path_cost=0):
self.state = state # the current state
self.parent = parent # parent node
self.ac on = ac on # the ac on taken to get to this state
self.path_cost = path_cost # cost of the path to reach this state
def __lt__(self, other):
return self.path_cost < other.path_cost
# Uniform Cost Search algorithm
def uniform_cost_search(start_state, goal_state, graph):
# Priority Queue to store the nodes to be explored (min-heap based on path
cost)
fron er = []
heapq.heappush(fron er, Node(start_state, path_cost=0))
# Set to keep track of visited states
explored = set()
# While there are nodes to explore
while fron er:
# Get the node with the lowest path cost
node = heapq.heappop(fron er)
# If the goal state is reached, return the path to the goal
if node.state == goal_state:
path = []
while node:
path.append(node.state)
node = node.parent
return path[::-1] # Return reversed path (from start to goal)
# Mark the current node as explored
explored.add(node.state)
# Expand the current node
for ac on, cost, next_state in graph[node.state]:
if next_state not in explored:
child_node = Node(next_state, parent=node, ac on=ac on,
path_cost=node.path_cost + cost)
heapq.heappush(fron er, child_node)
# If no solu on is found
return None
# Example Graph representa on (Adjacency list with costs)
graph = {
'A': [('B', 1, 'B'), ('C', 4, 'C')],
'B': [('A', 1, 'A'), ('C', 2, 'C'), ('D', 5, 'D')],
'C': [('A', 4, 'A'), ('B', 2, 'B'), ('D', 1, 'D')],
'D': [('B', 5, 'B'), ('C', 1, 'C')]
}
# Start and goal states
start = 'A'
goal = 'D'
# Running Uniform Cost Search
path = uniform_cost_search(start, goal, graph)
if path:
print("Path found:", path)
else:
print("No path found")

Output Example:
For the given problem, the output would be:
Path found: ['move_to_B', 'move_to_D', 'move_to_goal']
This indicates that the least-cost path from state 'A' to the goal is:
 Move from 'A' to 'B' (cost = 1)
 Move from 'B' to 'D' (cost = 2)
 Move from 'D' to 'Goal' (cost = 1)
Thus, the total cost is 4, and the solu on path consists of the ac ons
['move_to_B', 'move_to_D', 'move_to_goal'].
4.WRITE PROGRAM TO SOLVE THE MONKEY BANANA PROBLEM

from collec ons import deque


# Define the state space
class State:
def __init__(self, monkey_posi on, box_posi on, has_banana):
self.monkey_posi on = monkey_posi on # True: on box, False: on
ground
self.box_posi on = box_posi on # True: under banana, False: not
under banana
self.has_banana = has_banana #True: monkey has banana, False:
monkey does not have banana
def __repr__(self):
return f"Monkey({'box' if self.monkey_posi on else 'ground'}),
Box({'under' if self.box_posi on else 'not under'} banana), {'Has banana'
if self.has_banana else 'No banana'}"

def __eq__(self, other):


return (self.monkey_posi on == other.monkey_posi on and
self.box_posi on == other.box_posi on and
self.has_banana == other.has_banana)

def __hash__(self):
return hash((self.monkey_posi on, self.box_posi on,
self.has_banana))

# Define possible ac ons


def ac ons(state):
"""Returns a list of possible ac ons from the given state"""
possible_ac ons = []

# Ac on 1: Move (monkey moves, but this doesn't change the state)


if state.monkey_posi on: # Monkey is on the box
possible_ac ons.append("Monkey stays on box")
else: # Monkey is on the ground
possible_ac ons.append("Monkey moves to box")

# Ac on 2: Push the box under the banana if it's not already under the
banana
if not state.box_posi on:
possible_ac ons.append("Push box under banana")

# Ac on 3: Climb onto the box (if it's not already on the box)
if not state.monkey_posi on and state.box_posi on:
possible_ac ons.append("Climb onto box")

# Ac on 4: Get the banana (only if the monkey is on the box and the
box is under the banana)
if state.monkey_posi on and state.box_posi on and not
state.has_banana:
possible_ac ons.append("Get the banana")

return possible_ac ons

# Define a func on to perform an ac on and return a new state


def perform_ac on(state, ac on):
if ac on == "Monkey stays on box":
return state # No change, monkey is already on box
elif ac on == "Monkey moves to box":
return State(monkey_posi on=True,
box_posi on=state.box_posi on, has_banana=state.has_banana)
elif ac on == "Push box under banana":
return State(monkey_posi on=state.monkey_posi on,
box_posi on=True, has_banana=state.has_banana)
elif ac on == "Climb onto box":
return State(monkey_posi on=True,
box_posi on=state.box_posi on, has_banana=state.has_banana)
elif ac on == "Get the banana":
return State(monkey_posi on=state.monkey_posi on,
box_posi on=state.box_posi on, has_banana=True)

# BFS to find the solu on


def bfs(ini al_state, goal_state):
fron er = deque([ini al_state]) # Queue for BFS
explored = set() # Set to keep track of explored states

while fron er:


current_state = fron er.pople ()
if current_state == goal_state:
return current_state

explored.add(current_state)

# Get all possible ac ons from the current state


for ac on in ac ons(current_state):
new_state = perform_ac on(current_state, ac on)

# Only add the new state if it hasn't been explored


if new_state not in explored and new_state not in fron er:
fron er.append(new_state)

return None # No solu on found


# Set the ini al state and goal state
ini al_state = State(monkey_posi on=False, box_posi on=False,
has_banana=False)
goal_state = State(monkey_posi on=True, box_posi on=True,
has_banana=True)

# Run BFS to find the solu on


solu on = bfs(ini al_state, goal_state)
if solu on:
print(f"Goal reached! Final state: {solu on}")
else:
print("No solu on found")

Output:
Goal reached! Final state: Monkey(box), Box(under banana), Has banana
5. WRITE PROGRAM IN PROLOG FOR MEDICAL SCIENCES

% Facts: These represent known informa on about symptoms and diseases.


has_symptom(john, fever).
has_symptom(john, cough).
has_symptom(john, redness).
has_symptom(mary, fever).
has_symptom(mary, headache).
has_symptom(mary, sore_throat).
has_symptom(peter, cough).
has_symptom(peter, sneezing).
has_symptom(peter, runny_nose).

% Diseases: Facts that associate diseases with their common symptoms.


disease(flu, fever).
disease(flu, cough).
disease(flu, redness).
disease(cold, cough).
disease(cold, sneezing).
disease(cold, runny_nose).
disease(cold, sore_throat).
disease(covid, fever).
disease(covid, cough).
disease(covid, redness).
disease(covid, headache).
% Rule: If a person has a set of symptoms that match a disease, the person has
that disease.
diagnose(Person, Disease) :-
has_symptom(Person, Symptom),
disease(Disease, Symptom),
\+ (has_symptom(Person, OtherSymptom), disease(Disease,
OtherSymptom), OtherSymptom \= Symptom).

% Rule: Diagnose a person with a disease if the person has all symptoms of that
disease.
diagnose_person(Person, Disease) :-
findall(Symptom, disease(Disease, Symptom), Symptoms),
diagnose_with_symptoms(Person, Symptoms),
write(Person), write(' is diagnosed with '), write(Disease), nl.

% Rule to check if all symptoms match for a person


diagnose_with_symptoms(_, []).
diagnose_with_symptoms(Person, [Symptom | Rest]) :-
has_symptom(Person, Symptom),
diagnose_with_symptoms(Person, Rest).

% To find out the disease based on symptoms:


find_disease(Person) :-
diagnose_person(Person, Disease),
nl.
% Example query to diagnose based on symptoms:
% ?- find_disease(john).
% Output: john is diagnosed with flu

Output:
?- find_disease(john).
john is diagnosed with flu.
6. WRITE PROBLEM TO SOLVE MATHEMATICAL PROBLEM SUCH AS
CALCULATE FACTORIAL, GENERATE FABONACCI SERIES, ETC

 Calcula ng Factorial of a Number in Prolog

% Base case: Factorial of 0 is 1


factorial(0, 1).
% Recursive case: Factorial of N is N * factorial(N-1)
factorial(N, Result) :-
N > 0, % Ensure N is a posi ve number
N1 is N - 1,
factorial(N1, Result1),
Result is N * Result1.
Output:
?- factorial(5, Result).
Result = 120.

 Genera ng Fibonacci Series in Prolog

% Base cases
fibonacci(0, 0).
fibonacci(1, 1).
% Recursive case: Fibonacci of N is the sum of the two preceding Fibonacci
numbers
fibonacci(N, Result) :-
N > 1,
N1 is N - 1,
N2 is N - 2,
fibonacci(N1, Result1),
fibonacci(N2, Result2),
Result is Result1 + Result2.
Output:
?- fibonacci(6, Result).
Result = 8.

 Genera ng Fibonacci Series Up to a Given Number

% Base case: If the number is 0, the Fibonacci sequence ends


fib_up_to(0, [0]).
fib_up_to(1, [0, 1]).
% Recursive case: Generate Fibonacci sequence up to N
fib_up_to(N, Sequence) :-
N > 1,
fib_up_to(N1, Rest),
fibonacci(N, Fn),
append(Rest, [Fn], Sequence),
N1 is N - 1.
Output:
?- fib_up_to(6, Series).
Series = [0, 1, 1, 2, 3, 5, 8].
7. WRITE PROGRAM TO SOLVE 4-QUEEN/8-QUEEN PROBLEM

def is_safe(board, row, col, N):


# Check this column on the upper side
for i in range(row):
if board[i][col] == 1:
return False
# Check upper-le diagonal
for i, j in zip(range(row-1, -1, -1), range(col-1, -1, -1)):
if board[i][j] == 1:
return False
# Check upper-right diagonal
for i, j in zip(range(row-1, -1, -1), range(col+1, N)):
if board[i][j] == 1:
return False
return True
def solve_n_queens(board, row, N):
# If all queens are placed, return True
if row >= N:
return True
# Consider this row and try placing this queen in all columns one by one
for col in range(N):
if is_safe(board, row, col, N):
# Place the queen on the board
board[row][col] = 1
# Recur to place the next queen
if solve_n_queens(board, row + 1, N):
return True
# If placing queen in the current posi on doesn't lead to a solu on
# then backtrack: Remove the queen from the current posi on
board[row][col] = 0
# If the queen cannot be placed in any column in this row, return False
return False
def print_board(board, N):
for row in range(N):
for col in range(N):
print('Q' if board[row][col] else '.', end=" ")
print()
def n_queens(N):
# Create an empty board
board = [[0 for _ in range(N)] for _ in range(N)]
# Solve the N-Queens problem using backtracking
if not solve_n_queens(board, 0, N):
print("Solu on does not exist")
return
# Print the solu on
print_board(board, N)
# Example usage for the 8-Queens problem
n_queens(8)
Output:
Q.......
....Q...
......Q.
.......Q
.Q......
...Q....
..Q.....
.....Q..
8. WRITE A PROGRAM TO SOLVE TRAVELLING SALESMAN PROBLEM

import itertools
def calculate_total_distance(permuta on, distance_matrix):
total_distance = 0
for i in range(len(permuta on) - 1):
total_distance += distance_matrix[permuta on[i]][permuta on[i + 1]]
total_distance += distance_matrix[permuta on[-1]][permuta on[0]] #
Returning to the star ng city
return total_distance
def traveling_salesman_bruteforce(distance_matrix):
# Get all permuta ons of ci es (excluding the star ng city)
n = len(distance_matrix)
ci es = list(range(n))
# Generate all possible routes
min_route = None
min_distance = float('inf')
# Try every possible route (brute force approach)
for perm in itertools.permuta ons(ci es[1:]): # Start from city 0
route = [ci es[0]] + list(perm)
distance = calculate_total_distance(route, distance_matrix)
# Update the minimum distance and route
if distance < min_distance:
min_distance = distance
min_route = route
return min_route, min_distance
def print_solu on(route, distance):
print("Op mal Route: ", " -> ".join(map(str, route)))
print("Minimum Distance: ", distance)
# Example usage:
# Distance matrix (example with 4 ci es)
# The distance matrix should be symmetric (distance from city A to B is same as
from B to A)
distance_matrix = [
[0, 10, 15, 20],
[10, 0, 35, 25],
[15, 35, 0, 30],
[20, 25, 30, 0]
]
route, distance = traveling_salesman_bruteforce(distance_matrix)
print_solu on(route, distance)
Output:
0 10 15 20
10 0 35 25
15 35 0 30
20 25 30 0
9. WRITE PROGRAM TO SOLVE WATER JUG PROBLEM

from collec ons import deque


# Define the state as a tuple (amount of water in jug1, amount of water in jug2)
def bfs_water_jug_problem(x, y, z):
# If z is greater than the maximum of x and y, or z is not a mul ple of gcd(x,
y), return False
if z > max(x, y):
print(f"Target amount {z} is not reachable with jugs of capacity {x} and {y}")
return False
# BFS setup
queue = deque() # Queue to store the state (amount of water in jug1,
amount of water in jug2)
visited = set() # To avoid revisi ng the same state
# Ini al state (0, 0) meaning both jugs are empty
queue.append((0, 0))
visited.add((0, 0))
# List of all possible ac ons
ac ons = [
("Fill Jug1", lambda a, b: (x, b)), # Fill Jug1
("Fill Jug2", lambda a, b: (a, y)), # Fill Jug2
("Empty Jug1", lambda a, b: (0, b)), # Empty Jug1
("Empty Jug2", lambda a, b: (a, 0)), # Empty Jug2
("Pour Jug1 to Jug2", lambda a, b: (max(0, a - (y - b)), min(y, a + b))), # Pour
Jug1 to Jug2
("Pour Jug2 to Jug1", lambda a, b: (min(x, a + b), max(0, b - (x - a)))) # Pour
Jug2 to Jug1
]
# Perform BFS
while queue:
a, b = queue.pople ()
# If we reached the target, print the steps
if a == z or b == z:
print(f"Target of {z} liters achieved with jugs {x} and {y}")
return True
# Try all possible ac ons
for ac on, func in ac ons:
new_a, new_b = func(a, b)
if (new_a, new_b) not in visited:
visited.add((new_a, new_b))
queue.append((new_a, new_b))
print(f"Ac on: {ac on} => Jug1: {new_a}, Jug2: {new_b}")
# If no solu on is found
print(f"Solu on not found for target {z}")
return False
# Example usage
x = 4 # Capacity of jug 1
y = 3 # Capacity of jug 2
z = 2 # Target amount to measure
bfs_water_jug_problem(x, y, z)
Output:
Ac on: Fill Jug1 => Jug1: 4, Jug2: 0
Ac on: Pour Jug1 to Jug2 => Jug1: 1, Jug2: 3
Ac on: Empty Jug2 => Jug1: 1, Jug2: 0
Ac on: Pour Jug1 to Jug2 => Jug1: 0, Jug2: 1
Ac on: Fill Jug1 => Jug1: 4, Jug2: 1
Ac on: Pour Jug1 to Jug2 => Jug1: 2, Jug2: 3
Target of 2 liters achieved with jugs 4 and 3
10. WRITE PROGRAM TO SOLVE TIC-TAC TOE PROBLEM

# Func on to print the Tic-Tac-Toe board


def print_board(board):
for row in board:
print(" | ".join(row))
print("-" * 5)
# Func on to check if a player has won
def check_win(board, player):
# Check rows, columns, and diagonals for a win
for i in range(3):
# Check rows and columns
if all([cell == player for cell in board[i]]) or all([board[j][i] == player for j in
range(3)]):
return True
# Check diagonals
if all([board[i][i] == player for i in range(3)]) or all([board[i][2 - i] == player for
i in range(3)]):
return True
return False
# Func on to check if the board is full (draw condi on)
def check_draw(board):
for row in board:
if " " in row:
return False
return True
# Func on to take a player's move
def player_move(board, player):
while True:
try:
move = int(input(f"Player {player}, enter your move (1-9): "))
if move < 1 or move > 9:
print("Invalid input. Please enter a number between 1 and 9.")
con nue
row, col = divmod(move - 1, 3)
if board[row][col] != " ":
print("Cell already taken. Please choose another cell.")
else:
board[row][col] = player
break
except ValueError:
print("Invalid input. Please enter a valid number between 1 and 9.")
# Main func on to play the game
def c_tac_toe():
board = [[" " for _ in range(3)] for _ in range(3)] # Ini alize empty 3x3 board
players = ["X", "O"] # Player 1 is "X" and Player 2 is "O"
turn = 0 # Start with Player 1
while True:
print_board(board)
# Player's turn
player = players[turn % 2]
player_move(board, player)
# Check for win
if check_win(board, player):
print_board(board)
print(f"Player {player} wins!")
break
# Check for draw
if check_draw(board):
print_board(board)
print("It's a draw!")
break
# Switch turn
turn += 1
# Start the game
c_tac_toe()

Output:
| |
---------
| |
---------
| |
Player X, enter your move (1-9): 1
X| |
---------
| |
---------
| |
Player O, enter your move (1-9): 5
X| |
---------
|O|
---------
| |
Player X, enter your move (1-9): 2
X|X|
---------
|O|
---------
| |
Player O, enter your move (1-9): 9
X|X|
---------
|O|
---------
| |O
Player X, enter your move (1-9): 3
X|X|X
---------
|O|
---------
| |
Player X wins!

You might also like