// Module 7: Resolving rules. Each test matches a heading in scenarios.md. import { expect, test } from "vitest"; import { newBaba, type Baba } from "../src/harness"; /** An empty level `width` wide and `height` high. */ const emptyLevel = (width: number, height: number) => ({ width, height, objects: [] }); /** Place one text object per word: `[word, x, y]`. */ function write(b: Baba, words: [string, number, number][]): void { for (const [word, x, y] of words) b.place(`text:${word}`, x, y); } test("test_07_not_overrides", () => { const b = newBaba(emptyLevel(4, 5)); write(b, [ ["BABA", 0, 0], ["IS", 1, 0], ["YOU", 2, 0], ]); const baba = b.place("baba", 0, 4); expect(b.hasProperty(baba, "YOU")).toBe(true); write(b, [ ["BABA", 0, 2], ["IS", 1, 2], ["NOT", 2, 2], ["YOU", 3, 2], ]); expect(b.rules()).toEqual(["BABA IS NOT YOU", "BABA IS YOU", "TEXT IS PUSH"]); expect(b.activeRules()).toEqual(["BABA IS NOT YOU", "TEXT IS PUSH"]); expect(b.hasProperty(baba, "YOU")).toBe(false); }); test("test_07_x_is_x_blocks_conversion", () => { const b = newBaba(emptyLevel(3, 5)); write(b, [ ["BABA", 0, 0], ["IS", 1, 0], ["BABA", 2, 0], ["BABA", 0, 2], ["IS", 1, 2], ["ROCK", 2, 2], ["ROCK", 0, 4], ["IS", 1, 4], ["BABA", 2, 4], ]); expect(b.rules()).toEqual(["BABA IS BABA", "BABA IS ROCK", "ROCK IS BABA", "TEXT IS PUSH"]); expect(b.activeRules()).toEqual(["BABA IS BABA", "ROCK IS BABA", "TEXT IS PUSH"]); }); test("test_07_x_is_not_x_deletes_and_unlocks", () => { const b = newBaba(emptyLevel(4, 5)); write(b, [ ["BABA", 0, 0], ["IS", 1, 0], ["NOT", 2, 0], ["BABA", 3, 0], ["BABA", 0, 2], ["IS", 1, 2], ["BABA", 2, 2], ["BABA", 0, 4], ["IS", 1, 4], ["ROCK", 2, 4], ]); expect(b.rules()).toEqual(["BABA IS BABA", "BABA IS NOT BABA", "BABA IS ROCK", "TEXT IS PUSH"]); expect(b.activeRules()).toContain("BABA IS ROCK"); expect(b.activeRules()).not.toContain("BABA IS BABA"); }); test("test_07_text_is_not_push", () => { const b = newBaba(emptyLevel(4, 3)); const rockText = b.place("text:ROCK", 0, 2); const rock = b.place("rock", 3, 2); expect(b.activeRules()).toEqual(["TEXT IS PUSH"]); expect(b.hasProperty(rockText, "PUSH")).toBe(true); expect(b.hasProperty(rock, "PUSH")).toBe(false); const textText = b.place("text:TEXT", 0, 0); write(b, [ ["IS", 1, 0], ["NOT", 2, 0], ["PUSH", 3, 0], ]); expect(b.rules()).toEqual(["TEXT IS NOT PUSH", "TEXT IS PUSH"]); expect(b.activeRules()).toEqual(["TEXT IS NOT PUSH"]); expect(b.hasProperty(rockText, "PUSH")).toBe(false); expect(b.hasProperty(textText, "PUSH")).toBe(false); }); test("test_07_leading_not_breaks_sentence", () => { const b = newBaba(emptyLevel(4, 2)); write(b, [ ["NOT", 0, 0], ["BABA", 1, 0], ["IS", 2, 0], ["YOU", 3, 0], ]); const baba = b.place("baba", 0, 1); expect(b.rules()).toEqual(["TEXT IS PUSH"]); expect(b.activeRules()).toEqual(["TEXT IS PUSH"]); expect(b.hasProperty(baba, "YOU")).toBe(false); });