diff options
Diffstat (limited to 'src/sokoban.adb')
-rw-r--r-- | src/sokoban.adb | 167 |
1 files changed, 167 insertions, 0 deletions
diff --git a/src/sokoban.adb b/src/sokoban.adb new file mode 100644 index 0000000..9c3e490 --- /dev/null +++ b/src/sokoban.adb @@ -0,0 +1,167 @@ + + +with + + Displays, + Grids, + Squares, + Things, + Ada.Command_Line, + Ada.Directories, + Ada.Text_IO, + Ada.Strings.Fixed, + Ada.Strings.Maps; + +use + + Ada.Text_IO; + + +package body Sokoban is + + + -- Forward declarations of helper functions. + + procedure Add_New_Grid_Item + (X, Y : in Natural; + Char : in Character); + + + + + -- Global state of the game. + + My_Display : Displays.Display := Displays.Create; + My_Grid : Grids.Grid := Grids.Create (0, 0); + Current_Level : LevelID; + + + + + -- Miscellaneous. + + Origin : String := Ada.Directories.Containing_Directory + (Ada.Directories.Full_Name (Ada.Command_Line.Command_Name)); + Level_Dir : String := Origin & "/../share/sokoban/level"; + + + + + -- Main program interface. + + procedure Load_Level + (Number : in LevelID) + is + use Ada.Strings, Ada.Strings.Fixed, Ada.Strings.Maps; + + Data_File : File_Type; + Filename : String := + Level_Dir & "/level" & Trim (LevelID'Image (Number), Both) & ".data"; + + Rows, Cols : Natural; + begin + Open (Data_File, In_File, Filename); + + declare + Row_Line : String := Get_Line (Data_File); + Col_Line : String := Get_Line (Data_File); + Start, Finish : Natural; + begin + Find_Token (Row_Line, To_Set ("0123456789"), 1, Inside, Start, Finish); + Rows := Natural'Value (Row_Line (Start .. Finish)); + Find_Token (Col_Line, To_Set ("0123456789"), 1, Inside, Start, Finish); + Cols := Natural'Value (Col_Line (Start .. Finish)); + end; + My_Display.Adjust_Grid (Cols, Rows); + + for Y in Integer range 1 .. Rows loop + declare + Working_Line : String := Get_Line (Data_File); + begin + for X in Integer range 1 .. Cols loop + Add_New_Grid_Item (X, Y, Working_Line (X)); + end loop; + end; + end loop; + + Close (Data_File); + + Current_Level := Number; + My_Display.Centre_On_Screen; + end Load_Level; + + + + + procedure Show is + begin + My_Display.Show; + end Show; + + + + + procedure Hide is + begin + My_Display.Hide; + end Hide; + + + + + -- Callbacks for keyboard controls. + + + + + -- Helper functions. + + procedure Add_New_Grid_Item + (X, Y : in Natural; + Char : in Character) + is + Temp : Squares.Square; + begin + case Char is + when '#' => + My_Grid.Set_Square (X, Y, Squares.Wall); + + when ' ' => + My_Grid.Set_Square (X, Y, Squares.Empty); + + when '$' => + Temp := Squares.Empty; + Temp.Set_Contents (Things.Treasure); + My_Grid.Set_Square (X, Y, Temp); + + when '*' => + Temp := Squares.Goal; + Temp.Set_Contents (Things.Treasure); + My_Grid.Set_Square (X, Y, Temp); + + when '!' => + My_Grid.Set_Square (X, Y, Squares.Space); + + when '.' => + My_Grid.Set_Square (X, Y, Squares.Goal); + + when '@' => + Temp := Squares.Empty; + Temp.Set_Contents (Things.Man); + My_Grid.Set_Square (X, Y, Temp); + + when others => + raise Program_Error; + + end case; + end Add_New_Grid_Item; + + +begin + + + My_Display.Set_Grid (My_Grid); + + +end Sokoban; + |