BHASKAR INSTITUTE OF TECHNOLOGY AND SCINECE
2025 - 2026
ARTIFICIAL INTELLIGENCE LAB
R23-REGULATION
For
B.Tech III Year I Sem (C5E & AI)
DEPARTMENT OF COMPUTER SCONCE AND ENGINEERING
BHASKAR INSTITUTE OF TECHNOLOGY AND SCIENCE
BANDAPALLI, RAYACHOTY.ANNAMAYYA (Dist.).
ANDHRA PRADESH — 516270
1. Program to Implement Breadth First Search using Python
Program:
graph = (
'A' : [’B','C’],
'B' : ['D', 'E’],
'C' : [’F’],
'D' : [],
'E' : [’F’],
'F' : []
visited = [] # List to keep track of visited nodes.
Queue = [] #Initialize a queue
def bfs(visited, graph, node):
visited.append(node)
Queue.append{node
) while Queue:
s = Que ue.pop(0)
print (s, end =" ")
for neighbour in graph[s]:
if neighbour not in visited:
visited.append(neighbour)
Queue.append(neighbour)
bfs{visited, graph, A‘)
ABCDEF
2. program to implement Best First Searching Algorithm
Program’
import heapq
def best first search(graph, heuristics, start, goal):
visited = set()
priority queue = []
heapq. heappush(priority queue, {heuristics{start], start))
path = []
while prio rity que ue:
h, current node = heapq.heappop(priority queue)
if current n ode in visited:
cont in e
visited.add(current node}
path append(current node)
print{f"Visited’ (current node}")
if current node == goal:
print("Goal reached!")
return path
for neighbor in graph[current node]:
if neighbor not in visited:
heapq heappush(priority queue, (heuristics[neighbor], neighbor))
return path
graph = (
’A': [’B', ’C'],
’B“. |'D', 'E’],
’C': [’F’],
’D’: [],
heuristics = t
'A:6,
’B’: 4,
'C': 5,
'D'' 2,
'E': 3,
'F': 0
Start node= 'A'
goaI_node = '£'
path = best first searchTgraph, heuristics, start node, goal node)
print("\nPath:", " -> '.join(path))
Output:
Visited: A
Visited' B
Visited: D
Visited' E
Visited: F
6oaIreached!
Path:A-›B.›D-›E -›f
3. Program to Implement Depth First Search using Python.
Program:
graph =
('3','7'],
'3' : ['2', '4'],
'7' : ['8’],
'2' : [),
'4' : ['8’],
'8' : []
visited = set() # Set to keep track of visited nodes of graph.
def dfs(visited, graph, node): #function for dfs
if node not in visited:
print (node)
visited.add(node)
for neighbour in graph[node]:
dfs(visited, graph, neighbour)
# Driver Code
print("Following is the Depth-First Search")
dfs(visited, graph, '5')
output:
Following is the Depth-First Search
S
3
2
4
7
4. program to implement the Heuristic Search.
Program:
import heapq
def a star search(graph, heuristics, start, goal):
# Priority queue stores (f(n), g(n), node, path)
open list = []
heapq.heappush(open list, (heuristics[start], 0, start, [start]))
visited = set()
while Dpen list:
f, g, ct rrent, path - heapq.heappop(open list)
if current in visited:
continue
visited.add(current)
print(f"Visiting: (current} with path: (path) and cost: (g)")
if current == goal:
print("GDal reached!"
return path, g
for neighbor, cost in graph.get(current, []):
if neighbor not in visited:
g new = g + cost
f new = g new + heuristics[neighbor]
heapq.heappush{open list, (f new, g new, neighbor, path + [neighbor]))
return None, float(’inf')
# Example graph: adjacency list with (neighbor, cost)
graph
'A': [('B', IQ, ('C', 3)),
'B': [(’D', 3), ('E', 1)],
'C'. (l'F', 5l},
# heuristics estimated cost from node to goal
heuristics - (
'A' 6,
’B': 4,
'E': 3,
ë Start and Goal
start node = 'A'
goal node = 'F'
ë Run A* Search
path, total cost = a star search(graph, heuristics, start node, goaI_node)
print("\nOptimaI Path: , ' -> ".join(path))
print("Total Cost:", totaI_cost)
0 utput:
Visiting: A with path: 'A'] and cost: 0
Visiting: B with path: ['A', 'B'] and cost: 1
Visiting: E with path: ['A', 'B', 'E' and cost: 2
Visiting: F with path: 'A', 'B', 'E', 'F'] and cost: 4
Goal reached!
Optimal Path: A -> B -> E -> F
Total Cost: 4
5. python program to implement A* and AO” algorithm.
(Ex: find the shortest path)
Program:
import heapq
# ---------------- A‘ Search Implementation -----------—-- #
def a star search(graph, heuristics, start, goalj:
open list = []
heapq.heappush(open list, (heuristics(start], 0, start, [start])
while open list:
f, g, current, path = heapq.heappop(open list)
if current -= goal:
print{"A* Path:"," -> ".join(paths)
print("Total Cost:", g)
return path
for neighbor, cost in graph.get(current, (]):
g new - g + cost
f new = g new + heuristics[neighbor]
heapq.heappush(open list, {f new, g new, neighbor, path + [neighbor]))
return None
# --------------- AO* Algorithm Implementation---------------- #
class AOStar:
def init (self, graph, heuristics):
self.graph - graph
sel f.heuristics = heuristics
self.solution graph - {)
sel f. status - ()
self.parent - )
def ao star(self, nodes:
print(f"Expanding Node: (node)"j
if node not in self.graph or len(self.graph(node]j -= 0:
self.status(node] = "solved"
return self.heuristics[node]
min cost - float(’inf')
best path = None
for branch in self.graph[nodes:
COST Q
for child, edge cost in branch:
cost += edge cost + self.heuristics[childs
if cost < min cost:
min cost - cost
best path — branch
self.heuristics[node] = min cost
self.solution graph[node] = best path
solved = True
for child, in best path:
if self.status.get(childs != "solved":
self.parent[childs = node
self.ao star{chi d
if self.status.get(child) != "solved":
solved = False
if solved:
self.status[node] = "solved"
return self. he uristics[node]
def print_soIution(self, node):
if n ode n at in self. solut ion grap h:
print(node)
ret urn
print(node, end=" -> ")
children = self.solution graph[node]
for child, in children:
self.print solution(child)
# ---------------- Example Inputs ---------
# Graph for A‘ Search (weighted, no AND/OR)
a star raph = (
'A': [('B', 1), ('C', 3) ,
'B': ['D, 3) (E, 1)
'C': ('F', 5) ,
’D“. [],
'E': (’F', 2)],
’F“. []
heuristics astar = (
’A': 6, 'B': 4, ’C’: 5,
’D“. 2, 'E“. 3, 'F': 0
# Graph for AO’ Search (AND-OR graph]
# Each node maps to a list of branches, where each branch is a list of (child, cost)
ao graph=(
'A': [[('B', 1), ('C', )], [('D', 2)] ,
'B': [[('E', 1)]],
'C': [[('F', 1)]],
'D“. [[(’G', 1), ('H', ) ,
’E': [],
’F“. [],
’G’: [],
’H’: []
heuristics ao = (
'A': 999, 'B'. 3, 'C': 2, 'D' : 4,
’E': 2, 'F': 2, 'G': 1, 'H': 3
Both Algorithms
print("\n--- A’ Search ---")
print("\n--- AO’ Search ---")
aostar = AOStar(ao raph, heuristics ao)
aostar.ao star('A')
print("AO’ Solution Path:")
aostar. print solution(’A')
0 utput:
- - A“ Search --
A* Path: A -> B -> E -> F
Tot aI Cost: 4
- - AO* Search ---
Expanding Node. A
Expanding Nocle. D
Expanding Node. G
Expanding Nocle. H
AU* Solution Path:
A -> D -> G
H
6. Program to Implement Water-Jug problem using Python.
from cDllections import deque
# Function to check if the current state is the goal state
def is goal state(state, goal):
return state[0] == gDal or state[1J == goal
# Function to perform all possible moves
def get possible moves(capacity a, capacity b, state):
moves= [
a, b = state
# 1. Fill Jug A completely
if a < capacity a:
moves.append((capacity a, b))
# 2. Fill Jug B completely
if b < capacity b:
moves.append((a, capacity b)
# 3. Empty Jug A
if a > 0:
moves.append((0, b))
# 4. Empty Jug B
i b > 0:
moves.append((a, 0))
# 5. Pour water from Jug A to Jug B
if a > 0 and b < capacity b:
pour = min(a, capacity b - b
moves.append((a - pour, b + pour))
# 6. Pour water from Jug B to Jug A
i b > 0 and a < capacity a:
pour = min(b, capacity a - a)
moves.append((a + pour, b - pour))
return moves
# BFS function to solve the Water Jug problem
def water_jug bfs(capacity a, capacity b, goal):
# Initial state: both jugs are empty
start state = (0, 0)
# Queue for BFS
queue = deque([(start state, [])]) # (state, path)
visited = set([start state])
while queue:
current state, path = queue.popIeft(
/t If we have reached the goal state
if is goal state(current state, goal):
return path + |current state)
# Generate all possible moves from the current state
for move in get possible moveslcapacity a, capacitv b, current state):
if move not in visited’
visited.add(move)
queue.append((move, path + current state]))
return None # If no solution is found
a Function to print the solution path
def print solution(solution):
print("Steps to reach the goal:")
for state in solution’
print(f"Jug A’ (state[0)) liters, Jug B: estate[1]) liters")
else:
print(' No solution found!")
# Main function to solve the Water Jug Problem
def main()'
# Input capacities of the jugs and the goal
capacity a = int(input(" Enter capacity of Jug A: ))
capacity b - int(input("Enter capacity of Jug B: "))
goal = int(inputl"Enter the goal (amount of water to measure): "))
if goal > max(capacity a, capacity b):
print(f"Goal is nat pDsSible with the given jugs. It must be less than or equal to the larger jug's
capacity.")
return
# SDlve the problem using BFS
solution = water_jug bfs(capacity a, capacity b, goal)
# Print the solution
print solution(solution)
if name main ":
main()
0 utput:
Enter capacity of Jug A: 3
Enter capacity of Jug B: 2
Enter the goal (amDunt of water to measure): 1
Steps to reach the goal:
Jug A: 0 liters, Jug B: 0 liters
Jug A: 3 liters, Jug B: 0 liters
Jug A: 1 liters, Jug B: 2 liters
7. Program to Implement Alpha-Beta Pruning using Python.
Program:
# A slmple game tree structure for Alpha-Beta Prunlng
# Function to Implement the Alpha-Beta Prunlng
def aIpha_beta_pruning(node, depth, alpha, beta, maxImizing_pIayer):
If depth -= 0 or is_termlnaI(node): # If we reach a leaf node or max depth
return evaluate(node)
If maxImizing_pIayer: # Maxlmizer's move
max_evaI - float('-inf')
for chlld In get_chiIdren(node):
eval = alpha_beta_prunlng(child, depth-1, alpha, beta, False)
max_evaI - max(max_evaI, eval)
alpha - max(alpha, eval)
both <= alpha: # Beta cut-off(pruning)
break
return max_evaI
else: it Minimizer's move
min_evaI - float('inf')
for ch1Id In get_chIIdren(node):
eval = aIpha_beta_prunIng(child, depth-1, alpha, beta, True)
mIn_evaI = min(min_evaI, eval)
beta = mIn(beta, eval)
if beta <= alpha: # Alpha cut-off (pruning)
break
return min eval
# A utility function to evaluate the node (for simplicity, we assume it returns a static value)
def evaluate(node):
return node # Assuming node contains the score directly
# Function to get children of a node fa r simplicity, assume it returns a list of possible child nodes)
def get children(node):
# Here, the children are just numbers representing the next possible states (you can expand this)
# In an actual game, you would generate the possible next states {children) from the current node
return anode - 1, node + 1, node - 2]
# Function to check i the node is terminal (for simplicity, we assume that terminal nodes are those
with value <= 0j
def is terminal{node):
return node <= 0
# MB in function to execute Alpha- Beta Pruning
def main():
initial node - 4 Starting point (root of the tree)
depth = 3 depth of the search tree
alpha = float(’-inf') ft Initial alpha value
beta = float(’inf’) 4 Initial beta value
maximizing player = True # True means it's the maximizing player's turn
result = alpha beta pruning(initial node, depth, alpha, beta, maximizing player)
print(f™The optimal value is: (result)"
if name ==" main ”
main()
Output:
The optimal value is: 4
8. Program to implement 8-Queens Problem using Python.
Program:
# Function tD print the chessboard configuration
def print board(board):
N = len(board)
for i in range(N):
row = [’Q’ if board[i] == j else ’.’ for j in range(N)]
print(' ’.join(row))
print()
# Function tD check if a queen can be placed at board[row][col]
def is safe(board, row, CDI):
N = len(board)
# Check the column for any queen
for i in range(row):
if board[i] == col or bDard[i] - i == col - row a r board[i] + i == col + row:
ret urn False
return True
# Backtracking function to solve the 8-Queens problem
def solve 8 queens(board, row):
N = len(board)
# If all queens are placed
if row == N :
print board(board)
return True # Return true to indicate that a solution was found
# Try placing the queen in all columns one by one
for col in range(N):
if is safe(board, row, col):
board[row] = col # Place the queen
# Recur to place the queen in the next row
if solve 8 queens(board, row + 1):
return True # If placing queen leads to a solution, return true
board[row] = -1 # Backtrack if placing queen doesn't lead to a solution
return False # Return false if no valid placement is found
# Function to solve the 8-Queens problem
def eight queens():
N = 8 # We have an 8x8 chessboard
board = [-1] * N # Initialize board with -1, indicating no queen placed yet
if not solve 8 queens(board, 0):
print("No solution exists.")
# Main function to run the 8-Queens solver
if name ==" main ":
eight queens()
0 utput:
9. program to schedule a meeting among a 5 busy people
using Default Reasoning the output should give the time,
place and day of the meeting.
Program:
from collectlons import defaultd ct
# Deflne the structure for a person
class Person:
def inlt (self, name, avaTIabIIity):
self.name - name
self.availability = availability # A dlctlonary wlth day -> available tlmes
# Function to schedule the meeting
def scheduIe_meetlng(people, defauIt_day, defauIt_tlme, defauIt_pIace):
Dictionary to track available time slots for all people
time slots = defauItdlct(int) # day -> available count of people
# Loop through each person's avallablllty and count available slots
for person in people:
for day, times In person.avaiIabi 1ty.items():
for time In times:
t1me_sIots((day, tlme)j += 1
# find a time slot where the majority of people are available
best_time = None
max_avaTIabTI›ty = 0
for (day, tlme), count in time slots.Items():
if count > max availability:
best time = (day, time)
max availability - count
if best time:
# If we find a suitable time, return the schedule
return best time[0], bE'St time[1], default place
else:
# If no optimal slot is found, fallback to default assumptions
return default day, default time, default place
# Define people and their availability
people =
Person("Alice", ("Monday”: ["9am", "10am"], "Tuesday": ["1pm"]}],
Person("Bob", {"Monday": "10am", "11am"], "Wednesday": ["9am"]) ,
Person("Charlie", ("Monday": ["9am"], "Tuesday": ["2pm"] ),
Person("Diana", ("Monday": "10am"],"Wednesday": "1pm" ),
Person("Eve", ("Tuesday": ["9am", "11am"],"Wednesday": ["9am"]) ,
# Default settings
default day= "wednesday"
default time = "9am"
default lace = "Conference Room A"
# Schedule the meeting
day, time, place = schedule meeting(people, default day, default time, default place)
P Output the result
print(f"The meeting is scheduled on (day) at {time) in (place).")
0 utput:
The meeting is scheduled on Monday at 10am in Conference Room A.
10. program to implement the Unification algorithm.
Program:
class Unificat ionError(Exce ption):
pass
def is variable(term):
"" 'Check if the term is a variable (i.e., a symbol that starts with a capital letter) """
return isinstance(term, str) and term[0].is upper()
def unify(term 1, term2, substitution=None):
"""Unifies two terms recursively."" '
if substitution is None:
substitution = (]
# Base case: if terms are equal, no need for further unification
if term1 == term 2:
return substitution
# Case 1: term1 is a variable and term2 is not
if is variable(term1):
return unify variable(term 1, term2, substitution)
# Case 2: term2 is a variable and term1 is not
if is variable(term2):
return unify variable(term2, term 1, substitution)
# Case 3: Both terms are compound terms (e g., functions)
if isinstance(term1, tuple) and isinstance(term2, tuple) and Ien{term 1) -= Ien(term2):
for t1, t2 in zip(term 1, term2):
substitution = unify{t 1, t2, substitution)
return substitution
# Case 4: No match found, terms cannot be unified
raise UnificationError(f"Cannot unify (term1) wlth {term2)")
def unify variable(var, term, substitution):
""' Handles the case where one of the terms is a variable."""
# If the variable is already in the substitution, substitute it
if var in substitution:
return unify(substitution(var], term, substitution)
# If term is the same as the variable, no substitution needed
if var == term:
return substitution
# If the term is a variable, we don't want a variable to unify with itself
if is variable(term):
raise Unifi¢ationError(f"Cannot unify {var) with tterm} as it leads to a cyclic substitution"I
# Perform the substitution
substitution(var] - term
return substitution
# Test cases for the unification algorithm
def test unification():
try:
# Unify simple terms
res ult = unify("X', "a")
print(f"Unific ation re sult: (resul t)")
# Unify compound terms
result = unify((' f", "X" , (" ", " "
print(f 'Unification re sult: {resul t)")
# Unify more complex compound terms
result = unify(("f", "X", "Y"}, ("I", "a", "b”))
print(f 'Unification re sult: {resul t)")
# Unify with failure case
res ult = unify("X”, "Y")
print(f 'Unification re sult: {resul t)")
except UnificationE rror as e:
print(f"Unification failed: te)")
if name == " main "
test_unification()
0 utput:
Unification re sult: ’X“. 'a’)
Unification re sult: ’X“. 'a’)
Unification re sult: ’X“. 'a’, 'Y“. 'b’
Unification failed: Cannot unify X with Y as i t leads to a cyclic substitution
11. Develop a knowledge base system consisting of
facts and rules about some specialized knowledge
domain
class KnowledgeBaseSystem:
init (self):
self.facts = set() # Facts about the patient's symptoms
self.diagnoses = [] # Diagnoses that will be inferred
def add fact(self, fact):
"""Add a new fact (symptom) to the facts lis
self.facts.add(fact)
def remove fact(self, fact):
"""Remove a fact {symptom) from the facts list."'"'
i fact in self.facts:
self.facts.remove{fact)
def check facts(self, symptoms]:
"""Check if the patient's symptoms match a rul
return symptoms.is subset(self.facts]
def infer diagnosis(self):
"""Infer diagnosis based on facts using predefined rules."""
# Define rules for diagnosing Flu, Cold, and COVID-19
rules = [
"diagnosis™: "Flu", "symptoms": ("Fever™, "Cough", "Fatigue")),
"diagnosis":" D d", "symptoms": ("Runny Nose", "Sore Throa Headache")),
"diagnosis": "COVID-19", "symptoms": ("Fever", "Cough", "Shortness of Breath™, "Loss of
Taste/Smell"))
for rule in rules:
if self.check facts(ruIe["symptoms")):
self.diagnoses.append(rule["diagnosis"])
def display diagnosis(self):
"""Display the possible diagnoses."""
if sell.diagnoses:
print("Possible Diagnoses based Dn Symptoms:")
for diagnosis in self.diagnoses:
print(f"- (diagnosis)")
else:
print("No diagnosis fDund. Consider consulting a healthcare professiDnal.")
# Example usage:
def main():
# Create an instance of the K nowledgeBaseSystem
kbs = KnowledgeBaseSystem()
# Add facts (symptoms) for the patient
kbs.add fact("Runny NDse")
kbs.add fact("Sore Throat")
kbs.add fact("Headache")
# Infer diagnosis based on facts
kbs.infer diagnosis()
# Display the possible diagnoses
kbs.display diagnosis()
# Example of adding another symptom and diagnosing again
print(" nAdding a new symptom (Headache]...")
kbs.add fact("Headache")
kbs. infer diagnosis()
kbs.display diagnDsiS()
if name ==" main ":
0 utput:
Possible Diagnoses based on Symptoms:
Adding a new symptom (headache).
Possible Diagnoses based on Symptoms:
.Cold
12.(a) 8 puzzle programs using different heuristics
Program:
import heapq
import time
# A class to represent a node in the search space for A’ algorithm
class NDde:
def init (self, bDard, g, h, parent=None] :
self.board = board # The current state of the puzzle (flat list)
self.g = g # Cost tD reach this node (number of moves)
self.h = h # Heuristic value (Manhattan distance or Misplaced tiles)
self.f = g + h # Total cost (f= g + h]
self.parent = parent # Parent node to reconstruct the path
def It (self, other] :
return self.f < other.f
# Heuristic: Manhattan Distance
def manhattan distance(board, goal state):
distance = 0
for i in range(9): # Iterate over all 9 positions in the flat board
value = board[i)
if value != 0: # Ignore the empty space (0)
goal pos = goal state.index(value)
goal i, goaI_j = diVFNDd(goal pos, 3) # Convert goal position to row and column
i row, i cot = di ad(i, 3) # Convert current position to row and column
distance += abs(i row - goal i) + abs(i col - goaI_j)
return distance
# Heuristic: Misplaced Tiles
def misplaced tiles(board, goal state):
return sum(1 for i in range(9) if board[i] != goal state[i] and board[i] != )
# A‘ Search Algorithm to solve the 8 Puzzle
def a star search(start state, goal state, heuristic func):
open list = []
closed list = set()
# Start node initialization
start node = Node(start state, 0, heuristic func(start state, goal state)]
heapq.heappush(open list, start node)
nodes generated = 0
cutoff values = [)
while open list:
current node = heapq.heappop(open list)
current state = current node.board
# If we have reached the goal state
if current state == goal state:
path = []
while current node:
path.append(current node.board)
current node = current node.parent
path.reverse(l
return path, nodes generated, cutoff values
P Generate child nodes (neighbors)
zero pos = current state.index(0I
x, y = divmod(zero pos, 3) # Get row and column for the empty space
# Possible moves (up, down, left, right)
moves = [(-1, 0), (1, 0), (0, -1t,(0, 1))
for dx, dy in moves'
it <= nx 3 and 0 - ny < 3’ P Ensure valid move within the 3x3 grid
new sta te - ¢urrent state[:]
new stated zero pos], new state(nx * 3 + ny] = new state[nx ’ 3 + ny],
new state(zero pos]
if tuple(new statel not in closed list:
g - current node g + 1
h - heuristic func(new state, goal state)
cutoff values.append(h) P Store cutoff values (heuristic values at each step)
nodes generated += 1
new node = Node(new state, g, h, current node)
heapq heappush(open list, new node)
closed list.add(tupIe{new state))
return None, nodes generated, cutoff values
# Print the solution path
def print solution(path):
for state in path:
for i in range(3]:
print(state[i”3:(i+1)’3])
print()
# Main function for running the 8 Puzzle
def run 8 puzzle():
start state = [1, 2, 3, 4, 6, 5, 0, 8, 7] # Unsolved puzzle state
goal state = {1, 2, 3, 4, 5, 6, 7, 8, 0] # Goal configuration (solved puzzle)
# Choose a heuristic: Manhattan Distance or M isplaced Tiles
print("Choose a heuristic:"j
print("1: Manhattan Distance")
print("2: Misplaced Tiles")
choice = int{input("Enter 1 or 2: ")
heuristic = manhattan distance if choice == 1 else misplaced tiles
# Start the A’ search
start time = time.time()
path, nodes generated, cutoff values = a star search{start state, goal state, heuristic)
end time = time.time()
if path:
print("Solution found!")
print_soIution(path)
print(f"Nodes generated: (nodes generated}")
print(f"Execution Time: {end time - start Iime:.6f) seconds' )
print("Cutoff values at each stage (Heuristic):", cutoff values}
else:
print("No solution found!")
run 8 puzzle()
Output:
Choose a heuristic:
1: Manhattan Distance
: Misplaced Tiles
Enter 1 or 2: 2
Solution found
|1, 2, 3)
|4, 6, S]
|O,8,7)
|1, 2, 3)
|0, 6, S]
|4,8,7)
|1, 2, 3)
|4, 8, 7]
|4, 0, 7]
|4, 7,0)
[1, 2, 3)
[6, 8, 0]
[1, 2, 3]
[6, 0, 8]
4, 7, 5|
[1, 2, 3]
[0, 6, 8]
[4, 7, 5]
[1, 2, 3]
[4, 6, 8]
[0, 7, 5]
[1, 2, 3]
[4, 6, 8]
[7, 0, 5]
[4, 6, 8]
[7, 5, 0]
[4, 6, 0)
|7, 5, 8
|1, 2, 3)
|4, 0, 6]
|7, 5, 8
|1,2,3)
|4, 5, 6]
|7, 0, 8
|1,2,3)
|4,5, 6)
|7, 8, 0]
Nodes generated: 423
Execution Time: 0.015644 seconds
Cutoff values ot each stage (Heuristic): (4, 4, S, 3, 4, 4, 4, 5, 5, 3, 5, 5, 3, 4, 3,
4, 4, 3, 6, 4, 3, , 3, , 3, , 5, , , 4, 2, , 3, 3, 3, 6, S, 5, 5, S, 6, 6, 5, 4, 4, 5, 4, 5, 5, 6, 6, 7, 5, S, , 5,
, , 6, 4, 5, , , 6, 7, 6, 6, 6, 4, 4, 7, 6, 5, 6, 5, , 5, 4, 3, 6, 3, 7, 3, 3, 5, , 6, S, 6, 5, 5, 4, S, 6, 6, 6, 6,
4, 6, 6, , 6, 6, 7, 6, 6, S, 4, 6, S, 7, 4, 4, 4, 6, 5, 5, , 6, 4, 3, 4, 6, 7, 8, 7, 6, 6, 7, 6, 5, 7, 7, 7, S, , 4, 6,
5, 7, 6, 6, 3, 7, 6, 7, , 3, 3, 4, 4, 6, 6, S, S, 4, 6, 4, 4, 6, 6, 7, , 7, 6, 7, , 6, 7, 6, 7, 7, 6, 6, S, , 6, 5, 5,
4, 7, 6, 6, 7, 6, 7, 5, 6, 6, 3, 4, 3, 6, 4, 4, 3, 5, 4, 6, 5, 5, 6, 3, 7, 5, 5, 7, 7, S, 6, S, 4, 7, 6, 6, 7, 7, 6, 5, 5,
6, , 5, 6, 6, 7, 6, 7, 7, 6, , 4, 7, 6, S, , 6, , 4, 3, S, S, 7, 4, 6, 5, 3, , 4, 4, 6, 6, 6, 7, 7, 6, 6, 6, S, 7, 6,
5, 6, 6, 7, 4, 5, 4, 3, 4, 8, 4, 7, 7, 7, , 6, 7, 7, 7, 6, 6, 7, 6, 7, , 6, 6, , 6, 6, , 6, , , S, 6, 7, 6, , , ,
6, 7, 6, 7, 8, 7, 4, 2, 6, 4, 3, 4, 3, 3, 3, 7, 8, 7, 7, 7, 7, 8, 6, 7, , 8, 7, 5, 7, 7, 8, 7, 7, 6, 6, 6, 7, 6, 5, 6, 5,
6, 7, 6, 7, 8, 5, 4, 2, 7, 7, 7, 6, 7, , S, , 8, 7, 7, 6, , S, 3, 4, 6, 6, 6, 5, 6, , 6, , 5, 7, 6, 6, 7, 6, 7, 6, 5,
5, 4, 6, 5, 5, 4, 4, 6, S, 7, 7, 4, 6, 6, , 6, 7, 4, 3, 7, 7, 6, 5, 7, 7, 7, 7, 7, 3, 1, 3, S, S, 8, 7, 2, 0, 6, 7]
12(b). play the game Tic-Tac-Toe at the end the game the program
should display the no. of nodes generated, cutoff values at each
stage in the form of a table.
import random
# Function to print the Tic-Tae-Toe board
def print board(board]:
print(f™\n(board(0]) | (board(1] | (board(2])"j
print(" ------ ")
print(f™(board[3 I I aboard[4]) | (board[5])")
print("------- ")
print(f"(board[6 I I aboard[7]) | (board[8])")
print()
# Check if a player has won
def check win(board, player]:
win combinations = [(0, 1, 2 , (3, 4, 5], (6, 7, 8 , (0, 3, 6), (1, 4, 7), {2, 5, 8), (0, 4, 8), {2, 4, 6)]
for comb in win combinations:
i board[comb[0 ) == board[comb[1]] == board(comb[2]] == player:
return True
return False
# Minimax algorithm
def minimax(board, depth, is maximizing, nodes generated):
if check win(board, "X"):
return -1 # X is the opponent, AI loses
if check win(board, "0"):
return 1 # 0 is the AI, AI wins
if not any(space ==" " for space in board): # Draw
return D
if is maximizing:
best value = -float('ink’)
for i in range(9}:
if board[i] ==" "
board[i] = "0'
best value = max(best value, minimax(board, depth + 1, False, nodes generated))
board[i] =""
nodes generated [0] += 1
return best value
else:
best value = float(’inf')
for i in range(9}:
if board[i] ==" "
board[i] = "X"
best value = min(best value, minimax(board, depth + 1, True, nodes generated))
board[i] =" "
nodes generated [0] += 1
return best value
# AI Move (using minimax)
def ai move(board):
best value = -float('inf’)
best move = -1
nodes generated = [0)
far i in range(9):
bDa d i] ="0"
move value = minimax(board, 0, False, nodes generated)
board[]=""
if move value > best value:
best value = move value
best move = i
print(f"AI chose position {best move + 1)")
board[best move] = "0"
return nDdes generated[0]
#PayT -Tac-Toe
def play game():
board = ["" for in range(9)]
print board(board)
# Player vs AI game
while" "inboard:
player move = int(input("Enter your move (1-9] : ")) - 1
if board[pl ayer mDve] ==" " :
board [player move] = "X"
if check win(board, "X"):
print board(board)
print("You win!' )
break
if " ' not in board’
print board{board
print("It's a draw! )
break
print board(board)
4 AI move
ai move(board)
if check win(board, 'O"):
print board(board)
print("AI wins!")
break
# Start the Tic-Tac-Toe game
play game()
0 utput:
Enter your move (1-9]: 2
As chose position 1
0I* I
Enter your move (1-9]: 5
0 I /1
IxI
AT chose position 8
IxI
10
Enter your move (1-9 4
0| X
10
Ai chose position 6
10
Enter your move (1-9l’ 9
O| X
X| X| 0
10 | X
Al chose position 3
0 IX10
X | "X" | 0
10 | X
En|eryour move(1.9)' 7
X|X|O
X| 0 I X
It's a draw!