From c602113cdb101e4664037eed3771559c0770f1c5 Mon Sep 17 00:00:00 2001 From: Carl Worth <cworth@cworth.org> Date: Fri, 23 Dec 2022 09:52:22 -0800 Subject: [PATCH] Assign different default code to each boy Also, draw the solution text in white on top, (so if they generate their picture frequently, they can just make out the letters and numbers). --- bus.html | 21 ++++------- index.js | 75 ++++++++++++++++++++++++++++++++++++++- interpret-cairo-to-svg.py | 73 +++++++++++++++++++++++++++++++++++-- 3 files changed, 151 insertions(+), 18 deletions(-) diff --git a/bus.html b/bus.html index f16a509..5760786 100644 --- a/bus.html +++ b/bus.html @@ -117,23 +117,10 @@ </div> <div id="program" style="visibility: hidden"> - <h1> - Magic School Bus Central Processor + <h1>Magic School Bus</h1> </h1> <form id="form"> - <textarea id="code" rows="10" width="100%">def random_dot(): - x = 200 * random() - y = 200 * random() - radius = 4 + 6 * random() - circle(x, y, radius) - fill() - -for i in range(100): - if i %2 == 0: - set_color('red') - else: - set_color('blue') - random_dot()</textarea> + <textarea id="code" rows="15" width="100%"></textarea> <button type="submit">Run code</button> </form> <img id="output"></img> @@ -185,6 +172,10 @@ for i in range(100): students.textContent = count.toString(); }); + socket.on('code', (code_string) => { + code.value = code_string; + }); + socket.on('timer', (value) => { timer_div.style.visibility = "visible"; timer.textContent = value.toString(); diff --git a/index.js b/index.js index 6aef48c..606fba7 100644 --- a/index.js +++ b/index.js @@ -180,6 +180,52 @@ function start_bus_timer() { bus_interval = setInterval(emit_bus_timer, 1000); } +bus_code = [ + `def random_dot(): + x = random_within(512) + y = random_within(512) + radius = 4 + random_within(6) + circle(x, y, radius) + fill() + +for i in range(400): + set_color('midnight blue' if i % 2 == 0 else 'navy blue') + set_opacity(0.5) + random_dot()`, + + `def random_line(): + x = random_within(512) - 60 + y = random_within(512) - 60 + dx = 60 + random_within(20) + dy = 40 + random_within(20) + set_opacity(random_within(0.5)) + line(x, y, dx, dy) + stroke() + +for i in range(200): + set_color('black') + random_line()`, + + `def random_blob(): + move_to(random_within(512), random_within(512)) + wiggle() + set_opacity(random_within(1.0)) + fill() + +for i in range(100): + set_random_color() + random_blob()`, + + `def random_curve(): + move_to(random_within(512), random_within(512)) + wiggle() + stroke() + +for i in range(200): + set_color('pink' if i % 2 == 0 else 'lime green') + random_curve()` +]; + io_bus.on("connection", (socket) => { if (! socket.request.session.name) { console.log("Error: Someone showed up at the Magic School Bus without a name."); @@ -188,6 +234,7 @@ io_bus.on("connection", (socket) => { const name = socket.request.session.name; const bus = state.bus; + var player_number; // Let the new user know the state of the bus socket.emit("state", bus.state); @@ -196,6 +243,32 @@ io_bus.on("connection", (socket) => { start_bus_timer(); } + // Assign each boy a different portion of the solution + switch (name[0]) { + case 'C': + case 'c': + player_number = 0; + break; + case 'H': + case' h': + player_number = 1; + break; + case 'A': + case 'a': + player_number = 2; + break; + case 'S': + case 's': + player_number = 3; + break; + default: + player_number = Math.floor(Math.random()*4); + break; + } + + // And send them different code based on their number + socket.emit("code", bus_code[player_number]); + if (! bus.students.names.includes(name)) { bus.students.count = bus.students.count + 1; io_bus.emit('students', bus.students.count); @@ -204,7 +277,7 @@ io_bus.on("connection", (socket) => { socket.on('run', code => { try { - output = child_process.execFileSync(python_path, [interpret_cairo_script, code], { input: code }); + output = child_process.execFileSync(python_path, [interpret_cairo_script, player_number], { input: code }); // Grab just first line of output const nl = output.indexOf("\n"); if (nl === -1) diff --git a/interpret-cairo-to-svg.py b/interpret-cairo-to-svg.py index bc0c6b1..99edf1b 100755 --- a/interpret-cairo-to-svg.py +++ b/interpret-cairo-to-svg.py @@ -26,6 +26,13 @@ if "import" in input: os.close(fd) os.chmod(filename, 0o644) +if len(sys.argv) < 2: + sys.stderr.write("This script requires a single argument (value, 1 - 4)") + sys.exit(1) + +user = int(sys.argv[1]) +stderr = sys.stderr + # Also delete our import for some more safety del tempfile del os @@ -791,10 +798,38 @@ COLORS = { 'yellowgreen': (0x9a/0xff, 0xcd/0xff, 0x32/0xff) } +hint = [ + "WAT", "ER ", "PLA", "NET" +] + +code = [ + "304", "570", "325", "6" +] + +r = 0 +g = 0 +b = 0 +a = 1.0 + with cairo.SVGSurface(filename, 512, 512) as surface: + cr = cairo.Context(surface); + cr.set_font_size(190) + cr.select_font_face("sans", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_BOLD) del cairo + def random_within(max): + return max * random() + + def wiggle(): + delta = 200 + cr.rel_curve_to(-delta/2 + random_within(delta), + -delta/2 + random_within(delta), + -delta/2 + random_within(delta), + -delta/2 + random_within(delta), + -delta/2 + random_within(delta), + -delta/2 + random_within(delta)) + def arc(x, y, r, a1, a2): cr.arc(x, y, r, a1, a2) @@ -804,18 +839,52 @@ with cairo.SVGSurface(filename, 512, 512) as surface: def fill(): cr.fill() + def stroke(): + cr.stroke() + def set_color(color): + global r, g, b, a if color in COLORS: (r,g,b) = COLORS[color] else: (r,g,b) = (0,0,0) - cr.set_source_rgb(r, g, b) + cr.set_source_rgba(r, g, b, a) + + def set_random_color(): + global r, g, b, a + (r,g,b) = rand.choice(list(COLORS.values())) + cr.set_source_rgba(r, g, b, a) + + def set_opacity(opacity): + global a + a = opacity + cr.set_source_rgba(r, g, b, a) + + def move_to(x, y): + cr.move_to(x, y) - cr.set_line_width(6) + def line_to(x, y): + cr.line_to(x, y) + + def line(x, y, dx, dy): + cr.move_to(x, y) + cr.rel_line_to(dx, dy) + + def set_line_width(width): + cr.set_line_width(width) # Run the submitted code exec(input) + # After the submitted code, draw the solution in white, (so it will + # only be clearly visible if they've made their drawing big enough). + cr.set_source_rgb(1, 1, 1) + cr.move_to(0,250) + cr.show_text(hint[user]) + cr.set_font_size(240) + cr.move_to(0,480) + cr.show_text(code[user]) + web_file = filename.removeprefix(OUTPUT_DIR_PREFIX) print(web_file) -- 2.45.2