ludic/packages/ludic.steps/arc.ludic
Orkuncakilkaya 19fcf60599 wip(0.S3): packages and examples migrated again from their pre-0.S sources in one run
ludic migrate state packages <every example program> packages/ludic.lab/example/plate.ludic
  1804 vars into 126 states, 64 into lets; 23498 edits in 460 files

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 15:31:34 +03:00

78 lines
3.6 KiB
Text

# arc.ludic - an arc is a table of chapters, each a table of up to STEPS_PER_CHAPTER steps. The
# game builds one with steps_chapter_add / steps_add; what a chapter is called is the game's.
# empty the tables for another arc (the progress goes back to the first chapter)
export function steps_arc_clear(steps_st: mut StepsState) -> void {
steps_st.steps__n = new []int
steps_st.steps__kind = new []int
steps_st.steps__param = new []int
steps_st.steps__need = new []int
steps_st.steps__cur = 0
steps_st.steps__done = 0
}
function steps__ready(steps_st: mut StepsState) -> void { if steps_st.steps__n == null { steps_arc_clear(steps_st) } }
# open the next chapter; its number
export function steps_chapter_add(steps_st: mut StepsState) -> int {
steps__ready(steps_st)
push(steps_st.steps__n, 0)
for i in 0 .. STEPS_PER_CHAPTER {
push(steps_st.steps__kind, -1)
push(steps_st.steps__param, 0)
push(steps_st.steps__need, 0)
}
return len(steps_st.steps__n) - 1
}
# a step in the chapter just opened; false when there is no chapter or it is full
export function steps_add(steps_st: mut StepsState, kind: int, param: int, need: int) -> bool {
steps__ready(steps_st)
let c = len(steps_st.steps__n) - 1
if c < 0 or steps_st.steps__n[c] >= STEPS_PER_CHAPTER { return false }
let k = c * STEPS_PER_CHAPTER + steps_st.steps__n[c]
steps_st.steps__kind[k] = kind
steps_st.steps__param[k] = param
steps_st.steps__need[k] = need
steps_st.steps__n[c] += 1
return true
}
export function steps_count(steps_st: StepsState) -> int {
if steps_st.steps__n == null { return 0 }
return len(steps_st.steps__n)
}
export function steps_in(steps_st: StepsState, ch: int) -> int {
if ch < 0 or ch >= steps_count(steps_st) { return 0 }
return steps_st.steps__n[ch]
}
# a step by its flat index, ch * STEPS_PER_CHAPTER + i (-1, 0, 0 past the table)
export function steps_kind_at(steps_st: StepsState, k: int) -> int {
if steps_st.steps__kind == null or k < 0 or k >= len(steps_st.steps__kind) { return -1 }
return steps_st.steps__kind[k]
}
export function steps_param_at(steps_st: StepsState, k: int) -> int {
if steps_st.steps__param == null or k < 0 or k >= len(steps_st.steps__param) { return 0 }
return steps_st.steps__param[k]
}
export function steps_need_at(steps_st: StepsState, k: int) -> int {
if steps_st.steps__need == null or k < 0 or k >= len(steps_st.steps__need) { return 0 }
return steps_st.steps__need[k]
}
export function steps_kind(steps_st: StepsState, ch: int, i: int) -> int { return steps_kind_at(steps_st, ch * STEPS_PER_CHAPTER + i) }
export function steps_param(steps_st: StepsState, ch: int, i: int) -> int { return steps_param_at(steps_st, ch * STEPS_PER_CHAPTER + i) }
export function steps_need(steps_st: StepsState, ch: int, i: int) -> int { return steps_need_at(steps_st, ch * STEPS_PER_CHAPTER + i) }
# the chapter being played, and which of its steps are done (sticky)
export function steps_current(steps_st: StepsState) -> int { return steps_st.steps__cur }
export function steps_done_mask(steps_st: StepsState) -> int { return steps_st.steps__done }
export function steps_done(steps_st: StepsState, i: int) -> bool { return (steps_st.steps__done & (1 << i)) != 0 }
export function steps_finished(steps_st: StepsState) -> bool { return steps_st.steps__cur >= steps_count(steps_st) }
# the progress outright: a load, the host's word, a test
export function steps_set_current(steps_st: mut StepsState, ch: int) -> void { steps_st.steps__cur = ch }
export function steps_set_done(steps_st: mut StepsState, mask: int) -> void { steps_st.steps__done = mask }