# 15 puzzle python code

Asked by wiki @ & viewed by 11 persons

### Python 15 puzzle solver with A* algorithm can't find a solution for most cases

I've been trying to write a solver for 15 puzzle in python but now I reached a dead end where I can't figure out what's wrong with my code. It works for simple cases, where amount of moves required to solve the puzzle is low, this one for example:

```5 1 2 3 9 7 11 4 13 6 15 8 14 10 0 12```

where `0` represents blank tile.

When I use more complex cases (generated here), the program seems to go into an infinite loop, and even for simple cases I feel like it's not finding the optimal solution. I've been trying to figure out what's causing the problem, but after debugging it for multiple hours I didn't find anything, all of the methods seem to work properly. Can you tell me what is wrong with this code? Here's the solver class:

``````from copy import deepcopy

class Fifteen:

heur = ''
tiles = []
undo_move = ''
h_score = 0  # calculated using heuristic
depth = 0
previous_moves = []
zero_x = 0
zero_y = 0

def __init__(self, heur, fin, parent=None):
if parent is None:
self.heur = heur
fi = open(fin, 'r', encoding='utf-8')
self.tiles = [list(map(int, line.split())) for line in fi]
self.zero_x, self.zero_y = self.find()
fi.close()
elif parent is not None:
self.heur = deepcopy(parent.heur)
self.tiles = deepcopy(parent.tiles)
self.undo_move = deepcopy(parent.undo_move)
self.depth = deepcopy(parent.depth) + 1
self.previous_moves = deepcopy(parent.previous_moves)
self.zero_x = deepcopy(parent.zero_x)
self.zero_y = deepcopy(parent.zero_y)

def find(self, tile=0):
for y in range(len(self.tiles)):
for x in range(len(self.tiles[y])):
if self.tiles[y][x] == tile:
return x, y
raise NameError

def move_tile(self, direction):
x, y = self.zero_x, self.zero_y
if direction == 'u':
self.tiles[y][x], self.tiles[y - 1][x] = self.tiles[y - 1][x], self.tiles[y][x]
self.zero_y = self.zero_y - 1
self.previous_moves.append('u')
self.undo_move = 'd'
elif direction == 'd':
self.tiles[y][x], self.tiles[y + 1][x] = self.tiles[y + 1][x], self.tiles[y][x]
self.zero_y = self.zero_y + 1
self.previous_moves.append('d')
self.undo_move = 'u'
elif direction == 'l':
self.tiles[y][x], self.tiles[y][x - 1] = self.tiles[y][x - 1], self.tiles[y][x]
self.zero_x = self.zero_x - 1
self.previous_moves.append('l')
self.undo_move = 'r'
elif direction == 'r':
self.tiles[y][x], self.tiles[y][x + 1] = self.tiles[y][x + 1], self.tiles[y][x]
self.zero_x = self.zero_x + 1
self.previous_moves.append('r')
self.undo_move = 'l'
else:
raise NameError

def generate_next_states(self):
next_states = []
x, y = self.zero_x, self.zero_y
if y != 0 and self.undo_move != 'u':
child = Fifteen(None, None, self)
child.move_tile('u')
next_states.append(child)
if y != len(self.tiles) - 1 and self.undo_move != 'd':
child = Fifteen(None, None, self)
child.move_tile('d')
next_states.append(child)
if x != 0 and self.undo_move != 'l':
child = Fifteen(None, None, self)
child.move_tile('l')
next_states.append(child)
if x != len(self.tiles[y]) - 1 and self.undo_move != 'r':
child = Fifteen(None, None, self)
child.move_tile('r')
next_states.append(child)
return next_states

def heuristic(self):
if self.heur == 'hamm':
return self.hamming()
return self.manhattan()

def hamming(self):
diff = 0
for y in range(len(self.tiles)):
for x in range(len(self.tiles[y])):
if y == len(self.tiles) - 1 and x == len(self.tiles[y]) - 1:
if self.tiles[y][x] != 0:
diff += 1
elif self.tiles[y][x] != y * len(self.tiles) + x + 1:
diff += 1
return diff

def manhattan(self):
score = 0
value = 1
for y in range(len(self.tiles)):
for x in range(len(self.tiles[y])):
if value == 16:
value = 0
x_real, y_real = self.find(value)
dx = abs(x - x_real)
dy = abs(y - y_real)
score += dx + dy
value += 1
return score

def astar(self):

queue = [self]
closed_set = {}
while len(queue) > 0:
current_state = queue.pop(0)
closed_set[repr(current_state.tiles)] = current_state
if current_state.heuristic() == 0:
print(current_state.tiles)
print(current_state.previous_moves)
print(len(current_state.previous_moves))
return
for state in current_state.generate_next_states():
if repr(state.tiles) in closed_set:
continue
state.h_score = state.heuristic()
queue.append(state)
queue.sort(key=lambda x: x.h_score, reverse=False)
print(-1)
return
``````

And this is how I run it:

``````from fifteen import Fifteen

f = Fifteen('manh', "start.txt")
f.astar()
``````

The first argument can be either `manh` or `hamm`, depending on the heuristic used, second one is name of file containing initial puzzle setup.

