0% found this document useful (0 votes)
4 views27 pages

Source Code

The document contains multiple source codes for different algorithms and games, including BFS for solving N-Puzzles, DFS for water jug problems, A* algorithm for pathfinding, AO* for decision-making, and a GUI for the 8-Queens problem using hill climbing. Each section includes input handling and methods for solving the respective problems. The last part introduces a Tic Tac Toe AI but is incomplete.

Uploaded by

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

Source Code

The document contains multiple source codes for different algorithms and games, including BFS for solving N-Puzzles, DFS for water jug problems, A* algorithm for pathfinding, AO* for decision-making, and a GUI for the 8-Queens problem using hill climbing. Each section includes input handling and methods for solving the respective problems. The last part introduces a Tic Tac Toe AI but is incomplete.

Uploaded by

charuc0608
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd

SOURCE CODE:

from collections import deque


def is_solvable(state, n):
inv_count = 0
flat = [tile for tile in state if tile != 0]
for i in range(len(flat)):
for j in range(i + 1, len(flat)):
if flat[i] > flat[j]:
inv_count += 1
if n % 2 == 1:
return inv_count % 2 == 0
else:
zero_row = [Link](0) // n
return (inv_count + zero_row) % 2 == 1

def get_neighbors(state, n):


neighbors = []
zero_index = [Link](0)
x, y = divmod(zero_index, n)
directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]
for dx, dy in directions:
new_x, new_y = x + dx, y + dy
if 0 <= new_x < n and 0 <= new_y < n:
new_index = new_x * n + new_y
new_state = list(state)
new_state[zero_index], new_state[new_index] = new_state[new_index],
new_state[zero_index]
[Link]((tuple(new_state), new_state[zero_index]))
return neighbors

def print_board(state, n):


for i in range(n):
row = state[i*n:(i+1)*n]
print(' '.join(str(x) if x != 0 else '_' for x in row))
print()

def reconstruct_path(parents, end_state):


path = []
state = end_state
while parents[state][0] is not None:
parent_state, moved_tile = parents[state]
[Link]((state, moved_tile))
state = parent_state
[Link]((state, None)) # start state, no move
[Link]()
return path

def bfs(start, goal, n):


if not is_solvable(start, n):
print("❌ Puzzle is not solvable.")
return

queue = deque([start])
visited = set([start])
parents = {start: (None, None)}

while queue:
current = [Link]()
if current == goal:
path = reconstruct_path(parents, current)
print(f"\n✅ Total moves: {len(path) - 1}")
print("🔁 Sequence of states and moves:\n")
for i, (state, move) in enumerate(path):
print(f"Step {i}:", end=' ')
if move is not None:
print(f"(Moved tile {move})")
else:
print("(Start state)")
print_board(state, n)
return

for neighbor, moved_tile in get_neighbors(current, n):


if neighbor not in visited:
[Link](neighbor)
parents[neighbor] = (current, moved_tile)
[Link](neighbor)

print("❌ Goal not reachable.")

# ===== Input Section =====


n = int(input("Enter N for N-Puzzle (e.g., 3 for 8-puzzle, 4 for 15-puzzle): "))
print(f"Enter {n*n} space-separated values for start state (0 for blank):")
start = tuple(map(int, input().split()))
print(f"Enter {n*n} space-separated values for goal state:")
goal = tuple(map(int, input().split()))

bfs(start, goal, n)

INPUT AND OUTPUT :


SOURCE CODE :
def is_goal(state, target_jug, target_value):
return state[target_jug - 1] == target_value

def get_next_states(state, jug1_cap, jug2_cap):


x, y = state
possible_states = set()

# Fill Jug 1 or Jug 2


possible_states.add((jug1_cap, y))
possible_states.add((x, jug2_cap))

# Empty Jug 1 or Jug 2


possible_states.add((0, y))
possible_states.add((x, 0))

# Pour Jug 1 → Jug 2


transfer = min(x, jug2_cap - y)
possible_states.add((x - transfer, y + transfer))

# Pour Jug 2 → Jug 1


transfer = min(y, jug1_cap - x)
possible_states.add((x + transfer, y - transfer))

return possible_states

def dfs(jug1_cap, jug2_cap, target_value, target_jug):


visited = set()
stack = [((0, 0), [])] # (current_state, path)

while stack:
current_state, path = [Link]()
if current_state in visited:
continue
[Link](current_state)

path = path + [current_state]

if is_goal(current_state, target_jug, target_value):


print("\nSolution Path (DFS):")
for step in path:
print(f"Jug1: {step[0]}, Jug2: {step[1]}")
return

for next_state in get_next_states(current_state, jug1_cap, jug2_cap):


if next_state not in visited:
[Link]((next_state, path))

print("No solution found.")

# === 🔹 Example Usage ===


if __name__ == "__main__":
jug1_cap = int(input("Enter capacity of Jug 1: "))
jug2_cap = int(input("Enter capacity of Jug 2: "))
target_value = int(input("Enter target amount of water: "))

while True:
target_jug = int(input("Which jug should contain the target amount? (1 or 2): "))
if target_jug in [1, 2]:
break
else:
print("Please enter 1 or 2.")

dfs(jug1_cap, jug2_cap, target_value, target_jug)

INPUT AND OUTPUT :

SOURCE CODE :
import heapq
from math import inf

def reconstruct_path(came_from, current):


path = [current]
while current in came_from:
current = came_from[current]
[Link](current)
[Link]()
return path

def a_star(graph, heuristics, start, goal):


# g_score: best known cost from start
g_score = {node: inf for node in graph}
g_score[start] = 0

# Min-heap of (f, counter, node); counter breaks ties to keep heap stable
open_heap = []
counter = 0
f_start = g_score[start] + [Link](start, inf)
[Link](open_heap, (f_start, counter, start))
counter += 1

# For pretty/accurate printing


open_set = {start}
closed_set = set()

# For path reconstruction


came_from = {}
step = 1
while open_heap:
# Clean printing of current OPEN/CLOSED (names only, sorted)
print(f"\n--- Step {step} ---")
print("Open List:", sorted(open_set))
print("Closed List:", sorted(closed_set))

# Pop best; skip stale entries


f, _, current = [Link](open_heap)
if current in closed_set:
# Already expanded with a better path earlier
continue
# It's no longer in open_set since we're expanding it now
if current in open_set:
open_set.remove(current)
print(f"Expanding node: {current}")
# Goal check
if current == goal:
path = reconstruct_path(came_from, current)
return path, g_score[current]
# Mark current as expanded
closed_set.add(current)
# Explore neighbors
for neighbor, weight in graph[current].items():
if neighbor in closed_set:
continue

tentative_g = g_score[current] + weight


if tentative_g < g_score[neighbor]:
# Found a better path to neighbor
came_from[neighbor] = current
g_score[neighbor] = tentative_g
f_neighbor = tentative_g + [Link](neighbor, inf)
[Link](open_heap, (f_neighbor, counter, neighbor))
counter += 1
open_set.add(neighbor)

step += 1

return None, inf # No path found

# ---------------------- INPUT FUNCTIONS ----------------------

def input_graph():
n = int(input("Enter number of nodes: "))
print("Enter node names (space separated):")
nodes = input().split()

# Initialize adjacency as dict-of-dicts to dedupe edges (keep minimum weight)


graph = {u: {} for u in nodes}

undirected = input("Is the graph undirected? (y/n): ").strip().lower() in ("y", "yes")

m = int(input("Enter number of edges: "))


print("Enter edges as: source destination weight")
for _ in range(m):
u, v, w = input().split()
w = int(w)
# Keep only the minimum weight for (u,v)
if v not in graph[u] or w < graph[u][v]:
graph[u][v] = w
if undirected:
if u not in graph[v] or w < graph[v][u]:
graph[v][u] = w

print("Enter heuristic values for each node (name heuristic):")


heuristics = {}
for _ in range(n):
node, h = input().split()
heuristics[node] = int(h)
start = input("Enter start node: ").strip()
goal = input("Enter goal node: ").strip()

# Basic validation
if start not in graph or goal not in graph:
raise ValueError("Start/Goal must be among the listed nodes.")

return graph, heuristics, start, goal


# ---------------------- MAIN ----------------------
if __name__ == "__main__":
graph, heuristics, start, goal = input_graph()
path, cost = a_star(graph, heuristics, start, goal)

if path:
print("\n✅ Shortest path found by A*:")
print(" -> ".join(path))
print("Total cost:", cost)
else:
print("❌ No path found.")

INPUT AND OUTPUT :


SOURCE CODE:
class AOStar:
def __init__(self, graph, heuristics):
[Link] = graph
self.H = heuristics
self.solution_graph = {}

def get_neighbors(self, node):


return [Link](node, [])

def ao_star(self, node, backtrack=False):


print(f"\nProcessing Node: {node}")

if node not in [Link]:


print(f"{node} is a goal node.")
return self.H[node]

min_cost = float('inf')
best_child = None

# Evaluate all child groups (AND/OR sets)


for child_group in self.get_neighbors(node):
cost = 0
for (child, edge_cost) in child_group:
cost += edge_cost + self.H[child]
print(f"Evaluating children {child_group} → Total cost = {cost}")

if cost < min_cost:


min_cost = cost
best_child = child_group

self.H[node] = min_cost
self.solution_graph[node] = best_child
print(f"Best choice for {node} → {best_child} with cost {min_cost}")

# Recursively solve best children


for (child, _) in best_child:
self.ao_star(child)

if backtrack:
print("Backtracking...")
self.ao_star(node)

def print_solution(self):
print("\nFinal Solution Graph:")
for k, v in self.solution_graph.items():
print(f"{k} → {v}")
graph = {}
heuristics = {}
n = int(input("Enter number of nodes: "))

for _ in range(n):
# Ask node name and heuristic in one line
node_input = input("\nEnter node name and heuristic value (format: Node,Heuristic): ")
node_name, h_val = node_input.split(",")
heuristics[node_name.strip()] = int(h_val.strip())

# Ask number of child groups


groups = int(input(f"How many AND/OR child groups for {node_name}? "))
child_groups = []

for _ in range(groups):
# Ask children with costs in one line
cg_input = input("Enter children and costs (format: child,cost child,cost ...): ").split()
child_group = [([Link](",")[0], int([Link](",")[1])) for c in cg_input]
child_groups.append(child_group)

if child_groups:
graph[node_name] = child_groups

ao = AOStar(graph, heuristics)
start = input("\nEnter start node: ")
ao.ao_star(start)
ao.print_solution()

INPUT AND OUTPUT :


SOURCE CODE :
import tkinter as tk
import random
import time

BOARD_SIZE = 8
QUEEN_SYMBOL = "♛"

class EightQueensHillClimb:
def __init__(self, root):
[Link] = root
[Link]("8-Queens Hill Climbing")
[Link] = []
self.create_board()
self.solve_button = [Link]([Link], text="Solve with Hill Climbing",
command=self.start_solving)
self.solve_button.pack(pady=10)

def create_board(self):
frame = [Link]([Link])
[Link]()
for i in range(BOARD_SIZE):
row_buttons = []
for j in range(BOARD_SIZE):
btn = [Link](frame, text="", width=4, height=2, relief="ridge", font=("Arial",
18))
[Link](row=i, column=j)
color = "white" if (i + j) % 2 == 0 else "lightgray"
[Link](bg=color)
row_buttons.append(btn)
[Link](row_buttons)

def display_state(self, state):


"""Show queens on the GUI board"""
for i in range(BOARD_SIZE):
for j in range(BOARD_SIZE):
[Link][i][j]['text'] = ""
for col, row in enumerate(state):
[Link][row][col]['text'] = QUEEN_SYMBOL
[Link]()
[Link](0.4)

def heuristic(self, state):


"""Count number of attacking pairs of queens"""
conflicts = 0
for i in range(BOARD_SIZE):
for j in range(i + 1, BOARD_SIZE):
if state[i] == state[j] or abs(state[i] - state[j]) == abs(i - j):
conflicts += 1
return conflicts

def get_best_neighbor(self, state):


"""Generate neighbors and return best one"""
best_state = list(state)
best_h = [Link](state)
for col in range(BOARD_SIZE):
for row in range(BOARD_SIZE):
if state[col] != row:
neighbor = list(state)
neighbor[col] = row
h = [Link](neighbor)
if h < best_h:
best_h = h
best_state = neighbor
return best_state, best_h

