diff options
Diffstat (limited to 'js/baba-yaga/scratch/baba/life.baba')
-rw-r--r-- | js/baba-yaga/scratch/baba/life.baba | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/js/baba-yaga/scratch/baba/life.baba b/js/baba-yaga/scratch/baba/life.baba new file mode 100644 index 0000000..a5fbe79 --- /dev/null +++ b/js/baba-yaga/scratch/baba/life.baba @@ -0,0 +1,90 @@ +// Conway's Game of Life in Baba Yaga + +// headAt: return the element at index i from list xs +headAt : xs i -> with (tmp : slice xs i (i + 1)) -> tmp.0; + +// get2: 2D index for a grid (list of lists) +get2 : grid r c -> headAt (headAt grid r) c; + +// safeGet2: bounds-checked 2D get; returns 0 when out of bounds +safeGet2 : grid r c -> + with ( + rows : length grid; + cols : length (headAt grid 0); + rOk : (r >= 0) and (r < rows); + cOk : (c >= 0) and (c < cols); + ) -> + when (rOk and cOk) is + true then get2 grid r c + _ then 0; + +// range [lo, hi) as a list of Int +range : lo hi -> + when (lo >= hi) is + true then [] + _ then prepend lo (range (lo + 1) hi); + +// sum a list of numbers +sum : xs -> reduce (acc x -> acc + x) 0 xs; + +// deltas for neighborhood offsets +deltas : [-1, 0, 1]; + +// neighborsValues: list of neighbor cell values for (r,c) +neighborsValues : grid r c -> + reduce (acc dr -> + reduce (acc2 dc -> + when ((dr = 0) and (dc = 0)) is + true then acc2 + _ then append acc2 (safeGet2 grid (r + dr) (c + dc)) + ) acc deltas + ) [] deltas; + +// count live neighbors at (r,c) +countNeighbors : grid r c -> sum (neighborsValues grid r c); + +// nextCell: apply Game of Life rules at (r,c) +nextCell : grid r c -> + with ( + cell : get2 grid r c; + n : countNeighbors grid r c; + isAlive : cell = 1; + born : (cell = 0) and (n = 3); + survive : isAlive and ((n = 2) or (n = 3)); + ) -> + when survive is + true then 1 + _ then when born is true then 1 _ then 0; + +// build next row r given width w +rowNext : grid w r -> map (c -> nextCell grid r c) (range 0 w); + +// Single simulation step for the entire grid +step : grid -> + with ( + h : length grid; + w : length (headAt grid 0); + ) -> map (r -> rowNext grid w r) (range 0 h); + +// Demo: glider pattern in a 5x5 grid +g0 : [ + [0, 1, 0, 0, 0], + [0, 0, 1, 0, 0], + [1, 1, 1, 0, 0], + [0, 0, 0, 0, 0], + [0, 0, 0, 0, 0] +]; + +g1 : step g0; +g2 : step g1; +g3 : step g2; +g4 : step g3; + +// Print successive generations +io.out g0; +io.out g1; +io.out g2; +io.out g3; +io.out g4; + + |