-
Notifications
You must be signed in to change notification settings - Fork 0
/
visualizer.py
132 lines (114 loc) · 4.63 KB
/
visualizer.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
from tkinter import *
from os import system
from os.path import basename
from sys import exit, executable
from platform import system as platform_system
import argparse
GUI_FONT = ('Arial', 32)
GUI_BOX_SIZE = 100
GUI_BOX_SPACING = 10
GUI_BOX_BORDER_WIDTH = 3
GUI_FRAME_INDEX = 0
GUI_DELAY = 200
GUI_COLOR_1 = '#f5f5dc'
GUI_COLOR_2 = '#e9e9af'
GUI_COLOR_3 = '#dddd88'
GUI_OUTLINE_1 = '#ff0000'
GUI_OUTLINE_2 = '#00ff00'
GUI_OUTLINE_3 = '#0000ff'
GUI_COLOR_GREEN = '#00bb00'
GUI_COLOR_RED = '#bb0000'
GUI_COLOR_BLACK = '#000000'
GUI_DASH = (5,4,5,3)
def gui_replay(master, canvas, item_matrix, solution, puzzle_size):
global GUI_FRAME_INDEX
numbers = solution[GUI_FRAME_INDEX]
next_zero = None
color_this = None
if GUI_FRAME_INDEX + 1 < len(solution):
next_zero = solution[GUI_FRAME_INDEX + 1].index(0)
color_this = solution[GUI_FRAME_INDEX][next_zero]
for y in range(puzzle_size):
for x in range(puzzle_size):
n = numbers[y+puzzle_size*x]
BORDER_COLOR = None
if n == solution[-1][y+puzzle_size*x]:
BORDER_COLOR = GUI_COLOR_GREEN #if number is in place, show green cell border
else:
BORDER_COLOR = GUI_COLOR_RED #else red cell border
if n == 0:
canvas.itemconfig(item_matrix[y][x][0],
fill=GUI_COLOR_2,
outline=GUI_COLOR_2,
width=GUI_BOX_BORDER_WIDTH)
elif n == color_this:
canvas.itemconfig(item_matrix[y][x][0],
fill=GUI_COLOR_1,
outline=BORDER_COLOR,
width=GUI_BOX_BORDER_WIDTH)
else:
canvas.itemconfig(item_matrix[y][x][0],
fill=GUI_COLOR_1,
outline=BORDER_COLOR,
width=GUI_BOX_BORDER_WIDTH)
s = str(n)
if not n:
s = ''
canvas.itemconfig(item_matrix[y][x][1], text=s)
GUI_FRAME_INDEX += 1
if GUI_FRAME_INDEX >= len(solution):
GUI_FRAME_INDEX = 0
canvas.update()
if GUI_FRAME_INDEX != 0:
master.after(GUI_DELAY, gui_replay, master, canvas, item_matrix, solution, puzzle_size)
def gui_close(event):
exit(0)
def gui_item_matrix(canvas, puzzle_size):
item_matrix = [[[None, None] for x in range(puzzle_size)] for y in range(puzzle_size)]
for y in range(puzzle_size):
for x in range(puzzle_size):
y0 = y * GUI_BOX_SIZE + GUI_BOX_SPACING
x0 = x * GUI_BOX_SIZE + GUI_BOX_SPACING
y1 = y0 + GUI_BOX_SIZE - GUI_BOX_SPACING
x1 = x0 + GUI_BOX_SIZE - GUI_BOX_SPACING
item_matrix[y][x][0] = canvas.create_rectangle(y0, x0, y1, x1, dash=GUI_DASH, fill=GUI_COLOR_1)
yt = y0 + ((GUI_BOX_SIZE - GUI_BOX_SPACING) / 2)
xt = x0 + ((GUI_BOX_SIZE - GUI_BOX_SPACING) / 2)
item_matrix[y][x][1] = canvas.create_text((yt, xt), font=GUI_FONT, text='')
return item_matrix
def visualizer(solution, puzzle_size):
master = Tk()
canvas_width = (GUI_BOX_SIZE * puzzle_size) + GUI_BOX_SPACING
canvas_height = (GUI_BOX_SIZE * puzzle_size) + GUI_BOX_SPACING
canvas = Canvas(master, width=canvas_width+1, height=canvas_height+1, bg=GUI_COLOR_2, borderwidth=0, highlightthickness=0)
canvas.pack()
item_matrix = gui_item_matrix(canvas, puzzle_size)
master.bind('<Escape>', gui_close)
master.bind('<Q>', gui_close)
master.bind('<q>', gui_close)
master.after(0, gui_replay, master, canvas, item_matrix, solution, puzzle_size)
if platform_system() is 'Darwin':
system('''/usr/bin/osascript -e 'tell app "Finder" to set frontmost of process "''' + basename(executable) + '''" to true' ''')
master.mainloop()
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='n-puzzle visulizer')
parser.add_argument('file', help='input file', type=argparse.FileType('r'))
args = parser.parse_args()
data = args.file.read().splitlines()
steps = []
size = int(data[0])
#Initial Pose
steps.append([int(x) for x in data[1].split(',')])
gap = steps[0].index(0)
o_x = int(gap/size); o_y = gap%size
# data validation check
for l in data[1:]:
steps.append([int(x) for x in l.split(',')])
gap = steps[-1].index(0)
n_x = int(gap/size); n_y = gap%size
if (n_x == o_x and abs(n_y-o_y) == 1) or (n_y == o_y and abs(n_x-o_x) == 1):
o_x=n_x
o_y=n_y
continue
print("ILLEGAL MOVE AT STEP {}".format(len(steps)))
visualizer(steps, size)