-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinter.py
171 lines (133 loc) · 4.47 KB
/
inter.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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
from tensorflow.keras.models import load_model
import numpy as np
import data_factory
import unblock
# Load the model
class ML_Unblocker:
def __init__(self, grid):
self.model = load_model('models/unblock_me_solver')
#need some functions from here
self.data_f = data_factory.Level_Factory()
self.unblocker = unblock.Unblocker()
self.moves = []
self.grid = grid
def solve_state(self, state):
processed_state = self.data_factory.convert_to_one_hot(state)
# Ensure that this new_state should be preprocessed (normalized/encoded) in the same way as training data.
new_state = np.array([processed_new_state]) #
new_state = new_state.reshape(-1, 6, 6, 6)
# Use the model to predict the best move for the given state.
predicted_move = model.predict(new_state)
#print(type(predicted_move))
new_state, move = decode_move(predicted_move)
moves.append(move)
if state[2][5] == "R" and state[2][4] == "R":
#print("After examining " + str(i) + " game states the game was solved in")
return moves
#visually update teh grid
update_grid(new_state)
#solve new state
solve_state(new_state)
def update_grid(self,state):
if self.grid != None:
self.grid.grid = state
#takes in a move from the ml model and outputs a state
def decode_move(self, move, state):
new_state = None
move = list(map(lambda x: int(x*5),move))
r1,c1,r2,c2 = move
gridside = self.unblocker.get_gridside(r1,c1,state)
block = state[r1][c1]
direction = ""
#get move direction and check for move validity based on coordinates
#using t for top/up and b for bottom/down to be consistant with gridside
if r1 != r2 and c1 != c2:
self.move_error("Can't move diagonally.", move)
if abs(r1-r2) > 1 or abs(c1-c2) > 1:
self.move_error("Can't move more than one position at a time.", move)
if r1 > r2:
direction = "t"
elif r2 > r1:
direction = "b"
elif c1 > c2:
direction = "l"
elif c2 > c1:
direction = "r"
else:
self.move_error("No move was made.", move)
#check for move validity based on gridside of starting coordinate and begin state genera
if gridside == "m":
self.move_error("Can't perform move on middle of block.", move)
if gridside == "n":
self.move_error("Can't perform a move on an empty space.", move)
if gridside == direction:
#check move validy based on location
match r1,c1, direction:
case 5, _, "d":
self.move_error("Cannot move downwards from row 5.", move)
case 0, _, "u":
self.move_error("Cannot move upward from row 0.", move)
case _, 0, "l":
self.move_error("Cannot move leftwards from col 0.", move)
case _, 5, "r":
self.move_error("Cannot move rightwards from col 5.", move)
case _,_,_:
new_state = self.state_from_move(gridside, block, state, r1, c1)
else:
self.move_error("Cant perform a move " + str(direction) + " on side " + str(gridside) + ".", move)
return [new_state, pretty_print_move(move)]
def state_from_move(self, side, block, state, r, c):
#repurposed code from unblock.py
new_state = state
if block.isupper():
#move right
if side == "r" and c != 5 and b[r][c+1] == ".":
new_state[r][c+1] = block
if block == "B":
new_state[r][c-2] = "."
else:
new_state[r][c-1] = "."
#move left
if side == "l" and c != 0 and b[r][c-1] == ".":
new_state[r][c-1] = block
if block == "B":
new_state[r][c+2] = "."
else:
new_state[r][c+1] = "."
else:
#move down
if side == "d" and r != 5 and b[r+1][c] == ".":
new_state[r+1][c] = block
if block == "b":
new_state[r-2][c] = "."
else:
new_state[r-1][c] = '.'
#move up
if side == "u" and r != 0 and b[r-1][c] == ".":
new_state[r-1][c] = block
if block == "b":
new_state[r+2][c] = "."
else:
new_state[r+1][c] = '.'
return new_state
def move_error(self, details, move):
print("Error Invalid Move: " + details + "\n" + self.pretty_print_move(move))
quit()
def pretty_print_move(self,move):
#pretty prints a move array
r1,c1,r2,c2 = move
return "(" + str(r1) + "," +str(c1) + ") -> " + "(" + str(r2) + "," + str(c2) +")"
def print_state(self,state):
self.mutex.acquire()
if self.grid != None:
self.grid.grid = state
#prints a game state for debugging purposes
for row in state:
line = "[ "
for cell in row:
line += cell + " "
line += "]"
# print(line)
#print("---------------")
self.mutex.release()
#function to run solver on its own, without the GUI and threading nonsense.