def hill_climb(self):
"""Perform hill climbing with step logging"""
state = [[Link](0, BOARD_SIZE - 1) for _ in range(BOARD_SIZE)]
h = [Link](state)
step_count = 0

print(f"\n🚀 Starting new attempt with initial state: {state}, h={h}")


self.display_state(state)

while True:
neighbor, h_new = self.get_best_neighbor(state)
if h_new >= h: # No improvement
print(f"⚠️Local optimum reached at state {state}, h={h}")
break

print(f"➡️Step {step_count+1}: Move to {neighbor}, h={h_new}")


state, h = neighbor, h_new
step_count += 1
self.display_state(state)

return state, h, step_count

def start_solving(self):
attempt = 1
while True:
print(f"\n================ Attempt {attempt} ================")
state, h, steps = self.hill_climb()
if h == 0:
self.display_state(state)
print(f"\n✅ Solution found in Attempt {attempt} after {steps} steps!")
print("Final state (row positions by column):", state)
break
else:
print("🔄 Restarting with a new random state...")
attempt += 1

# Run
if __name__ == "__main__":
root = [Link]()
game = EightQueensHillClimb(root)
[Link]()

INPUT AND OUTPUT :


SOURCE CODE :
import tkinter as tk
from tkinter import messagebox
import math

# ----------- Tic Tac Toe AI -----------


class TicTacToe:
def __init__(self, n):
self.n = n
[Link] = [['' for _ in range(n)] for _ in range(n)]
[Link] = 'X'
[Link] = 'O'

def make_move(self, row, col, player):


if [Link][row][col] == '':
[Link][row][col] = player
return True
return False

def check_winner(self, board=None):


if board is None:
board = [Link]
n = self.n
# Rows and columns
for i in range(n):
if board[i][0] != '' and all(board[i][j] == board[i][0] for j in range(n)):
return board[i][0]
if board[0][i] != '' and all(board[j][i] == board[0][i] for j in range(n)):
return board[0][i]
# Diagonals
if board[0][0] != '' and all(board[i][i] == board[0][0] for i in range(n)):
return board[0][0]
if board[0][n-1] != '' and all(board[i][n-1-i] == board[0][n-1] for i in range(n)):
return board[0][n-1]
# Check tie
if all(board[i][j] != '' for i in range(n) for j in range(n)):
return 'Tie'
return None

# ----------- Minimax with Alpha-Beta -----------


def minimax(self, board, depth, is_max, alpha, beta):
winner = self.check_winner(board)
if winner == [Link]:
return 10 - depth
elif winner == [Link]:
return depth - 10
elif winner == 'Tie':
return 0
if is_max: # AI's move (Maximizer)
best = -[Link]
for i in range(self.n):
for j in range(self.n):
if board[i][j] == '':
board[i][j] = [Link]
print(" " * depth*2 + f"Max: Trying ({i},{j}), α={alpha}, β={beta}")
val = [Link](board, depth+1, False, alpha, beta)
board[i][j] = ''
best = max(best, val)
alpha = max(alpha, best)
print(" " * depth*2 + f"Max updated best={best}, α={alpha}, β={beta}")
if beta <= alpha:
print(" " * depth*2 + f"Pruned at ({i},{j}) with α={alpha}, β={beta}")
break
return best
else: # Player's move (Minimizer)
best = [Link]
for i in range(self.n):
for j in range(self.n):
if board[i][j] == '':
board[i][j] = [Link]
print(" " * depth*2 + f"Min: Trying ({i},{j}), α={alpha}, β={beta}")
val = [Link](board, depth+1, True, alpha, beta)
board[i][j] = ''
best = min(best, val)
beta = min(beta, best)
print(" " * depth*2 + f"Min updated best={best}, α={alpha}, β={beta}")
if beta <= alpha:
print(" " * depth*2 + f"Pruned at ({i},{j}) with α={alpha}, β={beta}")
break
return best

def best_move(self):
best_val = -[Link]
move = None
for i in range(self.n):
for j in range(self.n):
if [Link][i][j] == '':
[Link][i][j] = [Link]
move_val = [Link]([Link], 0, False, -[Link], [Link])
[Link][i][j] = ''
if move_val > best_val:
best_val = move_val
move = (i, j)
return move

# ----------- GUI -----------


class TicTacToeGUI:
def __init__(self, root, n):
[Link] = root
self.n = n
[Link] = TicTacToe(n)
[Link] = [[None for _ in range(n)] for _ in range(n)]
self.create_board()

def create_board(self):
for i in range(self.n):
for j in range(self.n):
b = [Link]([Link], text='', font=('Helvetica', 24), width=4, height=2,
command=lambda row=i, col=j: self.player_move(row, col))
[Link](row=i, column=j)
[Link][i][j] = b
reset_btn = [Link]([Link], text='Reset', font=('Helvetica', 14),
command=self.reset_board)
reset_btn.grid(row=self.n, column=0, columnspan=self.n, sticky='we')

def player_move(self, row, col):


if [Link].make_move(row, col, [Link]):
[Link][row][col].config(text=[Link])
winner = [Link].check_winner()
if winner:
self.end_game(winner)
return
# AI move
ai_move = [Link].best_move()
if ai_move:
ai_row, ai_col = ai_move
[Link].make_move(ai_row, ai_col, [Link])
[Link][ai_row][ai_col].config(text=[Link])
winner = [Link].check_winner()
if winner:
self.end_game(winner)
else:
[Link]("Invalid Move", "Cell already occupied!")

def end_game(self, winner):


if winner == 'Tie':
[Link]("Game Over", "It's a Tie!")
else:
[Link]("Game Over", f"{winner} wins!")
print(f"\nFinal Board:")
for row in [Link]:
print(row)

def reset_board(self):
[Link] = TicTacToe(self.n)
for i in range(self.n):
for j in range(self.n):
[Link][i][j].config(text='')
# ----------- Run Game -----------
if __name__ == "__main__":
n = int(input("Enter board size n (e.g., 3 for 3x3): "))
root = [Link]()
[Link](f"{n}x{n} Tic Tac Toe vs AI (Alpha-Beta)")
gui = TicTacToeGUI(root, n)
[Link]()

INPUT AND OUTPUT :


SOURCE CODE :
from itertools import permutations

def solve_cryptarithmetic(puzzle):
"""
Solve a cryptarithmetic puzzle like SEND + MORE = MONEY
"""
# Remove spaces
puzzle = [Link](" ", "")

# Split left and right side


if '=' not in puzzle or '+' not in puzzle:
print("Puzzle format must be like SEND + MORE = MONEY")
return

left, right = [Link]('=')


left_terms = [Link]('+')

# Extract unique letters


letters = set(''.join(left_terms) + right)
if len(letters) > 10:
print("Too many unique letters (>10), cannot assign digits")
return

letters = list(letters)
digits = range(10)

# Try all permutations of digits for the letters


for perm in permutations(digits, len(letters)):
mapping = dict(zip(letters, perm))

# Skip if first letter of any term or result is 0


if any(mapping[word[0]] == 0 for word in left_terms + [right]):
continue

# Compute numeric values


left_sum = sum(int(''.join(str(mapping[ch]) for ch in word)) for word in left_terms)
right_value = int(''.join(str(mapping[ch]) for ch in right))

if left_sum == right_value:
print("Solution found!")
print("Mapping:", mapping)
print(f"{' + '.join([''.join(str(mapping[ch]) for ch in word) for word in left_terms])} =
{right_value}")
return mapping

print("No solution found.")

# ----------- Example Usage -------------


if __name__ == "__main__":
print("Cryptarithmetic Solver")
puzzle = input("Enter puzzle (format: SEND + MORE = MONEY): ")
solve_cryptarithmetic(puzzle)

INPUT AND OUPUT :


SOURCE CODE:
import math
import time

# Tic Tac Toe Board


board = [" " for _ in range(9)]

# Track nodes visited


minimax_nodes = 0
alphabeta_nodes = 0

# Print board
def print_board():
for row in [board[i*3:(i+1)*3] for i in range(3)]:
print("| " + " | ".join(row) + " |")
print()

# Check winner
def check_winner(brd):
win_conditions = [
[0,1,2], [3,4,5], [6,7,8], # rows
[0,3,6], [1,4,7], [2,5,8], # cols
[0,4,8], [2,4,6] # diagonals
]
for cond in win_conditions:
if brd[cond[0]] == brd[cond[1]] == brd[cond[2]] and brd[cond[0]] != " ":
return brd[cond[0]]
if " " not in brd:
return "Tie"
return None

# ---------------- Minimax ---------------- #


def minimax(brd, depth, is_maximizing):
global minimax_nodes
minimax_nodes += 1
result = check_winner(brd)
if result == "O":
return 10 - depth
elif result == "X":
return depth - 10
elif result == "Tie":
return 0

if is_maximizing:
best_score = -[Link]
for i in range(9):
if brd[i] == " ":
brd[i] = "O"
score = minimax(brd, depth+1, False)
brd[i] = " "
best_score = max(best_score, score)
return best_score
else:
best_score = [Link]
for i in range(9):
if brd[i] == " ":
brd[i] = "X"
score = minimax(brd, depth+1, True)
brd[i] = " "
best_score = min(best_score, score)
return best_score

def best_move_minimax():
global minimax_nodes
minimax_nodes = 0
best_score = -[Link]
move = None
start = [Link]()
for i in range(9):
if board[i] == " ":
board[i] = "O"
score = minimax(board, 0, False)
board[i] = " "
if score > best_score:
best_score = score
move = i
end = [Link]()
return move, best_score, (end-start), minimax_nodes

# ---------------- Alpha-Beta ---------------- #


def alpha_beta(brd, depth, alpha, beta, is_maximizing):
global alphabeta_nodes
alphabeta_nodes += 1
result = check_winner(brd)
if result == "O":
return 10 - depth
elif result == "X":
return depth - 10
elif result == "Tie":
return 0

if is_maximizing:
best_score = -[Link]
for i in range(9):
if brd[i] == " ":
brd[i] = "O"
score = alpha_beta(brd, depth+1, alpha, beta, False)
brd[i] = " "
best_score = max(best_score, score)
alpha = max(alpha, score)
if beta <= alpha:
break
return best_score
else:
best_score = [Link]
for i in range(9):
if brd[i] == " ":
brd[i] = "X"
score = alpha_beta(brd, depth+1, alpha, beta, True)
brd[i] = " "
best_score = min(best_score, score)
beta = min(beta, score)
if beta <= alpha:
break
return best_score

def best_move_alphabeta():
global alphabeta_nodes
alphabeta_nodes = 0
best_score = -[Link]
move = None
start = [Link]()
for i in range(9):
if board[i] == " ":
board[i] = "O"
score = alpha_beta(board, 0, -[Link], [Link], False)
board[i] = " "
if score > best_score:
best_score = score
move = i
end = [Link]()
return move, best_score, (end-start), alphabeta_nodes

# ---------------- Play ---------------- #


def play_game():
print("Welcome to Tic Tac Toe! You are X, AI is O.")
print_board()

while True:
# Human move
move = int(input("Enter your move (1-9): ")) - 1
if board[move] != " ":
print("Invalid move, try again.")
continue
board[move] = "X"
print_board()
if check_winner(board):
break
# AI move with Minimax
move_m, score_m, time_m, nodes_m = best_move_minimax()
# AI move with Alpha-Beta
move_ab, score_ab, time_ab, nodes_ab = best_move_alphabeta()

# Use Alpha-Beta move for AI


board[move_ab] = "O"

print(f"Minimax → Move: {move_m+1}, Score: {score_m}, Time: {time_m:.8f}s,


Nodes: {nodes_m}")
print(f"Alpha-Beta → Move: {move_ab+1}, Score: {score_ab}, Time: {time_ab:.8f}s,
Nodes: {nodes_ab}")
print_board()

if check_winner(board):
break

winner = check_winner(board)
if winner == "Tie":
print("It's a Tie!")
else:
print(winner, "wins!")

# Run
if __name__ == "__main__":
play_game()
INPUT AND OUTPUT :

You might also like