Practical No.
1
Building an Expert System Using Rule-Based Systems - Objective: Develop an
Expert System that provides simple decision-making.
Code
def expert_system():
print("Welcome to the Simple Medical Expert System")
print("Answer with yes or no\n")
fever = input("Do you have fever? ").lower()
cough = input("Do you have cough? ").lower()
headache = input("Do you have headache? ").lower()
fatigue = input("Do you feel tired or weak? ").lower()
if fever == "yes" and cough == "yes":
print("\nPossible Diagnosis: You may have the FLU.")
elif fever == "yes" and headache == "yes" and fatigue == "yes":
print("\nPossible Diagnosis: You may have MALARIA.")
elif cough == "yes" and fever == "no":
print("\nPossible Diagnosis: You may have a COLD.")
elif headache == "yes" and fatigue == "no":
print("\nPossible Diagnosis: You may have a STRESS headache.")
else:
print("\nDiagnosis unclear. Please consult a doctor.")
expert_system()
Practical No.2
Implementing AI Search Algorithms (BFS & DFS) - Maze Solver Objective:
Solve AI search problems using Graph Search Algorithms.
Code
from collections import deque
maze = [
[0, 1, 0, 0, 0],
[0, 1, 0, 1, 0],
[0, 0, 0, 1, 0],
[1, 1, 0, 0, 0], ]
start = (0, 0)
goal = (3, 4)
directions = [(-1,0), (1,0), (0,-1), (0,1)]
def is_valid(x, y):
return 0 <= x < len(maze) and 0 <= y < len(maze[0]) and maze[x][y] == 0
def bfs(start, goal):
queue = deque([(start, [start])]) # (current_position, path)
visited = set([start])
while queue:
(x, y), path = [Link]()
if (x, y) == goal:
return path # Found the goal
for dx, dy in directions:
nx, ny = x + dx, y + dy
if is_valid(nx, ny) and (nx, ny) not in visited:
[Link]((nx, ny))
[Link](((nx, ny), path + [(nx, ny)]))
return None
def dfs(start, goal):
stack = [(start, [start])]
visited = set([start])
while stack:
(x, y), path = [Link]()
if (x, y) == goal:
return path
for dx, dy in directions:
nx, ny = x + dx, y + dy
if is_valid(nx, ny) and (nx, ny) not in visited:
[Link]((nx, ny))
[Link](((nx, ny), path + [(nx, ny)]))
return None
print("Maze:")
for row in maze:
print(row)
bfs_path = bfs(start, goal)
dfs_path = dfs(start, goal)
print("\nBFS Path:", bfs_path)
print("DFS Path:", dfs_path)
Practical No.3
Implementation of A* algorithm Objective: Solve AI search problems using
Graph Search Algorithm.
Code
from queue import PriorityQueue
def a_star_search(graph, start, goal, heuristic):
open_list = PriorityQueue()
open_list.put((0, start))
came_from = {}
g_cost = {node: float('inf') for node in graph}
g_cost[start] = 0
while not open_list.empty():
current_cost, current_node = open_list.get()
if current_node == goal:
path = []
while current_node in came_from:
[Link](current_node)
current_node = came_from[current_node]
[Link](start)
[Link]()
return path, g_cost[goal]
for neighbor, cost in graph[current_node].items():
new_cost = g_cost[current_node] + cost
if new_cost < g_cost[neighbor]:
g_cost[neighbor] = new_cost
f_cost = new_cost + heuristic[neighbor]
open_list.put((f_cost, neighbor))
came_from[neighbor] = current_node
return None, float('inf')
graph = {
'A': {'B': 1, 'C': 4},
'B': {'A': 1, 'C': 2, 'D': 5},
'C': {'A': 4, 'B': 2, 'D': 1},
'D': {'B': 5, 'C': 1}
}
heuristic = {
'A': 7,
'B': 6,
'C': 2,
'D': 0
path, cost = a_star_search(graph, 'A', 'D', heuristic)
print("Shortest Path:", path)
print("Total Cost:", cost)
Practical No. 4
Implement a solution for Constraint Satisfaction Problem (CSP) Objective: To
implement a CSP-based solution for solving real-world problems like Map
Coloring, Sudoku, or Timetable Scheduling using backtracking with constraint
propagation.
Code
puzzle = [
[5, 3, 0, 0, 7, 0, 0, 0, 0],
[6, 0, 0, 1, 9, 5, 0, 0, 0],
[0, 9, 8, 0, 0, 0, 0, 6, 0],
[8, 0, 0, 0, 6, 0, 0, 0, 3],
[4, 0, 0, 8, 0, 3, 0, 0, 1],
[7, 0, 0, 0, 2, 0, 0, 0, 6],
[0, 6, 0, 0, 0, 0, 2, 8, 0],
[0, 0, 0, 4, 1, 9, 0, 0, 5],
[0, 0, 0, 0, 8, 0, 0, 7, 9]
]
def print_grid(grid):
for i in range(9):
if i % 3 == 0 and i != 0:
print("- - - - - - - - - - - -")
for j in range(9):
if j % 3 == 0 and j != 0:
print(" | ", end="")
if j == 8:
print(grid[i][j])
else:
print(str(grid[i][j]) + " ", end="")
def find_empty(grid):
for i in range(9):
for j in range(9):
if grid[i][j] == 0:
return (i, j)
return None
def is_valid(grid, num, row, col):
if num in grid[row]:
return False
for i in range(9):
if grid[i][col] == num:
return False
start_row = (row // 3) * 3
start_col = (col // 3) * 3
for i in range(start_row, start_row + 3):
for j in range(start_col, start_col + 3):
if grid[i][j] == num:
return False
return True
def solve_sudoku(grid):
find = find_empty(grid)
if not find:
return True
else:
row, col = find
for num in range(1, 10):
if is_valid(grid, num, row, col):
grid[row][col] = num
if solve_sudoku(grid):
return True
grid[row][col] = 0 # backtrack
return False
print("Original Sudoku:")
print_grid(puzzle)
print("\nSolving...\n")
if solve_sudoku(puzzle):
print("Sudoku Solved:")
print_grid(puzzle)
else:
print("No solution found.")
Practical No.5
Implementing Minimax Algorithm Objective: Understand and implement the
basic Minimax algorithm for two-player deterministic games.
Code
board = [" " for _ in range(9)]
def print_board():
print()
for i in range(3):
print(board[3*i], "|", board[3*i+1], "|", board[3*i+2])
if i < 2:
print("--+---+--")
print()
def check_winner(b):
wins = [(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 x,y,z in wins:
if b[x] == b[y] == b[z] and b[x] != " ":
return b[x]
return None
def is_full(b):
return " " not in b
def minimax(b, is_maximizing):
winner = check_winner(b)
if winner == "X": # Human
return -1
elif winner == "O": # Computer
return 1
elif is_full(b):
return 0
if is_maximizing:
best_score = -999
for i in range(9):
if b[i] == " ":
b[i] = "O"
score = minimax(b, False)
b[i] = " "
best_score = max(score, best_score)
return best_score
else:
best_score = 999
for i in range(9):
if b[i] == " ":
b[i] = "X"
score = minimax(b, True)
b[i] = " "
best_score = min(score, best_score)
return best_score
def computer_move():
best_score = -999
move = 0
for i in range(9):
if board[i] == " ":
board[i] = "O"
score = minimax(board, False)
board[i] = " "
if score > best_score:
best_score = score
move = i
board[move] = "O"
while True:
print_board()
if check_winner(board) or is_full(board):
break
move = int(input("Enter your move (0-8): "))
if board[move] == " ":
board[move] = "X"
else:
print("Invalid move!")
continue
if check_winner(board) or is_full(board):
break
computer_move()
print_board()
winner = check_winner(board)
if winner == "X":
print("You win!")
elif winner == "O":
print("Computer wins!")
else:
print("It's a draw!")
Practical No.6
Minimax with Alpha-Beta Pruning Objective: Enhance Minimax using Alpha-
Beta pruning to reduce computation time.
Code
import math
import copy
def print_board(board):
for r in range(3):
print(board[3*r] + '|' + board[3*r+1] + '|' + board[3*r+2])
if r < 2: print('-+-+-')
print()
def available_moves(board):
return [i for i, v in enumerate(board) if v == ' ']
def check_winner(board):
wins = [
(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 a,b,c in wins:
if board[a] == board[b] == board[c] and board[a] != ' ':
return board[a]
if ' ' not in board:
return 'Draw'
return None
nodes_plain = 0
def minimax_plain(board, is_maximizing):
global nodes_plain
nodes_plain += 1
winner = check_winner(board)
if winner == 'X': return 1
if winner == 'O': return -1
if winner == 'Draw': return 0
if is_maximizing:
best = -[Link]
for mv in available_moves(board):
board[mv] = 'X'
val = minimax_plain(board, False)
board[mv] = ' '
best = max(best, val)
return best
else:
best = [Link]
for mv in available_moves(board):
board[mv] = 'O'
val = minimax_plain(board, True)
board[mv] = ' '
best = min(best, val)
return best
nodes_ab = 0
def minimax_ab(board, is_maximizing, alpha=-[Link], beta=[Link]):
global nodes_ab
nodes_ab += 1
winner = check_winner(board)
if winner == 'X': return 1
if winner == 'O': return -1
if winner == 'Draw': return 0
if is_maximizing:
value = -[Link]
for mv in available_moves(board):
board[mv] = 'X'
value = max(value, minimax_ab(board, False, alpha, beta))
board[mv] = ' '
alpha = max(alpha, value)
if alpha >= beta:
# Beta cut-off
break
return value
else:
value = [Link]
for mv in available_moves(board):
board[mv] = 'O'
value = min(value, minimax_ab(board, True, alpha, beta))
board[mv] = ' '
beta = min(beta, value)
if alpha >= beta:
break
return value
def best_move_plain(board):
best_val = -[Link]
best_mv = None
for mv in available_moves(board):
board[mv] = 'X'
val = minimax_plain(board, False)
board[mv] = ' '
if val > best_val:
best_val = val
best_mv = mv
return best_mv, best_val
def best_move_ab(board):
best_val = -[Link]
best_mv = None
alpha = -[Link]
beta = [Link]
for mv in available_moves(board):
board[mv] = 'X'
val = minimax_ab(board, False, alpha, beta)
board[mv] = ' '
if val > best_val:
best_val = val
best_mv = mv
alpha = max(alpha, best_val)
return best_mv, best_val
if __name__ == "__main__":
# Example board: 'X' to move.
# Use an intermediate position to make search meaningful:
#X|O|X
# -+-+-
# |O|
# -+-+-
# | |
board = ['X','O','X',
' ','O',' ',
' ',' ',' ']
print("Current board:")
print_board(board)
nodes_plain = 0
mv_plain, val_plain = best_move_plain(board)
print(f"Plain Minimax -> best move: {mv_plain}, value: {val_plain}, nodes visited:
{nodes_plain}")
nodes_ab = 0
mv_ab, val_ab = best_move_ab(board)
print(f"Alpha-Beta -> best move: {mv_ab}, value: {val_ab}, nodes visited: {nodes_ab}")
board[mv_ab] = 'X'
print("\nBoard after alpha-beta best move:")
print_board(board)