// Conway's Game of Life in Baba Yaga // Clean, working implementation // Get element at index from list (with bounds checking) at : xs i -> when (i >= 0 and i < length xs) is true then slice xs i (i + 1).0 _ then 0; // Get 2D element from grid get2d : grid row col -> when (row >= 0 and row < length grid) is true then at (at grid row) col _ then 0; // Create range of integers [start, end) range : start end -> when (start >= end) is true then [] _ then prepend start (range (start + 1) end); // Sum a list of numbers sum : xs -> reduce (acc x -> acc + x) 0 xs; // Count living neighbors around position (row, col) countNeighbors : grid row col -> with ( // Get all 8 neighbor positions neighbors : [ get2d grid (row - 1) (col - 1), get2d grid (row - 1) col, get2d grid (row - 1) (col + 1), get2d grid row (col - 1), get2d grid row (col + 1), get2d grid (row + 1) (col - 1), get2d grid (row + 1) col, get2d grid (row + 1) (col + 1) ]; ) -> sum neighbors; // Apply Game of Life rules to a single cell nextCellState : grid row col -> with ( current : get2d grid row col; neighbors : countNeighbors grid row col; isAlive : current = 1; ) -> when isAlive is true then when (neighbors = 2 or neighbors = 3) is true then 1 _ then 0 _ then when (neighbors = 3) is true then 1 _ then 0; // Generate next row for the grid nextRow : grid rowIndex width -> map (col -> nextCellState grid rowIndex col) (range 0 width); // Generate next generation of the entire grid nextGeneration : grid -> with ( height : length grid; width : length (at grid 0); ) -> map (row -> nextRow grid row width) (range 0 height); // Pretty print a grid printGrid : grid title -> with ( printRow : row -> io.out (map (cell -> when cell is 1 then "#" _ then ".") row); ) -> with ( _ : io.out ""; _ : io.out title; _ : io.out (map (_ -> "-") (range 0 20)); _ : map printRow grid; _ : io.out ""; ) -> grid; // Test patterns // Glider pattern (moves diagonally) glider : [ [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] ]; // Blinker pattern (oscillates) blinker : [ [0, 0, 0], [1, 1, 1], [0, 0, 0] ]; // Block pattern (still life) block : [ [1, 1], [1, 1] ]; // Run simulations io.out "Conway's Game of Life in Baba Yaga"; io.out "===================================="; // Glider evolution g0 : printGrid glider "Glider - Generation 0"; g1 : printGrid (nextGeneration g0) "Glider - Generation 1"; g2 : printGrid (nextGeneration g1) "Glider - Generation 2"; g3 : printGrid (nextGeneration g2) "Glider - Generation 3"; g4 : printGrid (nextGeneration g3) "Glider - Generation 4"; // Blinker oscillation b0 : printGrid blinker "Blinker - Generation 0"; b1 : printGrid (nextGeneration b0) "Blinker - Generation 1"; b2 : printGrid (nextGeneration b1) "Blinker - Generation 2"; // Block (should stay the same) bl0 : printGrid block "Block - Generation 0"; bl1 : printGrid (nextGeneration bl0) "Block - Generation 1"; io.out "Simulation complete!";