## 15 puzzle solver python

Asked by wiki @ & viewed by 20 persons

Python 15 puzzle solver with A* algorithm can't find a solution for most cases I've been trying to write a …

## 15 puzzle problem solution in python

Asked by wiki @ & viewed by 16 persons

Python 15 puzzle solver with A* algorithm can't find a solution for most cases I've been trying to write a …

## Crossword puzzle python code

Asked by wiki @ & viewed by 7 persons

Placing a crossword puzzle into a tkiner in python 3.2 I managed to write code (through a tutorial) that runs …

## Crossword puzzle source code in python

Asked by wiki @ & viewed by 30 persons

Algorithm to generate a crossword Given a list of words, how would you go about arranging them into a crossword …

## Crossword puzzle code in python

Asked by wiki @ & viewed by 17 persons

Placing a crossword puzzle into a tkiner in python 3.2 I managed to write code (through a tutorial) that runs …

## Secure python code

Asked by wiki @ & viewed by 11 persons

How do I protect Python code from being read by users? I am developing a piece of software in Python …

## How to run python code in terminal ubuntu

Asked by wiki @ & viewed by 6 persons

How to run python script on terminal (ubuntu)? I'm new with python, I've been learning for a few weeks. However …

## How to run python code in atom

Asked by wiki @ & viewed by 11 persons

Running Python from Atom In Sublime, we have an easy and convent way to run Python or almost any language …

## Return status code python

Asked by wiki @ & viewed by 10 persons

Return HTTP status code 201 in flask We're using Flask for one of our API's and I was just wondering …

## Code visualizer python

Asked by wiki @ & viewed by 9 persons

Visualizing your code's architecture Each weekend I'm coding on a personal project which over time has reached a certain complexity …

## Rgb python code

Asked by wiki @ & viewed by 9 persons

Converting Hex to RGB value in Python Working off Jeremy's response here: Converting hex color to RGB and vice-versa I …

## How to run python code in cmd

Asked by wiki @ & viewed by 7 persons

How do I run a Python program in the Command Prompt in Windows 7? I'm trying to figure out how …

## Python survey code

Asked by wiki @ & viewed by 6 persons

How to implement a survey? I want to build a survey consisting of some question (<10) with 4 options each. …

## Tip calculator python code

Asked by wiki @ & viewed by 7 persons

Variable Tip Calculator Inputs I am trying to create a tip calculator like every other newbie and of course I …

## Return code in python

Asked by wiki @ & viewed by 6 persons

Exit codes in Python I got a message saying script xyz.py returned exit code 0. What does this mean? What …

## Python strftime milliseconds

Asked by wiki @ & viewed by 200 persons

Format a datetime into a string with milliseconds I want to have a datetime string from the date with milliseconds. …

## What does the percent sign mean in python

Asked by wiki @ & viewed by 136 persons

What does the percentage sign mean in Python In the tutorial there is an example for finding prime numbers: >>> …

## Self keyword in python

Asked by wiki @ & viewed by 134 persons

What is the purpose of the word 'self'? What is the purpose of the self word in Python? I understand …

## Check object type python

Asked by wiki @ & viewed by 132 persons

Determine the type of an object? Is there a simple way to determine if a variable is a list, dictionary, …

## Correlation matrix python

Asked by wiki @ & viewed by 131 persons

Plot correlation matrix using pandas I have a data set with huge number of features, so analysing the correlation matrix …

## Alphabetical sort python

Asked by wiki @ & viewed by 131 persons

Python data structure sort list alphabetically I am a bit confused regarding data structure in python; (),[], and {}. I …

## Python random

Asked by wiki @ & viewed by 127 persons

Generate random integers between 0 and 9 How can I generate random integers between 0 and 9 (inclusive) in Python? …

## Python one line for loop

Asked by wiki @ & viewed by 124 persons

Python one-line “for” expression I'm not sure if I need a lambda, or something else. But still, I need the …

## Python create dataframe from list

Asked by wiki @ & viewed by 124 persons

Python: create a pandas data frame from a list I am using the following code to create a data frame …

## How to add a column to dataframe python

Asked by wiki @ & viewed by 123 persons

Adding new column to existing DataFrame in Python pandas I have the following indexed DataFrame with named columns and rows …

## Why we use self in python

Asked by wiki @ & viewed by 116 persons

What is the purpose of the word 'self'? What is the purpose of the self word in Python? I understand …

## Shape 0 python

Asked by wiki @ & viewed by 115 persons

x.shape[0] vs x[0].shape in NumPy Let say, I have an array with x.shape = (10,1024) when I try to print …

## Python print working directory

Asked by wiki @ & viewed by 112 persons

Find current directory and file's directory [duplicate] This question already has answers here: How do you properly determine the current …

## Image shape python

Asked by wiki @ & viewed by 110 persons

Python OpenCV2 (cv2) wrapper to get image size? How to get the size of an image in cv2 wrapper in …

## Interface grafica python

Asked by wiki @ & viewed by 108 persons

Como criar interface gráfica em Python? [duplicada] Essa pergunta já tem uma resposta aqui: É possível criar interfaces gráficas para …