Skip to content

Commit

Permalink
Update Eightpuzzle.py
Browse files Browse the repository at this point in the history
  • Loading branch information
JDeep1234 authored Feb 12, 2025
1 parent 98ad15d commit fc4dce6
Showing 1 changed file with 59 additions and 23 deletions.
82 changes: 59 additions & 23 deletions Eightpuzzle.py
Original file line number Diff line number Diff line change
@@ -1,38 +1,74 @@
import numpy as np
from queue import PriorityQueue

def solve_puzzle(start, goal):
def h(s): return np.sum(s != goal) # Count misplaced tiles
def manhattan_distance(state, goal):
"""Calculate Manhattan distance heuristic."""
distance = 0
for num in range(1, 9): # Ignore 0 (empty space)
x1, y1 = np.argwhere(state == num)[0]
x2, y2 = np.argwhere(goal == num)[0]
distance += abs(x1 - x2) + abs(y1 - y2)
return distance

def get_neighbors(state):
"""Generate valid moves for the empty tile (0)."""
x, y = np.argwhere(state == 0)[0]
neighbors = []
moves = {'Right': (0,1), 'Down': (1,0), 'Left': (0,-1), 'Up': (-1,0)}

for move, (dx, dy) in moves.items():
nx, ny = x + dx, y + dy
if 0 <= nx < 3 and 0 <= ny < 3:
new_state = state.copy()
new_state[x, y], new_state[nx, ny] = new_state[nx, ny], 0
neighbors.append((move, new_state))
return neighbors

def solve_puzzle(start, goal):
"""A* algorithm to solve the 8-puzzle problem."""
queue = PriorityQueue()
queue.put((h(start), start.tobytes(), []))
queue.put((manhattan_distance(start, goal), 0, start, [])) # (f, g, state, path)
visited = set()

while not queue.empty():
_, state_bytes, path = queue.get()
state = np.frombuffer(state_bytes, dtype=int).reshape(3, 3)
f, g, state, path = queue.get()
state_tuple = tuple(map(tuple, state)) # Convert to hashable format

if np.array_equal(state, goal): return path + [state]
visited.add(state_bytes)
if np.array_equal(state, goal):
return path # Return solution path

x, y = np.argwhere(state == 0)[0]
for dx, dy in [(0,1), (1,0), (0,-1), (-1,0)]:
nx, ny = x + dx, y + dy
if 0 <= nx < 3 and 0 <= ny < 3:
new_state = state.copy()
new_state[x, y], new_state[nx, ny] = new_state[nx, ny], 0
new_bytes = new_state.tobytes()

if new_bytes not in visited:
queue.put((h(new_state), new_bytes, path + [state]))
visited.add(state_tuple)

for move, new_state in get_neighbors(state):
new_tuple = tuple(map(tuple, new_state))
if new_tuple not in visited:
queue.put((g + 1 + manhattan_distance(new_state, goal), g + 1, new_state, path + [move]))

return None

start = np.array([[2, 8, 1], [0, 4, 3], [7, 6, 5]])
goal = np.array([[1, 2, 3], [8, 0, 4], [7, 6, 5]])
def input_puzzle():
"""Take user input for 3x3 puzzle state."""
print("Enter the puzzle as a 3x3 grid (use 0 for the empty space):")
matrix = []
for i in range(3):
row = list(map(int, input(f"Row {i+1}: ").split()))
matrix.append(row)
return np.array(matrix)

# Get input from user
print("Enter the START state:")
start = input_puzzle()

print("Enter the GOAL state:")
goal = input_puzzle()

# Solve the puzzle
solution = solve_puzzle(start, goal)

# Output result
if solution:
for step in solution: print(step)
print("Moves:", len(solution) - 1)
print("\nSolution Found!")
print("Moves:", solution)
print("Total Moves:", len(solution))
else:
print("No solution!")
print("\nNo solution exists for this configuration!")

0 comments on commit fc4dce6

Please sign in to comment.