-
Notifications
You must be signed in to change notification settings - Fork 1
/
state.py
76 lines (61 loc) · 2.1 KB
/
state.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
from copy import deepcopy
# State object
class State:
def __init__(self, val, preAction, preState, emptyIndex, depth=0):
self.value = val # Array value
self.previousAction = preAction
self.previousState = preState
self.emptyIndex = emptyIndex
self.depth = depth # Depth, in uniform cost (1), it equals g(x)
self.cost = 0
def __str__(self):
line = f'-------\n'
out = ""
out += line
for r in self.value:
out += f'|{r[0]}|{r[1]}|{r[2]}|\n'
out += line
return out
# Comparator for heapq
def __gt__(self, state):
return self.cost > state.cost
# Generate neighbors of current state
def neighbors(self):
(row, col) = self.emptyIndex
actions = []
neighbors = []
if (col > 0):
actions.append("LEFT")
if (row > 0):
actions.append("UP")
if (col < 2):
actions.append("RIGHT")
if (row < 2):
actions.append("DOWN")
for action in actions:
neighbors.append(apply_action(self, action, row, col))
return neighbors
# Helper function to create the neighbor state
def apply_action(state, action, r, c):
newValue = deepcopy(state.value)
if (action == "UP"):
newValue[r-1][c], newValue[r][c] = newValue[r][c], newValue[r-1][c]
r -= 1
if (action == "DOWN"):
newValue[r+1][c], newValue[r][c] = newValue[r][c], newValue[r+1][c]
r += 1
if (action == "LEFT"):
newValue[r][c-1], newValue[r][c] = newValue[r][c], newValue[r][c-1]
c -= 1
if (action == "RIGHT"):
newValue[r][c+1], newValue[r][c] = newValue[r][c], newValue[r][c+1]
c += 1
return State(newValue, action, state, (r, c), state.depth + 1)
def create_initial_state(arr):
def get_empty_index(state):
for i in range(3):
for j in range(3):
if state[i][j] == 0:
return (i, j)
return (0, 0)
return State(arr, None, None, get_empty_index(arr))