├── .gitignore ├── thumbnail.png ├── README.md ├── LICENSE └── gol.adb /.gitignore: -------------------------------------------------------------------------------- 1 | gol 2 | *.ali 3 | *.o -------------------------------------------------------------------------------- /thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tsoding/ada-gol/HEAD/thumbnail.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Game of Life in [Ada](https://www.adaic.org/) 2 | 3 | ![thumbnail](thumbnail.png) 4 | 5 | Simple Game of Life implementation in Ada. 6 | 7 | ## Quick Code 8 | 9 | Install [GNAT](https://www.adacore.com/download) first. 10 | 11 | ```console 12 | $ gnatmake -gnatwa gol.adb 13 | $ ./gol 14 | ``` 15 | 16 | ## Screencast 17 | | Thumbnail | Link | 18 | | --- | --- | 19 | | [![thumbnail](http://i3.ytimg.com/vi/qJAuyoDt03A/default.jpg)](https://www.youtube.com/watch?v=qJAuyoDt03A) | [Game of Life in Ada](https://www.youtube.com/watch?v=qJAuyoDt03A) | 20 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2021 Alexey Kutepov 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /gol.adb: -------------------------------------------------------------------------------- 1 | with Ada.Text_IO; 2 | with Ada.Characters.Latin_1; -- There's also 'with ASCII;', but that's obsolete 3 | with Ada.Strings.Fixed; 4 | 5 | procedure Gol is 6 | use Ada.Text_IO; 7 | 8 | Width : constant Positive := 5; 9 | Height : constant Positive := 5; 10 | 11 | type Cell is (Dead, Alive); 12 | type Rows is mod Height; 13 | type Cols is mod Width; 14 | type Board is array (Rows, Cols) of Cell; 15 | type Neighbors is range 0 .. 8; 16 | 17 | procedure Render_Board(B: Board) is 18 | begin 19 | for Row in Rows loop 20 | for Col in Cols loop 21 | case B(Row, Col) is 22 | when Alive => Put('#'); 23 | when Dead => Put('.'); 24 | end case; 25 | end loop; 26 | New_Line; 27 | end loop; 28 | end; 29 | 30 | function Count_Neighbors(B: Board; Row0: Rows; Col0: Cols) return Neighbors is 31 | begin 32 | return Result : Neighbors := 0 do 33 | for Delta_Row in Rows range 0 .. 2 loop 34 | for Delta_Col in Cols range 0 .. 2 loop 35 | if Delta_Row /= 1 or Delta_Col /= 1 then 36 | declare 37 | Row : constant Rows := Row0 + Delta_Row - 1; 38 | Col : constant Cols := Col0 + Delta_Col - 1; 39 | begin 40 | if B(Row, Col) = Alive then 41 | Result := Result + 1; 42 | end if; 43 | end; 44 | end if; 45 | end loop; 46 | end loop; 47 | end return; 48 | end; 49 | 50 | function Next(Current : Board) return Board is 51 | begin 52 | return Result : Board do 53 | for Row in Rows loop 54 | for Col in Cols loop 55 | declare 56 | N : constant Neighbors := Count_Neighbors(Current, Row, Col); 57 | begin 58 | case Current(Row, Col) is 59 | when Dead => 60 | Result(Row, Col) := (if N = 3 then Alive else Dead); 61 | when Alive => 62 | Result(Row, Col) := (if N in 2 .. 3 then Alive else Dead); 63 | end case; 64 | end; 65 | end loop; 66 | end loop; 67 | end return; 68 | end; 69 | 70 | Current : Board := ( 71 | ( Dead, Alive, Dead, others => Dead), 72 | ( Dead, Dead, Alive, others => Dead), 73 | (Alive, Alive, Alive, others => Dead), 74 | others => (others => Dead) 75 | ); 76 | begin 77 | --for I in 1 .. 2 78 | loop 79 | Render_Board(Current); 80 | Current := Next(Current); 81 | delay Duration(0.25); 82 | Put(Ada.Characters.Latin_1.ESC & "[" & Ada.Strings.Fixed.Trim(Height'Image, Ada.Strings.Left) & "A"); 83 | Put(Ada.Characters.Latin_1.ESC & "[" & Ada.Strings.Fixed.Trim(Width'Image, Ada.Strings.Left) & "D"); 84 | end loop; 85 | end; 86 | --------------------------------------------------------------------------------