diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/displays.adb | 36 | ||||
| -rw-r--r-- | src/displays.ads | 20 | ||||
| -rw-r--r-- | src/moves.adb | 10 | ||||
| -rw-r--r-- | src/moves.ads | 9 | ||||
| -rw-r--r-- | src/sokoban.adb | 43 | 
5 files changed, 104 insertions, 14 deletions
| diff --git a/src/displays.adb b/src/displays.adb index 03a0d43..4f3da3d 100644 --- a/src/displays.adb +++ b/src/displays.adb @@ -34,18 +34,26 @@ package body Displays is          return Display      is          My_Width  : Integer := Max (Message_Box_Width, W); -        My_Height : Integer := Max (Message_Box_Height, H); +        My_Height : Integer := Max (Message_Box_Height + Stat_Box_Height, H);      begin          return This : Display :=                     (WD.Double_Window'(WD.Create (X, Y, My_Width, My_Height, Text)) with                      Message_Box => B.Box'(B.Create                          (0, 0, Message_Box_Width, Message_Box_Height, "")), +                    Level_Box => B.Box'(B.Create +                        (0, Message_Box_Height, Stat_Box_Width, Stat_Box_Height, "")), +                    Move_Box => B.Box'(B.Create +                        (Stat_Box_Width, Message_Box_Height, Stat_Box_Width, Stat_Box_Height, "")),                      Current_Grid => null,                      Key_Func => null) do              This.Add (This.Message_Box); +            This.Add (This.Level_Box); +            This.Add (This.Move_Box);              This.Message_Box.Set_Label_Size (Text_Size); +            This.Level_Box.Set_Label_Size (Text_Size); +            This.Move_Box.Set_Label_Size (Text_Size);          end return;      end Create; @@ -104,13 +112,17 @@ package body Displays is          New_Width : Integer :=              Max (Message_Box_Width, This.Current_Grid.Get_W);          New_Height : Integer := -            Message_Box_Height + This.Current_Grid.Get_H; +            Message_Box_Height + This.Current_Grid.Get_H + Stat_Box_Height;          Grid_X : Integer :=              Max (0, (Message_Box_Width - This.Current_Grid.Get_W) / 2);      begin          This.Current_Grid.Reposition (Grid_X, 0);          This.Message_Box.Resize (New_Width, This.Message_Box.Get_H);          This.Message_Box.Reposition (This.Message_Box.Get_X, This.Current_Grid.Get_H); +        This.Level_Box.Resize (New_Width / 2, This.Level_Box.Get_H); +        This.Level_Box.Reposition (0, New_Height - Stat_Box_Height); +        This.Move_Box.Resize (New_Width / 2, This.Move_Box.Get_H); +        This.Move_Box.Reposition (New_Width / 2, New_Height - Stat_Box_Height);          This.Resize (New_Width, New_Height);      end Ensure_Correct_Size; @@ -140,6 +152,26 @@ package body Displays is +    procedure Set_Level_Number +           (This : in out Display; +            To   : in     Natural) is +    begin +        This.Level_Box.Set_Label ("Level:" & Natural'Image (To)); +    end Set_Level_Number; + + + + +    procedure Set_Move_Number +           (This : in out Display; +            To   : in     Natural) is +    begin +        This.Move_Box.Set_Label ("Moves:" & Natural'Image (To)); +    end Set_Move_Number; + + + +      procedure Set_Keyboard_Callback             (This : in out Display;              Func : in     Keyboard_Callback) is diff --git a/src/displays.ads b/src/displays.ads index e8b04d8..d029dac 100644 --- a/src/displays.ads +++ b/src/displays.ads @@ -59,6 +59,16 @@ package Displays is              Msg  : in     String); +    procedure Set_Level_Number +           (This : in out Display; +            To   : in     Natural); + + +    procedure Set_Move_Number +           (This : in out Display; +            To   : in     Natural); + +      procedure Set_Keyboard_Callback             (This : in out Display;              Func : in     Keyboard_Callback); @@ -75,14 +85,20 @@ private      type Display is new FLTK.Widgets.Groups.Windows.Double.Double_Window with record          Message_Box  : FLTK.Widgets.Boxes.Box; +        Level_Box    : FLTK.Widgets.Boxes.Box; +        Move_Box     : FLTK.Widgets.Boxes.Box;          Current_Grid : access Grids.Grid;          Key_Func     : Keyboard_Callback;      end record;      Text_Size : constant FLTK.Font_Size := 12; -    Message_Box_Width  : constant Integer := 500; -    Message_Box_Height : constant Integer := 100; +    Message_Box_Width  : constant Integer := 440; +    Message_Box_Height : constant Integer := 80; + + +    Stat_Box_Width  : constant Integer := Message_Box_Width / 2; +    Stat_Box_Height : constant Integer := 20;  end Displays; diff --git a/src/moves.adb b/src/moves.adb index e9bffc1..11f92b4 100644 --- a/src/moves.adb +++ b/src/moves.adb @@ -40,5 +40,15 @@ package body Moves is      end Drop_Latest; + + +    function Length +           (This : in Path) +        return Natural is +    begin +        return Natural (Move_Vectors.Vector (This).Length); +    end Length; + +  end Moves; diff --git a/src/moves.ads b/src/moves.ads index ebf2bb1..1462847 100644 --- a/src/moves.ads +++ b/src/moves.ads @@ -14,9 +14,6 @@ package Moves is      end record; -    Null_Move : constant Move; - -      type Path is tagged private; @@ -44,6 +41,11 @@ package Moves is             (This : in out Path); +    function Length +           (This : in Path) +        return Natural; + +  private @@ -54,7 +56,6 @@ private      type Path is new Move_Vectors.Vector with null record; -    Null_Move : constant Move := (Delta_X => 0, Delta_Y => 0, Push => False);      Empty_Path : constant Path := (Move_Vectors.Empty_Vector with null record); diff --git a/src/sokoban.adb b/src/sokoban.adb index b58874b..16b646e 100644 --- a/src/sokoban.adb +++ b/src/sokoban.adb @@ -123,6 +123,8 @@ package body Sokoban is          My_Display.Centre_On_Screen;          Move_Record := Moves.Empty_Path;          My_Display.Set_Message (Play_Message); +        My_Display.Set_Level_Number (Natural (Current_Level)); +        My_Display.Set_Move_Number (Move_Record.Length);          My_Grid.Redraw;          Level_State := Play;      end Load_Level; @@ -169,7 +171,9 @@ package body Sokoban is              elsif Key = FLTK.Right_Key then                  Move_Man (1, 0);              elsif Key = U_Key then -                Undo_Movement; +                if Move_Record.Length > 0 then +                    Undo_Movement; +                end if;              elsif Key = N_Key then                  if Current_Level = LevelID'Last then                      My_Display.Set_Message (Fully_Complete_Message); @@ -266,11 +270,13 @@ package body Sokoban is                  Current_Man_Y := Current_Man_Y + Delta_Y;                  Next.Set_Contents (Things.Man);                  My_Grid.Set_Square (Current_Man_X, Current_Man_Y, Next); +                  Move_Record.Add ((Delta_X => Delta_X, Delta_Y => Delta_Y, Push => False)); +                My_Display.Set_Move_Number (Move_Record.Length);                  My_Grid.Redraw; -            elsif -                Next.Get_Contents = Things.Treasure and Next_Next.Is_Walkable and -                Next_Next.Get_Contents = Things.Nothing + +            elsif Next.Get_Contents = Things.Treasure and +                Next_Next.Is_Walkable and Next_Next.Get_Contents = Things.Nothing              then                  Current.Set_Contents (Things.Nothing);                  My_Grid.Set_Square (Current_Man_X, Current_Man_Y, Current); @@ -280,7 +286,9 @@ package body Sokoban is                  My_Grid.Set_Square (Current_Man_X, Current_Man_Y, Next);                  Next_Next.Set_Contents (Things.Treasure);                  My_Grid.Set_Square (Current_Man_X + Delta_X, Current_Man_Y + Delta_Y, Next_Next); +                  Move_Record.Add ((Delta_X => Delta_X, Delta_Y => Delta_Y, Push => True)); +                My_Display.Set_Move_Number (Move_Record.Length);                  My_Grid.Redraw;                  if Next = Squares.Goal and Next_Next /= Squares.Goal then @@ -300,9 +308,32 @@ package body Sokoban is -    procedure Undo_Movement is +    procedure Undo_Movement +    is +        Last : Moves.Move := Move_Record.Latest; + +        Prev : Squares.Square := +            My_Grid.Get_Square (Current_Man_X - Last.Delta_X, Current_Man_Y - Last.Delta_Y); +        Current : Squares.Square := +            My_Grid.Get_Square (Current_Man_X, Current_Man_Y); +        Next : Squares.Square := +            My_Grid.Get_Square (Current_Man_X + Last.Delta_X, Current_Man_Y + Last.Delta_Y);      begin -        null; +        if Last.Push then +            Current.Set_Contents (Things.Treasure); +            Next.Set_Contents (Things.Nothing); +        else +            Current.Set_Contents (Things.Nothing); +        end if; +        Prev.Set_Contents (Things.Man); +        My_Grid.Set_Square (Current_Man_X, Current_Man_Y, Current); +        My_Grid.Set_Square (Current_Man_X + Last.Delta_X, Current_Man_Y + Last.Delta_Y, Next); +        My_Grid.Set_Square (Current_Man_X - Last.Delta_X, Current_Man_Y - Last.Delta_Y, Prev); +        Current_Man_X := Current_Man_X - Last.Delta_X; +        Current_Man_Y := Current_Man_Y - Last.Delta_Y; +        Move_Record.Drop_Latest; +        My_Display.Set_Move_Number (Move_Record.Length); +        My_Grid.Redraw;      end Undo_Movement; | 
