Skip to content

Instantly share code, notes, and snippets.

@sflanker
Last active September 30, 2020 00:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sflanker/e76015959a85e3e42b887e8946efc0fa to your computer and use it in GitHub Desktop.
Save sflanker/e76015959a85e3e42b887e8946efc0fa to your computer and use it in GitHub Desktop.
Conway's Game of Life in Lizpy for SR2
(program "conway"
(comment "This is an implementation of conway's game of life for a 32x32 toroidal grid.")
(comment "For more information about Lizpy see: https://github.com/sflanker/lizpy/")
(declarel part_ids)
(declarel game_state_a)
(declarel game_state_b)
(declarel last_frame)
(declare render_a)
(declare prev_state)
(declare next_state)
(declare frame_num)
(declare row_ix)
(declare col_ix)
(declare n_row)
(declare n_col)
(declare n_count)
(declare ix)
(declare is_live)
(on-start
(set! render_a true)
(for 1 32 1
(set! row_ix i)
(for 1 32 1
(list/add! part_ids (craft/part-id (format "pixel_{0:f0}_{1:f0}" row_ix i)))
(list/add! game_state_a (if (> (rand 0 1) 0.5) true false))
(list/add! game_state_b false))
(list/add! last_frame 0)
(broadcast! "init-renderer" row_ix))
(set! prev_state game_state_a)
(set! next_state game_state_b)
(set! frame_num 1)
(while true
;; Todo: multithread? painful without local variables.
(comment "Update the state of all cells.")
(for 1 32 1
(set! row_ix i)
(for 1 32 1
(set! col_ix i)
;; Todo: optimize by keeping some kind of running count as we traverse each row?
(comment "Count living neighbors")
(set! n_count 0)
(for (- row_ix 1) (+ row_ix 1) 1
(set! n_row (if (< i 1) 32 (if (> i 32) 1 i)))
(for (- col_ix 1) (+ col_ix 1) 1
(set! n_col (if (< i 1) 32 (if (> i 32) 1 i)))
(if (and (or (!= row_ix n_row) (!= col_ix n_col))
(list/get-item prev_state (+ (* (- n_row 1) 32) n_col)))
(set! n_count (+ n_count 1)))))
(comment "Update the square status")
(set! ix (+ (* (- row_ix 1) 32) col_ix))
(set! is_live (list/get-item prev_state ix))
(if is_live
(if (and (<= 2 n_count) (<= n_count 3))
(list/set-at! next_state ix true)
(list/set-at! next_state ix false))
(if (= n_count 3)
(list/set-at! next_state ix true)
(list/set-at! next_state ix false)))
)
)
(comment "Swap buffers and trigger the next render pass")
(if render_a
(do
(set! render_a false)
(set! prev_state game_state_b)
(set! next_state game_state_a))
(do
(set! render_a true)
(set! prev_state game_state_a)
(set! next_state game_state_b)))
(set! frame_num (+ frame_num 1))
)
)
(on-message-received "init-renderer"
(while true
;; Wait until we're signaled to refresh the screen
(wait-until (> frame_num (list/get-item last_frame data)))
(list/set-at! last_frame data frame_num)
(for (+ (* (- data 1) 32) 1) (+ (* (- data 1) 32) 32) 1
(craft/set-part-property!
:Activated
(list/get-item part_ids i)
(list/get-item prev_state i)))))
(do
(comment "a log instruction that can be helpful for debugging. \"i\" and \"data\" need to be replaced with local variables")
(console/log (format "{0:0}.{1:0} ({2}) - {3}" "data" "i" (list/get-item part_ids "i") (list/get-item prev_state "i"))))
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment