Last active
January 24, 2021 09:32
-
-
Save rexim/36f09ab6913ef6825fe38498d1b2dd49 to your computer and use it in GitHub Desktop.
Game of Life in Ada
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
-- $ gnatmake gol.adb | |
-- $ ./gol | |
with Ada.Text_IO; | |
procedure Gol is | |
use Ada.Text_IO; | |
Width : constant Integer := 10; | |
Height : constant Integer := 10; | |
type Cell is (Dead, Alive); | |
type Rows is mod Width; | |
type Cols is mod Height; | |
type Board is array (Rows, Cols) of Cell; | |
type Neighbors is range 0 .. 8; | |
procedure Render_Board(B: in Board) is | |
begin | |
for Row in Rows loop | |
for Col in Cols loop | |
case B(Row, Col) is | |
when Dead => Put('.'); | |
when Alive => Put('#'); | |
end case; | |
end loop; | |
New_Line; | |
end loop; | |
end; | |
function Count_Neighbors(B: in Board; Row0: Rows; Col0: Cols) return Neighbors is | |
begin | |
return Result : Neighbors := 0 do | |
for Delta_Row in Rows range 0 .. 2 loop | |
for Delta_Col in Cols range 0 .. 2 loop | |
if Delta_Row /= 1 or Delta_Col /= 1 then | |
declare | |
Row : constant Rows := Row0 + Delta_Row - 1; | |
Col : constant Cols := Col0 + Delta_Col - 1; | |
begin | |
if B(Row, Col) = Alive then | |
Result := Result + 1; | |
end if; | |
end; | |
end if; | |
end loop; | |
end loop; | |
end return; | |
end Count_Neighbors; | |
function Next(Prev: in Board) return Board is | |
begin | |
return Result: Board do | |
for Row in Rows loop | |
for Col in Cols loop | |
declare | |
N : constant Neighbors := Count_Neighbors(Prev, Row, Col); | |
begin | |
Result(Row, Col) := | |
(case Prev(Row, Col) is | |
when Dead => | |
(if N = 3 then Alive else Dead), | |
when Alive => | |
(if N in 2 .. 3 then Alive else Dead)); | |
end; | |
end loop; | |
end loop; | |
end return; | |
end; | |
Current : Board := ( | |
( Dead, Alive, Dead, others => Dead), | |
( Dead, Dead, Alive, others => Dead), | |
(Alive, Alive, Alive, others => Dead), | |
others => (others => Dead) | |
); | |
begin | |
loop | |
Render_Board(Current); | |
Current := Next(Current); | |
delay Duration(0.15); | |
Put(Character'Val(27) & "[" & Width'Image & "A"); | |
Put(Character'Val(27) & "[" & Height'Image & "D"); | |
end loop; | |
end; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment