Skip to content

Instantly share code, notes, and snippets.

@ltriant
Last active October 17, 2019 06:09
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 ltriant/ad76ba19febb8a06f3bc0ed87341390b to your computer and use it in GitHub Desktop.
Save ltriant/ad76ba19febb8a06f3bc0ed87341390b to your computer and use it in GitHub Desktop.
Conway's Game of Life in Nim
# Conway's Game of Life
#
# Initialises the canvas randomly
#
# nimble install sdl2
# nim c -r life.nim
from random import randomize, rand
import sdl2
const SCREEN_WIDTH = 256
const SCREEN_HEIGHT = 240
func next_step(canvas: array[SCREEN_HEIGHT, array[SCREEN_WIDTH, bool]], x: int, y: int): bool =
var on = 0
# Vertical neighbors
if y > 0 and canvas[y - 1][x]:
on += 1;
if (y < ScreenHeight - 1) and canvas[y + 1][x]:
on += 1;
# Horizontal neighbors
if x > 0 and canvas[y][x - 1]:
on += 1;
if (x < ScreenWidth - 1) and canvas[y][x + 1]:
on += 1;
# Diagonally adjacent neighbors
if x > 0 and y > 0 and canvas[y - 1][x - 1]:
on += 1;
if (x < ScreenWidth - 1) and (y < ScreenHeight - 1) and canvas[y + 1][x + 1]:
on += 1;
if x > 0 and (y < ScreenHeight - 1) and canvas[y + 1][x - 1]:
on += 1;
if (x < ScreenWidth - 1) and y > 0 and canvas[y - 1][x + 1]:
on += 1;
if canvas[y][x]:
if on == 1:
return false
elif on == 2 or on == 3:
return true
elif on == 4:
return false
elif on == 3:
return true
return false
proc main =
randomize()
var current_canvas: array[SCREEN_HEIGHT, array[SCREEN_WIDTH, bool]]
for y in 0 .. SCREEN_HEIGHT - 1:
for x in 0 .. SCREEN_WIDTH - 1:
current_canvas[y][x] = rand(1.0) < 0.5
if not sdl2.init(INIT_VIDEO):
echo "sdl2 init failed"
return
defer: sdl2.quit()
let window = sdl2.createWindow(
"Game of Life",
100,
100,
SCREEN_WIDTH * 2,
SCREEN_HEIGHT * 2,
sdl2.SDL_WINDOW_SHOWN
)
defer: window.destroy()
let surface = sdl2.getSurface(window)
var quit = false
var next_canvas: array[SCREEN_HEIGHT, array[SCREEN_WIDTH, bool]]
var event = sdl2.defaultEvent
while not quit:
while sdl2.pollEvent(event):
if event.kind == sdl2.QuitEvent:
quit = true
for y in 0 .. SCREEN_HEIGHT - 1:
for x in 0 .. SCREEN_WIDTH - 1:
let onoff = next_step(current_canvas, x, y)
next_canvas[y][x] = onoff
let rgb: uint32 = if onoff: 0x00 else: 0xff
let color = (rgb shl 24) or (rgb shl 16) or (rgb shl 8) or rgb
var rect = sdl2.rect(cint(x) * 2, cint(y) * 2, 2, 2)
sdl2.fillRect(surface, rect.addr, color)
current_canvas = next_canvas
if not sdl2.updateSurface(window):
echo "Failed to update surface"
break
sdl2.delay(100)
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment