From 751f0ac7e8f695413d8c1a56deefa428d5314b9b Mon Sep 17 00:00:00 2001 From: Jed Barber Date: Sat, 5 Aug 2017 19:49:18 +1000 Subject: Undo and level/move number display boxes added --- src/displays.adb | 36 ++++++++++++++++++++++++++++++++++-- src/displays.ads | 20 ++++++++++++++++++-- src/moves.adb | 10 ++++++++++ src/moves.ads | 9 +++++---- 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; -- cgit