johnny961 commited on
Commit
75ffe4b
·
1 Parent(s): c58bd5e
static/game/apt.json ADDED
@@ -0,0 +1,3370 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "grid": [
3
+ [
4
+ {
5
+ "type": "wall",
6
+ "room": null,
7
+ "color": null
8
+ },
9
+ {
10
+ "type": "wall",
11
+ "room": null,
12
+ "color": null
13
+ },
14
+ {
15
+ "type": "wall",
16
+ "room": null,
17
+ "color": null
18
+ },
19
+ {
20
+ "type": "wall",
21
+ "room": null,
22
+ "color": null
23
+ },
24
+ {
25
+ "type": "wall",
26
+ "room": null,
27
+ "color": null
28
+ },
29
+ {
30
+ "type": "wall",
31
+ "room": null,
32
+ "color": null
33
+ },
34
+ {
35
+ "type": "wall",
36
+ "room": null,
37
+ "color": null
38
+ },
39
+ {
40
+ "type": "empty",
41
+ "room": null,
42
+ "color": null
43
+ },
44
+ {
45
+ "type": "empty",
46
+ "room": null,
47
+ "color": null
48
+ },
49
+ {
50
+ "type": "empty",
51
+ "room": null,
52
+ "color": null
53
+ },
54
+ {
55
+ "type": "empty",
56
+ "room": null,
57
+ "color": null
58
+ },
59
+ {
60
+ "type": "empty",
61
+ "room": null,
62
+ "color": null
63
+ },
64
+ {
65
+ "type": "empty",
66
+ "room": null,
67
+ "color": null
68
+ },
69
+ {
70
+ "type": "wall",
71
+ "room": null,
72
+ "color": null
73
+ },
74
+ {
75
+ "type": "wall",
76
+ "room": null,
77
+ "color": null
78
+ },
79
+ {
80
+ "type": "wall",
81
+ "room": null,
82
+ "color": null
83
+ },
84
+ {
85
+ "type": "wall",
86
+ "room": null,
87
+ "color": null
88
+ },
89
+ {
90
+ "type": "wall",
91
+ "room": null,
92
+ "color": null
93
+ },
94
+ {
95
+ "type": "wall",
96
+ "room": null,
97
+ "color": null
98
+ },
99
+ {
100
+ "type": "wall",
101
+ "room": null,
102
+ "color": null
103
+ },
104
+ {
105
+ "type": "wall",
106
+ "room": null,
107
+ "color": null
108
+ },
109
+ {
110
+ "type": "wall",
111
+ "room": null,
112
+ "color": null
113
+ },
114
+ {
115
+ "type": "wall",
116
+ "room": null,
117
+ "color": null
118
+ },
119
+ {
120
+ "type": "wall",
121
+ "room": null,
122
+ "color": null
123
+ },
124
+ {
125
+ "type": "wall",
126
+ "room": null,
127
+ "color": null
128
+ },
129
+ {
130
+ "type": "wall",
131
+ "room": null,
132
+ "color": null
133
+ },
134
+ {
135
+ "type": "wall",
136
+ "room": null,
137
+ "color": null
138
+ },
139
+ {
140
+ "type": "wall",
141
+ "room": null,
142
+ "color": null
143
+ },
144
+ {
145
+ "type": "wall",
146
+ "room": null,
147
+ "color": null
148
+ },
149
+ {
150
+ "type": "wall",
151
+ "room": null,
152
+ "color": null
153
+ },
154
+ {
155
+ "type": "wall",
156
+ "room": null,
157
+ "color": null
158
+ },
159
+ {
160
+ "type": "wall",
161
+ "room": null,
162
+ "color": null
163
+ }
164
+ ],
165
+ [
166
+ {
167
+ "type": "wall",
168
+ "room": null,
169
+ "color": null
170
+ },
171
+ {
172
+ "type": "empty",
173
+ "room": null,
174
+ "color": null
175
+ },
176
+ {
177
+ "type": "empty",
178
+ "room": null,
179
+ "color": "green"
180
+ },
181
+ {
182
+ "type": "empty",
183
+ "room": null,
184
+ "color": "green"
185
+ },
186
+ {
187
+ "type": "empty",
188
+ "room": null,
189
+ "color": "green"
190
+ },
191
+ {
192
+ "type": "empty",
193
+ "room": null,
194
+ "color": null
195
+ },
196
+ {
197
+ "type": "wall",
198
+ "room": null,
199
+ "color": null
200
+ },
201
+ {
202
+ "type": "empty",
203
+ "room": null,
204
+ "color": null
205
+ },
206
+ {
207
+ "type": "empty",
208
+ "room": null,
209
+ "color": null
210
+ },
211
+ {
212
+ "type": "empty",
213
+ "room": null,
214
+ "color": null
215
+ },
216
+ {
217
+ "type": "empty",
218
+ "room": null,
219
+ "color": null
220
+ },
221
+ {
222
+ "type": "empty",
223
+ "room": null,
224
+ "color": null
225
+ },
226
+ {
227
+ "type": "empty",
228
+ "room": null,
229
+ "color": null
230
+ },
231
+ {
232
+ "type": "wall",
233
+ "room": null,
234
+ "color": null
235
+ },
236
+ {
237
+ "type": "empty",
238
+ "room": null,
239
+ "color": null
240
+ },
241
+ {
242
+ "type": "empty",
243
+ "room": null,
244
+ "color": null
245
+ },
246
+ {
247
+ "type": "empty",
248
+ "room": null,
249
+ "color": null
250
+ },
251
+ {
252
+ "type": "empty",
253
+ "room": null,
254
+ "color": null
255
+ },
256
+ {
257
+ "type": "empty",
258
+ "room": null,
259
+ "color": null
260
+ },
261
+ {
262
+ "type": "empty",
263
+ "room": null,
264
+ "color": null
265
+ },
266
+ {
267
+ "type": "empty",
268
+ "room": null,
269
+ "color": null
270
+ },
271
+ {
272
+ "type": "empty",
273
+ "room": null,
274
+ "color": null
275
+ },
276
+ {
277
+ "type": "empty",
278
+ "room": null,
279
+ "color": null
280
+ },
281
+ {
282
+ "type": "empty",
283
+ "room": null,
284
+ "color": null
285
+ },
286
+ {
287
+ "type": "empty",
288
+ "room": null,
289
+ "color": null
290
+ },
291
+ {
292
+ "type": "wall",
293
+ "room": null,
294
+ "color": null
295
+ },
296
+ {
297
+ "type": "empty",
298
+ "room": null,
299
+ "color": null
300
+ },
301
+ {
302
+ "type": "empty",
303
+ "room": null,
304
+ "color": "green"
305
+ },
306
+ {
307
+ "type": "empty",
308
+ "room": null,
309
+ "color": "green"
310
+ },
311
+ {
312
+ "type": "empty",
313
+ "room": null,
314
+ "color": "green"
315
+ },
316
+ {
317
+ "type": "empty",
318
+ "room": null,
319
+ "color": null
320
+ },
321
+ {
322
+ "type": "wall",
323
+ "room": null,
324
+ "color": null
325
+ }
326
+ ],
327
+ [
328
+ {
329
+ "type": "wall",
330
+ "room": null,
331
+ "color": null
332
+ },
333
+ {
334
+ "type": "empty",
335
+ "room": null,
336
+ "color": null
337
+ },
338
+ {
339
+ "type": "empty",
340
+ "room": null,
341
+ "color": null
342
+ },
343
+ {
344
+ "type": "empty",
345
+ "room": null,
346
+ "color": null
347
+ },
348
+ {
349
+ "type": "empty",
350
+ "room": null,
351
+ "color": null
352
+ },
353
+ {
354
+ "type": "empty",
355
+ "room": null,
356
+ "color": null
357
+ },
358
+ {
359
+ "type": "wall",
360
+ "room": null,
361
+ "color": null
362
+ },
363
+ {
364
+ "type": "wall",
365
+ "room": null,
366
+ "color": null
367
+ },
368
+ {
369
+ "type": "wall",
370
+ "room": null,
371
+ "color": null
372
+ },
373
+ {
374
+ "type": "wall",
375
+ "room": null,
376
+ "color": null
377
+ },
378
+ {
379
+ "type": "wall",
380
+ "room": null,
381
+ "color": null
382
+ },
383
+ {
384
+ "type": "wall",
385
+ "room": null,
386
+ "color": null
387
+ },
388
+ {
389
+ "type": "wall",
390
+ "room": null,
391
+ "color": null
392
+ },
393
+ {
394
+ "type": "wall",
395
+ "room": null,
396
+ "color": null
397
+ },
398
+ {
399
+ "type": "empty",
400
+ "room": null,
401
+ "color": null
402
+ },
403
+ {
404
+ "type": "empty",
405
+ "room": null,
406
+ "color": null
407
+ },
408
+ {
409
+ "type": "empty",
410
+ "room": null,
411
+ "color": null
412
+ },
413
+ {
414
+ "type": "empty",
415
+ "room": null,
416
+ "color": null
417
+ },
418
+ {
419
+ "type": "empty",
420
+ "room": null,
421
+ "color": "yellow"
422
+ },
423
+ {
424
+ "type": "empty",
425
+ "room": null,
426
+ "color": "yellow"
427
+ },
428
+ {
429
+ "type": "empty",
430
+ "room": null,
431
+ "color": "yellow"
432
+ },
433
+ {
434
+ "type": "empty",
435
+ "room": null,
436
+ "color": "yellow"
437
+ },
438
+ {
439
+ "type": "empty",
440
+ "room": null,
441
+ "color": "yellow"
442
+ },
443
+ {
444
+ "type": "empty",
445
+ "room": null,
446
+ "color": null
447
+ },
448
+ {
449
+ "type": "empty",
450
+ "room": null,
451
+ "color": null
452
+ },
453
+ {
454
+ "type": "wall",
455
+ "room": null,
456
+ "color": null
457
+ },
458
+ {
459
+ "type": "empty",
460
+ "room": null,
461
+ "color": null
462
+ },
463
+ {
464
+ "type": "empty",
465
+ "room": null,
466
+ "color": null
467
+ },
468
+ {
469
+ "type": "empty",
470
+ "room": null,
471
+ "color": null
472
+ },
473
+ {
474
+ "type": "empty",
475
+ "room": null,
476
+ "color": null
477
+ },
478
+ {
479
+ "type": "empty",
480
+ "room": null,
481
+ "color": "green"
482
+ },
483
+ {
484
+ "type": "wall",
485
+ "room": null,
486
+ "color": null
487
+ }
488
+ ],
489
+ [
490
+ {
491
+ "type": "wall",
492
+ "room": null,
493
+ "color": null
494
+ },
495
+ {
496
+ "type": "empty",
497
+ "room": null,
498
+ "color": null
499
+ },
500
+ {
501
+ "type": "empty",
502
+ "room": null,
503
+ "color": null
504
+ },
505
+ {
506
+ "type": "empty",
507
+ "room": null,
508
+ "color": null
509
+ },
510
+ {
511
+ "type": "empty",
512
+ "room": null,
513
+ "color": null
514
+ },
515
+ {
516
+ "type": "empty",
517
+ "room": null,
518
+ "color": null
519
+ },
520
+ {
521
+ "type": "door",
522
+ "room": null,
523
+ "color": null
524
+ },
525
+ {
526
+ "type": "empty",
527
+ "room": null,
528
+ "color": null
529
+ },
530
+ {
531
+ "type": "empty",
532
+ "room": null,
533
+ "color": null
534
+ },
535
+ {
536
+ "type": "empty",
537
+ "room": null,
538
+ "color": null
539
+ },
540
+ {
541
+ "type": "empty",
542
+ "room": null,
543
+ "color": null
544
+ },
545
+ {
546
+ "type": "empty",
547
+ "room": null,
548
+ "color": null
549
+ },
550
+ {
551
+ "type": "empty",
552
+ "room": null,
553
+ "color": null
554
+ },
555
+ {
556
+ "type": "door",
557
+ "room": null,
558
+ "color": null
559
+ },
560
+ {
561
+ "type": "empty",
562
+ "room": null,
563
+ "color": null
564
+ },
565
+ {
566
+ "type": "empty",
567
+ "room": null,
568
+ "color": null
569
+ },
570
+ {
571
+ "type": "empty",
572
+ "room": null,
573
+ "color": null
574
+ },
575
+ {
576
+ "type": "empty",
577
+ "room": null,
578
+ "color": null
579
+ },
580
+ {
581
+ "type": "empty",
582
+ "room": null,
583
+ "color": "yellow"
584
+ },
585
+ {
586
+ "type": "empty",
587
+ "room": null,
588
+ "color": "yellow"
589
+ },
590
+ {
591
+ "type": "empty",
592
+ "room": null,
593
+ "color": "yellow"
594
+ },
595
+ {
596
+ "type": "empty",
597
+ "room": null,
598
+ "color": "yellow"
599
+ },
600
+ {
601
+ "type": "empty",
602
+ "room": null,
603
+ "color": "yellow"
604
+ },
605
+ {
606
+ "type": "empty",
607
+ "room": null,
608
+ "color": null
609
+ },
610
+ {
611
+ "type": "empty",
612
+ "room": null,
613
+ "color": null
614
+ },
615
+ {
616
+ "type": "door",
617
+ "room": null,
618
+ "color": null
619
+ },
620
+ {
621
+ "type": "empty",
622
+ "room": null,
623
+ "color": null
624
+ },
625
+ {
626
+ "type": "empty",
627
+ "room": null,
628
+ "color": null
629
+ },
630
+ {
631
+ "type": "empty",
632
+ "room": null,
633
+ "color": null
634
+ },
635
+ {
636
+ "type": "empty",
637
+ "room": null,
638
+ "color": null
639
+ },
640
+ {
641
+ "type": "empty",
642
+ "room": null,
643
+ "color": "green"
644
+ },
645
+ {
646
+ "type": "wall",
647
+ "room": null,
648
+ "color": null
649
+ }
650
+ ],
651
+ [
652
+ {
653
+ "type": "wall",
654
+ "room": null,
655
+ "color": null
656
+ },
657
+ {
658
+ "type": "empty",
659
+ "room": null,
660
+ "color": null
661
+ },
662
+ {
663
+ "type": "empty",
664
+ "room": null,
665
+ "color": null
666
+ },
667
+ {
668
+ "type": "empty",
669
+ "room": null,
670
+ "color": null
671
+ },
672
+ {
673
+ "type": "empty",
674
+ "room": null,
675
+ "color": null
676
+ },
677
+ {
678
+ "type": "empty",
679
+ "room": null,
680
+ "color": null
681
+ },
682
+ {
683
+ "type": "wall",
684
+ "room": null,
685
+ "color": null
686
+ },
687
+ {
688
+ "type": "wall",
689
+ "room": null,
690
+ "color": null
691
+ },
692
+ {
693
+ "type": "wall",
694
+ "room": null,
695
+ "color": null
696
+ },
697
+ {
698
+ "type": "wall",
699
+ "room": null,
700
+ "color": null
701
+ },
702
+ {
703
+ "type": "wall",
704
+ "room": null,
705
+ "color": null
706
+ },
707
+ {
708
+ "type": "wall",
709
+ "room": null,
710
+ "color": null
711
+ },
712
+ {
713
+ "type": "wall",
714
+ "room": null,
715
+ "color": null
716
+ },
717
+ {
718
+ "type": "wall",
719
+ "room": null,
720
+ "color": null
721
+ },
722
+ {
723
+ "type": "empty",
724
+ "room": null,
725
+ "color": null
726
+ },
727
+ {
728
+ "type": "empty",
729
+ "room": null,
730
+ "color": null
731
+ },
732
+ {
733
+ "type": "empty",
734
+ "room": null,
735
+ "color": null
736
+ },
737
+ {
738
+ "type": "empty",
739
+ "room": null,
740
+ "color": null
741
+ },
742
+ {
743
+ "type": "empty",
744
+ "room": null,
745
+ "color": null
746
+ },
747
+ {
748
+ "type": "empty",
749
+ "room": null,
750
+ "color": null
751
+ },
752
+ {
753
+ "type": "empty",
754
+ "room": null,
755
+ "color": null
756
+ },
757
+ {
758
+ "type": "empty",
759
+ "room": null,
760
+ "color": null
761
+ },
762
+ {
763
+ "type": "empty",
764
+ "room": null,
765
+ "color": null
766
+ },
767
+ {
768
+ "type": "empty",
769
+ "room": null,
770
+ "color": null
771
+ },
772
+ {
773
+ "type": "empty",
774
+ "room": null,
775
+ "color": null
776
+ },
777
+ {
778
+ "type": "wall",
779
+ "room": null,
780
+ "color": null
781
+ },
782
+ {
783
+ "type": "empty",
784
+ "room": null,
785
+ "color": null
786
+ },
787
+ {
788
+ "type": "empty",
789
+ "room": null,
790
+ "color": null
791
+ },
792
+ {
793
+ "type": "empty",
794
+ "room": null,
795
+ "color": null
796
+ },
797
+ {
798
+ "type": "empty",
799
+ "room": null,
800
+ "color": null
801
+ },
802
+ {
803
+ "type": "empty",
804
+ "room": null,
805
+ "color": "green"
806
+ },
807
+ {
808
+ "type": "wall",
809
+ "room": null,
810
+ "color": null
811
+ }
812
+ ],
813
+ [
814
+ {
815
+ "type": "wall",
816
+ "room": null,
817
+ "color": null
818
+ },
819
+ {
820
+ "type": "empty",
821
+ "room": null,
822
+ "color": null
823
+ },
824
+ {
825
+ "type": "empty",
826
+ "room": null,
827
+ "color": "red"
828
+ },
829
+ {
830
+ "type": "empty",
831
+ "room": null,
832
+ "color": "red"
833
+ },
834
+ {
835
+ "type": "empty",
836
+ "room": null,
837
+ "color": "red"
838
+ },
839
+ {
840
+ "type": "empty",
841
+ "room": null,
842
+ "color": null
843
+ },
844
+ {
845
+ "type": "wall",
846
+ "room": null,
847
+ "color": null
848
+ },
849
+ {
850
+ "type": "empty",
851
+ "room": null,
852
+ "color": null
853
+ },
854
+ {
855
+ "type": "empty",
856
+ "room": null,
857
+ "color": null
858
+ },
859
+ {
860
+ "type": "empty",
861
+ "room": null,
862
+ "color": null
863
+ },
864
+ {
865
+ "type": "empty",
866
+ "room": null,
867
+ "color": null
868
+ },
869
+ {
870
+ "type": "empty",
871
+ "room": null,
872
+ "color": null
873
+ },
874
+ {
875
+ "type": "empty",
876
+ "room": null,
877
+ "color": null
878
+ },
879
+ {
880
+ "type": "wall",
881
+ "room": null,
882
+ "color": null
883
+ },
884
+ {
885
+ "type": "empty",
886
+ "room": null,
887
+ "color": null
888
+ },
889
+ {
890
+ "type": "empty",
891
+ "room": null,
892
+ "color": null
893
+ },
894
+ {
895
+ "type": "empty",
896
+ "room": null,
897
+ "color": null
898
+ },
899
+ {
900
+ "type": "empty",
901
+ "room": null,
902
+ "color": null
903
+ },
904
+ {
905
+ "type": "empty",
906
+ "room": null,
907
+ "color": null
908
+ },
909
+ {
910
+ "type": "empty",
911
+ "room": null,
912
+ "color": null
913
+ },
914
+ {
915
+ "type": "empty",
916
+ "room": null,
917
+ "color": null
918
+ },
919
+ {
920
+ "type": "empty",
921
+ "room": null,
922
+ "color": null
923
+ },
924
+ {
925
+ "type": "empty",
926
+ "room": null,
927
+ "color": null
928
+ },
929
+ {
930
+ "type": "empty",
931
+ "room": null,
932
+ "color": null
933
+ },
934
+ {
935
+ "type": "empty",
936
+ "room": null,
937
+ "color": null
938
+ },
939
+ {
940
+ "type": "wall",
941
+ "room": null,
942
+ "color": null
943
+ },
944
+ {
945
+ "type": "empty",
946
+ "room": null,
947
+ "color": null
948
+ },
949
+ {
950
+ "type": "empty",
951
+ "room": null,
952
+ "color": "green"
953
+ },
954
+ {
955
+ "type": "empty",
956
+ "room": null,
957
+ "color": "green"
958
+ },
959
+ {
960
+ "type": "empty",
961
+ "room": null,
962
+ "color": "green"
963
+ },
964
+ {
965
+ "type": "empty",
966
+ "room": null,
967
+ "color": null
968
+ },
969
+ {
970
+ "type": "wall",
971
+ "room": null,
972
+ "color": null
973
+ }
974
+ ],
975
+ [
976
+ {
977
+ "type": "wall",
978
+ "room": null,
979
+ "color": null
980
+ },
981
+ {
982
+ "type": "wall",
983
+ "room": null,
984
+ "color": null
985
+ },
986
+ {
987
+ "type": "wall",
988
+ "room": null,
989
+ "color": null
990
+ },
991
+ {
992
+ "type": "wall",
993
+ "room": null,
994
+ "color": null
995
+ },
996
+ {
997
+ "type": "wall",
998
+ "room": null,
999
+ "color": null
1000
+ },
1001
+ {
1002
+ "type": "wall",
1003
+ "room": null,
1004
+ "color": null
1005
+ },
1006
+ {
1007
+ "type": "wall",
1008
+ "room": null,
1009
+ "color": null
1010
+ },
1011
+ {
1012
+ "type": "empty",
1013
+ "room": null,
1014
+ "color": null
1015
+ },
1016
+ {
1017
+ "type": "empty",
1018
+ "room": null,
1019
+ "color": null
1020
+ },
1021
+ {
1022
+ "type": "empty",
1023
+ "room": null,
1024
+ "color": null
1025
+ },
1026
+ {
1027
+ "type": "empty",
1028
+ "room": null,
1029
+ "color": null
1030
+ },
1031
+ {
1032
+ "type": "empty",
1033
+ "room": null,
1034
+ "color": null
1035
+ },
1036
+ {
1037
+ "type": "empty",
1038
+ "room": null,
1039
+ "color": null
1040
+ },
1041
+ {
1042
+ "type": "wall",
1043
+ "room": null,
1044
+ "color": null
1045
+ },
1046
+ {
1047
+ "type": "wall",
1048
+ "room": null,
1049
+ "color": null
1050
+ },
1051
+ {
1052
+ "type": "wall",
1053
+ "room": null,
1054
+ "color": null
1055
+ },
1056
+ {
1057
+ "type": "wall",
1058
+ "room": null,
1059
+ "color": null
1060
+ },
1061
+ {
1062
+ "type": "wall",
1063
+ "room": null,
1064
+ "color": null
1065
+ },
1066
+ {
1067
+ "type": "wall",
1068
+ "room": null,
1069
+ "color": null
1070
+ },
1071
+ {
1072
+ "type": "wall",
1073
+ "room": null,
1074
+ "color": null
1075
+ },
1076
+ {
1077
+ "type": "wall",
1078
+ "room": null,
1079
+ "color": null
1080
+ },
1081
+ {
1082
+ "type": "door",
1083
+ "room": null,
1084
+ "color": null
1085
+ },
1086
+ {
1087
+ "type": "door",
1088
+ "room": null,
1089
+ "color": null
1090
+ },
1091
+ {
1092
+ "type": "wall",
1093
+ "room": null,
1094
+ "color": null
1095
+ },
1096
+ {
1097
+ "type": "wall",
1098
+ "room": null,
1099
+ "color": null
1100
+ },
1101
+ {
1102
+ "type": "wall",
1103
+ "room": null,
1104
+ "color": null
1105
+ },
1106
+ {
1107
+ "type": "wall",
1108
+ "room": null,
1109
+ "color": null
1110
+ },
1111
+ {
1112
+ "type": "wall",
1113
+ "room": null,
1114
+ "color": null
1115
+ },
1116
+ {
1117
+ "type": "wall",
1118
+ "room": null,
1119
+ "color": null
1120
+ },
1121
+ {
1122
+ "type": "wall",
1123
+ "room": null,
1124
+ "color": null
1125
+ },
1126
+ {
1127
+ "type": "wall",
1128
+ "room": null,
1129
+ "color": null
1130
+ },
1131
+ {
1132
+ "type": "wall",
1133
+ "room": null,
1134
+ "color": null
1135
+ }
1136
+ ],
1137
+ [
1138
+ {
1139
+ "type": "empty",
1140
+ "room": null,
1141
+ "color": null
1142
+ },
1143
+ {
1144
+ "type": "empty",
1145
+ "room": null,
1146
+ "color": null
1147
+ },
1148
+ {
1149
+ "type": "empty",
1150
+ "room": null,
1151
+ "color": null
1152
+ },
1153
+ {
1154
+ "type": "empty",
1155
+ "room": null,
1156
+ "color": null
1157
+ },
1158
+ {
1159
+ "type": "empty",
1160
+ "room": null,
1161
+ "color": null
1162
+ },
1163
+ {
1164
+ "type": "empty",
1165
+ "room": null,
1166
+ "color": null
1167
+ },
1168
+ {
1169
+ "type": "empty",
1170
+ "room": null,
1171
+ "color": null
1172
+ },
1173
+ {
1174
+ "type": "empty",
1175
+ "room": null,
1176
+ "color": null
1177
+ },
1178
+ {
1179
+ "type": "empty",
1180
+ "room": null,
1181
+ "color": null
1182
+ },
1183
+ {
1184
+ "type": "empty",
1185
+ "room": null,
1186
+ "color": null
1187
+ },
1188
+ {
1189
+ "type": "empty",
1190
+ "room": null,
1191
+ "color": null
1192
+ },
1193
+ {
1194
+ "type": "empty",
1195
+ "room": null,
1196
+ "color": null
1197
+ },
1198
+ {
1199
+ "type": "empty",
1200
+ "room": null,
1201
+ "color": null
1202
+ },
1203
+ {
1204
+ "type": "empty",
1205
+ "room": null,
1206
+ "color": null
1207
+ },
1208
+ {
1209
+ "type": "wall",
1210
+ "room": null,
1211
+ "color": null
1212
+ },
1213
+ {
1214
+ "type": "empty",
1215
+ "room": null,
1216
+ "color": "yellow"
1217
+ },
1218
+ {
1219
+ "type": "empty",
1220
+ "room": null,
1221
+ "color": null
1222
+ },
1223
+ {
1224
+ "type": "empty",
1225
+ "room": null,
1226
+ "color": null
1227
+ },
1228
+ {
1229
+ "type": "wall",
1230
+ "room": null,
1231
+ "color": null
1232
+ },
1233
+ {
1234
+ "type": "empty",
1235
+ "room": null,
1236
+ "color": null
1237
+ },
1238
+ {
1239
+ "type": "empty",
1240
+ "room": null,
1241
+ "color": null
1242
+ },
1243
+ {
1244
+ "type": "empty",
1245
+ "room": null,
1246
+ "color": null
1247
+ },
1248
+ {
1249
+ "type": "empty",
1250
+ "room": null,
1251
+ "color": null
1252
+ },
1253
+ {
1254
+ "type": "empty",
1255
+ "room": null,
1256
+ "color": null
1257
+ },
1258
+ {
1259
+ "type": "empty",
1260
+ "room": null,
1261
+ "color": null
1262
+ },
1263
+ {
1264
+ "type": "wall",
1265
+ "room": null,
1266
+ "color": null
1267
+ },
1268
+ {
1269
+ "type": "empty",
1270
+ "room": null,
1271
+ "color": null
1272
+ },
1273
+ {
1274
+ "type": "empty",
1275
+ "room": null,
1276
+ "color": null
1277
+ },
1278
+ {
1279
+ "type": "empty",
1280
+ "room": null,
1281
+ "color": null
1282
+ },
1283
+ {
1284
+ "type": "empty",
1285
+ "room": null,
1286
+ "color": null
1287
+ },
1288
+ {
1289
+ "type": "empty",
1290
+ "room": null,
1291
+ "color": null
1292
+ },
1293
+ {
1294
+ "type": "empty",
1295
+ "room": null,
1296
+ "color": null
1297
+ }
1298
+ ],
1299
+ [
1300
+ {
1301
+ "type": "empty",
1302
+ "room": null,
1303
+ "color": null
1304
+ },
1305
+ {
1306
+ "type": "empty",
1307
+ "room": null,
1308
+ "color": null
1309
+ },
1310
+ {
1311
+ "type": "empty",
1312
+ "room": null,
1313
+ "color": null
1314
+ },
1315
+ {
1316
+ "type": "empty",
1317
+ "room": null,
1318
+ "color": null
1319
+ },
1320
+ {
1321
+ "type": "empty",
1322
+ "room": null,
1323
+ "color": null
1324
+ },
1325
+ {
1326
+ "type": "empty",
1327
+ "room": null,
1328
+ "color": null
1329
+ },
1330
+ {
1331
+ "type": "empty",
1332
+ "room": null,
1333
+ "color": null
1334
+ },
1335
+ {
1336
+ "type": "empty",
1337
+ "room": null,
1338
+ "color": null
1339
+ },
1340
+ {
1341
+ "type": "empty",
1342
+ "room": null,
1343
+ "color": null
1344
+ },
1345
+ {
1346
+ "type": "empty",
1347
+ "room": null,
1348
+ "color": null
1349
+ },
1350
+ {
1351
+ "type": "empty",
1352
+ "room": null,
1353
+ "color": null
1354
+ },
1355
+ {
1356
+ "type": "empty",
1357
+ "room": null,
1358
+ "color": null
1359
+ },
1360
+ {
1361
+ "type": "empty",
1362
+ "room": null,
1363
+ "color": null
1364
+ },
1365
+ {
1366
+ "type": "empty",
1367
+ "room": null,
1368
+ "color": null
1369
+ },
1370
+ {
1371
+ "type": "wall",
1372
+ "room": null,
1373
+ "color": null
1374
+ },
1375
+ {
1376
+ "type": "empty",
1377
+ "room": null,
1378
+ "color": "yellow"
1379
+ },
1380
+ {
1381
+ "type": "empty",
1382
+ "room": null,
1383
+ "color": null
1384
+ },
1385
+ {
1386
+ "type": "empty",
1387
+ "room": null,
1388
+ "color": null
1389
+ },
1390
+ {
1391
+ "type": "wall",
1392
+ "room": null,
1393
+ "color": null
1394
+ },
1395
+ {
1396
+ "type": "empty",
1397
+ "room": null,
1398
+ "color": "green"
1399
+ },
1400
+ {
1401
+ "type": "empty",
1402
+ "room": null,
1403
+ "color": null
1404
+ },
1405
+ {
1406
+ "type": "empty",
1407
+ "room": null,
1408
+ "color": null
1409
+ },
1410
+ {
1411
+ "type": "empty",
1412
+ "room": null,
1413
+ "color": null
1414
+ },
1415
+ {
1416
+ "type": "empty",
1417
+ "room": null,
1418
+ "color": null
1419
+ },
1420
+ {
1421
+ "type": "empty",
1422
+ "room": null,
1423
+ "color": null
1424
+ },
1425
+ {
1426
+ "type": "wall",
1427
+ "room": null,
1428
+ "color": null
1429
+ },
1430
+ {
1431
+ "type": "empty",
1432
+ "room": null,
1433
+ "color": null
1434
+ },
1435
+ {
1436
+ "type": "empty",
1437
+ "room": null,
1438
+ "color": null
1439
+ },
1440
+ {
1441
+ "type": "empty",
1442
+ "room": null,
1443
+ "color": null
1444
+ },
1445
+ {
1446
+ "type": "empty",
1447
+ "room": null,
1448
+ "color": null
1449
+ },
1450
+ {
1451
+ "type": "empty",
1452
+ "room": null,
1453
+ "color": null
1454
+ },
1455
+ {
1456
+ "type": "empty",
1457
+ "room": null,
1458
+ "color": null
1459
+ }
1460
+ ],
1461
+ [
1462
+ {
1463
+ "type": "empty",
1464
+ "room": null,
1465
+ "color": null
1466
+ },
1467
+ {
1468
+ "type": "empty",
1469
+ "room": null,
1470
+ "color": null
1471
+ },
1472
+ {
1473
+ "type": "empty",
1474
+ "room": null,
1475
+ "color": null
1476
+ },
1477
+ {
1478
+ "type": "empty",
1479
+ "room": null,
1480
+ "color": null
1481
+ },
1482
+ {
1483
+ "type": "empty",
1484
+ "room": null,
1485
+ "color": null
1486
+ },
1487
+ {
1488
+ "type": "empty",
1489
+ "room": null,
1490
+ "color": null
1491
+ },
1492
+ {
1493
+ "type": "empty",
1494
+ "room": null,
1495
+ "color": null
1496
+ },
1497
+ {
1498
+ "type": "empty",
1499
+ "room": null,
1500
+ "color": null
1501
+ },
1502
+ {
1503
+ "type": "empty",
1504
+ "room": null,
1505
+ "color": null
1506
+ },
1507
+ {
1508
+ "type": "empty",
1509
+ "room": null,
1510
+ "color": null
1511
+ },
1512
+ {
1513
+ "type": "empty",
1514
+ "room": null,
1515
+ "color": null
1516
+ },
1517
+ {
1518
+ "type": "empty",
1519
+ "room": null,
1520
+ "color": null
1521
+ },
1522
+ {
1523
+ "type": "empty",
1524
+ "room": null,
1525
+ "color": null
1526
+ },
1527
+ {
1528
+ "type": "empty",
1529
+ "room": null,
1530
+ "color": null
1531
+ },
1532
+ {
1533
+ "type": "wall",
1534
+ "room": null,
1535
+ "color": null
1536
+ },
1537
+ {
1538
+ "type": "empty",
1539
+ "room": null,
1540
+ "color": null
1541
+ },
1542
+ {
1543
+ "type": "empty",
1544
+ "room": null,
1545
+ "color": null
1546
+ },
1547
+ {
1548
+ "type": "empty",
1549
+ "room": null,
1550
+ "color": null
1551
+ },
1552
+ {
1553
+ "type": "wall",
1554
+ "room": null,
1555
+ "color": null
1556
+ },
1557
+ {
1558
+ "type": "empty",
1559
+ "room": null,
1560
+ "color": "green"
1561
+ },
1562
+ {
1563
+ "type": "empty",
1564
+ "room": null,
1565
+ "color": null
1566
+ },
1567
+ {
1568
+ "type": "empty",
1569
+ "room": null,
1570
+ "color": null
1571
+ },
1572
+ {
1573
+ "type": "empty",
1574
+ "room": null,
1575
+ "color": null
1576
+ },
1577
+ {
1578
+ "type": "empty",
1579
+ "room": null,
1580
+ "color": null
1581
+ },
1582
+ {
1583
+ "type": "empty",
1584
+ "room": null,
1585
+ "color": null
1586
+ },
1587
+ {
1588
+ "type": "wall",
1589
+ "room": null,
1590
+ "color": null
1591
+ },
1592
+ {
1593
+ "type": "empty",
1594
+ "room": null,
1595
+ "color": null
1596
+ },
1597
+ {
1598
+ "type": "empty",
1599
+ "room": null,
1600
+ "color": null
1601
+ },
1602
+ {
1603
+ "type": "empty",
1604
+ "room": null,
1605
+ "color": null
1606
+ },
1607
+ {
1608
+ "type": "empty",
1609
+ "room": null,
1610
+ "color": null
1611
+ },
1612
+ {
1613
+ "type": "empty",
1614
+ "room": null,
1615
+ "color": null
1616
+ },
1617
+ {
1618
+ "type": "empty",
1619
+ "room": null,
1620
+ "color": null
1621
+ }
1622
+ ],
1623
+ [
1624
+ {
1625
+ "type": "empty",
1626
+ "room": null,
1627
+ "color": null
1628
+ },
1629
+ {
1630
+ "type": "empty",
1631
+ "room": null,
1632
+ "color": null
1633
+ },
1634
+ {
1635
+ "type": "empty",
1636
+ "room": null,
1637
+ "color": null
1638
+ },
1639
+ {
1640
+ "type": "empty",
1641
+ "room": null,
1642
+ "color": null
1643
+ },
1644
+ {
1645
+ "type": "empty",
1646
+ "room": null,
1647
+ "color": null
1648
+ },
1649
+ {
1650
+ "type": "empty",
1651
+ "room": null,
1652
+ "color": null
1653
+ },
1654
+ {
1655
+ "type": "empty",
1656
+ "room": null,
1657
+ "color": null
1658
+ },
1659
+ {
1660
+ "type": "empty",
1661
+ "room": null,
1662
+ "color": null
1663
+ },
1664
+ {
1665
+ "type": "empty",
1666
+ "room": null,
1667
+ "color": null
1668
+ },
1669
+ {
1670
+ "type": "empty",
1671
+ "room": null,
1672
+ "color": null
1673
+ },
1674
+ {
1675
+ "type": "empty",
1676
+ "room": null,
1677
+ "color": null
1678
+ },
1679
+ {
1680
+ "type": "empty",
1681
+ "room": null,
1682
+ "color": null
1683
+ },
1684
+ {
1685
+ "type": "empty",
1686
+ "room": null,
1687
+ "color": null
1688
+ },
1689
+ {
1690
+ "type": "empty",
1691
+ "room": null,
1692
+ "color": null
1693
+ },
1694
+ {
1695
+ "type": "wall",
1696
+ "room": null,
1697
+ "color": null
1698
+ },
1699
+ {
1700
+ "type": "empty",
1701
+ "room": null,
1702
+ "color": null
1703
+ },
1704
+ {
1705
+ "type": "empty",
1706
+ "room": null,
1707
+ "color": null
1708
+ },
1709
+ {
1710
+ "type": "empty",
1711
+ "room": null,
1712
+ "color": null
1713
+ },
1714
+ {
1715
+ "type": "wall",
1716
+ "room": null,
1717
+ "color": null
1718
+ },
1719
+ {
1720
+ "type": "empty",
1721
+ "room": null,
1722
+ "color": "green"
1723
+ },
1724
+ {
1725
+ "type": "empty",
1726
+ "room": null,
1727
+ "color": null
1728
+ },
1729
+ {
1730
+ "type": "empty",
1731
+ "room": null,
1732
+ "color": null
1733
+ },
1734
+ {
1735
+ "type": "empty",
1736
+ "room": null,
1737
+ "color": null
1738
+ },
1739
+ {
1740
+ "type": "empty",
1741
+ "room": null,
1742
+ "color": null
1743
+ },
1744
+ {
1745
+ "type": "empty",
1746
+ "room": null,
1747
+ "color": null
1748
+ },
1749
+ {
1750
+ "type": "wall",
1751
+ "room": null,
1752
+ "color": null
1753
+ },
1754
+ {
1755
+ "type": "empty",
1756
+ "room": null,
1757
+ "color": null
1758
+ },
1759
+ {
1760
+ "type": "empty",
1761
+ "room": null,
1762
+ "color": null
1763
+ },
1764
+ {
1765
+ "type": "empty",
1766
+ "room": null,
1767
+ "color": null
1768
+ },
1769
+ {
1770
+ "type": "empty",
1771
+ "room": null,
1772
+ "color": null
1773
+ },
1774
+ {
1775
+ "type": "empty",
1776
+ "room": null,
1777
+ "color": null
1778
+ },
1779
+ {
1780
+ "type": "empty",
1781
+ "room": null,
1782
+ "color": null
1783
+ }
1784
+ ],
1785
+ [
1786
+ {
1787
+ "type": "empty",
1788
+ "room": null,
1789
+ "color": null
1790
+ },
1791
+ {
1792
+ "type": "empty",
1793
+ "room": null,
1794
+ "color": null
1795
+ },
1796
+ {
1797
+ "type": "empty",
1798
+ "room": null,
1799
+ "color": null
1800
+ },
1801
+ {
1802
+ "type": "empty",
1803
+ "room": null,
1804
+ "color": null
1805
+ },
1806
+ {
1807
+ "type": "empty",
1808
+ "room": null,
1809
+ "color": null
1810
+ },
1811
+ {
1812
+ "type": "empty",
1813
+ "room": null,
1814
+ "color": null
1815
+ },
1816
+ {
1817
+ "type": "empty",
1818
+ "room": null,
1819
+ "color": null
1820
+ },
1821
+ {
1822
+ "type": "empty",
1823
+ "room": null,
1824
+ "color": null
1825
+ },
1826
+ {
1827
+ "type": "empty",
1828
+ "room": null,
1829
+ "color": null
1830
+ },
1831
+ {
1832
+ "type": "empty",
1833
+ "room": null,
1834
+ "color": null
1835
+ },
1836
+ {
1837
+ "type": "empty",
1838
+ "room": null,
1839
+ "color": null
1840
+ },
1841
+ {
1842
+ "type": "empty",
1843
+ "room": null,
1844
+ "color": null
1845
+ },
1846
+ {
1847
+ "type": "empty",
1848
+ "room": null,
1849
+ "color": null
1850
+ },
1851
+ {
1852
+ "type": "empty",
1853
+ "room": null,
1854
+ "color": null
1855
+ },
1856
+ {
1857
+ "type": "wall",
1858
+ "room": null,
1859
+ "color": null
1860
+ },
1861
+ {
1862
+ "type": "empty",
1863
+ "room": null,
1864
+ "color": null
1865
+ },
1866
+ {
1867
+ "type": "empty",
1868
+ "room": null,
1869
+ "color": null
1870
+ },
1871
+ {
1872
+ "type": "empty",
1873
+ "room": null,
1874
+ "color": null
1875
+ },
1876
+ {
1877
+ "type": "wall",
1878
+ "room": null,
1879
+ "color": null
1880
+ },
1881
+ {
1882
+ "type": "empty",
1883
+ "room": null,
1884
+ "color": null
1885
+ },
1886
+ {
1887
+ "type": "empty",
1888
+ "room": null,
1889
+ "color": null
1890
+ },
1891
+ {
1892
+ "type": "empty",
1893
+ "room": null,
1894
+ "color": null
1895
+ },
1896
+ {
1897
+ "type": "empty",
1898
+ "room": null,
1899
+ "color": null
1900
+ },
1901
+ {
1902
+ "type": "empty",
1903
+ "room": null,
1904
+ "color": null
1905
+ },
1906
+ {
1907
+ "type": "empty",
1908
+ "room": null,
1909
+ "color": null
1910
+ },
1911
+ {
1912
+ "type": "wall",
1913
+ "room": null,
1914
+ "color": null
1915
+ },
1916
+ {
1917
+ "type": "empty",
1918
+ "room": null,
1919
+ "color": null
1920
+ },
1921
+ {
1922
+ "type": "empty",
1923
+ "room": null,
1924
+ "color": null
1925
+ },
1926
+ {
1927
+ "type": "empty",
1928
+ "room": null,
1929
+ "color": null
1930
+ },
1931
+ {
1932
+ "type": "empty",
1933
+ "room": null,
1934
+ "color": null
1935
+ },
1936
+ {
1937
+ "type": "empty",
1938
+ "room": null,
1939
+ "color": null
1940
+ },
1941
+ {
1942
+ "type": "empty",
1943
+ "room": null,
1944
+ "color": null
1945
+ }
1946
+ ],
1947
+ [
1948
+ {
1949
+ "type": "wall",
1950
+ "room": null,
1951
+ "color": null
1952
+ },
1953
+ {
1954
+ "type": "wall",
1955
+ "room": null,
1956
+ "color": null
1957
+ },
1958
+ {
1959
+ "type": "wall",
1960
+ "room": null,
1961
+ "color": null
1962
+ },
1963
+ {
1964
+ "type": "wall",
1965
+ "room": null,
1966
+ "color": null
1967
+ },
1968
+ {
1969
+ "type": "wall",
1970
+ "room": null,
1971
+ "color": null
1972
+ },
1973
+ {
1974
+ "type": "wall",
1975
+ "room": null,
1976
+ "color": null
1977
+ },
1978
+ {
1979
+ "type": "wall",
1980
+ "room": null,
1981
+ "color": null
1982
+ },
1983
+ {
1984
+ "type": "wall",
1985
+ "room": null,
1986
+ "color": null
1987
+ },
1988
+ {
1989
+ "type": "wall",
1990
+ "room": null,
1991
+ "color": null
1992
+ },
1993
+ {
1994
+ "type": "wall",
1995
+ "room": null,
1996
+ "color": null
1997
+ },
1998
+ {
1999
+ "type": "wall",
2000
+ "room": null,
2001
+ "color": null
2002
+ },
2003
+ {
2004
+ "type": "wall",
2005
+ "room": null,
2006
+ "color": null
2007
+ },
2008
+ {
2009
+ "type": "wall",
2010
+ "room": null,
2011
+ "color": null
2012
+ },
2013
+ {
2014
+ "type": "wall",
2015
+ "room": null,
2016
+ "color": null
2017
+ },
2018
+ {
2019
+ "type": "wall",
2020
+ "room": null,
2021
+ "color": null
2022
+ },
2023
+ {
2024
+ "type": "wall",
2025
+ "room": null,
2026
+ "color": null
2027
+ },
2028
+ {
2029
+ "type": "door",
2030
+ "room": null,
2031
+ "color": null
2032
+ },
2033
+ {
2034
+ "type": "wall",
2035
+ "room": null,
2036
+ "color": null
2037
+ },
2038
+ {
2039
+ "type": "wall",
2040
+ "room": null,
2041
+ "color": null
2042
+ },
2043
+ {
2044
+ "type": "wall",
2045
+ "room": null,
2046
+ "color": null
2047
+ },
2048
+ {
2049
+ "type": "wall",
2050
+ "room": null,
2051
+ "color": null
2052
+ },
2053
+ {
2054
+ "type": "door",
2055
+ "room": null,
2056
+ "color": null
2057
+ },
2058
+ {
2059
+ "type": "door",
2060
+ "room": null,
2061
+ "color": null
2062
+ },
2063
+ {
2064
+ "type": "wall",
2065
+ "room": null,
2066
+ "color": null
2067
+ },
2068
+ {
2069
+ "type": "wall",
2070
+ "room": null,
2071
+ "color": null
2072
+ },
2073
+ {
2074
+ "type": "wall",
2075
+ "room": null,
2076
+ "color": null
2077
+ },
2078
+ {
2079
+ "type": "wall",
2080
+ "room": null,
2081
+ "color": null
2082
+ },
2083
+ {
2084
+ "type": "wall",
2085
+ "room": null,
2086
+ "color": null
2087
+ },
2088
+ {
2089
+ "type": "wall",
2090
+ "room": null,
2091
+ "color": null
2092
+ },
2093
+ {
2094
+ "type": "wall",
2095
+ "room": null,
2096
+ "color": null
2097
+ },
2098
+ {
2099
+ "type": "wall",
2100
+ "room": null,
2101
+ "color": null
2102
+ },
2103
+ {
2104
+ "type": "wall",
2105
+ "room": null,
2106
+ "color": null
2107
+ }
2108
+ ],
2109
+ [
2110
+ {
2111
+ "type": "wall",
2112
+ "room": null,
2113
+ "color": null
2114
+ },
2115
+ {
2116
+ "type": "empty",
2117
+ "room": null,
2118
+ "color": null
2119
+ },
2120
+ {
2121
+ "type": "empty",
2122
+ "room": null,
2123
+ "color": null
2124
+ },
2125
+ {
2126
+ "type": "empty",
2127
+ "room": null,
2128
+ "color": "yellow"
2129
+ },
2130
+ {
2131
+ "type": "empty",
2132
+ "room": null,
2133
+ "color": "yellow"
2134
+ },
2135
+ {
2136
+ "type": "empty",
2137
+ "room": null,
2138
+ "color": "yellow"
2139
+ },
2140
+ {
2141
+ "type": "empty",
2142
+ "room": null,
2143
+ "color": null
2144
+ },
2145
+ {
2146
+ "type": "empty",
2147
+ "room": null,
2148
+ "color": null
2149
+ },
2150
+ {
2151
+ "type": "empty",
2152
+ "room": null,
2153
+ "color": null
2154
+ },
2155
+ {
2156
+ "type": "wall",
2157
+ "room": null,
2158
+ "color": null
2159
+ },
2160
+ {
2161
+ "type": "empty",
2162
+ "room": null,
2163
+ "color": null
2164
+ },
2165
+ {
2166
+ "type": "empty",
2167
+ "room": null,
2168
+ "color": null
2169
+ },
2170
+ {
2171
+ "type": "empty",
2172
+ "room": null,
2173
+ "color": null
2174
+ },
2175
+ {
2176
+ "type": "empty",
2177
+ "room": null,
2178
+ "color": null
2179
+ },
2180
+ {
2181
+ "type": "empty",
2182
+ "room": null,
2183
+ "color": null
2184
+ },
2185
+ {
2186
+ "type": "empty",
2187
+ "room": null,
2188
+ "color": null
2189
+ },
2190
+ {
2191
+ "type": "empty",
2192
+ "room": null,
2193
+ "color": null
2194
+ },
2195
+ {
2196
+ "type": "empty",
2197
+ "room": null,
2198
+ "color": null
2199
+ },
2200
+ {
2201
+ "type": "wall",
2202
+ "room": null,
2203
+ "color": null
2204
+ },
2205
+ {
2206
+ "type": "empty",
2207
+ "room": null,
2208
+ "color": null
2209
+ },
2210
+ {
2211
+ "type": "empty",
2212
+ "room": null,
2213
+ "color": null
2214
+ },
2215
+ {
2216
+ "type": "empty",
2217
+ "room": null,
2218
+ "color": null
2219
+ },
2220
+ {
2221
+ "type": "empty",
2222
+ "room": null,
2223
+ "color": null
2224
+ },
2225
+ {
2226
+ "type": "empty",
2227
+ "room": null,
2228
+ "color": null
2229
+ },
2230
+ {
2231
+ "type": "empty",
2232
+ "room": null,
2233
+ "color": null
2234
+ },
2235
+ {
2236
+ "type": "wall",
2237
+ "room": null,
2238
+ "color": null
2239
+ },
2240
+ {
2241
+ "type": "empty",
2242
+ "room": null,
2243
+ "color": null
2244
+ },
2245
+ {
2246
+ "type": "empty",
2247
+ "room": null,
2248
+ "color": "green"
2249
+ },
2250
+ {
2251
+ "type": "empty",
2252
+ "room": null,
2253
+ "color": "green"
2254
+ },
2255
+ {
2256
+ "type": "empty",
2257
+ "room": null,
2258
+ "color": "green"
2259
+ },
2260
+ {
2261
+ "type": "empty",
2262
+ "room": null,
2263
+ "color": null
2264
+ },
2265
+ {
2266
+ "type": "wall",
2267
+ "room": null,
2268
+ "color": null
2269
+ }
2270
+ ],
2271
+ [
2272
+ {
2273
+ "type": "wall",
2274
+ "room": null,
2275
+ "color": null
2276
+ },
2277
+ {
2278
+ "type": "empty",
2279
+ "room": null,
2280
+ "color": null
2281
+ },
2282
+ {
2283
+ "type": "empty",
2284
+ "room": null,
2285
+ "color": null
2286
+ },
2287
+ {
2288
+ "type": "empty",
2289
+ "room": null,
2290
+ "color": "yellow"
2291
+ },
2292
+ {
2293
+ "type": "empty",
2294
+ "room": null,
2295
+ "color": "yellow"
2296
+ },
2297
+ {
2298
+ "type": "empty",
2299
+ "room": null,
2300
+ "color": "yellow"
2301
+ },
2302
+ {
2303
+ "type": "empty",
2304
+ "room": null,
2305
+ "color": null
2306
+ },
2307
+ {
2308
+ "type": "empty",
2309
+ "room": null,
2310
+ "color": null
2311
+ },
2312
+ {
2313
+ "type": "empty",
2314
+ "room": null,
2315
+ "color": null
2316
+ },
2317
+ {
2318
+ "type": "wall",
2319
+ "room": null,
2320
+ "color": null
2321
+ },
2322
+ {
2323
+ "type": "empty",
2324
+ "room": null,
2325
+ "color": null
2326
+ },
2327
+ {
2328
+ "type": "empty",
2329
+ "room": null,
2330
+ "color": null
2331
+ },
2332
+ {
2333
+ "type": "empty",
2334
+ "room": null,
2335
+ "color": null
2336
+ },
2337
+ {
2338
+ "type": "empty",
2339
+ "room": null,
2340
+ "color": null
2341
+ },
2342
+ {
2343
+ "type": "empty",
2344
+ "room": null,
2345
+ "color": null
2346
+ },
2347
+ {
2348
+ "type": "empty",
2349
+ "room": null,
2350
+ "color": null
2351
+ },
2352
+ {
2353
+ "type": "empty",
2354
+ "room": null,
2355
+ "color": null
2356
+ },
2357
+ {
2358
+ "type": "empty",
2359
+ "room": null,
2360
+ "color": null
2361
+ },
2362
+ {
2363
+ "type": "wall",
2364
+ "room": null,
2365
+ "color": null
2366
+ },
2367
+ {
2368
+ "type": "empty",
2369
+ "room": null,
2370
+ "color": null
2371
+ },
2372
+ {
2373
+ "type": "empty",
2374
+ "room": null,
2375
+ "color": null
2376
+ },
2377
+ {
2378
+ "type": "empty",
2379
+ "room": null,
2380
+ "color": null
2381
+ },
2382
+ {
2383
+ "type": "empty",
2384
+ "room": null,
2385
+ "color": null
2386
+ },
2387
+ {
2388
+ "type": "empty",
2389
+ "room": null,
2390
+ "color": null
2391
+ },
2392
+ {
2393
+ "type": "empty",
2394
+ "room": null,
2395
+ "color": null
2396
+ },
2397
+ {
2398
+ "type": "door",
2399
+ "room": null,
2400
+ "color": null
2401
+ },
2402
+ {
2403
+ "type": "empty",
2404
+ "room": null,
2405
+ "color": null
2406
+ },
2407
+ {
2408
+ "type": "empty",
2409
+ "room": null,
2410
+ "color": null
2411
+ },
2412
+ {
2413
+ "type": "empty",
2414
+ "room": null,
2415
+ "color": null
2416
+ },
2417
+ {
2418
+ "type": "empty",
2419
+ "room": null,
2420
+ "color": null
2421
+ },
2422
+ {
2423
+ "type": "empty",
2424
+ "room": null,
2425
+ "color": null
2426
+ },
2427
+ {
2428
+ "type": "wall",
2429
+ "room": null,
2430
+ "color": null
2431
+ }
2432
+ ],
2433
+ [
2434
+ {
2435
+ "type": "wall",
2436
+ "room": null,
2437
+ "color": null
2438
+ },
2439
+ {
2440
+ "type": "empty",
2441
+ "room": null,
2442
+ "color": null
2443
+ },
2444
+ {
2445
+ "type": "empty",
2446
+ "room": null,
2447
+ "color": null
2448
+ },
2449
+ {
2450
+ "type": "empty",
2451
+ "room": null,
2452
+ "color": "yellow"
2453
+ },
2454
+ {
2455
+ "type": "empty",
2456
+ "room": null,
2457
+ "color": "yellow"
2458
+ },
2459
+ {
2460
+ "type": "empty",
2461
+ "room": null,
2462
+ "color": "yellow"
2463
+ },
2464
+ {
2465
+ "type": "empty",
2466
+ "room": null,
2467
+ "color": null
2468
+ },
2469
+ {
2470
+ "type": "empty",
2471
+ "room": null,
2472
+ "color": null
2473
+ },
2474
+ {
2475
+ "type": "empty",
2476
+ "room": null,
2477
+ "color": null
2478
+ },
2479
+ {
2480
+ "type": "door",
2481
+ "room": null,
2482
+ "color": null
2483
+ },
2484
+ {
2485
+ "type": "empty",
2486
+ "room": null,
2487
+ "color": null
2488
+ },
2489
+ {
2490
+ "type": "empty",
2491
+ "room": null,
2492
+ "color": null
2493
+ },
2494
+ {
2495
+ "type": "empty",
2496
+ "room": null,
2497
+ "color": null
2498
+ },
2499
+ {
2500
+ "type": "empty",
2501
+ "room": null,
2502
+ "color": null
2503
+ },
2504
+ {
2505
+ "type": "empty",
2506
+ "room": null,
2507
+ "color": null
2508
+ },
2509
+ {
2510
+ "type": "empty",
2511
+ "room": null,
2512
+ "color": null
2513
+ },
2514
+ {
2515
+ "type": "empty",
2516
+ "room": null,
2517
+ "color": null
2518
+ },
2519
+ {
2520
+ "type": "empty",
2521
+ "room": null,
2522
+ "color": null
2523
+ },
2524
+ {
2525
+ "type": "door",
2526
+ "room": null,
2527
+ "color": null
2528
+ },
2529
+ {
2530
+ "type": "empty",
2531
+ "room": null,
2532
+ "color": null
2533
+ },
2534
+ {
2535
+ "type": "empty",
2536
+ "room": null,
2537
+ "color": null
2538
+ },
2539
+ {
2540
+ "type": "empty",
2541
+ "room": null,
2542
+ "color": null
2543
+ },
2544
+ {
2545
+ "type": "empty",
2546
+ "room": null,
2547
+ "color": null
2548
+ },
2549
+ {
2550
+ "type": "empty",
2551
+ "room": null,
2552
+ "color": null
2553
+ },
2554
+ {
2555
+ "type": "empty",
2556
+ "room": null,
2557
+ "color": null
2558
+ },
2559
+ {
2560
+ "type": "wall",
2561
+ "room": null,
2562
+ "color": null
2563
+ },
2564
+ {
2565
+ "type": "empty",
2566
+ "room": null,
2567
+ "color": null
2568
+ },
2569
+ {
2570
+ "type": "empty",
2571
+ "room": null,
2572
+ "color": null
2573
+ },
2574
+ {
2575
+ "type": "empty",
2576
+ "room": null,
2577
+ "color": null
2578
+ },
2579
+ {
2580
+ "type": "empty",
2581
+ "room": null,
2582
+ "color": null
2583
+ },
2584
+ {
2585
+ "type": "empty",
2586
+ "room": null,
2587
+ "color": null
2588
+ },
2589
+ {
2590
+ "type": "wall",
2591
+ "room": null,
2592
+ "color": null
2593
+ }
2594
+ ],
2595
+ [
2596
+ {
2597
+ "type": "wall",
2598
+ "room": null,
2599
+ "color": null
2600
+ },
2601
+ {
2602
+ "type": "empty",
2603
+ "room": null,
2604
+ "color": null
2605
+ },
2606
+ {
2607
+ "type": "empty",
2608
+ "room": null,
2609
+ "color": null
2610
+ },
2611
+ {
2612
+ "type": "empty",
2613
+ "room": null,
2614
+ "color": null
2615
+ },
2616
+ {
2617
+ "type": "empty",
2618
+ "room": null,
2619
+ "color": null
2620
+ },
2621
+ {
2622
+ "type": "empty",
2623
+ "room": null,
2624
+ "color": null
2625
+ },
2626
+ {
2627
+ "type": "empty",
2628
+ "room": null,
2629
+ "color": null
2630
+ },
2631
+ {
2632
+ "type": "empty",
2633
+ "room": null,
2634
+ "color": null
2635
+ },
2636
+ {
2637
+ "type": "empty",
2638
+ "room": null,
2639
+ "color": null
2640
+ },
2641
+ {
2642
+ "type": "door",
2643
+ "room": null,
2644
+ "color": null
2645
+ },
2646
+ {
2647
+ "type": "empty",
2648
+ "room": null,
2649
+ "color": null
2650
+ },
2651
+ {
2652
+ "type": "empty",
2653
+ "room": null,
2654
+ "color": null
2655
+ },
2656
+ {
2657
+ "type": "empty",
2658
+ "room": null,
2659
+ "color": null
2660
+ },
2661
+ {
2662
+ "type": "empty",
2663
+ "room": null,
2664
+ "color": null
2665
+ },
2666
+ {
2667
+ "type": "empty",
2668
+ "room": null,
2669
+ "color": null
2670
+ },
2671
+ {
2672
+ "type": "empty",
2673
+ "room": null,
2674
+ "color": null
2675
+ },
2676
+ {
2677
+ "type": "empty",
2678
+ "room": null,
2679
+ "color": null
2680
+ },
2681
+ {
2682
+ "type": "empty",
2683
+ "room": null,
2684
+ "color": null
2685
+ },
2686
+ {
2687
+ "type": "door",
2688
+ "room": null,
2689
+ "color": null
2690
+ },
2691
+ {
2692
+ "type": "empty",
2693
+ "room": null,
2694
+ "color": null
2695
+ },
2696
+ {
2697
+ "type": "empty",
2698
+ "room": null,
2699
+ "color": null
2700
+ },
2701
+ {
2702
+ "type": "empty",
2703
+ "room": null,
2704
+ "color": "red"
2705
+ },
2706
+ {
2707
+ "type": "empty",
2708
+ "room": null,
2709
+ "color": "red"
2710
+ },
2711
+ {
2712
+ "type": "empty",
2713
+ "room": null,
2714
+ "color": null
2715
+ },
2716
+ {
2717
+ "type": "empty",
2718
+ "room": null,
2719
+ "color": null
2720
+ },
2721
+ {
2722
+ "type": "wall",
2723
+ "room": null,
2724
+ "color": null
2725
+ },
2726
+ {
2727
+ "type": "empty",
2728
+ "room": null,
2729
+ "color": null
2730
+ },
2731
+ {
2732
+ "type": "empty",
2733
+ "room": null,
2734
+ "color": null
2735
+ },
2736
+ {
2737
+ "type": "empty",
2738
+ "room": null,
2739
+ "color": null
2740
+ },
2741
+ {
2742
+ "type": "empty",
2743
+ "room": null,
2744
+ "color": null
2745
+ },
2746
+ {
2747
+ "type": "empty",
2748
+ "room": null,
2749
+ "color": null
2750
+ },
2751
+ {
2752
+ "type": "wall",
2753
+ "room": null,
2754
+ "color": null
2755
+ }
2756
+ ],
2757
+ [
2758
+ {
2759
+ "type": "wall",
2760
+ "room": null,
2761
+ "color": null
2762
+ },
2763
+ {
2764
+ "type": "empty",
2765
+ "room": null,
2766
+ "color": null
2767
+ },
2768
+ {
2769
+ "type": "empty",
2770
+ "room": null,
2771
+ "color": null
2772
+ },
2773
+ {
2774
+ "type": "empty",
2775
+ "room": null,
2776
+ "color": null
2777
+ },
2778
+ {
2779
+ "type": "empty",
2780
+ "room": null,
2781
+ "color": null
2782
+ },
2783
+ {
2784
+ "type": "empty",
2785
+ "room": null,
2786
+ "color": null
2787
+ },
2788
+ {
2789
+ "type": "empty",
2790
+ "room": null,
2791
+ "color": null
2792
+ },
2793
+ {
2794
+ "type": "empty",
2795
+ "room": null,
2796
+ "color": null
2797
+ },
2798
+ {
2799
+ "type": "empty",
2800
+ "room": null,
2801
+ "color": null
2802
+ },
2803
+ {
2804
+ "type": "wall",
2805
+ "room": null,
2806
+ "color": null
2807
+ },
2808
+ {
2809
+ "type": "empty",
2810
+ "room": null,
2811
+ "color": null
2812
+ },
2813
+ {
2814
+ "type": "empty",
2815
+ "room": null,
2816
+ "color": null
2817
+ },
2818
+ {
2819
+ "type": "empty",
2820
+ "room": null,
2821
+ "color": null
2822
+ },
2823
+ {
2824
+ "type": "empty",
2825
+ "room": null,
2826
+ "color": null
2827
+ },
2828
+ {
2829
+ "type": "empty",
2830
+ "room": null,
2831
+ "color": null
2832
+ },
2833
+ {
2834
+ "type": "empty",
2835
+ "room": null,
2836
+ "color": null
2837
+ },
2838
+ {
2839
+ "type": "empty",
2840
+ "room": null,
2841
+ "color": null
2842
+ },
2843
+ {
2844
+ "type": "empty",
2845
+ "room": null,
2846
+ "color": null
2847
+ },
2848
+ {
2849
+ "type": "wall",
2850
+ "room": null,
2851
+ "color": null
2852
+ },
2853
+ {
2854
+ "type": "empty",
2855
+ "room": null,
2856
+ "color": null
2857
+ },
2858
+ {
2859
+ "type": "empty",
2860
+ "room": null,
2861
+ "color": null
2862
+ },
2863
+ {
2864
+ "type": "empty",
2865
+ "room": null,
2866
+ "color": null
2867
+ },
2868
+ {
2869
+ "type": "empty",
2870
+ "room": null,
2871
+ "color": null
2872
+ },
2873
+ {
2874
+ "type": "empty",
2875
+ "room": null,
2876
+ "color": null
2877
+ },
2878
+ {
2879
+ "type": "empty",
2880
+ "room": null,
2881
+ "color": null
2882
+ },
2883
+ {
2884
+ "type": "wall",
2885
+ "room": null,
2886
+ "color": null
2887
+ },
2888
+ {
2889
+ "type": "empty",
2890
+ "room": null,
2891
+ "color": null
2892
+ },
2893
+ {
2894
+ "type": "empty",
2895
+ "room": null,
2896
+ "color": "yellow"
2897
+ },
2898
+ {
2899
+ "type": "empty",
2900
+ "room": null,
2901
+ "color": "yellow"
2902
+ },
2903
+ {
2904
+ "type": "empty",
2905
+ "room": null,
2906
+ "color": "yellow"
2907
+ },
2908
+ {
2909
+ "type": "empty",
2910
+ "room": null,
2911
+ "color": null
2912
+ },
2913
+ {
2914
+ "type": "wall",
2915
+ "room": null,
2916
+ "color": null
2917
+ }
2918
+ ],
2919
+ [
2920
+ {
2921
+ "type": "wall",
2922
+ "room": null,
2923
+ "color": null
2924
+ },
2925
+ {
2926
+ "type": "empty",
2927
+ "room": null,
2928
+ "color": null
2929
+ },
2930
+ {
2931
+ "type": "empty",
2932
+ "room": null,
2933
+ "color": null
2934
+ },
2935
+ {
2936
+ "type": "empty",
2937
+ "room": null,
2938
+ "color": "green"
2939
+ },
2940
+ {
2941
+ "type": "empty",
2942
+ "room": null,
2943
+ "color": "green"
2944
+ },
2945
+ {
2946
+ "type": "empty",
2947
+ "room": null,
2948
+ "color": "green"
2949
+ },
2950
+ {
2951
+ "type": "empty",
2952
+ "room": null,
2953
+ "color": null
2954
+ },
2955
+ {
2956
+ "type": "empty",
2957
+ "room": null,
2958
+ "color": null
2959
+ },
2960
+ {
2961
+ "type": "empty",
2962
+ "room": null,
2963
+ "color": null
2964
+ },
2965
+ {
2966
+ "type": "wall",
2967
+ "room": null,
2968
+ "color": null
2969
+ },
2970
+ {
2971
+ "type": "empty",
2972
+ "room": null,
2973
+ "color": null
2974
+ },
2975
+ {
2976
+ "type": "empty",
2977
+ "room": null,
2978
+ "color": null
2979
+ },
2980
+ {
2981
+ "type": "empty",
2982
+ "room": null,
2983
+ "color": null
2984
+ },
2985
+ {
2986
+ "type": "empty",
2987
+ "room": null,
2988
+ "color": "red"
2989
+ },
2990
+ {
2991
+ "type": "empty",
2992
+ "room": null,
2993
+ "color": "red"
2994
+ },
2995
+ {
2996
+ "type": "empty",
2997
+ "room": null,
2998
+ "color": "red"
2999
+ },
3000
+ {
3001
+ "type": "empty",
3002
+ "room": null,
3003
+ "color": null
3004
+ },
3005
+ {
3006
+ "type": "empty",
3007
+ "room": null,
3008
+ "color": null
3009
+ },
3010
+ {
3011
+ "type": "wall",
3012
+ "room": null,
3013
+ "color": null
3014
+ },
3015
+ {
3016
+ "type": "empty",
3017
+ "room": null,
3018
+ "color": null
3019
+ },
3020
+ {
3021
+ "type": "empty",
3022
+ "room": null,
3023
+ "color": null
3024
+ },
3025
+ {
3026
+ "type": "empty",
3027
+ "room": null,
3028
+ "color": "red"
3029
+ },
3030
+ {
3031
+ "type": "empty",
3032
+ "room": null,
3033
+ "color": "red"
3034
+ },
3035
+ {
3036
+ "type": "empty",
3037
+ "room": null,
3038
+ "color": null
3039
+ },
3040
+ {
3041
+ "type": "empty",
3042
+ "room": null,
3043
+ "color": null
3044
+ },
3045
+ {
3046
+ "type": "wall",
3047
+ "room": null,
3048
+ "color": null
3049
+ },
3050
+ {
3051
+ "type": "empty",
3052
+ "room": null,
3053
+ "color": null
3054
+ },
3055
+ {
3056
+ "type": "empty",
3057
+ "room": null,
3058
+ "color": "yellow"
3059
+ },
3060
+ {
3061
+ "type": "empty",
3062
+ "room": null,
3063
+ "color": "yellow"
3064
+ },
3065
+ {
3066
+ "type": "empty",
3067
+ "room": null,
3068
+ "color": "yellow"
3069
+ },
3070
+ {
3071
+ "type": "empty",
3072
+ "room": null,
3073
+ "color": null
3074
+ },
3075
+ {
3076
+ "type": "wall",
3077
+ "room": null,
3078
+ "color": null
3079
+ }
3080
+ ],
3081
+ [
3082
+ {
3083
+ "type": "wall",
3084
+ "room": null,
3085
+ "color": null
3086
+ },
3087
+ {
3088
+ "type": "wall",
3089
+ "room": null,
3090
+ "color": null
3091
+ },
3092
+ {
3093
+ "type": "wall",
3094
+ "room": null,
3095
+ "color": null
3096
+ },
3097
+ {
3098
+ "type": "wall",
3099
+ "room": null,
3100
+ "color": null
3101
+ },
3102
+ {
3103
+ "type": "wall",
3104
+ "room": null,
3105
+ "color": null
3106
+ },
3107
+ {
3108
+ "type": "wall",
3109
+ "room": null,
3110
+ "color": null
3111
+ },
3112
+ {
3113
+ "type": "wall",
3114
+ "room": null,
3115
+ "color": null
3116
+ },
3117
+ {
3118
+ "type": "wall",
3119
+ "room": null,
3120
+ "color": null
3121
+ },
3122
+ {
3123
+ "type": "wall",
3124
+ "room": null,
3125
+ "color": null
3126
+ },
3127
+ {
3128
+ "type": "wall",
3129
+ "room": null,
3130
+ "color": null
3131
+ },
3132
+ {
3133
+ "type": "wall",
3134
+ "room": null,
3135
+ "color": null
3136
+ },
3137
+ {
3138
+ "type": "wall",
3139
+ "room": null,
3140
+ "color": null
3141
+ },
3142
+ {
3143
+ "type": "wall",
3144
+ "room": null,
3145
+ "color": null
3146
+ },
3147
+ {
3148
+ "type": "wall",
3149
+ "room": null,
3150
+ "color": null
3151
+ },
3152
+ {
3153
+ "type": "wall",
3154
+ "room": null,
3155
+ "color": null
3156
+ },
3157
+ {
3158
+ "type": "wall",
3159
+ "room": null,
3160
+ "color": null
3161
+ },
3162
+ {
3163
+ "type": "wall",
3164
+ "room": null,
3165
+ "color": null
3166
+ },
3167
+ {
3168
+ "type": "wall",
3169
+ "room": null,
3170
+ "color": null
3171
+ },
3172
+ {
3173
+ "type": "wall",
3174
+ "room": null,
3175
+ "color": null
3176
+ },
3177
+ {
3178
+ "type": "wall",
3179
+ "room": null,
3180
+ "color": null
3181
+ },
3182
+ {
3183
+ "type": "wall",
3184
+ "room": null,
3185
+ "color": null
3186
+ },
3187
+ {
3188
+ "type": "wall",
3189
+ "room": null,
3190
+ "color": null
3191
+ },
3192
+ {
3193
+ "type": "wall",
3194
+ "room": null,
3195
+ "color": null
3196
+ },
3197
+ {
3198
+ "type": "wall",
3199
+ "room": null,
3200
+ "color": null
3201
+ },
3202
+ {
3203
+ "type": "wall",
3204
+ "room": null,
3205
+ "color": null
3206
+ },
3207
+ {
3208
+ "type": "wall",
3209
+ "room": null,
3210
+ "color": null
3211
+ },
3212
+ {
3213
+ "type": "wall",
3214
+ "room": null,
3215
+ "color": null
3216
+ },
3217
+ {
3218
+ "type": "wall",
3219
+ "room": null,
3220
+ "color": null
3221
+ },
3222
+ {
3223
+ "type": "wall",
3224
+ "room": null,
3225
+ "color": null
3226
+ },
3227
+ {
3228
+ "type": "wall",
3229
+ "room": null,
3230
+ "color": null
3231
+ },
3232
+ {
3233
+ "type": "wall",
3234
+ "room": null,
3235
+ "color": null
3236
+ },
3237
+ {
3238
+ "type": "wall",
3239
+ "room": null,
3240
+ "color": null
3241
+ }
3242
+ ]
3243
+ ],
3244
+ "rooms": [
3245
+ [
3246
+ "Kichen",
3247
+ [
3248
+ {
3249
+ "x": 28,
3250
+ "y": 3
3251
+ },
3252
+ {
3253
+ "x": 28,
3254
+ "y": 3
3255
+ }
3256
+ ]
3257
+ ],
3258
+ [
3259
+ "Storage",
3260
+ [
3261
+ {
3262
+ "x": 3,
3263
+ "y": 3
3264
+ }
3265
+ ]
3266
+ ],
3267
+ [
3268
+ "My Bedroom",
3269
+ [
3270
+ {
3271
+ "x": 4,
3272
+ "y": 16
3273
+ },
3274
+ {
3275
+ "x": 4,
3276
+ "y": 16
3277
+ }
3278
+ ]
3279
+ ],
3280
+ [
3281
+ "Bathroom",
3282
+ [
3283
+ {
3284
+ "x": 16,
3285
+ "y": 10
3286
+ }
3287
+ ]
3288
+ ],
3289
+ [
3290
+ "Main Hallway",
3291
+ [
3292
+ {
3293
+ "x": 14,
3294
+ "y": 15
3295
+ }
3296
+ ]
3297
+ ],
3298
+ [
3299
+ "Living Room",
3300
+ [
3301
+ {
3302
+ "x": 21,
3303
+ "y": 15
3304
+ },
3305
+ {
3306
+ "x": 21,
3307
+ "y": 15
3308
+ },
3309
+ {
3310
+ "x": 21,
3311
+ "y": 15
3312
+ },
3313
+ {
3314
+ "x": 21,
3315
+ "y": 15
3316
+ }
3317
+ ]
3318
+ ],
3319
+ [
3320
+ "Guest Bedroom",
3321
+ [
3322
+ {
3323
+ "x": 28,
3324
+ "y": 15
3325
+ }
3326
+ ]
3327
+ ],
3328
+ [
3329
+ "Dining Room",
3330
+ [
3331
+ {
3332
+ "x": 16,
3333
+ "y": 3
3334
+ }
3335
+ ]
3336
+ ],
3337
+ [
3338
+ "Office",
3339
+ [
3340
+ {
3341
+ "x": 21,
3342
+ "y": 9
3343
+ },
3344
+ {
3345
+ "x": 21,
3346
+ "y": 9
3347
+ }
3348
+ ]
3349
+ ],
3350
+ [
3351
+ "North Hallway",
3352
+ [
3353
+ {
3354
+ "x": 9,
3355
+ "y": 3
3356
+ },
3357
+ {
3358
+ "x": 9,
3359
+ "y": 3
3360
+ }
3361
+ ]
3362
+ ]
3363
+ ],
3364
+ "characterPos": {
3365
+ "x": 28,
3366
+ "y": 15
3367
+ },
3368
+ "gridCols": 32,
3369
+ "gridRows": 20
3370
+ }
static/game/game-with-chat.html ADDED
@@ -0,0 +1,537 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Get Me Out! - Apartment Escape Game with Chat</title>
5
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.7.0/p5.min.js"></script>
6
+ <style>
7
+ /* Layout */
8
+ body {
9
+ margin: 0;
10
+ font-family: Arial, sans-serif;
11
+ display: flex;
12
+ height: 100vh;
13
+ }
14
+ #gameContainer {
15
+ display: flex;
16
+ width: 100%;
17
+ height: 100%;
18
+ }
19
+ #mapSection {
20
+ flex: 1;
21
+ position: relative;
22
+ background: #f5f5f5;
23
+ display: flex;
24
+ flex-direction: column;
25
+ align-items: center;
26
+ }
27
+ /* We'll place the P5 canvas in here */
28
+ .map-wrapper {
29
+ margin: 20px;
30
+ transform-origin: top left;
31
+ }
32
+
33
+ #chatSection {
34
+ width: 400px;
35
+ border-left: 1px solid #ddd;
36
+ display: flex;
37
+ flex-direction: column;
38
+ background: white;
39
+ }
40
+ #chatHistory {
41
+ flex: 1;
42
+ overflow-y: auto;
43
+ padding: 20px;
44
+ background: #f8f9fa;
45
+ }
46
+ #chatControls {
47
+ padding: 20px;
48
+ border-top: 1px solid #ddd;
49
+ background: white;
50
+ }
51
+ .chat-message {
52
+ padding: 10px;
53
+ margin: 5px 0;
54
+ border-radius: 16px;
55
+ max-width: 80%;
56
+ word-wrap: break-word;
57
+ }
58
+ .user-message {
59
+ background: #007AFF;
60
+ color: white;
61
+ margin-left: auto;
62
+ border-radius: 16px 16px 4px 16px;
63
+ }
64
+ .assistant-message {
65
+ background: #E9E9EB;
66
+ color: black;
67
+ margin-right: auto;
68
+ border-radius: 16px 16px 16px 4px;
69
+ }
70
+ textarea {
71
+ width: 100%;
72
+ padding: 10px;
73
+ border: 1px solid #ddd;
74
+ border-radius: 4px;
75
+ margin-bottom: 10px;
76
+ resize: none;
77
+ font-family: inherit;
78
+ }
79
+ button {
80
+ padding: 8px 16px;
81
+ background: #007AFF;
82
+ color: white;
83
+ border: none;
84
+ border-radius: 4px;
85
+ cursor: pointer;
86
+ }
87
+ button:hover {
88
+ background: #0056b3;
89
+ }
90
+ .loading-dots {
91
+ display: inline-flex;
92
+ gap: 4px;
93
+ padding: 5px;
94
+ margin: 5px 0;
95
+ }
96
+ .dot {
97
+ width: 8px;
98
+ height: 8px;
99
+ background: #6c757d;
100
+ border-radius: 50%;
101
+ animation: wave 1.3s linear infinite;
102
+ }
103
+ .dot:nth-child(2) { animation-delay: -1.1s; }
104
+ .dot:nth-child(3) { animation-delay: -0.9s; }
105
+ @keyframes wave {
106
+ 0%, 60%, 100% { transform: translateY(0); }
107
+ 30% { transform: translateY(-4px); }
108
+ }
109
+
110
+ /* Modal for API key (if needed) */
111
+ #apiKeyModal {
112
+ display: none;
113
+ position: fixed;
114
+ top: 0; left: 0;
115
+ width: 100%; height: 100%;
116
+ background: rgba(0,0,0,0.5);
117
+ justify-content: center;
118
+ align-items: center;
119
+ }
120
+ .modal-content {
121
+ background: white;
122
+ padding: 20px;
123
+ border-radius: 8px;
124
+ width: 300px;
125
+ }
126
+ #apiKey {
127
+ width: 100%;
128
+ margin: 10px 0;
129
+ padding: 8px;
130
+ }
131
+ </style>
132
+ </head>
133
+ <body>
134
+ <div id="gameContainer">
135
+ <div id="mapSection">
136
+ <div id="mapWrapper" class="map-wrapper">
137
+ <!-- P5.js canvas goes here -->
138
+ </div>
139
+ </div>
140
+ <div id="chatSection">
141
+ <div id="chatHistory"></div>
142
+ <div id="chatControls">
143
+ <textarea id="prompt" placeholder="Type your message..." rows="3"></textarea>
144
+ <button onclick="sendMessage()">Send</button>
145
+ </div>
146
+ </div>
147
+ </div>
148
+ <div id="apiKeyModal">
149
+ <div class="modal-content">
150
+ <h3>Enter Mistral API Key</h3>
151
+ <input type="password" id="apiKey" placeholder="Enter your API key">
152
+ <button onclick="saveApiKey()">Save</button>
153
+ </div>
154
+ </div>
155
+
156
+ <script>
157
+ /*
158
+ * This script loads ./apt.json to set up the map,
159
+ * draws it in p5.js, and provides a chat interface on the right.
160
+ */
161
+
162
+ // Constants and variables for the map
163
+ const CELL_SIZE = 30;
164
+ let GRID_COLS = 0;
165
+ let GRID_ROWS = 0;
166
+ let grid = [];
167
+ let rooms = new Map();
168
+ let characterPos = null;
169
+ let path = [];
170
+ let isMoving = false;
171
+ let moveInterval = null;
172
+
173
+ // Chat variables
174
+ let apiKey = localStorage.getItem('mistralApiKey');
175
+ const systemPrompt = `You are the game master of "Get Me Out!", a single-player text-based survival game. The scenario: a player must guide their girlfriend to safety via text messages while she's being hunted by a murderous clown in their apartment. The player has access to security cameras and can send instructions through text.
176
+
177
+ RESPONSE FORMAT:
178
+ You must ALWAYS respond with a JSON object. The response should reflect the girlfriend's reaction to the player's message.
179
+
180
+ 1. For movement instructions ("go" action):
181
+ {
182
+ "action": "go",
183
+ "to": "[room name]",
184
+ "textMessage": "[girlfriend's response]"
185
+ }
186
+
187
+ 2. For any other input or unclear instructions:
188
+ {
189
+ "textMessage": "[girlfriend's response]"
190
+ }
191
+
192
+ VALID ROOMS:
193
+ Only these rooms are recognized for movement:
194
+ - Main Bathroom
195
+ - Guest Toilet
196
+ - Dining Room
197
+ - Kitchen
198
+ - TV Room
199
+ - Living Room
200
+ - Hallway
201
+ - Office
202
+ - Bedroom
203
+
204
+ CHARACTER BEHAVIOR:
205
+ The girlfriend is aware of the danger and extremely distressed. Her text responses should be:
206
+ - Brief and urgent
207
+ - Reflect genuine fear and panic
208
+ - Written like real text messages (short, quick responses)
209
+ - No time for pleasantries or long explanations
210
+ - May include typos or rushed writing due to stress
211
+ `;
212
+
213
+ // Load apt.json upon page start
214
+ async function loadAptJson() {
215
+ try {
216
+ const response = await fetch('./apt.json');
217
+ if (!response.ok) {
218
+ alert("Failed to load apt.json!");
219
+ return;
220
+ }
221
+ const data = await response.json();
222
+ // Update local variables from apt.json
223
+ GRID_COLS = data.gridCols || 40;
224
+ GRID_ROWS = data.gridRows || 20;
225
+ grid = data.grid || [];
226
+ rooms = new Map(data.rooms);
227
+ characterPos = data.characterPos || { x: 0, y: 0 };
228
+
229
+ // Once loaded, initialize the P5 canvas with correct dims
230
+ let canvas = createCanvas(GRID_COLS * CELL_SIZE, GRID_ROWS * CELL_SIZE);
231
+ canvas.parent('mapWrapper');
232
+ adjustScale();
233
+
234
+ } catch (e) {
235
+ console.error("Error loading apt.json:", e);
236
+ }
237
+ }
238
+
239
+ function adjustScale() {
240
+ const availableWidth = window.innerWidth - 400 - 40; // space for chat + margins
241
+ const actualCanvasWidth = GRID_COLS * CELL_SIZE;
242
+ const scale = availableWidth / actualCanvasWidth;
243
+ const mapWrapper = document.querySelector('#mapSection .map-wrapper');
244
+ if (mapWrapper) {
245
+ // use CSS zoom or transform
246
+ mapWrapper.style.zoom = scale;
247
+ }
248
+ }
249
+
250
+ window.addEventListener('resize', adjustScale);
251
+
252
+ // p5.js setup
253
+ function setup() {
254
+ // We'll wait to createCanvas until apt.json is loaded
255
+ loadAptJson();
256
+ }
257
+
258
+ // p5.js draw loop
259
+ function draw() {
260
+ if (!grid || grid.length === 0) {
261
+ // No grid loaded yet or apt.json not ready
262
+ return;
263
+ }
264
+ background(255);
265
+ drawGrid();
266
+ drawRooms();
267
+ drawWallsAndDoors();
268
+ drawPath();
269
+ drawCharacter();
270
+ }
271
+
272
+ function drawGrid() {
273
+ stroke(200);
274
+ for (let x = 0; x <= GRID_COLS; x++) {
275
+ line(x * CELL_SIZE, 0, x * CELL_SIZE, GRID_ROWS*CELL_SIZE);
276
+ }
277
+ for (let y = 0; y <= GRID_ROWS; y++) {
278
+ line(0, y * CELL_SIZE, GRID_COLS*CELL_SIZE, y * CELL_SIZE);
279
+ }
280
+ }
281
+
282
+ function drawRooms() {
283
+ for (let [roomName, cells] of rooms) {
284
+ const hue = stringToHue(roomName);
285
+ fill(hue, 30, 95, 0.3);
286
+ noStroke();
287
+ for (let cell of cells) {
288
+ rect(cell.x * CELL_SIZE, cell.y * CELL_SIZE, CELL_SIZE, CELL_SIZE);
289
+ }
290
+ if (cells.length > 0) {
291
+ fill(0);
292
+ textAlign(CENTER, CENTER);
293
+ textSize(10);
294
+ text(roomName,
295
+ cells[0].x * CELL_SIZE + CELL_SIZE/2,
296
+ cells[0].y * CELL_SIZE + CELL_SIZE/2
297
+ );
298
+ }
299
+ }
300
+ }
301
+
302
+ function drawWallsAndDoors() {
303
+ for (let y = 0; y < GRID_ROWS; y++) {
304
+ for (let x = 0; x < GRID_COLS; x++) {
305
+ const cell = grid[y][x];
306
+ if (cell.type === 'wall') {
307
+ fill(0);
308
+ noStroke();
309
+ rect(x * CELL_SIZE, y * CELL_SIZE, CELL_SIZE, CELL_SIZE);
310
+ } else if (cell.type === 'door') {
311
+ fill(255, 0, 0);
312
+ noStroke();
313
+ rect(x * CELL_SIZE, y * CELL_SIZE, CELL_SIZE, CELL_SIZE);
314
+ }
315
+ }
316
+ }
317
+ }
318
+
319
+ function drawPath() {
320
+ if (path.length > 0 && isMoving) {
321
+ noFill();
322
+ stroke(0, 255, 0);
323
+ strokeWeight(2);
324
+ line(
325
+ characterPos.x * CELL_SIZE + CELL_SIZE/2,
326
+ characterPos.y * CELL_SIZE + CELL_SIZE/2,
327
+ path[0].x * CELL_SIZE + CELL_SIZE/2,
328
+ path[0].y * CELL_SIZE + CELL_SIZE/2
329
+ );
330
+ for (let i = 0; i < path.length - 1; i++) {
331
+ line(
332
+ path[i].x * CELL_SIZE + CELL_SIZE/2,
333
+ path[i].y * CELL_SIZE + CELL_SIZE/2,
334
+ path[i + 1].x * CELL_SIZE + CELL_SIZE/2,
335
+ path[i + 1].y * CELL_SIZE + CELL_SIZE/2
336
+ );
337
+ }
338
+ strokeWeight(1);
339
+ }
340
+ }
341
+
342
+ function drawCharacter() {
343
+ if (characterPos) {
344
+ textSize(CELL_SIZE * 0.8);
345
+ textAlign(CENTER, CENTER);
346
+ text('👧',
347
+ characterPos.x * CELL_SIZE + CELL_SIZE/2,
348
+ characterPos.y * CELL_SIZE + CELL_SIZE/2
349
+ );
350
+ }
351
+ }
352
+
353
+ function stringToHue(str) {
354
+ let hash = 0;
355
+ for (let i = 0; i < str.length; i++) {
356
+ hash = str.charCodeAt(i) + ((hash << 5) - hash);
357
+ }
358
+ return hash % 360;
359
+ }
360
+
361
+ // Simple BFS for pathfinding
362
+ function findPath(start, end) {
363
+ const queue = [[start]];
364
+ const visited = new Set();
365
+ const key = pos => `${pos.x},${pos.y}`;
366
+ visited.add(key(start));
367
+
368
+ while (queue.length > 0) {
369
+ const currentPath = queue.shift();
370
+ const current = currentPath[currentPath.length - 1];
371
+
372
+ if (current.x === end.x && current.y === end.y) {
373
+ return currentPath;
374
+ }
375
+ const neighbors = [
376
+ { x: current.x, y: current.y - 1 },
377
+ { x: current.x+1, y: current.y },
378
+ { x: current.x, y: current.y+1 },
379
+ { x: current.x-1, y: current.y }
380
+ ];
381
+ for (const next of neighbors) {
382
+ if (next.x < 0 || next.x >= GRID_COLS || next.y < 0 || next.y >= GRID_ROWS) continue;
383
+ if (visited.has(key(next))) continue;
384
+
385
+ const cell = grid[next.y][next.x];
386
+ if (cell.type === 'wall') continue;
387
+
388
+ visited.add(key(next));
389
+ queue.push([...currentPath, next]);
390
+ }
391
+ }
392
+ return [];
393
+ }
394
+
395
+ function moveToRoom(roomName) {
396
+ const targetRoom = Array.from(rooms.entries())
397
+ .find(([name]) => name.toLowerCase() === roomName.toLowerCase());
398
+ if (!targetRoom || !characterPos) return false;
399
+
400
+ const [_, cells] = targetRoom;
401
+ if (cells.length === 0) return false;
402
+ path = findPath(characterPos, cells[0]);
403
+ if (path.length > 0) {
404
+ isMoving = true;
405
+ moveCharacterAlongPath();
406
+ return true;
407
+ }
408
+ return false;
409
+ }
410
+
411
+ function moveCharacterAlongPath() {
412
+ if (moveInterval) clearInterval(moveInterval);
413
+ moveInterval = setInterval(() => {
414
+ if (path.length === 0) {
415
+ isMoving = false;
416
+ clearInterval(moveInterval);
417
+ return;
418
+ }
419
+ const nextPos = path.shift();
420
+ characterPos = nextPos;
421
+ }, 200);
422
+ }
423
+
424
+ /* Chat / Mistral-related code */
425
+ function createLoadingIndicator() {
426
+ const loadingDiv = document.createElement('div');
427
+ loadingDiv.className = 'chat-message assistant-message';
428
+ loadingDiv.innerHTML = `
429
+ <div class="loading-dots">
430
+ <div class="dot"></div>
431
+ <div class="dot"></div>
432
+ <div class="dot"></div>
433
+ </div>
434
+ `;
435
+ return loadingDiv;
436
+ }
437
+
438
+ function addMessageToChat(role, content) {
439
+ const chatHistory = document.getElementById('chatHistory');
440
+ const messageDiv = document.createElement('div');
441
+ messageDiv.className = `chat-message ${role}-message`;
442
+ messageDiv.textContent = content;
443
+ chatHistory.appendChild(messageDiv);
444
+ chatHistory.scrollTop = chatHistory.scrollHeight;
445
+ }
446
+
447
+ async function sendMessage() {
448
+ const prompt = document.getElementById('prompt').value.trim();
449
+ if (!prompt) return;
450
+
451
+ if (!apiKey) {
452
+ alert('Please enter your Mistral API key first');
453
+ document.getElementById('apiKeyModal').style.display = 'flex';
454
+ return;
455
+ }
456
+
457
+ // Add user message to the chat
458
+ addMessageToChat('user', prompt);
459
+ document.getElementById('prompt').value = '';
460
+
461
+ // Add loading indicator
462
+ const chatHistory = document.getElementById('chatHistory');
463
+ const loadingIndicator = createLoadingIndicator();
464
+ chatHistory.appendChild(loadingIndicator);
465
+
466
+ try {
467
+ // Make call to Mistral or any AI endpoint
468
+ const response = await fetch('https://api.mistral.ai/v1/chat/completions', {
469
+ method: 'POST',
470
+ headers: {
471
+ 'Content-Type': 'application/json',
472
+ 'Authorization': `Bearer ${apiKey}`
473
+ },
474
+ body: JSON.stringify({
475
+ model: 'mistral-large-latest',
476
+ messages: [
477
+ { role: 'system', content: systemPrompt },
478
+ { role: 'user', content: prompt }
479
+ ]
480
+ })
481
+ });
482
+
483
+ if (!response.ok) {
484
+ throw new Error(`HTTP error! status: ${response.status}`);
485
+ }
486
+
487
+ const data = await response.json();
488
+ const assistantResponse = data.choices[0].message.content || "";
489
+
490
+ try {
491
+ const jsonStart = assistantResponse.indexOf('{');
492
+ const jsonEnd = assistantResponse.lastIndexOf('}') + 1;
493
+ const jsonContent = assistantResponse.substring(jsonStart, jsonEnd);
494
+ const jsonResponse = JSON.parse(jsonContent);
495
+
496
+ if (jsonResponse.textMessage) {
497
+ addMessageToChat('assistant', jsonResponse.textMessage);
498
+ }
499
+ if (jsonResponse.action === 'go' && jsonResponse.to) {
500
+ moveToRoom(jsonResponse.to);
501
+ }
502
+ } catch (e) {
503
+ console.error('Error parsing JSON from response:', e);
504
+ addMessageToChat('assistant', 'Sorry, I had trouble understanding that response.');
505
+ }
506
+ } catch (error) {
507
+ addMessageToChat('assistant', `Error: ${error.message}`);
508
+ } finally {
509
+ loadingIndicator.remove();
510
+ }
511
+ }
512
+
513
+ function saveApiKey() {
514
+ const key = document.getElementById('apiKey').value.trim();
515
+ if (key) {
516
+ apiKey = key;
517
+ localStorage.setItem('mistralApiKey', key);
518
+ document.getElementById('apiKeyModal').style.display = 'none';
519
+ }
520
+ }
521
+
522
+ // Allow sending message with Enter
523
+ document.addEventListener('DOMContentLoaded', () => {
524
+ document.getElementById('prompt').addEventListener('keypress', function(e) {
525
+ if (e.key === 'Enter' && !e.shiftKey) {
526
+ e.preventDefault();
527
+ sendMessage();
528
+ }
529
+ });
530
+
531
+ if (!apiKey) {
532
+ document.getElementById('apiKeyModal').style.display = 'flex';
533
+ }
534
+ });
535
+ </script>
536
+ </body>
537
+ </html>
static/game/index.html ADDED
@@ -0,0 +1,568 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Get Me Out! - Apartment Escape Game with Chat</title>
5
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.7.0/p5.min.js"></script>
6
+ <style>
7
+ /* Layout */
8
+ body {
9
+ margin: 0;
10
+ font-family: Arial, sans-serif;
11
+ display: flex;
12
+ height: 100vh;
13
+ }
14
+ #gameContainer {
15
+ display: flex;
16
+ width: 100%;
17
+ height: 100%;
18
+ }
19
+ #mapSection {
20
+ flex: 1;
21
+ position: relative;
22
+ background: #f5f5f5;
23
+ display: flex;
24
+ flex-direction: column;
25
+ align-items: center;
26
+ }
27
+ /* We'll place the P5 canvas in here */
28
+ .map-wrapper {
29
+ margin: 20px;
30
+ transform-origin: top left;
31
+ }
32
+
33
+ #chatSection {
34
+ width: 400px;
35
+ border-left: 1px solid #ddd;
36
+ display: flex;
37
+ flex-direction: column;
38
+ background: white;
39
+ }
40
+ #chatHistory {
41
+ flex: 1;
42
+ overflow-y: auto;
43
+ padding: 20px;
44
+ background: #f8f9fa;
45
+ }
46
+ #chatControls {
47
+ padding: 20px;
48
+ border-top: 1px solid #ddd;
49
+ background: white;
50
+ }
51
+ .chat-message {
52
+ padding: 10px;
53
+ margin: 5px 0;
54
+ border-radius: 16px;
55
+ max-width: 80%;
56
+ word-wrap: break-word;
57
+ }
58
+ .user-message {
59
+ background: #007AFF;
60
+ color: white;
61
+ margin-left: auto;
62
+ border-radius: 16px 16px 4px 16px;
63
+ }
64
+ .assistant-message {
65
+ background: #E9E9EB;
66
+ color: black;
67
+ margin-right: auto;
68
+ border-radius: 16px 16px 16px 4px;
69
+ }
70
+ textarea {
71
+ width: 100%;
72
+ padding: 10px;
73
+ border: 1px solid #ddd;
74
+ border-radius: 4px;
75
+ margin-bottom: 10px;
76
+ resize: none;
77
+ font-family: inherit;
78
+ }
79
+ button {
80
+ padding: 8px 16px;
81
+ background: #007AFF;
82
+ color: white;
83
+ border: none;
84
+ border-radius: 4px;
85
+ cursor: pointer;
86
+ }
87
+ button:hover {
88
+ background: #0056b3;
89
+ }
90
+ .loading-dots {
91
+ display: inline-flex;
92
+ gap: 4px;
93
+ padding: 5px;
94
+ margin: 5px 0;
95
+ }
96
+ .dot {
97
+ width: 8px;
98
+ height: 8px;
99
+ background: #6c757d;
100
+ border-radius: 50%;
101
+ animation: wave 1.3s linear infinite;
102
+ }
103
+ .dot:nth-child(2) { animation-delay: -1.1s; }
104
+ .dot:nth-child(3) { animation-delay: -0.9s; }
105
+ @keyframes wave {
106
+ 0%, 60%, 100% { transform: translateY(0); }
107
+ 30% { transform: translateY(-4px); }
108
+ }
109
+
110
+ /* Modal for API key (if needed) */
111
+ #apiKeyModal {
112
+ display: none;
113
+ position: fixed;
114
+ top: 0; left: 0;
115
+ width: 100%; height: 100%;
116
+ background: rgba(0,0,0,0.5);
117
+ justify-content: center;
118
+ align-items: center;
119
+ }
120
+ .modal-content {
121
+ background: white;
122
+ padding: 20px;
123
+ border-radius: 8px;
124
+ width: 300px;
125
+ }
126
+ #apiKey {
127
+ width: 100%;
128
+ margin: 10px 0;
129
+ padding: 8px;
130
+ }
131
+ </style>
132
+ </head>
133
+ <body>
134
+ <div id="gameContainer">
135
+ <div id="mapSection">
136
+ <div id="mapWrapper" class="map-wrapper">
137
+ <!-- P5.js canvas goes here -->
138
+ </div>
139
+ </div>
140
+ <div id="chatSection">
141
+ <div id="chatHistory"></div>
142
+ <div id="chatControls">
143
+ <textarea id="prompt" placeholder="Type your message..." rows="3"></textarea>
144
+ <button onclick="sendMessage()">Send</button>
145
+ </div>
146
+ </div>
147
+ </div>
148
+ <div id="apiKeyModal">
149
+ <div class="modal-content">
150
+ <h3>Enter Mistral API Key</h3>
151
+ <input type="password" id="apiKey" placeholder="Enter your API key">
152
+ <button onclick="saveApiKey()">Save</button>
153
+ </div>
154
+ </div>
155
+
156
+ <script>
157
+ /*
158
+ * This script loads ./apt.json to set up the map,
159
+ * draws it in p5.js, and provides a chat interface on the right.
160
+ */
161
+
162
+ // Constants and variables for the map
163
+ const CELL_SIZE = 30;
164
+ let GRID_COLS = 0;
165
+ let GRID_ROWS = 0;
166
+ let grid = [];
167
+ let rooms = new Map();
168
+ let characterPos = null;
169
+ let path = [];
170
+ let isMoving = false;
171
+ let moveInterval = null;
172
+
173
+ // Chat variables
174
+ let apiKey = localStorage.getItem('mistralApiKey');
175
+ const systemPrompt = `You are the game master of "Get Me Out!", a single-player text-based survival game. The scenario: a player must guide their girlfriend to safety via text messages while she's being hunted by a murderous clown in their apartment. The player has access to security cameras and can send instructions through text.
176
+
177
+ RESPONSE FORMAT:
178
+ You must ALWAYS respond with a JSON object. The response should reflect the girlfriend's reaction to the player's message.
179
+
180
+ 1. For movement instructions ("go" action):
181
+ {
182
+ "action": "go",
183
+ "to": "[room name]",
184
+ "textMessage": "[girlfriend's response]"
185
+ }
186
+
187
+ 2. For any other input or unclear instructions:
188
+ {
189
+ "textMessage": "[girlfriend's response]"
190
+ }
191
+
192
+ VALID ROOMS:
193
+ Only these rooms are recognized for movement:
194
+ - Main Bathroom
195
+ - Guest Toilet
196
+ - Dining Room
197
+ - Kitchen
198
+ - TV Room
199
+ - Living Room
200
+ - Hallway
201
+ - Office
202
+ - Bedroom
203
+
204
+ CHARACTER BEHAVIOR:
205
+ The girlfriend is aware of the danger and extremely distressed. Her text responses should be:
206
+ - Brief and urgent
207
+ - Reflect genuine fear and panic
208
+ - Written like real text messages (short, quick responses)
209
+ - No time for pleasantries or long explanations
210
+ - May include typos or rushed writing due to stress
211
+ `;
212
+
213
+ // Load apt.json upon page start
214
+ async function loadAptJson() {
215
+ try {
216
+ const response = await fetch('/static/game/apt.json');
217
+ if (!response.ok) {
218
+ alert("Failed to load apt.json!");
219
+ return;
220
+ }
221
+ const data = await response.json();
222
+ // Update local variables from apt.json
223
+ GRID_COLS = data.gridCols || 40;
224
+ GRID_ROWS = data.gridRows || 20;
225
+ grid = data.grid || [];
226
+
227
+ // Ensure each cell has the color property if it exists in the data
228
+ for (let y = 0; y < GRID_ROWS; y++) {
229
+ for (let x = 0; x < GRID_COLS; x++) {
230
+ if (!grid[y]) grid[y] = [];
231
+ if (!grid[y][x]) {
232
+ grid[y][x] = { type: 'empty', color: null };
233
+ } else if (typeof grid[y][x] === 'string') {
234
+ // Handle old format where grid cells were just strings
235
+ grid[y][x] = { type: grid[y][x], color: null };
236
+ }
237
+ }
238
+ }
239
+
240
+ rooms = new Map(data.rooms);
241
+ characterPos = data.characterPos || { x: 0, y: 0 };
242
+
243
+ // Once loaded, initialize the P5 canvas with correct dims
244
+ let canvas = createCanvas(GRID_COLS * CELL_SIZE, GRID_ROWS * CELL_SIZE);
245
+ canvas.parent('mapWrapper');
246
+ adjustScale();
247
+
248
+ } catch (e) {
249
+ console.error("Error loading apt.json:", e);
250
+ }
251
+ }
252
+
253
+ function adjustScale() {
254
+ const availableWidth = window.innerWidth - 400 - 40; // space for chat + margins
255
+ const actualCanvasWidth = GRID_COLS * CELL_SIZE;
256
+ const scale = availableWidth / actualCanvasWidth;
257
+ const mapWrapper = document.querySelector('#mapSection .map-wrapper');
258
+ if (mapWrapper) {
259
+ // use CSS zoom or transform
260
+ mapWrapper.style.zoom = scale;
261
+ }
262
+ }
263
+
264
+ window.addEventListener('resize', adjustScale);
265
+
266
+ // p5.js setup
267
+ function setup() {
268
+ // We'll wait to createCanvas until apt.json is loaded
269
+ loadAptJson();
270
+ }
271
+
272
+ // p5.js draw loop
273
+ function draw() {
274
+ if (!grid || grid.length === 0) {
275
+ // No grid loaded yet or apt.json not ready
276
+ return;
277
+ }
278
+ background(255);
279
+ drawGrid();
280
+ drawRooms();
281
+ drawWallsAndDoors();
282
+ drawPath();
283
+ drawCharacter();
284
+ }
285
+
286
+ function drawGrid() {
287
+ stroke(200);
288
+ for (let x = 0; x <= GRID_COLS; x++) {
289
+ line(x * CELL_SIZE, 0, x * CELL_SIZE, GRID_ROWS*CELL_SIZE);
290
+ }
291
+ for (let y = 0; y <= GRID_ROWS; y++) {
292
+ line(0, y * CELL_SIZE, GRID_COLS*CELL_SIZE, y * CELL_SIZE);
293
+ }
294
+ }
295
+
296
+ function drawRooms() {
297
+ for (let [roomName, cells] of rooms) {
298
+ const hue = stringToHue(roomName);
299
+ fill(hue, 30, 95, 0.3);
300
+ noStroke();
301
+ for (let cell of cells) {
302
+ rect(cell.x * CELL_SIZE, cell.y * CELL_SIZE, CELL_SIZE, CELL_SIZE);
303
+ }
304
+ if (cells.length > 0) {
305
+ fill(0);
306
+ textAlign(CENTER, CENTER);
307
+ textSize(10);
308
+ text(roomName,
309
+ cells[0].x * CELL_SIZE + CELL_SIZE/2,
310
+ cells[0].y * CELL_SIZE + CELL_SIZE/2
311
+ );
312
+ }
313
+ }
314
+ }
315
+
316
+ function drawWallsAndDoors() {
317
+ for (let y = 0; y < GRID_ROWS; y++) {
318
+ for (let x = 0; x < GRID_COLS; x++) {
319
+ const cell = grid[y][x];
320
+ if (cell.type === 'wall') {
321
+ fill(0);
322
+ noStroke();
323
+ rect(x * CELL_SIZE, y * CELL_SIZE, CELL_SIZE, CELL_SIZE);
324
+ } else if (cell.type === 'door') {
325
+ fill(139, 69, 19); // Brown color for doors
326
+ noStroke();
327
+ rect(x * CELL_SIZE, y * CELL_SIZE, CELL_SIZE, CELL_SIZE);
328
+ } else if (cell.color) {
329
+ noStroke();
330
+ switch(cell.color) {
331
+ case 'yellow':
332
+ fill('#ffeb3b');
333
+ break;
334
+ case 'blue':
335
+ fill('#2196f3');
336
+ break;
337
+ case 'green':
338
+ fill('#4caf50');
339
+ break;
340
+ case 'red':
341
+ fill('#f44336');
342
+ break;
343
+ }
344
+ rect(x * CELL_SIZE, y * CELL_SIZE, CELL_SIZE, CELL_SIZE);
345
+ }
346
+ }
347
+ }
348
+ }
349
+
350
+ function drawPath() {
351
+ if (path.length > 0 && isMoving) {
352
+ noFill();
353
+ stroke(0, 255, 0);
354
+ strokeWeight(2);
355
+ line(
356
+ characterPos.x * CELL_SIZE + CELL_SIZE/2,
357
+ characterPos.y * CELL_SIZE + CELL_SIZE/2,
358
+ path[0].x * CELL_SIZE + CELL_SIZE/2,
359
+ path[0].y * CELL_SIZE + CELL_SIZE/2
360
+ );
361
+ for (let i = 0; i < path.length - 1; i++) {
362
+ line(
363
+ path[i].x * CELL_SIZE + CELL_SIZE/2,
364
+ path[i].y * CELL_SIZE + CELL_SIZE/2,
365
+ path[i + 1].x * CELL_SIZE + CELL_SIZE/2,
366
+ path[i + 1].y * CELL_SIZE + CELL_SIZE/2
367
+ );
368
+ }
369
+ strokeWeight(1);
370
+ }
371
+ }
372
+
373
+ function drawCharacter() {
374
+ if (characterPos) {
375
+ textSize(CELL_SIZE * 0.8);
376
+ textAlign(CENTER, CENTER);
377
+ text('👧',
378
+ characterPos.x * CELL_SIZE + CELL_SIZE/2,
379
+ characterPos.y * CELL_SIZE + CELL_SIZE/2
380
+ );
381
+ }
382
+ }
383
+
384
+ function stringToHue(str) {
385
+ let hash = 0;
386
+ for (let i = 0; i < str.length; i++) {
387
+ hash = str.charCodeAt(i) + ((hash << 5) - hash);
388
+ }
389
+ return hash % 360;
390
+ }
391
+
392
+ // Simple BFS for pathfinding
393
+ function findPath(start, end) {
394
+ const queue = [[start]];
395
+ const visited = new Set();
396
+ const key = pos => `${pos.x},${pos.y}`;
397
+ visited.add(key(start));
398
+
399
+ while (queue.length > 0) {
400
+ const currentPath = queue.shift();
401
+ const current = currentPath[currentPath.length - 1];
402
+
403
+ if (current.x === end.x && current.y === end.y) {
404
+ return currentPath;
405
+ }
406
+ const neighbors = [
407
+ { x: current.x, y: current.y - 1 },
408
+ { x: current.x+1, y: current.y },
409
+ { x: current.x, y: current.y+1 },
410
+ { x: current.x-1, y: current.y }
411
+ ];
412
+ for (const next of neighbors) {
413
+ if (next.x < 0 || next.x >= GRID_COLS || next.y < 0 || next.y >= GRID_ROWS) continue;
414
+ if (visited.has(key(next))) continue;
415
+
416
+ const cell = grid[next.y][next.x];
417
+ if (cell.type === 'wall') continue;
418
+
419
+ visited.add(key(next));
420
+ queue.push([...currentPath, next]);
421
+ }
422
+ }
423
+ return [];
424
+ }
425
+
426
+ function moveToRoom(roomName) {
427
+ const targetRoom = Array.from(rooms.entries())
428
+ .find(([name]) => name.toLowerCase() === roomName.toLowerCase());
429
+ if (!targetRoom || !characterPos) return false;
430
+
431
+ const [_, cells] = targetRoom;
432
+ if (cells.length === 0) return false;
433
+ path = findPath(characterPos, cells[0]);
434
+ if (path.length > 0) {
435
+ isMoving = true;
436
+ moveCharacterAlongPath();
437
+ return true;
438
+ }
439
+ return false;
440
+ }
441
+
442
+ function moveCharacterAlongPath() {
443
+ if (moveInterval) clearInterval(moveInterval);
444
+ moveInterval = setInterval(() => {
445
+ if (path.length === 0) {
446
+ isMoving = false;
447
+ clearInterval(moveInterval);
448
+ return;
449
+ }
450
+ const nextPos = path.shift();
451
+ characterPos = nextPos;
452
+ }, 200);
453
+ }
454
+
455
+ /* Chat / Mistral-related code */
456
+ function createLoadingIndicator() {
457
+ const loadingDiv = document.createElement('div');
458
+ loadingDiv.className = 'chat-message assistant-message';
459
+ loadingDiv.innerHTML = `
460
+ <div class="loading-dots">
461
+ <div class="dot"></div>
462
+ <div class="dot"></div>
463
+ <div class="dot"></div>
464
+ </div>
465
+ `;
466
+ return loadingDiv;
467
+ }
468
+
469
+ function addMessageToChat(role, content) {
470
+ const chatHistory = document.getElementById('chatHistory');
471
+ const messageDiv = document.createElement('div');
472
+ messageDiv.className = `chat-message ${role}-message`;
473
+ messageDiv.textContent = content;
474
+ chatHistory.appendChild(messageDiv);
475
+ chatHistory.scrollTop = chatHistory.scrollHeight;
476
+ }
477
+
478
+ async function sendMessage() {
479
+ const prompt = document.getElementById('prompt').value.trim();
480
+ if (!prompt) return;
481
+
482
+ if (!apiKey) {
483
+ alert('Please enter your Mistral API key first');
484
+ document.getElementById('apiKeyModal').style.display = 'flex';
485
+ return;
486
+ }
487
+
488
+ // Add user message to the chat
489
+ addMessageToChat('user', prompt);
490
+ document.getElementById('prompt').value = '';
491
+
492
+ // Add loading indicator
493
+ const chatHistory = document.getElementById('chatHistory');
494
+ const loadingIndicator = createLoadingIndicator();
495
+ chatHistory.appendChild(loadingIndicator);
496
+
497
+ try {
498
+ // Make call to Mistral or any AI endpoint
499
+ const response = await fetch('https://api.mistral.ai/v1/chat/completions', {
500
+ method: 'POST',
501
+ headers: {
502
+ 'Content-Type': 'application/json',
503
+ 'Authorization': `Bearer ${apiKey}`
504
+ },
505
+ body: JSON.stringify({
506
+ model: 'mistral-large-latest',
507
+ messages: [
508
+ { role: 'system', content: systemPrompt },
509
+ { role: 'user', content: prompt }
510
+ ]
511
+ })
512
+ });
513
+
514
+ if (!response.ok) {
515
+ throw new Error(`HTTP error! status: ${response.status}`);
516
+ }
517
+
518
+ const data = await response.json();
519
+ const assistantResponse = data.choices[0].message.content || "";
520
+
521
+ try {
522
+ const jsonStart = assistantResponse.indexOf('{');
523
+ const jsonEnd = assistantResponse.lastIndexOf('}') + 1;
524
+ const jsonContent = assistantResponse.substring(jsonStart, jsonEnd);
525
+ const jsonResponse = JSON.parse(jsonContent);
526
+
527
+ if (jsonResponse.textMessage) {
528
+ addMessageToChat('assistant', jsonResponse.textMessage);
529
+ }
530
+ if (jsonResponse.action === 'go' && jsonResponse.to) {
531
+ moveToRoom(jsonResponse.to);
532
+ }
533
+ } catch (e) {
534
+ console.error('Error parsing JSON from response:', e);
535
+ addMessageToChat('assistant', 'Sorry, I had trouble understanding that response.');
536
+ }
537
+ } catch (error) {
538
+ addMessageToChat('assistant', `Error: ${error.message}`);
539
+ } finally {
540
+ loadingIndicator.remove();
541
+ }
542
+ }
543
+
544
+ function saveApiKey() {
545
+ const key = document.getElementById('apiKey').value.trim();
546
+ if (key) {
547
+ apiKey = key;
548
+ localStorage.setItem('mistralApiKey', key);
549
+ document.getElementById('apiKeyModal').style.display = 'none';
550
+ }
551
+ }
552
+
553
+ // Allow sending message with Enter
554
+ document.addEventListener('DOMContentLoaded', () => {
555
+ document.getElementById('prompt').addEventListener('keypress', function(e) {
556
+ if (e.key === 'Enter' && !e.shiftKey) {
557
+ e.preventDefault();
558
+ sendMessage();
559
+ }
560
+ });
561
+
562
+ if (!apiKey) {
563
+ document.getElementById('apiKeyModal').style.display = 'flex';
564
+ }
565
+ });
566
+ </script>
567
+ </body>
568
+ </html>
static/index.html CHANGED
@@ -1 +1,150 @@
1
- hello
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>The Last Message - Horror Escape Game</title>
5
+ <style>
6
+ body {
7
+ margin: 0;
8
+ padding: 0;
9
+ min-height: 100vh;
10
+ font-family: 'Arial', sans-serif;
11
+ background: linear-gradient(135deg, #0a0a0a 0%, #1a1a1a 100%);
12
+ color: #ffffff;
13
+ display: flex;
14
+ flex-direction: column;
15
+ align-items: center;
16
+ justify-content: center;
17
+ overflow: hidden;
18
+ }
19
+
20
+ .container {
21
+ text-align: center;
22
+ padding: 2rem;
23
+ max-width: 800px;
24
+ position: relative;
25
+ z-index: 1;
26
+ }
27
+
28
+ h1 {
29
+ font-size: 4rem;
30
+ margin-bottom: 1rem;
31
+ text-shadow: 0 0 10px #ff0000, 0 0 20px #ff0000;
32
+ animation: flicker 4s infinite;
33
+ letter-spacing: 2px;
34
+ }
35
+
36
+ .subtitle {
37
+ font-size: 1.2rem;
38
+ color: #bb0000;
39
+ margin-bottom: 3rem;
40
+ text-shadow: 0 0 5px #ff0000;
41
+ }
42
+
43
+ .menu {
44
+ display: grid;
45
+ gap: 2rem;
46
+ margin-top: 2rem;
47
+ }
48
+
49
+ .menu-item {
50
+ background: rgba(20, 20, 20, 0.8);
51
+ padding: 1.5rem;
52
+ border-radius: 5px;
53
+ cursor: pointer;
54
+ transition: all 0.3s ease;
55
+ text-decoration: none;
56
+ color: white;
57
+ border: 1px solid #440000;
58
+ box-shadow: 0 0 10px rgba(255, 0, 0, 0.2);
59
+ }
60
+
61
+ .menu-item:hover {
62
+ transform: scale(1.05);
63
+ background: rgba(40, 0, 0, 0.8);
64
+ border-color: #ff0000;
65
+ box-shadow: 0 0 20px rgba(255, 0, 0, 0.4);
66
+ }
67
+
68
+ .menu-item h2 {
69
+ margin: 0 0 0.5rem 0;
70
+ font-size: 1.8rem;
71
+ color: #ff0000;
72
+ }
73
+
74
+ .menu-item p {
75
+ margin: 0;
76
+ color: #cccccc;
77
+ font-size: 1rem;
78
+ }
79
+
80
+ @keyframes flicker {
81
+ 0%, 100% { opacity: 1; }
82
+ 92% { opacity: 1; }
83
+ 93% { opacity: 0.8; }
84
+ 94% { opacity: 1; }
85
+ 95% { opacity: 0.9; }
86
+ 96% { opacity: 1; }
87
+ }
88
+
89
+ /* Blood drips */
90
+ .blood-drip {
91
+ position: fixed;
92
+ top: 0;
93
+ width: 3px;
94
+ height: 60px;
95
+ background: linear-gradient(to bottom, transparent, rgba(255, 0, 0, 0.8));
96
+ animation: drip 4s infinite;
97
+ opacity: 0.7;
98
+ }
99
+
100
+ @keyframes drip {
101
+ 0% {
102
+ transform: translateY(-60px);
103
+ opacity: 0;
104
+ }
105
+ 50% {
106
+ opacity: 0.7;
107
+ }
108
+ 100% {
109
+ transform: translateY(100vh);
110
+ opacity: 0;
111
+ }
112
+ }
113
+
114
+
115
+ </style>
116
+ </head>
117
+ <body>
118
+ <!-- Blood drip effects -->
119
+ <div class="blood-drip" style="left: 15%"></div>
120
+ <div class="blood-drip" style="left: 35%; animation-delay: 1.5s"></div>
121
+ <div class="blood-drip" style="left: 55%; animation-delay: 2.5s"></div>
122
+ <div class="blood-drip" style="left: 75%; animation-delay: 1s"></div>
123
+ <div class="blood-drip" style="left: 95%; animation-delay: 2s"></div>
124
+
125
+ <div class="container">
126
+ <h1>THE LAST MESSAGE</h1>
127
+ <div class="subtitle">Will your final words save them?</div>
128
+
129
+ <div class="menu">
130
+ <a href="game/" class="menu-item">
131
+ <h2>📱 PLAY THE STORY</h2>
132
+ <p>Experience the original nightmare</p>
133
+ </a>
134
+
135
+ <a href="maker/" class="menu-item">
136
+ <h2>🏗️ CREATE & PLAY</h2>
137
+ <p>Design and play your own horror scenario</p>
138
+ </a>
139
+ </div>
140
+
141
+ </div>
142
+
143
+ <script>
144
+ // Add random delay and duration to blood drips
145
+ document.querySelectorAll('.blood-drip').forEach(drip => {
146
+ drip.style.animationDuration = (3 + Math.random() * 2) + 's';
147
+ });
148
+ </script>
149
+ </body>
150
+ </html>
static/maker/index.html ADDED
@@ -0,0 +1,545 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Apartment Simulator Level Editor</title>
5
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.7.0/p5.min.js"></script>
6
+ <style>
7
+ body {
8
+ margin: 0;
9
+ display: flex;
10
+ flex-direction: column;
11
+ align-items: center;
12
+ font-family: Arial, sans-serif;
13
+ }
14
+ #controls {
15
+ margin: 10px;
16
+ padding: 10px;
17
+ background: #f0f0f0;
18
+ border-radius: 5px;
19
+ }
20
+ button {
21
+ margin: 0 5px;
22
+ padding: 5px 10px;
23
+ cursor: pointer;
24
+ }
25
+ select, input[type="number"] {
26
+ margin: 0 5px;
27
+ padding: 5px;
28
+ }
29
+ .active {
30
+ background: #4CAF50;
31
+ color: white;
32
+ }
33
+ </style>
34
+ </head>
35
+ <body>
36
+ <div id="controls">
37
+ <button id="wallBtn" onclick="setTool('wall')">Wall</button>
38
+ <button id="doorBtn" onclick="setTool('door')">Door</button>
39
+ <button id="eraseBtn" onclick="setTool('erase')">Erase</button>
40
+ <button id="characterBtn" onclick="setTool('character')">Place Character</button>
41
+ |
42
+ <button id="yellowBtn" onclick="setTool('yellow')" style="background-color: #ffeb3b">Yellow</button>
43
+ <button id="blueBtn" onclick="setTool('blue')" style="background-color: #2196f3">Blue</button>
44
+ <button id="greenBtn" onclick="setTool('green')" style="background-color: #4caf50">Green</button>
45
+ <button id="redBtn" onclick="setTool('red')" style="background-color: #f44336">Red</button>
46
+ |
47
+ <input type="text" id="roomName" placeholder="Room name">
48
+ <button id="assignRoom" onclick="setTool('assign')">Assign Room</button>
49
+ <select id="roomSelect">
50
+ <option value="">Select Destination Room</option>
51
+ </select>
52
+ <select id="viaRoomSelect">
53
+ <option value="">Via Room (Optional)</option>
54
+ </select>
55
+ <button id="removeRoom" onclick="removeSelectedRoom()">Remove Room</button>
56
+ <button id="goBtn" onclick="startPathfinding()">Go!</button>
57
+ |
58
+ <button onclick="saveMap()">Save Map</button>
59
+ <button onclick="loadMap()">Load Map</button>
60
+ |
61
+ <input type="number" id="gridCols" value="40" min="1" style="width: 60px"> ×
62
+ <input type="number" id="gridRows" value="20" min="1" style="width: 60px">
63
+ <button onclick="resizeGrid()">Resize Grid</button>
64
+ </div>
65
+
66
+ <!-- Insert a new container for the P5 sketch -->
67
+ <div id="sketch-container"></div>
68
+
69
+ <!-- Move the JSON text areas here so they appear after the editor and canvas -->
70
+ <div style="margin-top: 20px; width: 100%; max-width: 1200px; text-align: center;">
71
+ <textarea id="roomsJson" readonly style="width: 90%; height: 100px; margin: 10px; padding: 10px;" placeholder="Rooms will appear here in JSON format"></textarea>
72
+ <textarea id="gameJson" readonly style="width: 90%; height: 200px; margin: 10px; padding: 10px;" placeholder="Complete game definition will appear here in JSON format"></textarea>
73
+ </div>
74
+
75
+ <script>
76
+ const CELL_SIZE = 30;
77
+ let GRID_COLS = 40;
78
+ let GRID_ROWS = 20;
79
+
80
+ let grid = [];
81
+ let rooms = new Map(); // roomName -> array of cells
82
+ let currentTool = 'wall';
83
+ let characterPos = null;
84
+ let isDragging = false;
85
+ let roomBeingAssigned = null;
86
+ let path = [];
87
+ let isMoving = false;
88
+ let moveInterval = null;
89
+
90
+ function setup() {
91
+ GRID_COLS = parseInt(document.getElementById('gridCols').value) || 40;
92
+ GRID_ROWS = parseInt(document.getElementById('gridRows').value) || 20;
93
+
94
+ // Attach the P5 canvas to #sketch-container
95
+ createCanvas(GRID_COLS * CELL_SIZE, GRID_ROWS * CELL_SIZE)
96
+ .parent('sketch-container');
97
+
98
+ initGrid();
99
+ }
100
+
101
+ function initGrid() {
102
+ grid = []; // Clear the grid first
103
+ for (let y = 0; y < GRID_ROWS; y++) {
104
+ grid[y] = [];
105
+ for (let x = 0; x < GRID_COLS; x++) {
106
+ grid[y][x] = {
107
+ type: 'empty',
108
+ room: null,
109
+ color: null
110
+ };
111
+ }
112
+ }
113
+ }
114
+
115
+ function draw() {
116
+ background(255);
117
+ drawGrid();
118
+ drawRooms();
119
+ drawWallsAndDoors();
120
+ drawPath();
121
+ drawCharacter();
122
+
123
+ // Draw hover effect
124
+ if (mouseInCanvas()) {
125
+ const [gridX, gridY] = getGridCoord(mouseX, mouseY);
126
+ noFill();
127
+ stroke(100);
128
+ rect(gridX * CELL_SIZE, gridY * CELL_SIZE, CELL_SIZE, CELL_SIZE);
129
+ }
130
+ }
131
+
132
+ function drawGrid() {
133
+ stroke(200);
134
+ for (let x = 0; x <= GRID_COLS; x++) {
135
+ line(x * CELL_SIZE, 0, x * CELL_SIZE, height);
136
+ }
137
+ for (let y = 0; y <= GRID_ROWS; y++) {
138
+ line(0, y * CELL_SIZE, width, y * CELL_SIZE);
139
+ }
140
+ }
141
+
142
+ function drawWallsAndDoors() {
143
+ for (let y = 0; y < GRID_ROWS; y++) {
144
+ for (let x = 0; x < GRID_COLS; x++) {
145
+ const cell = grid[y][x];
146
+ if (cell.type === 'wall') {
147
+ fill(0);
148
+ noStroke();
149
+ rect(x * CELL_SIZE, y * CELL_SIZE, CELL_SIZE, CELL_SIZE);
150
+ } else if (cell.type === 'door') {
151
+ fill(139, 69, 19);
152
+ noStroke();
153
+ rect(x * CELL_SIZE, y * CELL_SIZE, CELL_SIZE, CELL_SIZE);
154
+ } else if (cell.color) {
155
+ noStroke();
156
+ switch(cell.color) {
157
+ case 'yellow':
158
+ fill('#ffeb3b');
159
+ break;
160
+ case 'blue':
161
+ fill('#2196f3');
162
+ break;
163
+ case 'green':
164
+ fill('#4caf50');
165
+ break;
166
+ case 'red':
167
+ fill('#f44336');
168
+ break;
169
+ }
170
+ rect(x * CELL_SIZE, y * CELL_SIZE, CELL_SIZE, CELL_SIZE);
171
+ }
172
+ }
173
+ }
174
+ }
175
+
176
+ function drawRooms() {
177
+ for (let [roomName, cells] of rooms) {
178
+ const hue = stringToHue(roomName);
179
+ fill(hue, 30, 95, 0.3);
180
+ noStroke();
181
+ for (let cell of cells) {
182
+ rect(cell.x * CELL_SIZE, cell.y * CELL_SIZE, CELL_SIZE, CELL_SIZE);
183
+ }
184
+ // Draw room name on first cell
185
+ if (cells.length > 0) {
186
+ fill(0);
187
+ textAlign(CENTER, CENTER);
188
+ textSize(10);
189
+ text(roomName, cells[0].x * CELL_SIZE + CELL_SIZE/2, cells[0].y * CELL_SIZE + CELL_SIZE/2);
190
+ }
191
+ }
192
+ }
193
+
194
+ function drawCharacter() {
195
+ if (characterPos) {
196
+ textSize(CELL_SIZE * 0.8);
197
+ textAlign(CENTER, CENTER);
198
+ text('👧',
199
+ characterPos.x * CELL_SIZE + CELL_SIZE/2,
200
+ characterPos.y * CELL_SIZE + CELL_SIZE/2
201
+ );
202
+ }
203
+ }
204
+
205
+ function mousePressed() {
206
+ if (!mouseInCanvas()) return;
207
+ isDragging = true;
208
+ handleDraw();
209
+ }
210
+
211
+ function mouseDragged() {
212
+ if (isDragging) handleDraw();
213
+ }
214
+
215
+ function mouseReleased() {
216
+ isDragging = false;
217
+ if (currentTool === 'assign') {
218
+ const roomName = document.getElementById('roomName').value;
219
+ if (roomName && roomBeingAssigned && roomBeingAssigned.length > 0) {
220
+ rooms.set(roomName, roomBeingAssigned);
221
+ updateRoomDropdown();
222
+ }
223
+ roomBeingAssigned = null;
224
+ }
225
+ }
226
+
227
+ function handleDraw() {
228
+ if (!mouseInCanvas()) return;
229
+
230
+ const [gridX, gridY] = getGridCoord(mouseX, mouseY);
231
+
232
+ switch(currentTool) {
233
+ case 'wall':
234
+ grid[gridY][gridX].type = 'wall';
235
+ grid[gridY][gridX].color = null;
236
+ break;
237
+ case 'door':
238
+ grid[gridY][gridX].type = 'door';
239
+ grid[gridY][gridX].color = null;
240
+ break;
241
+ case 'erase':
242
+ grid[gridY][gridX].type = 'empty';
243
+ grid[gridY][gridX].color = null;
244
+ break;
245
+ case 'character':
246
+ characterPos = {x: gridX, y: gridY};
247
+ currentTool = 'wall'; // Reset to wall tool after placing character
248
+ break;
249
+ case 'assign':
250
+ if (!roomBeingAssigned) roomBeingAssigned = [];
251
+ roomBeingAssigned.push({x: gridX, y: gridY});
252
+ break;
253
+ case 'yellow':
254
+ case 'blue':
255
+ case 'green':
256
+ case 'red':
257
+ grid[gridY][gridX].type = 'empty';
258
+ grid[gridY][gridX].color = currentTool;
259
+ break;
260
+ }
261
+ updateGameJson(); // Update game JSON after any grid changes
262
+ }
263
+
264
+ function setTool(tool) {
265
+ currentTool = tool;
266
+ // Reset room being assigned if switching tools
267
+ if (tool !== 'assign') roomBeingAssigned = null;
268
+
269
+ // Update button states
270
+ document.querySelectorAll('button').forEach(btn => btn.classList.remove('active'));
271
+ document.getElementById(tool + 'Btn')?.classList.add('active');
272
+ }
273
+
274
+ function mouseInCanvas() {
275
+ return mouseX >= 0 && mouseX < width && mouseY >= 0 && mouseY < height;
276
+ }
277
+
278
+ function getGridCoord(x, y) {
279
+ const gridX = Math.floor(x / CELL_SIZE);
280
+ const gridY = Math.floor(y / CELL_SIZE);
281
+ return [
282
+ Math.min(Math.max(gridX, 0), GRID_COLS - 1),
283
+ Math.min(Math.max(gridY, 0), GRID_ROWS - 1)
284
+ ];
285
+ }
286
+
287
+ function stringToHue(str) {
288
+ let hash = 0;
289
+ for (let i = 0; i < str.length; i++) {
290
+ hash = str.charCodeAt(i) + ((hash << 5) - hash);
291
+ }
292
+ return hash % 360;
293
+ }
294
+
295
+ function updateRoomDropdown() {
296
+ const select = document.getElementById('roomSelect');
297
+ const viaSelect = document.getElementById('viaRoomSelect');
298
+ select.innerHTML = '<option value="">Select Destination Room</option>';
299
+ viaSelect.innerHTML = '<option value="">Via Room (Optional)</option>';
300
+ for (let roomName of rooms.keys()) {
301
+ const option = document.createElement('option');
302
+ option.value = roomName;
303
+ option.textContent = roomName;
304
+ select.appendChild(option.cloneNode(true));
305
+ viaSelect.appendChild(option);
306
+ }
307
+ updateRoomsJson();
308
+ }
309
+
310
+ function updateRoomsJson() {
311
+ const roomsTextArea = document.getElementById('roomsJson');
312
+ const roomsList = Array.from(rooms.keys());
313
+ roomsTextArea.value = JSON.stringify(roomsList, null, 2);
314
+ updateGameJson(); // Update game JSON whenever rooms are updated
315
+ }
316
+
317
+ function updateGameJson() {
318
+ const gameTextArea = document.getElementById('gameJson');
319
+ const gameData = {
320
+ grid: grid,
321
+ rooms: Array.from(rooms.entries()),
322
+ characterPos: characterPos,
323
+ gridCols: GRID_COLS,
324
+ gridRows: GRID_ROWS
325
+ };
326
+ gameTextArea.value = JSON.stringify(gameData, null, 2);
327
+ }
328
+
329
+ function startPathfinding() {
330
+ const targetRoom = document.getElementById('roomSelect').value;
331
+ const viaRoom = document.getElementById('viaRoomSelect').value;
332
+ if (!targetRoom || !characterPos) return;
333
+
334
+ const targetCells = rooms.get(targetRoom);
335
+ if (!targetCells || targetCells.length === 0) return;
336
+
337
+ if (viaRoom && viaRoom !== targetRoom) {
338
+ const viaCells = rooms.get(viaRoom);
339
+ if (!viaCells || viaCells.length === 0) return;
340
+
341
+ // Find path to via room first
342
+ const pathToVia = findPath(characterPos, viaCells[0]);
343
+ if (pathToVia.length === 0) return; // No path to via room
344
+
345
+ // Find path from via room to target
346
+ const pathFromVia = findPath(viaCells[0], targetCells[0]);
347
+ if (pathFromVia.length === 0) return; // No path from via to target
348
+
349
+ // Combine paths (remove duplicate via point)
350
+ path = [...pathToVia, ...pathFromVia.slice(1)];
351
+ } else {
352
+ // Direct path to target
353
+ path = findPath(characterPos, targetCells[0]);
354
+ }
355
+
356
+ if (path.length > 0) {
357
+ isMoving = true;
358
+ moveCharacterAlongPath();
359
+ }
360
+ }
361
+
362
+ function findPath(start, end) {
363
+ const queue = [[start]];
364
+ const visited = new Set();
365
+ const key = pos => `${pos.x},${pos.y}`;
366
+ visited.add(key(start));
367
+
368
+ while (queue.length > 0) {
369
+ const currentPath = queue.shift();
370
+ const current = currentPath[currentPath.length - 1];
371
+
372
+ if (current.x === end.x && current.y === end.y) {
373
+ return currentPath;
374
+ }
375
+
376
+ // Get neighbors (up, right, down, left)
377
+ const neighbors = [
378
+ {x: current.x, y: current.y - 1},
379
+ {x: current.x + 1, y: current.y},
380
+ {x: current.x, y: current.y + 1},
381
+ {x: current.x - 1, y: current.y}
382
+ ];
383
+
384
+ for (const next of neighbors) {
385
+ if (next.x < 0 || next.x >= GRID_COLS || next.y < 0 || next.y >= GRID_ROWS) continue;
386
+
387
+ const nextKey = key(next);
388
+ if (visited.has(nextKey)) continue;
389
+
390
+ // Check if the cell is walkable (empty or door)
391
+ const cell = grid[next.y][next.x];
392
+ if (cell.type === 'wall') continue;
393
+
394
+ visited.add(nextKey);
395
+ queue.push([...currentPath, next]);
396
+ }
397
+ }
398
+
399
+ return []; // No path found
400
+ }
401
+
402
+ function moveCharacterAlongPath() {
403
+ if (moveInterval) clearInterval(moveInterval);
404
+
405
+ moveInterval = setInterval(() => {
406
+ if (path.length === 0) {
407
+ isMoving = false;
408
+ clearInterval(moveInterval);
409
+ return;
410
+ }
411
+
412
+ const nextPos = path.shift();
413
+ characterPos = nextPos;
414
+ }, 200); // Move every 200ms
415
+ }
416
+
417
+ function drawPath() {
418
+ if (path.length > 0 && isMoving) {
419
+ noFill();
420
+ stroke(0, 255, 0);
421
+ strokeWeight(2);
422
+
423
+ // Draw line from character to first path point
424
+ line(
425
+ characterPos.x * CELL_SIZE + CELL_SIZE/2,
426
+ characterPos.y * CELL_SIZE + CELL_SIZE/2,
427
+ path[0].x * CELL_SIZE + CELL_SIZE/2,
428
+ path[0].y * CELL_SIZE + CELL_SIZE/2
429
+ );
430
+
431
+ // Draw lines between path points
432
+ for (let i = 0; i < path.length - 1; i++) {
433
+ line(
434
+ path[i].x * CELL_SIZE + CELL_SIZE/2,
435
+ path[i].y * CELL_SIZE + CELL_SIZE/2,
436
+ path[i + 1].x * CELL_SIZE + CELL_SIZE/2,
437
+ path[i + 1].y * CELL_SIZE + CELL_SIZE/2
438
+ );
439
+ }
440
+ strokeWeight(1);
441
+ }
442
+ }
443
+
444
+ function saveMap() {
445
+ const mapData = {
446
+ grid: grid,
447
+ rooms: Array.from(rooms.entries()),
448
+ characterPos: characterPos,
449
+ gridCols: GRID_COLS,
450
+ gridRows: GRID_ROWS
451
+ };
452
+ localStorage.setItem('apartmentMap', JSON.stringify(mapData));
453
+ alert('Map saved!');
454
+ updateGameJson(); // Update game JSON after saving
455
+ }
456
+
457
+ function loadMap() {
458
+ const mapData = localStorage.getItem('apartmentMap');
459
+ if (!mapData) {
460
+ alert('No saved map found!');
461
+ return;
462
+ }
463
+
464
+ const data = JSON.parse(mapData);
465
+
466
+ // Update grid dimensions and input fields
467
+ GRID_COLS = data.gridCols || 40;
468
+ GRID_ROWS = data.gridRows || 20;
469
+ document.getElementById('gridCols').value = GRID_COLS;
470
+ document.getElementById('gridRows').value = GRID_ROWS;
471
+
472
+ // Resize canvas and initialize grid
473
+ resizeCanvas(GRID_COLS * CELL_SIZE, GRID_ROWS * CELL_SIZE);
474
+ initGrid();
475
+
476
+ // Load saved data
477
+ grid = data.grid;
478
+ rooms = new Map(data.rooms);
479
+ characterPos = data.characterPos;
480
+ updateRoomDropdown();
481
+ updateGameJson(); // Update game JSON after loading
482
+ }
483
+
484
+ function removeSelectedRoom() {
485
+ const roomName = document.getElementById('roomSelect').value;
486
+ if (!roomName) return;
487
+
488
+ // Remove room from the rooms Map
489
+ rooms.delete(roomName);
490
+
491
+ // Update the dropdown
492
+ updateRoomDropdown();
493
+ }
494
+
495
+ function resizeGrid() {
496
+ const newCols = parseInt(document.getElementById('gridCols').value) || 40;
497
+ const newRows = parseInt(document.getElementById('gridRows').value) || 20;
498
+
499
+ // Save old grid data
500
+ const oldGrid = JSON.parse(JSON.stringify(grid)); // Deep copy
501
+ const oldCols = GRID_COLS;
502
+ const oldRows = GRID_ROWS;
503
+
504
+ // Update dimensions
505
+ GRID_COLS = newCols;
506
+ GRID_ROWS = newRows;
507
+
508
+ // Initialize new grid first
509
+ initGrid();
510
+
511
+ // Copy old data to new grid where possible
512
+ for (let y = 0; y < Math.min(oldRows, GRID_ROWS); y++) {
513
+ for (let x = 0; x < Math.min(oldCols, GRID_COLS); x++) {
514
+ if (oldGrid[y] && oldGrid[y][x]) {
515
+ grid[y][x] = oldGrid[y][x];
516
+ }
517
+ }
518
+ }
519
+
520
+ // Resize canvas
521
+ resizeCanvas(GRID_COLS * CELL_SIZE, GRID_ROWS * CELL_SIZE);
522
+
523
+ // Adjust character position if outside new bounds
524
+ if (characterPos) {
525
+ if (characterPos.x >= GRID_COLS) characterPos.x = GRID_COLS - 1;
526
+ if (characterPos.y >= GRID_ROWS) characterPos.y = GRID_ROWS - 1;
527
+ }
528
+
529
+ // Adjust room cells to fit new grid
530
+ for (let [roomName, cells] of rooms) {
531
+ rooms.set(roomName, cells.filter(cell =>
532
+ cell.x < GRID_COLS && cell.y < GRID_ROWS
533
+ ));
534
+ }
535
+
536
+ // Clear path if any
537
+ path = [];
538
+ if (moveInterval) clearInterval(moveInterval);
539
+ isMoving = false;
540
+
541
+ updateGameJson(); // Update game JSON after resizing
542
+ }
543
+ </script>
544
+ </body>
545
+ </html>