{
"id": "261",
"prompt": "A gas-in-a-box thermodynamics toy: five molecules bounce elastically inside a drawn container, and every wall impact increments a counter. Every 90 frames the accumulated count becomes the displayed PRESSURE and the tally resets - so pressure literally IS the wall-hit rate. Tapping the top half of the screen heats the gas (all velocities x5/4, capped), the bottom half cools it (x3/4) - watch pressure track temperature, and freeze the gas solid if you keep cooling. Molecule state lives in slot groups; color each molecule by its current speed.",
"solution_rl": "fn iabs(v: i32) -> i32 {\n if v < 0 { -v } else { v }\n}\n\nfn frame(t: i32) {\n let w: i32 = host::display::width();\n let h: i32 = host::display::height();\n if host::display::state_get(0) == 0 {\n host::display::state_set(0, 1);\n let mut i: i32 = 0;\n while i < 5 {\n host::display::state_set(8 + i * 4, (80 + i * 70) * 8);\n host::display::state_set(9 + i * 4, (90 + (i % 3) * 100) * 8);\n host::display::state_set(10 + i * 4, 20 + i * 6);\n host::display::state_set(11 + i * 4, 34 - i * 7);\n i = i + 1;\n }\n }\n let down: i32 = host::display::pointer_down();\n let prev: i32 = host::display::state_get(5);\n host::display::state_set(5, down);\n let tap: bool = down == 1 && prev == 0;\n let heat: bool = tap && host::display::pointer_y() < h / 2;\n let cool: bool = tap && host::display::pointer_y() >= h / 2;\n let mut hits: i32 = host::display::state_get(3);\n host::display::clear(0x0a0a0e);\n host::display::fill_rect(20, 20, w - 40, 2, 0x404050);\n host::display::fill_rect(20, h - 22, w - 40, 2, 0x404050);\n host::display::fill_rect(20, 20, 2, h - 40, 0x404050);\n host::display::fill_rect(w - 22, 20, 2, h - 40, 0x404050);\n let mut i: i32 = 0;\n while i < 5 {\n let b: i32 = 8 + i * 4;\n let mut x: i32 = host::display::state_get(b);\n let mut y: i32 = host::display::state_get(b + 1);\n let mut vx: i32 = host::display::state_get(b + 2);\n let mut vy: i32 = host::display::state_get(b + 3);\n if heat {\n vx = vx * 5 / 4;\n vy = vy * 5 / 4;\n if vx > 120 { vx = 120; }\n if vx < -120 { vx = -120; }\n if vy > 120 { vy = 120; }\n if vy < -120 { vy = -120; }\n }\n if cool {\n vx = vx * 3 / 4;\n vy = vy * 3 / 4;\n }\n x = x + vx;\n y = y + vy;\n if x < 26 * 8 { x = 26 * 8; vx = -vx; hits = hits + 1; }\n if x > (w - 26) * 8 { x = (w - 26) * 8; vx = -vx; hits = hits + 1; }\n if y < 26 * 8 { y = 26 * 8; vy = -vy; hits = hits + 1; }\n if y > (h - 26) * 8 { y = (h - 26) * 8; vy = -vy; hits = hits + 1; }\n host::display::state_set(b, x);\n host::display::state_set(b + 1, y);\n host::display::state_set(b + 2, vx);\n host::display::state_set(b + 3, vy);\n let sp: i32 = iabs(vx) + iabs(vy);\n let c: i32 = if sp > 60 { 0xff6040 } else if sp > 30 { 0xffc040 } else { 0x4080ff };\n host::display::fill_rect(x / 8 - 4, y / 8 - 4, 8, 8, c);\n i = i + 1;\n }\n if t % 90 == 0 {\n host::display::state_set(4, hits);\n hits = 0;\n }\n host::display::state_set(3, hits);\n host::display::draw_string(28, 28, \"PRESSURE\", 0x808080, 1);\n host::display::draw_number(110, 28, host::display::state_get(4), 0xffffff, 1);\n host::display::draw_string(28, h - 40, \"TAP TOP=HEAT BOTTOM=COOL\", 0x505050, 1);\n host::display::present();\n}\n",
"tags": [
"simulation",
"gas",
"state",
"pointer"
]
}