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;