wip(0.S3): the packages migrated by ludic migrate state packages - every package test green
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
1e8b5b0523
commit
07505e7ef2
294 changed files with 14996 additions and 14675 deletions
|
|
@ -1,45 +1,45 @@
|
|||
# card.ludic - a card read off the rail: the key opens the picked chip and puts it down, the arrows
|
||||
# walk the rail with the card up, and "I know this" mutes the card being read
|
||||
export function hints_card() -> int { return hn_card }
|
||||
export function hints_card(hints_st: HintsState) -> int { return hints_st.hn_card }
|
||||
|
||||
# the key: the picked card opened, or the open one put down
|
||||
export function hints_key() -> void {
|
||||
if hn_card >= 0 {
|
||||
hints_close()
|
||||
export function hints_key(base_st: mut BaseState, hints_st: mut HintsState) -> void {
|
||||
if hints_st.hn_card >= 0 {
|
||||
hints_close(base_st, hints_st)
|
||||
return
|
||||
}
|
||||
hints_open(hn_pick)
|
||||
hints_open(base_st, hints_st, hints_st.hn_pick)
|
||||
}
|
||||
|
||||
# the k-th chip on the rail opened as a card
|
||||
export function hints_open(k: int) -> void {
|
||||
if k < 0 or k >= hn_n { return }
|
||||
hn_pick = k
|
||||
hn_card = hn_top[k]
|
||||
hn_fact(HINTS_F_OPENED, hn_card)
|
||||
export function hints_open(base_st: mut BaseState, hints_st: mut HintsState, k: int) -> void {
|
||||
if k < 0 or k >= hints_st.hn_n { return }
|
||||
hints_st.hn_pick = k
|
||||
hints_st.hn_card = hints_st.hn_top[k]
|
||||
hn_fact(base_st, hints_st, HINTS_F_OPENED, hints_st.hn_card)
|
||||
}
|
||||
|
||||
export function hints_close() -> void {
|
||||
if hn_card < 0 { return }
|
||||
let c = hn_card
|
||||
hn_card = -1
|
||||
hn_fact(HINTS_F_CLOSED, c)
|
||||
export function hints_close(base_st: mut BaseState, hints_st: mut HintsState) -> void {
|
||||
if hints_st.hn_card < 0 { return }
|
||||
let c = hints_st.hn_card
|
||||
hints_st.hn_card = -1
|
||||
hn_fact(base_st, hints_st, HINTS_F_CLOSED, c)
|
||||
}
|
||||
|
||||
# the arrows, with a card up: the next chip along (d = 1) or the one before, round the ends
|
||||
export function hints_move(d: int) -> void {
|
||||
if hn_card < 0 or hn_n <= 1 { return }
|
||||
hints_open((hn_pick + hn_n + d) % hn_n)
|
||||
export function hints_move(base_st: mut BaseState, hints_st: mut HintsState, d: int) -> void {
|
||||
if hints_st.hn_card < 0 or hints_st.hn_n <= 1 { return }
|
||||
hints_open(base_st, hints_st, (hints_st.hn_pick + hints_st.hn_n + d) % hints_st.hn_n)
|
||||
}
|
||||
|
||||
# "I know this - do not show it again": the card off the rail until the mutes are given back
|
||||
export function hints_mute_card() -> void {
|
||||
if hn_card < 0 { return }
|
||||
let c = hn_card
|
||||
hints_mute(c, true)
|
||||
hn_card = -1
|
||||
hn_t = 0.0
|
||||
hn_fact(HINTS_F_MUTED, c)
|
||||
export function hints_mute_card(base_st: mut BaseState, hints_st: mut HintsState) -> void {
|
||||
if hints_st.hn_card < 0 { return }
|
||||
let c = hints_st.hn_card
|
||||
hints_mute(hints_st, c, true)
|
||||
hints_st.hn_card = -1
|
||||
hints_st.hn_t = 0.0
|
||||
hn_fact(base_st, hints_st, HINTS_F_MUTED, c)
|
||||
}
|
||||
|
||||
# a step's words and its picture (n 1..3): the glyph's name, or the item (-1 when it is a glyph)
|
||||
|
|
|
|||
|
|
@ -1,62 +1,60 @@
|
|||
# mute.ludic - the cards a player has said they know, kept BY KEY: a card added, removed or moved in
|
||||
# the registry leaves every other mute where it was, and a key this build does not know is carried
|
||||
var hn_mute: []bool = null
|
||||
var hn_foreign: []string = null # muted keys with no card in this build, written back as read
|
||||
|
||||
function hn_mute_ensure() -> void {
|
||||
if hn_mute != null { return }
|
||||
hn_mute = new []bool
|
||||
for i in 0 .. HINT_COUNT { push(hn_mute, false) }
|
||||
hn_foreign = new []string
|
||||
function hn_mute_ensure(hints_st: mut HintsState) -> void {
|
||||
if hints_st.hn_mute != null { return }
|
||||
hints_st.hn_mute = new []bool
|
||||
for i in 0 .. HINT_COUNT { push(hints_st.hn_mute, false) }
|
||||
hints_st.hn_foreign = new []string
|
||||
}
|
||||
|
||||
export function hints_muted(id: int) -> bool {
|
||||
hn_mute_ensure()
|
||||
export function hints_muted(hints_st: mut HintsState, id: int) -> bool {
|
||||
hn_mute_ensure(hints_st)
|
||||
if id < 0 or id >= HINT_COUNT { return false }
|
||||
return hn_mute[id]
|
||||
return hints_st.hn_mute[id]
|
||||
}
|
||||
|
||||
export function hints_mute(id: int, on: bool) -> void {
|
||||
hn_mute_ensure()
|
||||
export function hints_mute(hints_st: mut HintsState, id: int, on: bool) -> void {
|
||||
hn_mute_ensure(hints_st)
|
||||
if id < 0 or id >= HINT_COUNT { return }
|
||||
hn_mute[id] = on
|
||||
hints_st.hn_mute[id] = on
|
||||
}
|
||||
|
||||
export function hints_mute_count() -> int {
|
||||
hn_mute_ensure()
|
||||
export function hints_mute_count(hints_st: mut HintsState) -> int {
|
||||
hn_mute_ensure(hints_st)
|
||||
var n = 0
|
||||
for i in 0 .. HINT_COUNT { if hn_mute[i] { n += 1 } }
|
||||
for i in 0 .. HINT_COUNT { if hints_st.hn_mute[i] { n += 1 } }
|
||||
return n
|
||||
}
|
||||
|
||||
# every muted card given back, from the next pass
|
||||
export function hints_unmute_all() -> void {
|
||||
hn_mute_ensure()
|
||||
for i in 0 .. HINT_COUNT { hn_mute[i] = false }
|
||||
hn_foreign = new []string
|
||||
hn_t = 0.0
|
||||
hn_fact(HINTS_F_UNMUTED, -1)
|
||||
export function hints_unmute_all(base_st: mut BaseState, hints_st: mut HintsState) -> void {
|
||||
hn_mute_ensure(hints_st)
|
||||
for i in 0 .. HINT_COUNT { hints_st.hn_mute[i] = false }
|
||||
hints_st.hn_foreign = new []string
|
||||
hints_st.hn_t = 0.0
|
||||
hn_fact(base_st, hints_st, HINTS_F_UNMUTED, -1)
|
||||
}
|
||||
|
||||
# the mutes as a list of keys, for wherever the game keeps the player's own choices
|
||||
export function hints_mutes_save() -> Val {
|
||||
hn_mute_ensure()
|
||||
export function hints_mutes_save(hints_st: mut HintsState) -> Val {
|
||||
hn_mute_ensure(hints_st)
|
||||
let l = Value.list()
|
||||
for i in 0 .. HINT_COUNT { if hn_mute[i] { Value.add(l, Value.str(Hints[i].key)) } }
|
||||
for i in 0 .. len(hn_foreign) { Value.add(l, Value.str(hn_foreign[i])) }
|
||||
for i in 0 .. HINT_COUNT { if hints_st.hn_mute[i] { Value.add(l, Value.str(Hints[i].key)) } }
|
||||
for i in 0 .. len(hints_st.hn_foreign) { Value.add(l, Value.str(hints_st.hn_foreign[i])) }
|
||||
return l
|
||||
}
|
||||
|
||||
# a list of keys read back; anything that is not a list is no mutes
|
||||
export function hints_mutes_load(l: Val) -> void {
|
||||
hn_mute = null
|
||||
hn_mute_ensure()
|
||||
export function hints_mutes_load(hints_st: mut HintsState, l: Val) -> void {
|
||||
hints_st.hn_mute = null
|
||||
hn_mute_ensure(hints_st)
|
||||
if l == null or Value.kind(l) != 5 { return }
|
||||
for i in 0 .. Value.count(l) {
|
||||
let e = Value.at(l, i)
|
||||
if Value.kind(e) != 4 { continue }
|
||||
let k = Value.as_str(e)
|
||||
let id = hints_find(k)
|
||||
if id >= 0 { hn_mute[id] = true } else { push(hn_foreign, k) }
|
||||
if id >= 0 { hints_st.hn_mute[id] = true } else { push(hints_st.hn_foreign, k) }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,102 +1,106 @@
|
|||
# rail.ludic - the rail: once a pass (a second by default) the most urgent true cards, up to a few,
|
||||
# muted ones left out; in a tie the registry's order decides
|
||||
var hn_shown: int = 3 # how many the rail holds
|
||||
var hn_every: float = 1.0 # seconds between passes
|
||||
var hn_top: []int = null # the cards on the rail this pass
|
||||
var hn_n: int = 0
|
||||
var hn_t: float = 0.0 # seconds to the next pass
|
||||
var hn_pick: int = 0 # which chip the key would open
|
||||
var hn_card: int = -1 # the card being read, or -1
|
||||
var hn_facts: Queue<HintsFact> = null
|
||||
|
||||
export function hints_facts() -> Queue<HintsFact> {
|
||||
if hn_facts == null { hn_facts = queue_new("hints.facts") }
|
||||
return hn_facts
|
||||
export state HintsState {
|
||||
hn_mute: []bool = null
|
||||
hn_foreign: []string = null # muted keys with no card in this build, written back as read
|
||||
hn_shown: int = 3 # how many the rail holds
|
||||
hn_every: float = 1.0 # seconds between passes
|
||||
hn_top: []int = null # the cards on the rail this pass
|
||||
hn_n: int = 0
|
||||
hn_t: float = 0.0 # seconds to the next pass
|
||||
hn_pick: int = 0 # which chip the key would open
|
||||
hn_card: int = -1 # the card being read, or -1
|
||||
hn_facts: Queue<HintsFact> = null
|
||||
}
|
||||
|
||||
function hn_fact(what: int, card: int) -> void {
|
||||
export function hints_facts(base_st: mut BaseState, hints_st: mut HintsState) -> Queue<HintsFact> {
|
||||
if hints_st.hn_facts == null { hints_st.hn_facts = queue_new(base_st, "hints.facts") }
|
||||
return hints_st.hn_facts
|
||||
}
|
||||
|
||||
function hn_fact(base_st: mut BaseState, hints_st: mut HintsState, what: int, card: int) -> void {
|
||||
let f = new HintsFact
|
||||
f.what = what
|
||||
f.card = card
|
||||
q_push(hints_facts(), f)
|
||||
q_push(base_st, hints_facts(base_st, hints_st), f)
|
||||
}
|
||||
|
||||
# how many the rail holds and how often it is sorted
|
||||
export function hints_config(shown: int, every: float) -> void {
|
||||
hn_shown = shown
|
||||
hn_every = every
|
||||
hn_top = null
|
||||
export function hints_config(hints_st: mut HintsState, shown: int, every: float) -> void {
|
||||
hints_st.hn_shown = shown
|
||||
hints_st.hn_every = every
|
||||
hints_st.hn_top = null
|
||||
}
|
||||
|
||||
function hn_ensure() -> void {
|
||||
if hn_top == null or len(hn_top) != hn_shown {
|
||||
hn_top = new []int
|
||||
for i in 0 .. hn_shown { push(hn_top, -1) }
|
||||
function hn_ensure(hints_st: mut HintsState) -> void {
|
||||
if hints_st.hn_top == null or len(hints_st.hn_top) != hints_st.hn_shown {
|
||||
hints_st.hn_top = new []int
|
||||
for i in 0 .. hints_st.hn_shown { push(hints_st.hn_top, -1) }
|
||||
}
|
||||
hn_mute_ensure()
|
||||
hn_mute_ensure(hints_st)
|
||||
}
|
||||
|
||||
# the next pass comes on the next tick rather than in a second
|
||||
export function hints_refresh() -> void { hn_t = 0.0 }
|
||||
export function hints_refresh(hints_st: mut HintsState) -> void { hints_st.hn_t = 0.0 }
|
||||
|
||||
export function hints_tick(dt: float) -> void {
|
||||
hn_ensure()
|
||||
hn_t = hn_t - dt
|
||||
if hn_t > 0.0 { return }
|
||||
hn_t = hn_every
|
||||
hints_sort()
|
||||
export function hints_tick(hints_st: mut HintsState, dt: float) -> void {
|
||||
hn_ensure(hints_st)
|
||||
hints_st.hn_t = hints_st.hn_t - dt
|
||||
if hints_st.hn_t > 0.0 { return }
|
||||
hints_st.hn_t = hints_st.hn_every
|
||||
hints_sort(hints_st)
|
||||
}
|
||||
|
||||
# one pass now: the rail re-sorted, the pick kept in range, and the card following its subject
|
||||
# along the rail - or put down when what it was about stopped being true
|
||||
export function hints_sort() -> void {
|
||||
hn_ensure()
|
||||
hn_n = 0
|
||||
export function hints_sort(hints_st: mut HintsState) -> void {
|
||||
hn_ensure(hints_st)
|
||||
hints_st.hn_n = 0
|
||||
let on = HintsWorld.showing()
|
||||
for u in 0 .. 4 {
|
||||
let want = HINTS_URGENT - u
|
||||
for id in 0 .. HINT_COUNT {
|
||||
if not on or hn_n >= hn_shown { break }
|
||||
if Hints[id].urgency != want or hints_muted(id) { continue }
|
||||
if not on or hints_st.hn_n >= hints_st.hn_shown { break }
|
||||
if Hints[id].urgency != want or hints_muted(hints_st, id) { continue }
|
||||
if not HintsWorld.true_now(id) { continue }
|
||||
hn_top[hn_n] = id
|
||||
hn_n += 1
|
||||
hints_st.hn_top[hints_st.hn_n] = id
|
||||
hints_st.hn_n += 1
|
||||
}
|
||||
}
|
||||
if hn_pick >= hn_n { hn_pick = 0 }
|
||||
if hn_card < 0 { return }
|
||||
if not on or hints_muted(hn_card) or not HintsWorld.true_now(hn_card) {
|
||||
hn_card = -1
|
||||
if hints_st.hn_pick >= hints_st.hn_n { hints_st.hn_pick = 0 }
|
||||
if hints_st.hn_card < 0 { return }
|
||||
if not on or hints_muted(hints_st, hints_st.hn_card) or not HintsWorld.true_now(hints_st.hn_card) {
|
||||
hints_st.hn_card = -1
|
||||
return
|
||||
}
|
||||
for k in 0 .. hn_n { if hn_top[k] == hn_card { hn_pick = k } }
|
||||
for k in 0 .. hints_st.hn_n { if hints_st.hn_top[k] == hints_st.hn_card { hints_st.hn_pick = k } }
|
||||
}
|
||||
|
||||
# the cards on the rail, most urgent first (empty while the rail is not showing)
|
||||
export function hints_rail() -> []int {
|
||||
hn_ensure()
|
||||
export function hints_rail(hints_st: mut HintsState) -> []int {
|
||||
hn_ensure(hints_st)
|
||||
let out = new []int
|
||||
if not HintsWorld.showing() { return out }
|
||||
for k in 0 .. hn_n { push(out, hn_top[k]) }
|
||||
for k in 0 .. hints_st.hn_n { push(out, hints_st.hn_top[k]) }
|
||||
return out
|
||||
}
|
||||
|
||||
export function hints_count() -> int { return hn_n }
|
||||
export function hints_count(hints_st: HintsState) -> int { return hints_st.hn_n }
|
||||
|
||||
export function hints_at(k: int) -> int {
|
||||
if k < 0 or k >= hn_n { return -1 }
|
||||
return hn_top[k]
|
||||
export function hints_at(hints_st: HintsState, k: int) -> int {
|
||||
if k < 0 or k >= hints_st.hn_n { return -1 }
|
||||
return hints_st.hn_top[k]
|
||||
}
|
||||
|
||||
export function hints_pick() -> int { return hn_pick }
|
||||
export function hints_pick(hints_st: HintsState) -> int { return hints_st.hn_pick }
|
||||
|
||||
export function hints_hot(k: int) -> bool { return k == hn_pick }
|
||||
export function hints_hot(hints_st: HintsState, k: int) -> bool { return k == hints_st.hn_pick }
|
||||
|
||||
export function hints_reset() -> void {
|
||||
hn_top = null
|
||||
hn_n = 0
|
||||
hn_t = 0.0
|
||||
hn_pick = 0
|
||||
hn_card = -1
|
||||
q_clear(hints_facts())
|
||||
export function hints_reset(base_st: mut BaseState, hints_st: mut HintsState) -> void {
|
||||
hints_st.hn_top = null
|
||||
hints_st.hn_n = 0
|
||||
hints_st.hn_t = 0.0
|
||||
hints_st.hn_pick = 0
|
||||
hints_st.hn_card = -1
|
||||
q_clear(base_st, hints_facts(base_st, hints_st))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# system.ludic - the rail as a system in PH_PRESENT: it only reads the world, and a trip saves
|
||||
# nothing of it (the mutes are the player's, kept wherever the game keeps its settings)
|
||||
function hn_tick(t: Tick) -> void { hints_tick(t.dt) }
|
||||
function hn_tick(hints_st: mut HintsState, t: Tick) -> void { hints_tick(hints_st, t.dt) }
|
||||
|
||||
export function hints_system() -> System {
|
||||
let s = system_new("hints", PH_PRESENT)
|
||||
|
|
|
|||
|
|
@ -11,24 +11,26 @@ program HintsTest {
|
|||
def Hints night { urgency: HINTS_TIP, line: "Night soon" }
|
||||
def Hints from "cards.lres"
|
||||
|
||||
var on: []bool = null
|
||||
var showing: bool = true
|
||||
|
||||
function fake_true(i: int) -> bool { return on[i] }
|
||||
function fake_showing() -> bool { return showing }
|
||||
bind HintsWorld { true_now: fn fake_true, showing: fn fake_showing }
|
||||
|
||||
function fresh() -> void {
|
||||
on = new []bool
|
||||
for i in 0 .. HINT_COUNT { push(on, false) }
|
||||
showing = true
|
||||
hints_config(3, 1.0)
|
||||
hints_reset()
|
||||
hints_mutes_load(Value.list())
|
||||
state HintstestState {
|
||||
on: []bool = null
|
||||
showing: bool = true
|
||||
}
|
||||
|
||||
function count(what: int) -> int {
|
||||
let fs = q_drain(hints_facts())
|
||||
function fake_true(hintstest_st: HintstestState, i: int) -> bool { return hintstest_st.on[i] }
|
||||
function fake_showing(hintstest_st: HintstestState) -> bool { return hintstest_st.showing }
|
||||
bind HintsWorld { true_now: fn fake_true, showing: fn fake_showing }
|
||||
|
||||
function fresh(base_st: mut BaseState, hints_st: mut HintsState, hintstest_st: mut HintstestState) -> void {
|
||||
hintstest_st.on = new []bool
|
||||
for i in 0 .. HINT_COUNT { push(hintstest_st.on, false) }
|
||||
hintstest_st.showing = true
|
||||
hints_config(hints_st, 3, 1.0)
|
||||
hints_reset(base_st, hints_st)
|
||||
hints_mutes_load(hints_st, Value.list())
|
||||
}
|
||||
|
||||
function count(base_st: mut BaseState, hints_st: mut HintsState, what: int) -> int {
|
||||
let fs = q_drain(base_st, hints_facts(base_st, hints_st))
|
||||
var n = 0
|
||||
for i in 0 .. len(fs) { if fs[i].what == what { n += 1 } }
|
||||
return n
|
||||
|
|
@ -44,119 +46,119 @@ program HintsTest {
|
|||
expect(hints_step_text(HINT_THIRSTY, 1) == "Drink at a shore")
|
||||
}
|
||||
|
||||
test "the most urgent true cards, capped, ties in registry order" {
|
||||
fresh()
|
||||
for i in 0 .. HINT_COUNT { on[i] = true }
|
||||
hints_tick(1.0)
|
||||
expect_eq(hints_count(), 3)
|
||||
expect_eq(hints_at(0), HINT_PARCHED)
|
||||
expect_eq(hints_at(1), HINT_BEAR)
|
||||
expect_eq(hints_at(2), HINT_COLD)
|
||||
on[HINT_PARCHED] = false
|
||||
on[HINT_BEAR] = false
|
||||
hints_tick(0.5)
|
||||
expect_eq(hints_at(0), HINT_PARCHED) # not a second yet: the rail holds
|
||||
hints_tick(0.6)
|
||||
expect_eq(hints_at(0), HINT_COLD)
|
||||
expect_eq(hints_at(1), HINT_THIRSTY)
|
||||
expect_eq(hints_at(2), HINT_FIRE)
|
||||
test "the most urgent true cards, capped, ties in registry order" (base_st: mut BaseState, hints_st: mut HintsState, hintstest_st: mut HintstestState) {
|
||||
fresh(base_st, hints_st, hintstest_st)
|
||||
for i in 0 .. HINT_COUNT { hintstest_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)
|
||||
hintstest_st.on[HINT_PARCHED] = false
|
||||
hintstest_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" {
|
||||
fresh()
|
||||
on[HINT_COLD] = true
|
||||
showing = false
|
||||
hints_sort()
|
||||
expect_eq(len(hints_rail()), 0)
|
||||
expect_eq(hints_count(), 0)
|
||||
showing = true
|
||||
hints_sort()
|
||||
expect_eq(len(hints_rail()), 1)
|
||||
test "nothing on the rail while it is not showing" (base_st: mut BaseState, hints_st: mut HintsState, hintstest_st: mut HintstestState) {
|
||||
fresh(base_st, hints_st, hintstest_st)
|
||||
hintstest_st.on[HINT_COLD] = true
|
||||
hintstest_st.showing = false
|
||||
hints_sort(hints_st)
|
||||
expect_eq(len(hints_rail(hints_st)), 0)
|
||||
expect_eq(hints_count(hints_st), 0)
|
||||
hintstest_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" {
|
||||
fresh()
|
||||
on[HINT_COLD] = true
|
||||
on[HINT_THIRSTY] = true
|
||||
on[HINT_RAIN] = true
|
||||
hints_sort()
|
||||
hints_key()
|
||||
expect_eq(hints_card(), HINT_COLD)
|
||||
hints_move(1)
|
||||
expect_eq(hints_card(), HINT_THIRSTY)
|
||||
expect(hints_hot(1))
|
||||
hints_move(-1)
|
||||
hints_move(-1)
|
||||
expect_eq(hints_card(), HINT_RAIN)
|
||||
hints_key()
|
||||
expect_eq(hints_card(), -1)
|
||||
expect_eq(count(HINTS_F_OPENED), 4)
|
||||
test "the key opens the picked chip, the arrows walk round, the key puts it down" (base_st: mut BaseState, hints_st: mut HintsState, hintstest_st: mut HintstestState) {
|
||||
fresh(base_st, hints_st, hintstest_st)
|
||||
hintstest_st.on[HINT_COLD] = true
|
||||
hintstest_st.on[HINT_THIRSTY] = true
|
||||
hintstest_st.on[HINT_RAIN] = true
|
||||
hints_sort(hints_st)
|
||||
hints_key(base_st, hints_st)
|
||||
expect_eq(hints_card(hints_st), HINT_COLD)
|
||||
hints_move(base_st, hints_st, 1)
|
||||
expect_eq(hints_card(hints_st), HINT_THIRSTY)
|
||||
expect(hints_hot(hints_st, 1))
|
||||
hints_move(base_st, hints_st, -1)
|
||||
hints_move(base_st, hints_st, -1)
|
||||
expect_eq(hints_card(hints_st), HINT_RAIN)
|
||||
hints_key(base_st, hints_st)
|
||||
expect_eq(hints_card(hints_st), -1)
|
||||
expect_eq(count(base_st, 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" {
|
||||
fresh()
|
||||
on[HINT_THIRSTY] = true
|
||||
on[HINT_RAIN] = true
|
||||
hints_sort()
|
||||
hints_open(1)
|
||||
expect_eq(hints_card(), HINT_RAIN)
|
||||
on[HINT_COLD] = true
|
||||
hints_sort()
|
||||
expect_eq(hints_card(), HINT_RAIN)
|
||||
expect_eq(hints_pick(), 2)
|
||||
on[HINT_RAIN] = false
|
||||
hints_sort()
|
||||
expect_eq(hints_card(), -1)
|
||||
expect_eq(count(HINTS_F_CLOSED), 0) # it went; nobody put it down
|
||||
test "the card follows its subject as the rail re-sorts, and goes when it is no longer true" (base_st: mut BaseState, hints_st: mut HintsState, hintstest_st: mut HintstestState) {
|
||||
fresh(base_st, hints_st, hintstest_st)
|
||||
hintstest_st.on[HINT_THIRSTY] = true
|
||||
hintstest_st.on[HINT_RAIN] = true
|
||||
hints_sort(hints_st)
|
||||
hints_open(base_st, hints_st, 1)
|
||||
expect_eq(hints_card(hints_st), HINT_RAIN)
|
||||
hintstest_st.on[HINT_COLD] = true
|
||||
hints_sort(hints_st)
|
||||
expect_eq(hints_card(hints_st), HINT_RAIN)
|
||||
expect_eq(hints_pick(hints_st), 2)
|
||||
hintstest_st.on[HINT_RAIN] = false
|
||||
hints_sort(hints_st)
|
||||
expect_eq(hints_card(hints_st), -1)
|
||||
expect_eq(count(base_st, hints_st, HINTS_F_CLOSED), 0) # it went; nobody put it down
|
||||
}
|
||||
|
||||
test "I know this: muted off the rail, counted, given back" {
|
||||
fresh()
|
||||
on[HINT_COLD] = true
|
||||
on[HINT_THIRSTY] = true
|
||||
hints_sort()
|
||||
hints_key()
|
||||
hints_mute_card()
|
||||
expect_eq(hints_card(), -1)
|
||||
expect(hints_muted(HINT_COLD))
|
||||
expect_eq(hints_mute_count(), 1)
|
||||
expect_eq(count(HINTS_F_MUTED), 1)
|
||||
hints_tick(0.0) # the next pass comes at once
|
||||
expect_eq(hints_at(0), HINT_THIRSTY)
|
||||
expect_eq(hints_count(), 1)
|
||||
hints_unmute_all()
|
||||
hints_tick(0.0)
|
||||
expect_eq(hints_at(0), HINT_COLD)
|
||||
expect_eq(count(HINTS_F_UNMUTED), 1)
|
||||
test "I know this: muted off the rail, counted, given back" (base_st: mut BaseState, hints_st: mut HintsState, hintstest_st: mut HintstestState) {
|
||||
fresh(base_st, hints_st, hintstest_st)
|
||||
hintstest_st.on[HINT_COLD] = true
|
||||
hintstest_st.on[HINT_THIRSTY] = true
|
||||
hints_sort(hints_st)
|
||||
hints_key(base_st, hints_st)
|
||||
hints_mute_card(base_st, 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(base_st, 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(base_st, hints_st)
|
||||
hints_tick(hints_st, 0.0)
|
||||
expect_eq(hints_at(hints_st, 0), HINT_COLD)
|
||||
expect_eq(count(base_st, hints_st, HINTS_F_UNMUTED), 1)
|
||||
}
|
||||
|
||||
test "mutes are kept by key, and a key this build lacks is carried through" {
|
||||
fresh()
|
||||
hints_mute(HINT_NIGHT, true)
|
||||
hints_mute(HINT_BEAR, true)
|
||||
let l = hints_mutes_save()
|
||||
test "mutes are kept by key, and a key this build lacks is carried through" (base_st: mut BaseState, hints_st: mut HintsState, hintstest_st: mut HintstestState) {
|
||||
fresh(base_st, hints_st, hintstest_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(l)
|
||||
expect(hints_muted(HINT_NIGHT))
|
||||
expect(hints_muted(HINT_BEAR))
|
||||
expect(not hints_muted(HINT_RAIN))
|
||||
expect_eq(hints_mute_count(), 2)
|
||||
let back = hints_mutes_save()
|
||||
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(null)
|
||||
expect_eq(hints_mute_count(), 0)
|
||||
hints_mutes_load(hints_st, null)
|
||||
expect_eq(hints_mute_count(hints_st), 0)
|
||||
}
|
||||
|
||||
test "as a system it ticks the rail" {
|
||||
fresh()
|
||||
core_clear()
|
||||
core_add(hints_system())
|
||||
core_reset_all()
|
||||
on[HINT_FIRE] = true
|
||||
core_tick_all(tick_new(1.0, 1, 0.0))
|
||||
expect_eq(hints_at(0), HINT_FIRE)
|
||||
test "as a system it ticks the rail" (base_st: mut BaseState, hints_st: mut HintsState, hintstest_st: mut HintstestState) {
|
||||
fresh(base_st, hints_st, hintstest_st)
|
||||
core_clear(base_st)
|
||||
core_add(base_st, hints_system())
|
||||
core_reset_all(base_st)
|
||||
hintstest_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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue