localharness 0.78.0

Agents that own themselves: one Rust crate that's both an agent SDK (streaming, tools, hooks, policies, triggers, MCP) and a wallet-owning, self-sovereign agent that runs in the browser.
Documentation
1
2
3
4
5
6
7
8
9
10
11
{
  "id": "124",
  "prompt": "Memory pairs: 8 face-down cards in a 4x2 grid hiding four number pairs. Shuffle at init with a Fisher-Yates over state slots driven by an LCG hash (rustlite has no persistent arrays). Tap two cards: a match locks them green, a mismatch flips back after 45 frames, moves are counted, and matching all four opens a win banner that reshuffles on tap.",
  "solution_rl": "fn hash(seed: i32) -> i32 {\n    let mut h: i32 = seed * 747796405 + 2891336453;\n    h = (h >> 16) ^ h;\n    if h < 0 { h = 0 - h; }\n    h\n}\n\nfn frame(t: i32) {\n    if host::display::state_get(0) == 0 {\n        host::display::state_set(0, 1);\n        let sd: i32 = host::display::state_get(7);\n        let mut i: i32 = 0;\n        while i < 8 {\n            host::display::state_set(20 + i, i / 2);\n            host::display::state_set(30 + i, 0);\n            i = i + 1;\n        }\n        let mut j: i32 = 7;\n        while j > 0 {\n            let k: i32 = hash(sd * 31 + j) % (j + 1);\n            let a: i32 = host::display::state_get(20 + j);\n            let b: i32 = host::display::state_get(20 + k);\n            host::display::state_set(20 + j, b);\n            host::display::state_set(20 + k, a);\n            j = j - 1;\n        }\n        host::display::state_set(1, 0);\n        host::display::state_set(2, 0);\n        host::display::state_set(3, 0);\n        host::display::state_set(4, 0);\n        host::display::state_set(5, 0);\n        host::display::state_set(8, 0);\n    }\n    let down: i32 = host::display::pointer_down();\n    let tap: bool = down == 1 && host::display::state_get(6) == 0;\n    host::display::state_set(6, down);\n    let mut mmt: i32 = host::display::state_get(3);\n    if mmt > 0 {\n        mmt = mmt - 1;\n        if mmt == 0 {\n            let f: i32 = host::display::state_get(1);\n            let s: i32 = host::display::state_get(2);\n            host::display::state_set(30 + f - 1, 0);\n            host::display::state_set(30 + s - 1, 0);\n            host::display::state_set(1, 0);\n            host::display::state_set(2, 0);\n        }\n        host::display::state_set(3, mmt);\n    }\n    if host::display::state_get(8) == 1 {\n        if tap {\n            host::display::state_set(7, host::display::state_get(7) + 1);\n            host::display::state_set(0, 0);\n        }\n    } else if tap && mmt == 0 {\n        let px: i32 = host::display::pointer_x();\n        let py: i32 = host::display::pointer_y();\n        let c: i32 = (px - 40) / 110;\n        let r: i32 = (py - 120) / 140;\n        if px >= 40 && c >= 0 && c < 4 && px - 40 - c * 110 < 100 && py >= 120 && r >= 0 && r < 2 && py - 120 - r * 140 < 120 {\n            let idx: i32 = r * 4 + c;\n            if host::display::state_get(30 + idx) == 0 {\n                let first: i32 = host::display::state_get(1);\n                if first == 0 {\n                    host::display::state_set(1, idx + 1);\n                    host::display::state_set(30 + idx, 1);\n                } else if first != idx + 1 {\n                    host::display::state_set(30 + idx, 1);\n                    host::display::state_set(4, host::display::state_get(4) + 1);\n                    if host::display::state_get(20 + first - 1) == host::display::state_get(20 + idx) {\n                        host::display::state_set(30 + first - 1, 2);\n                        host::display::state_set(30 + idx, 2);\n                        host::display::state_set(1, 0);\n                        let m: i32 = host::display::state_get(5) + 1;\n                        host::display::state_set(5, m);\n                        if m == 4 { host::display::state_set(8, 1); }\n                    } else {\n                        host::display::state_set(2, idx + 1);\n                        host::display::state_set(3, 45);\n                    }\n                }\n            }\n        }\n    }\n    host::display::clear(0x101018);\n    host::display::draw_string(40, 30, \"PAIRS\", 0xffffff, 3);\n    host::display::draw_string(40, 70, \"MOVES\", 0x808080, 2);\n    host::display::draw_number(150, 70, host::display::state_get(4), 0xffffff, 2);\n    let mut i2: i32 = 0;\n    while i2 < 8 {\n        let cx: i32 = 40 + (i2 % 4) * 110;\n        let cy: i32 = 120 + (i2 / 4) * 140;\n        let st: i32 = host::display::state_get(30 + i2);\n        if st == 0 {\n            host::display::fill_rect(cx, cy, 100, 120, 0x28304a);\n            host::display::fill_rect(cx + 8, cy + 8, 84, 104, 0x1c2338);\n        } else {\n            let mut bg: i32 = 0x3a4a68;\n            if st == 2 { bg = 0x1a5a34; }\n            host::display::fill_rect(cx, cy, 100, 120, bg);\n            host::display::draw_number(cx + 38, cy + 44, host::display::state_get(20 + i2), 0xffffff, 4);\n        }\n        i2 = i2 + 1;\n    }\n    if host::display::state_get(8) == 1 {\n        host::display::fill_rect(60, 210, 392, 100, 0x000000);\n        host::display::draw_string(90, 230, \"ALL MATCHED\", 0x00ff88, 3);\n        host::display::draw_string(90, 270, \"TAP TO SHUFFLE AGAIN\", 0x808080, 2);\n    }\n    host::display::present();\n}\n",
  "tags": [
    "game",
    "state",
    "prng",
    "loops"
  ]
}