summaryrefslogtreecommitdiff
path: root/src/sokoban.adb
diff options
context:
space:
mode:
Diffstat (limited to 'src/sokoban.adb')
-rw-r--r--src/sokoban.adb167
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;
+