Skip to content

Instantly share code, notes, and snippets.

@Lucrecious
Last active February 28, 2025 17:38
Show Gist options
  • Save Lucrecious/39e73cb5c8c1b63270acc9a8635dc4d7 to your computer and use it in GitHub Desktop.
Save Lucrecious/39e73cb5c8c1b63270acc9a8635dc4d7 to your computer and use it in GitHub Desktop.
the same implementation of GoL but with generics in orso now
do:gol {
width := readint();
height := readint();
tile_count := width*height;
if tile_count == 0 {
printint(0);
println();
break:gol 1;
};
// new generics addition here...
// generic 'at' function to get address of an item
at :: (arr: &~u, i: ~v) -> &u {
// 'as' is used for casting rather than '<<'
return arr + (i as ptrdiff_t);
};
// another generic 'at' function
atxy :: (arr: &~u, x: ~v, y: v, width: v) -> &u {
return arr + (y*width + x as ptrdiff_t);
};
// generic array fill
fill :: (arr: &~u, value: u, count: ~v) -> void {
c: v = 0;
while c < count {
*at(arr, c) = value;
// added '<op>=' syntax
c += 1;
};
return;
};
// generic array maker
make_arr :: (value: ~u, count: ~v) -> &u {
arr := mreserve(sizeof(u)*(count as size_t)) as &u;
mmarkrw(arr, sizeof(u)*(count as size_t));
fill(arr, value, count);
return arr;
};
arr_free :: (arr: &~u, count: ~v) -> void {
mfree(arr, sizeof(u)*(count as size_t));
return;
};
// infers array type as 'u8', and infers the size given the expression
board := make_arr(0u8, tile_count*2);
buffer := at(board, tile_count);
// the rest is pretty much the same as the previous version but using the new inferred function semantics
printint(1);
println();
println();
initx := readint();
inity := readint();
until initx*inity == 0 {
x := initx - 1;
y := inity - 1;
if x < 0 or y < 0 or x >= width or y >= height {
printint(0);
println();
} else {
*atxy(board, x, y, width) = 1;
printint(1);
println();
};
println();
initx = readint();
inity = readint();
};
println();
render_board :: (board: &u8, width: int, height: int) -> void {
w := 0;
h := 0;
while h < height {
while w < width {
tile := *atxy(board, w, h, width) as int;
printint(tile);
w += 1;
};
w = 0;
h += 1;
println();
};
println();
return;
};
render_board(board, width, height);
neighbors :: (board: &u8, x: int, y: int, w: int, h: int) -> int {
sum := 0;
xi := 0;
yi := 0;
xs := x - 1;
ys := y - 1;
while yi < 3 {
while xi < 3 {
xn := xs + xi;
yn := ys + yi;
xi += 1;
if xn == x and yn == y then continue;
if xn < 0 or yn < 0 or xn >= w or yn >= h then continue;
sum = sum + (*atxy(board, xn, yn, w) as int);
};
xi = 0;
yi += 1;
};
return sum;
};
while readint() != 0 {
fill(buffer, 0, tile_count);
x := 0;
y := 0;
while y < height {
while x < width {
n := neighbors(board, x, y, width, height);
alive := *atxy(board, x, y, width);
// death by underpopulation
if alive > 0 and n < 2 then
*atxy(buffer, x, y, width) = 0
// lives to next generation
else if alive > 0 and (n == 2 or n == 3) then
*atxy(buffer, x, y, width) = 1
// death by overpopulation
else if alive > 0 and n > 3 then
*atxy(buffer, x, y, width) = 0
// reproduction
else if alive < 1 and n == 3 then
*atxy(buffer, x, y, width) = 1;
x += 1;
};
x = 0;
y += 1;
};
tmp := board;
board = buffer;
buffer = tmp;
render_board(board, width, height);
};
arr_free(buffer, tile_count);
arr_free(board, tile_count);
0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment