-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.html
More file actions
458 lines (426 loc) · 20.7 KB
/
index.html
File metadata and controls
458 lines (426 loc) · 20.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Python Maze Solver</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id="app">
<h1>Python Maze Solver</h1>
<h2>Code your own maze solver in Python! Scroll down for guides and
instructions.</h2>
<!--
Top row: the maze canvas and the control buttons.
The canvas is where the maze and player are drawn
by JavaScript.
-->
<div class="row" id="top-row">
<canvas id="mazeCanvas" width="480" height="480"></canvas>
<div id="buttons">
<button id="runBtn">Run program</button>
<button id="resetBtn">Reset position</button>
<label id="speedLabel">
Speed:
<input type="range" id="speed" min="1" max="200" value="100">
</label>
</div>
</div>
<!--
Middle row: left side is a text area where the user writes Python.
Right side is a text area that shows printed output and errors.
-->
<div class="row" id="middle-row">
<div>
<p class="panel-title">Python Code</p>
<div class="code-editor">
<pre id="lineNumbers" aria-hidden="true"></pre>
<textarea id="code" spellcheck="false" wrap="off"></textarea>
</div>
</div>
<div>
<p class="panel-title">Output</p>
<textarea id="output" readonly></textarea>
</div>
<div class="middle-actions">
<button id="sampleBtn" type="button">Load sample</button>
</div>
</div>
<!--
Bottom row: instructions / help windows
-->
<div class="row" id="bottom-row">
<div class="tabs" id="help-tabs">
<div class="tabs-nav">
<button type="button" data-tab="maze" class="active">Maze Instructions
</button>
<button type="button" data-tab="guide">Beginners Guide</button>
</div>
<div class="tabs-content">
<section class="tab-pane active" data-tab="maze">
<div class="tab-section">
<p><strong>Goal</strong></p>
<p>
Guide the blue triangle from the start (top left) to the
green goal square (bottom right) without walking into walls
using Python code.
</p>
<p><strong>Controls</strong></p>
<ul>
<li><em>Run program</em> runs whatever is in the program
box to move the triangle.
</li>
<li><em>Reset position</em> sends the triangle back to the
start.
</li>
<li>The <em>speed</em> slider adjusts animation speed.</li>
<li><em>Load sample</em> loads a sample right-hand maze
solver into the code box.
</li>
</ul>
</div>
<div class="tab-section">
<p>The <strong>Python Code</strong> pane contains an area to
write code for solving the maze. To move the triangle to the
end goal, you must write code in Python utilising the
following functions:</p>
<ul>
<li><code>at_goal()</code> – Returns <code>True</code> if
the triangle is on the green goal square, else returns
<code>False</code>.
</li>
<li><code>move()</code> – Moves the triangle one square
forward. Throws a <code>RuntimeError</code> if there is
a wall.
</li>
<li><code>turn_left()</code> – Turns the triangle 90 degrees
left.
</li>
<li><code>turn_right()</code> – Turns the triangle 90
degrees right.
</li>
<li><code>path_ahead()</code> – Returns <code>True</code> if
the cell in front of the triangle can be moved to, else
returns <code>False</code>.
</li>
<li><code>path_behind()</code> – Returns <code>True</code>
if the cell behind the triangle can be moved to, else
returns <code>False</code>.
</li>
<li><code>path_left()</code> – Returns <code>True</code> if
the cell to the left of the triangle can be moved to,
else returns <code>False</code>.
</li>
<li><code>path_right()</code> – Returns <code>True</code> if
the cell to the right of the triangle can be moved to,
else returns <code>False</code>.
</li>
</ul>
<p>To complete the maze, you can use variables, loops,
conditional statements, and functions among other Python
language features.</p>
<p>The <strong>Output</strong> pane will contain any
<code>print</code> statement or errors thrown when you run
your code.</p>
</div>
<div class="tab-section">
<p><strong>Loops</strong></p>
<p>Both <code>for</code> and <code>while</code> loops can be
used:</p>
<pre><code>steps = 0
while path_ahead():
move()
steps += 1
print(f"I moved {steps} steps")</code></pre>
<p>A <code>while</code> loop to run until you reach the end is
likely a core component of any implementation</p>
<p><strong>Conditions</strong></p>
<p>Standard conditional statements in <code>if</code>, <code>elif</code>
and <code>else</code> are available and crucial in
navigating the maze:</p>
<pre><code>if path_ahead():
move()
elif path_right():
turn_right()
else:
turn_left()</code></pre>
<p><strong>New Functions</strong></p>
<p>Both more complex solutions, you can create your own
functions:</p>
<pre><code>def go_forward_until_wall():
while path_ahead():
move()
go_forward_until_wall()</code></pre>
</div>
<div class="tab-section">
<p><strong>Common Mistakes</strong></p>
<ul>
<li>Missing colon (<code>:</code>) - <code>"SyntaxError:
expected ':'"</code> certain lines of code such as
conditionals (<code>if</code>, <code>elif</code> and
<code>else</code> and loops (<code>while</code> and
<code>for</code> ) must end in a <code>:</code>
character.
</li>
<li>Wrong indentation - <code>"IndentationError"</code> Code
after conditionals, loops and function declarations must
be evenly indented using spaces or tabs. Use the same
amount of spaces for all indentation (by default 4
spaces).
</li>
<li>Infinite loop - <code>"StepLimitError: Program
stopped"</code> When using loops, make sure there is a
way to exit, or it will run forever! This may also
happen if your program cannot find the goal. We
automatically stop the program for this exercise in both
cases.
</li>
<li>Running into a wall - <code>RuntimeError: Wall
ahead</code> If you attempt to move into a wall the
program will stop. Try using a function to check if
there is something where you want to move first.
</li>
</ul>
</div>
</section>
<section class="tab-pane" data-tab="guide">
<div class="tab-section">
<p><strong>Beginner guide</strong></p>
<p>
This activity is about giving the triangle instructions
using Python code to move it through the maze.
</p>
<p> Your program runs from top to bottom.
If it tries to walk into a wall, it stops and shows an error
in the Output box.</p>
<p>
In Python, spaces matter. Lines <em>inside</em> an
<code>if</code> or <code>while</code> must be indented
(usually 4 spaces). The Tab key on the right of the keyboard
can be used to enter 4 spaces in the code box.
</p>
</div>
<div class="tab-section">
<p><strong>Step 1: Your first commands</strong></p>
<p>Try these one at a time and press <em>Run program</em>:</p>
<pre><code>move()</code></pre>
<pre><code>turn_right()
move()
move()</code></pre>
<pre><code>turn_left()
move()
</code></pre>
<p>
What happens for each of them? What happens if you do not
remove the previous code before adding the next?
</p>
</div>
<div class="tab-section">
<p><strong>Step 2: Checking for a wall (if statements)</strong>
</p>
<p>
Before moving, you can ask “is there space ahead?”. These
functions return <code>True</code> or <code>False</code>.
</p>
<pre><code>if path_ahead():
move()
else:
turn_right()</code></pre>
<p>
Try adding <code>turn_right()</code> and/or <code>turn_left()</code>
before and see what happens how does this change the
triangles movement from before?
</p>
</div>
<div class="tab-section">
<p><strong>Step 3: Repeating actions (while loops)</strong></p>
<p>
A loop repeats code. <code>while</code> loops continue until
a condition is met. This one keeps moving until a wall is
directly ahead:
</p>
<pre><code>while path_ahead():
move()</code></pre>
<p>
In this case, the goal is to reach the green square, so we
will want to add a condition somewhere using an if or loop
to end any loops when <code>at_goal()</code> becomes <code>True</code>.
</p>
</div>
<div class="tab-section">
<p><strong>Step 4: Build a simple maze solver</strong></p>
<p>
We are going to build a small solver that follows these
rules:
</p>
<ol>
<li>If we can move forward, do it.</li>
<li>Otherwise, try turning right and moving.</li>
<li>If that is not possible, try turning left and moving.
</li>
<li>If none are possible, turn around (a dead end).</li>
</ol>
<p>
The key idea is: we keep repeating these rules until we
reach the goal.
</p>
</div>
<div class="tab-section">
<p><strong>Step 4a: Create a main loop</strong></p>
<p>
Start with a loop that will keep running until the triangle
reaches the green square:
</p>
<pre><code>while not at_goal():
move()</code></pre>
<p>
Try running this. You will find it runs into a wall soon,
but it will keep moving until then.
</p>
</div>
<div class="tab-section">
<p><strong>Step 4b: Add a step counter (optional)</strong></p>
<p>
Next let’s count how many actions we take. This is useful
for tracking progress. To do this we will create a variable
called "steps" and set it to 0. Add this to your current
code, including your line to move the triangle. It should
look somthing like this:
</p>
<pre><code>steps = 0
while not at_goal():
steps = steps + 1
print("Step", steps)</code></pre>
<p>
Try running your program with these additions. If we are
making progress and still moving you should see a few steps
printed before we run into a wall. If you see many
print-outs and the tab freezes for a few seconds, you may be
in an infinite loop. Try adding some movement code to your
program.
</p>
</div>
<div class="tab-section">
<p><strong>Step 4c: Rule 1 — move forward when possible</strong>
</p>
<p>
Now we add the first rule: if there is space ahead, move
forward.
</p>
<pre><code>while not at_goal():
if path_ahead():
move()</code></pre>
<p>
The triangle should move forward until it hits a wall, then
it will get stuck because we haven’t told it what to do when
forward is blocked.
</p>
<p>
Remember: indentation matters in Python! The
<code>move()</code> line must be indented under the
<code>if</code>. This can also be used to move your <code>print</code>
statement outside the loop if you find the multiple print
outs annoying and just want the final count at the end.
</p>
</div>
<div class="tab-section">
<p><strong>Step 4d: Rule 2 — if forward is blocked, try
right</strong></p>
<p>
Extend the <code>if</code> with an <code>elif</code> (“else
if”, another condition to check if the first is
<code>False</code>) We want to use the
<code>path_right()</code> function to check if we can turn
and <code>turn_right()</code> to orient our triangle.
</p>
<pre><code>while not at_goal():
if path_ahead():
move()
elif path_right():
turn_right()
move()</code></pre>
<p>
We should get further now, as the triangle can turn right
when it hits a wall.
</p>
</div>
<div class="tab-section">
<p><strong>Step 4e: Rule 3 — if right is blocked, try
left</strong></p>
<p>
Now do the same, but with functions to move left. </p>
<pre><code>while not at_goal():
if path_ahead():
move()
elif path_right():
turn_right()
move()
elif path_left():
turn_left()
move()</code></pre>
<p>
If your program runs correctly, you should notice that this
is enough to reach the end of this maze and reach the goal!
Good job!
</p>
<p>
</p>
</div>
<div class="tab-section">
<p><strong>Step 4f: Rule 4 — dead ends (turn around)</strong>
</p>
<p>
What if forward, left, and right are all blocked in a
different maze? That means we are in a dead end.
We can turn around by turning right twice. Add an
<code>else</code> block to handle this case, which runs of
none of the other conditionals are <code>true</code>.
</p>
<pre><code>while not at_goal():
if path_ahead():
move()
elif path_right():
turn_right()
move()
elif path_left():
turn_left()
move()
else:
turn_right()
turn_right()</code></pre>
</div>
<div class="tab-section">
<p>If you want to do extra, try changing the solver and see how
this changes the code, maze animation and output</p>
<ul>
<li><strong>Prefer left instead of right:</strong> swap the
<code>path_left()</code> and <code>path_right()</code>
blocks.
</li>
<li><strong>Print the final step count:</strong> count the
number of steps your make, and then print the number
outside the loop when the goal is reached.
</li>
<li>Create your own Python function like <code>def
turn_around():</code> and call it instead of repeating
two right turns.
</li>
</ul>
</div>
</section>
</div>
</div>
</div>
</div>
<!--
Pyodide is a Python interpreter compiled to WebAssembly.
This script loads Pyodide and provides a global loadPyodide() function.
-->
<script src="https://cdn.jsdelivr.net/pyodide/v0.26.2/full/pyodide.js"></script>
<!--
JavaScript code for the maze app. Handles running the user's Python code
in Pyodide, updating the maze canvas, and swapping between instruction tabs.
-->
<script type="module" src="maze.js"></script>
</body>
</html>