# hints_test.ludic - the rail sorted by urgency and capped, ties in registry order, the card walked # along it and put down when it stops being true, muting by key across a save, cards from a file import "ludic.hints" import "ludic.base" program HintsTest { numbers float def Hints thirsty { urgency: HINTS_NOTE, line: "Thirsty - drink", title: "Water", s1: "Drink at a shore", pic1: "water", item2: 7 } def Hints parched { urgency: HINTS_URGENT, line: "You must drink now", title: "Water, now" } def Hints rain { urgency: HINTS_TIP, line: "Rain coming" } def Hints cold { urgency: HINTS_WARN, line: "Cold" } def Hints night { urgency: HINTS_TIP, line: "Night soon" } def Hints from "cards.lres" state HintsTestState { on: []bool = null showing: bool = true } function fake_true(hints_test_st: HintsTestState, i: int) -> bool { return hints_test_st.on[i] } function fake_showing(hints_test_st: HintsTestState) -> bool { return hints_test_st.showing } bind HintsWorld { true_now: fn fake_true, showing: fn fake_showing } function fresh(hints_st: mut HintsState, hints_test_st: mut HintsTestState) -> void { hints_test_st.on = new []bool for i in 0 .. HINT_COUNT { push(hints_test_st.on, false) } hints_test_st.showing = true hints_config(hints_st, 3, 1.0) hints_reset(hints_st) hints_mutes_load(hints_st, Value.list()) } function count(hints_st: mut HintsState, what: int) -> int { let fs = q_drain(hints_facts(hints_st)) var n = 0 for i in 0 .. len(fs) { if fs[i].what == what { n += 1 } } return n } test "the registry is the game's, and a file adds to it" { expect_eq(HINT_COUNT, 7) expect_eq(hints_find("parched"), HINT_PARCHED) expect_eq(Hints[HINT_BEAR].urgency, HINTS_URGENT) expect(Hints[HINT_FIRE].later == "Carry three logs.") expect(hints_step_icon(HINT_THIRSTY, 1) == "water") expect_eq(hints_step_item(HINT_THIRSTY, 2), 7) expect(hints_step_text(HINT_THIRSTY, 1) == "Drink at a shore") } test "the most urgent true cards, capped, ties in registry order" (hints_st: mut HintsState, hints_test_st: mut HintsTestState) { fresh(hints_st, hints_test_st) for i in 0 .. HINT_COUNT { hints_test_st.on[i] = true } hints_tick(hints_st, 1.0) expect_eq(hints_count(hints_st), 3) expect_eq(hints_at(hints_st, 0), HINT_PARCHED) expect_eq(hints_at(hints_st, 1), HINT_BEAR) expect_eq(hints_at(hints_st, 2), HINT_COLD) hints_test_st.on[HINT_PARCHED] = false hints_test_st.on[HINT_BEAR] = false hints_tick(hints_st, 0.5) expect_eq(hints_at(hints_st, 0), HINT_PARCHED) # not a second yet: the rail holds hints_tick(hints_st, 0.6) expect_eq(hints_at(hints_st, 0), HINT_COLD) expect_eq(hints_at(hints_st, 1), HINT_THIRSTY) expect_eq(hints_at(hints_st, 2), HINT_FIRE) } test "nothing on the rail while it is not showing" (hints_st: mut HintsState, hints_test_st: mut HintsTestState) { fresh(hints_st, hints_test_st) hints_test_st.on[HINT_COLD] = true hints_test_st.showing = false hints_sort(hints_st) expect_eq(len(hints_rail(hints_st)), 0) expect_eq(hints_count(hints_st), 0) hints_test_st.showing = true hints_sort(hints_st) expect_eq(len(hints_rail(hints_st)), 1) } test "the key opens the picked chip, the arrows walk round, the key puts it down" (hints_st: mut HintsState, hints_test_st: mut HintsTestState) { fresh(hints_st, hints_test_st) hints_test_st.on[HINT_COLD] = true hints_test_st.on[HINT_THIRSTY] = true hints_test_st.on[HINT_RAIN] = true hints_sort(hints_st) hints_key(hints_st) expect_eq(hints_card(hints_st), HINT_COLD) hints_move(hints_st, 1) expect_eq(hints_card(hints_st), HINT_THIRSTY) expect(hints_hot(hints_st, 1)) hints_move(hints_st, -1) hints_move(hints_st, -1) expect_eq(hints_card(hints_st), HINT_RAIN) hints_key(hints_st) expect_eq(hints_card(hints_st), -1) expect_eq(count(hints_st, HINTS_F_OPENED), 4) } test "the card follows its subject as the rail re-sorts, and goes when it is no longer true" (hints_st: mut HintsState, hints_test_st: mut HintsTestState) { fresh(hints_st, hints_test_st) hints_test_st.on[HINT_THIRSTY] = true hints_test_st.on[HINT_RAIN] = true hints_sort(hints_st) hints_open(hints_st, 1) expect_eq(hints_card(hints_st), HINT_RAIN) hints_test_st.on[HINT_COLD] = true hints_sort(hints_st) expect_eq(hints_card(hints_st), HINT_RAIN) expect_eq(hints_pick(hints_st), 2) hints_test_st.on[HINT_RAIN] = false hints_sort(hints_st) expect_eq(hints_card(hints_st), -1) expect_eq(count(hints_st, HINTS_F_CLOSED), 0) # it went; nobody put it down } test "I know this: muted off the rail, counted, given back" (hints_st: mut HintsState, hints_test_st: mut HintsTestState) { fresh(hints_st, hints_test_st) hints_test_st.on[HINT_COLD] = true hints_test_st.on[HINT_THIRSTY] = true hints_sort(hints_st) hints_key(hints_st) hints_mute_card(hints_st) expect_eq(hints_card(hints_st), -1) expect(hints_muted(hints_st, HINT_COLD)) expect_eq(hints_mute_count(hints_st), 1) expect_eq(count(hints_st, HINTS_F_MUTED), 1) hints_tick(hints_st, 0.0) # the next pass comes at once expect_eq(hints_at(hints_st, 0), HINT_THIRSTY) expect_eq(hints_count(hints_st), 1) hints_unmute_all(hints_st) hints_tick(hints_st, 0.0) expect_eq(hints_at(hints_st, 0), HINT_COLD) expect_eq(count(hints_st, HINTS_F_UNMUTED), 1) } test "mutes are kept by key, and a key this build lacks is carried through" (hints_st: mut HintsState, hints_test_st: mut HintsTestState) { fresh(hints_st, hints_test_st) hints_mute(hints_st, HINT_NIGHT, true) hints_mute(hints_st, HINT_BEAR, true) let l = hints_mutes_save(hints_st) expect_eq(Value.count(l), 2) Value.add(l, Value.str("gone_card")) Value.add(l, Value.int(3)) # not a key: ignored hints_mutes_load(hints_st, l) expect(hints_muted(hints_st, HINT_NIGHT)) expect(hints_muted(hints_st, HINT_BEAR)) expect(not hints_muted(hints_st, HINT_RAIN)) expect_eq(hints_mute_count(hints_st), 2) let back = hints_mutes_save(hints_st) expect_eq(Value.count(back), 3) expect(Value.as_str(Value.at(back, 2)) == "gone_card") hints_mutes_load(hints_st, null) expect_eq(hints_mute_count(hints_st), 0) } test "as a system it ticks the rail" (base_st: mut BaseState, hints_st: mut HintsState, hints_test_st: mut HintsTestState) { fresh(hints_st, hints_test_st) core_clear(base_st) core_add(base_st, hints_system()) core_reset_all(base_st) hints_test_st.on[HINT_FIRE] = true core_tick_all(base_st, tick_new(1.0, 1, 0.0)) expect_eq(hints_at(hints_st, 0), HINT_FIRE) } }