# crafting_test.ludic - a recipe made from a fake pack: the makings, the station's say, room for # the result, what water leaves behind, a station that refuses, the hold, and the facts import "ludic.crafting" import "ludic.base" program CraftingTest { numbers float const WOOD: int = 0 const CLOTH: int = 1 const TORCH: int = 2 const ROPE: int = 3 const WATER: int = 4 const BOTTLE: int = 5 const TEA: int = 6 const HERB: int = 7 const BENCH: int = 1 const POT: int = 2 def CraftRecipes torch { out: TORCH, ins: [WOOD, CLOTH], ns: [1, 1] } def CraftRecipes rope { out: ROPE, n: 2, ins: [HERB], ns: [4], hold: 2.0 } def CraftRecipes tea { out: TEA, ins: [HERB, WATER], ns: [2, 1], station: POT, minutes: 8 } def CraftRecipes chair { out: TORCH, ins: [WOOD], ns: [3], station: BENCH } def CraftRecipes secret { out: TORCH, ins: [WOOD], ns: [1], learned: false } state CraftingTestState { pack: []int = null bench_near: bool = true pot_takes: bool = true pot_got: int = -1 } function count(crafting_test_st: CraftingTestState, it: int) -> int { return crafting_test_st.pack[it] } function take(crafting_test_st: mut CraftingTestState, it: int, n: int) -> bool { if crafting_test_st.pack[it] < n { return false } crafting_test_st.pack[it] = crafting_test_st.pack[it] - n return true } function add(crafting_test_st: mut CraftingTestState, it: int, n: int) -> int { crafting_test_st.pack[it] = crafting_test_st.pack[it] + n return n } function room(crafting_test_st: CraftingTestState, it: int) -> int { if it == TORCH { return 3 - crafting_test_st.pack[it] } return 99 } function leaves(it: int) -> int { if it == WATER { return BOTTLE } return -1 } function ready(crafting_test_st: CraftingTestState, st: int) -> bool { if st == BENCH { return crafting_test_st.bench_near } return true } function start(crafting_test_st: mut CraftingTestState, st: int, recipe: int) -> bool { if not crafting_test_st.pot_takes { return false } crafting_test_st.pot_got = recipe return true } bind CraftPack { count: fn count, take: fn take, add: fn add, room: fn room, leaves: fn leaves } bind CraftStations { ready: fn ready, start: fn start } function fresh(crafting_st: mut CraftingState, crafting_test_st: mut CraftingTestState) -> void { crafting_test_st.pack = new []int for i in 0 .. 8 { push(crafting_test_st.pack, 0) } craft_reset(crafting_st) } function facts(crafting_st: CraftingState) -> []Crafted { return q_drain(craft_facts(crafting_st)) } test "the registry is the game's, in the order written" { expect_eq(CRAFT_COUNT, 5) expect_eq(CRAFT_TEA, 2) expect_eq(craft_find(ROPE), CRAFT_ROPE) expect_eq(craft_by_key("chair"), CRAFT_CHAIR) expect_eq(craft_inputs(CRAFT_TEA), 2) expect_eq(craft_find(99), -1) } test "made at once from the makings, and said" (crafting_st: mut CraftingState, crafting_test_st: mut CraftingTestState) { fresh(crafting_st, crafting_test_st) expect(not craft_can(CRAFT_TORCH)) crafting_test_st.pack[WOOD] = 2 crafting_test_st.pack[CLOTH] = 1 expect(craft_make(crafting_st, CRAFT_TORCH)) expect_eq(crafting_test_st.pack[WOOD], 1) expect_eq(crafting_test_st.pack[CLOTH], 0) expect_eq(crafting_test_st.pack[TORCH], 1) let fs = facts(crafting_st) expect_eq(len(fs), 1) expect_eq(fs[0].item, TORCH) expect(not fs[0].queued) } test "nothing is taken when it cannot be made" (crafting_st: mut CraftingState, crafting_test_st: mut CraftingTestState) { fresh(crafting_st, crafting_test_st) crafting_test_st.pack[WOOD] = 1 expect(not craft_make(crafting_st, CRAFT_TORCH)) expect_eq(crafting_test_st.pack[WOOD], 1) expect_eq(len(facts(crafting_st)), 0) } test "the station decides, and so does the room for what it makes" (crafting_st: mut CraftingState, crafting_test_st: mut CraftingTestState) { fresh(crafting_st, crafting_test_st) crafting_test_st.pack[WOOD] = 9 crafting_test_st.bench_near = false expect(craft_has(CRAFT_CHAIR)) expect(not craft_can(CRAFT_CHAIR)) crafting_test_st.bench_near = true expect(craft_can(CRAFT_CHAIR)) crafting_test_st.pack[TORCH] = 3 expect(not craft_can(CRAFT_CHAIR)) } test "an unlearned recipe is never made" (crafting_st: mut CraftingState, crafting_test_st: mut CraftingTestState) { fresh(crafting_st, crafting_test_st) crafting_test_st.pack[WOOD] = 5 expect(not craft_can(CRAFT_SECRET)) } test "a timed recipe goes into its station, and water leaves its bottle" (crafting_st: mut CraftingState, crafting_test_st: mut CraftingTestState) { fresh(crafting_st, crafting_test_st) crafting_test_st.pack[HERB] = 2 crafting_test_st.pack[WATER] = 1 expect(craft_make(crafting_st, CRAFT_TEA)) expect_eq(crafting_test_st.pot_got, CRAFT_TEA) expect_eq(crafting_test_st.pack[TEA], 0) expect_eq(crafting_test_st.pack[WATER], 0) expect_eq(crafting_test_st.pack[BOTTLE], 1) let fs = facts(crafting_st) expect(fs[0].queued) expect_eq(fs[0].station, POT) } test "a station that says no gives everything back" (crafting_st: mut CraftingState, crafting_test_st: mut CraftingTestState) { fresh(crafting_st, crafting_test_st) crafting_test_st.pot_takes = false crafting_test_st.pack[HERB] = 2 crafting_test_st.pack[WATER] = 1 expect(not craft_make(crafting_st, CRAFT_TEA)) expect_eq(crafting_test_st.pack[HERB], 2) expect_eq(crafting_test_st.pack[WATER], 1) expect_eq(crafting_test_st.pack[BOTTLE], 0) expect_eq(len(facts(crafting_st)), 0) } test "a hold makes it after its seconds, and not before" (crafting_st: mut CraftingState, crafting_test_st: mut CraftingTestState) { fresh(crafting_st, crafting_test_st) crafting_test_st.pack[HERB] = 4 expect(craft_holds(CRAFT_ROPE)) expect(not craft_holds(CRAFT_TORCH)) expect(craft_hold_start(crafting_st, CRAFT_ROPE)) expect(not craft_hold_run(crafting_st, 1.0)) expect(craft_hold_frac(crafting_st, CRAFT_ROPE) == 0.5) expect(not craft_hold_run(crafting_st, 0.9)) expect(craft_hold_run(crafting_st, 0.2)) expect_eq(crafting_test_st.pack[ROPE], 2) expect_eq(craft_holding(crafting_st), -1) } test "letting go wastes nothing, and losing the makings stops the hold" (crafting_st: mut CraftingState, crafting_test_st: mut CraftingTestState) { fresh(crafting_st, crafting_test_st) crafting_test_st.pack[HERB] = 4 craft_hold_start(crafting_st, CRAFT_ROPE) craft_hold_run(crafting_st, 1.5) craft_hold_stop(crafting_st) expect_eq(crafting_test_st.pack[HERB], 4) craft_hold_start(crafting_st, CRAFT_ROPE) crafting_test_st.pack[HERB] = 3 expect(not craft_hold_run(crafting_st, 5.0)) expect_eq(craft_holding(crafting_st), -1) expect_eq(crafting_test_st.pack[ROPE], 0) } test "a click recipe cannot be held" (crafting_st: mut CraftingState, crafting_test_st: mut CraftingTestState) { fresh(crafting_st, crafting_test_st) crafting_test_st.pack[WOOD] = 1 crafting_test_st.pack[CLOTH] = 1 expect(not craft_hold_start(crafting_st, CRAFT_TORCH)) } }