Last active
October 17, 2019 06:09
-
-
Save ltriant/ad76ba19febb8a06f3bc0ed87341390b to your computer and use it in GitHub Desktop.
Conway's Game of Life in Nim
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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