Last active
February 28, 2025 17:38
-
-
Save Lucrecious/39e73cb5c8c1b63270acc9a8635dc4d7 to your computer and use it in GitHub Desktop.
the same implementation of GoL but with generics in orso now
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
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