-
Notifications
You must be signed in to change notification settings - Fork 0
/
8_Puzzle.py
101 lines (86 loc) · 2.97 KB
/
8_Puzzle.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import copy
from heapq import heappush, heappop
n = 3
rows = [ 1, 0, -1, 0 ]
cols = [ 0, -1, 0, 1 ]
class priorityQueue:
def __init__(self):
self.heap = []
def push(self, key):
heappush(self.heap, key)
def pop(self):
return heappop(self.heap)
def empty(self):
if not self.heap:
return True
else:
return False
class nodes:
def __init__(self, parent, mats, empty_tile_posi, costs, levels):
self.parent = parent
self.mats = mats
self.empty_tile_posi = empty_tile_posi
self.costs = costs
self.levels = levels
def __lt__(self, nxt):
return self.costs < nxt.costs
def calculateCosts(mats, final) -> int:
count = 0
for i in range(n):
for j in range(n):
if ((mats[i][j]) and
(mats[i][j] != final[i][j])):
count += 1
return count
def newNodes(mats, empty_tile_posi, new_empty_tile_posi, levels, parent, final) -> nodes:
new_mats = copy.deepcopy(mats)
x1 = empty_tile_posi[0]
y1 = empty_tile_posi[1]
x2 = new_empty_tile_posi[0]
y2 = new_empty_tile_posi[1]
new_mats[x1][y1], new_mats[x2][y2] = new_mats[x2][y2], new_mats[x1][y1]
costs = calculateCosts(new_mats, final)
new_nodes = nodes(parent, new_mats, new_empty_tile_posi, costs, levels)
return new_nodes
def printMatsrix(mats):
for i in range(n):
for j in range(n):
print("%d " % (mats[i][j]), end = " ")
def isSafe(x, y):
return x >= 0 and x < n and y >= 0 and y < n
def printPath(root):
if root == None:
return
printPath(root.parent)
printMatsrix(root.mats)
print()
def solve(initial, empty_tile_posi, final):
pq = priorityQueue()
costs = calculateCosts(initial, final)
root = nodes(None, initial,
empty_tile_posi, costs, 0)
pq.push(root)
while not pq.empty():
minimum = pq.pop()
if minimum.costs == 0:
printPath(minimum)
return
for i in range(n):
new_tile_posi = [
minimum.empty_tile_posi[0] + rows[i],
minimum.empty_tile_posi[1] + cols[i], ]
if isSafe(new_tile_posi[0], new_tile_posi[1]):
child = newNodes(minimum.mats,
minimum.empty_tile_posi,
new_tile_posi,
minimum.levels + 1,
minimum, final,)
pq.push(child)
initial = [ [ 1, 2, 3 ],
[ 5, 6, 0 ],
[ 7, 8, 4 ] ]
final = [ [ 1, 2, 3 ],
[ 5, 8, 6 ],
[ 0, 7, 4 ] ]
empty_tile_posi = [ 1, 2 ]
solve(initial, empty_tile_posi, final)