Demo Gnoga – Mine Detector

Description

The object of Mine Detector is to mark all cells containing mines and to step on all cells that do not contain a mine. There is at most one mine per cell. Each cell displays the total number of mines in itself and in the adjacent cells.

Unlike other mine-finding games, this game,  provide by Jeffrey R. Carter from  PragmAda Software Engineering, never requires guessing and is a intellectually challenging game

The GtkAda version of Mine Detector is now maintained by Pascal Malaise.

Source code

field.ads

-- Mine Detector Game
-- Copyright (C) 2014 by PragmAda Software Engineering.  All rights reserved.
-- **************************************************************************
--
-- Encapsulates the definition of the mine field
--
-- V7.1 2014 Dec 10          Protected field-updating operations
-- V7.0 2014 Dec 01          First Gnoga version
--
with Gnoga.Types;

package Field is
   subtype Valid_Row is Positive range 1 .. 16; -- Size of the mine field
   subtype Valid_Column is Positive range 1 .. 30;

   type Cell_Location is record
      Row    : Valid_Row    := 1;
      Column : Valid_Column := 1;
   end record;

   subtype Valid_Count is Natural range 0 .. 9; -- Count of # of mines in a cell & its neighbors

   type Field_Info (App_Data : Gnoga.Types.Pointer_to_Connection_Data_Class) is limited private;
private -- Field
   subtype Row_Id is Integer range Valid_Row'First - 1 .. Valid_Row'Last + 1; -- Row around field makes things easier
   subtype Column_Id is Integer range Valid_Column'First - 1 .. Valid_Column'Last + 1;

   type State_Id is (Normal, Marked, Stepped_On); -- Possible states of a cell

   subtype Count_Value is Integer range Valid_Count'First - 1 .. Valid_Count'Last; -- Extra value means not yet counted

   type Cell_Info is record
      State   : State_Id    := Normal;
      Mine    : Boolean     := False;
      Count   : Count_Value := Count_Value'First;
      Stepped : Boolean     := False;
   end record;

   type Field_Set is array (Row_Id, Column_Id) of Cell_Info; -- A mine field

   type Field_Info (App_Data : Gnoga.Types.Pointer_to_Connection_Data_Class) is record
      Num_Mines  : Natural := 0;  -- Changed when first game is started.
      Mine_Field : Field_Set;
      Dead       : Boolean := False;
      To_Mark    : Integer := 0;
      Step_Count : Natural := 0;
   end record;
end Field;
--
-- This is free software; you can redistribute it and/or modify it under
-- terms of the GNU General Public License as published by the Free Software
-- Foundation; version 2.
-- This software is distributed in the hope that it will be useful, but WITH
-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-- for more details. Free Software Foundation, 59 Temple Place - Suite
-- 330, Boston, MA 02111-1307, USA.

fiels_operations.ads

-- Mine Detector Game
-- Copyright (C) 2014 by PragmAda Software Engineering.  All rights reserved.
-- **************************************************************************
--
-- Encapsulates the operations on the mine field
--
-- V7.0 2014 Dec 01          First Gnoga version
--
package Field.Operations is
   procedure Reset (Field : in out Field_Info);
   -- Reset the mine field to its initial condition

   procedure Mark
     (Field : in out Field_Info;
      Cell  : in     Cell_Location);
   -- Mark a cell as having a mine, or unmark a marked cell

   procedure Step
     (Field : in out Field_Info;
      Cell  : in     Cell_Location);
   -- Step on a cell

   type Game_State_ID is (In_Progress, Won, Lost);

   function Game_State
     (Field : Field_Info)
      return Game_State_ID;

   procedure Set_Mine_Count
     (Field          : in out Field_Info;
      New_Mine_Count : in     Natural);
   -- Takes effect the next time a game is created.
end Field.Operations;
--
-- This is free software; you can redistribute it and/or modify it under
-- terms of the GNU General Public License as published by the Free Software
-- Foundation; version 2.
-- This software is distributed in the hope that it will be useful, but WITH
-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-- for more details. Free Software Foundation, 59 Temple Place - Suite
-- 330, Boston, MA 02111-1307, USA.

field-operations.adb

-- Mine Detector Game
-- Copyright (C) 2016 by PragmAda Software Engineering.  All rights reserved.
-- **************************************************************************
--
-- v7.2 2016 May 15          Speed improvement
-- v7.1 2016 Feb 15          Cleaned up unreferenced packages and variables that are not modified
-- V7.0 2014 Dec 01          First Gnoga version
--
with Ada.Numerics.Discrete_Random;

with User_IF;

package body Field.Operations is
   procedure Detect
     (Field : in out Field_Info;
      Cell  : in     Cell_Location)
   is
      -- null;
   begin -- Detect
      if Field.Dead then
         return;
      end if;

      if Field.Mine_Field (Cell.Row, Cell.Column).State = Marked then
         return; -- Can't count a marked cell
      end if;

      if Field.Mine_Field (Cell.Row, Cell.Column).Count not in Valid_Count then -- Cell has not been counted
         Field.Mine_Field (Cell.Row, Cell.Column).Count := 0;

         Count_Rows :
         for Row in Cell.Row - 1 .. Cell.Row + 1 loop
            Count_Columns :
            for Column in Cell.Column - 1 .. Cell.Column + 1 loop
               if Field.Mine_Field (Row, Column).Mine then
                  Field.Mine_Field (Cell.Row, Cell.Column).Count := Field.Mine_Field (Cell.Row, Cell.Column).Count + 1;
               end if;
            end loop Count_Columns;
         end loop Count_Rows;

         User_IF.Display_Count
           (Data    => Field.App_Data, Count => Field.Mine_Field (Cell.Row, Cell.Column).Count,
            Stepped => Field.Mine_Field (Cell.Row, Cell.Column).State = Stepped_On, Cell => Cell);
      end if;
   end Detect;

   procedure Set_Mine_Count
     (Field          : in out Field_Info;
      New_Mine_Count : in     Natural)
   is
      -- null;
   begin -- Set_Mine_Count
      Field.Num_Mines := New_Mine_Count;
   end Set_Mine_Count;

   procedure Reset (Field : in out Field_Info) is
      subtype Rand_Set_Index is Integer range 1 .. Valid_Row'Last * Valid_Column'Last;
      type Rand_Set is array (Rand_Set_Index) of Cell_Location; -- For randomly placing mines

      package Random is new Ada.Numerics.Discrete_Random (Rand_Set_Index);

      Rand_List : Rand_Set;
      Index     : Positive := Positive'Last;
      Gen       : Random.Generator;
      Temp      : Cell_Location;
   begin -- Reset
      Field.Dead       := False;
      Field.Mine_Field :=
        Field_Set'
          (others =>
             (others => Cell_Info'(State => Normal, Mine => False, Count => Count_Value'First, Stepped => False)));
      Field.To_Mark    := Field.Num_Mines;
      Field.Step_Count := 0;

      -- Set the extra ring around the field to stepped_on
      Step_On_Sides :
      for Row in Field.Mine_Field'range (1) loop
         Field.Mine_Field (Row, Field.Mine_Field'First (2)).State := Stepped_On;
         Field.Mine_Field (Row, Field.Mine_Field'Last (2)).State  := Stepped_On;
      end loop Step_On_Sides;

      Step_On_Top_Bottom :
      for Column in Field.Mine_Field'range (2) loop
         Field.Mine_Field (Field.Mine_Field'First (1), Column).State := Stepped_On;
         Field.Mine_Field (Field.Mine_Field'Last (1), Column).State  := Stepped_On;
      end loop Step_On_Top_Bottom;

      -- Fill Rand_List with all cell locations in preparation for placing mines
      Fill_Rows :
      for Row in Valid_Row loop
         Fill_Columns :
         for Column in Valid_Column loop
            Rand_List (Valid_Column'Last * (Row - 1) + Column) := Cell_Location'(Row => Row, Column => Column);
         end loop Fill_Columns;
      end loop Fill_Rows;

      Random.Reset (Gen);

      -- Shuffle Rand_List, a list of cell locations
      Shuffle :
      for I in Rand_List'range loop
         Index             := Random.Random (Gen);
         Temp              := Rand_List (I);
         Rand_List (I)     := Rand_List (Index);
         Rand_List (Index) := Temp;
      end loop Shuffle;

      -- Put mines in the first Num_Mines locations in Rand_List
      Set_Mines :
      for I in 1 .. Field.Num_Mines loop
         Field.Mine_Field (Rand_List (I).Row, Rand_List (I).Column).Mine := True;
      end loop Set_Mines;

      -- Display the mine field
      User_IF.Reset_Screen (Field.App_Data);

      Display_Rows :
      for Row in Valid_Row loop
         Display_Columns :
         for Column in Valid_Column loop
            if Row = Valid_Row'First or else Row = Valid_Row'Last or else Column = Valid_Column'First
              or else Column = Valid_Column'Last
            then -- Cell is on the edge; automatically count these for the player
               Detect (Field => Field, Cell => Cell_Location'(Row => Row, Column => Column));
            end if;
         end loop Display_Columns;
      end loop Display_Rows;

      User_IF.Display_To_Go (Data => Field.App_Data, To_Go => Field.To_Mark);
   end Reset;

   function Stepped_On_Neighbor
     (Field : Field_Info;
      Cell  : Cell_Location)
      return Boolean
   is
   -- See if a cell has a stepped-on neighbor

      -- null;
   begin -- Stepped_On_Neighbor
      Check_Row :
      for Row in Cell.Row - 1 .. Cell.Row + 1 loop
         Check_Column :
         for Column in Cell.Column - 1 .. Cell.Column + 1 loop
            if (Row /= Cell.Row or else Column /= Cell.Column)
              and then Field.Mine_Field (Row, Column).State = Stepped_On
            then
               return True;
            end if;
         end loop Check_Column;
      end loop Check_Row;

      return False;
   end Stepped_On_Neighbor;

   function Marked_Neighbor
     (Field : Field_Info;
      Cell  : Cell_Location)
      return Boolean
   is -- See if a cell has a marked neighbor
      -- null;
   begin -- Marked_Neighbor
      Check_Row :
      for Row in Cell.Row - 1 .. Cell.Row + 1 loop
         Check_Column :
         for Column in Cell.Column - 1 .. Cell.Column + 1 loop
            if (Row /= Cell.Row or else Column /= Cell.Column) and then Field.Mine_Field (Row, Column).State = Marked
            then
               return True;
            end if;
         end loop Check_Column;
      end loop Check_Row;

      return False;
   end Marked_Neighbor;

   function Num_Marked_Neighbors
     (Field : Field_Info;
      Cell  : Cell_Location)
      return Valid_Count
   is
      Result : Valid_Count := 0;
   begin -- Num_Marked_Neighbors
      Count_Rows :
      for Row in Cell.Row - 1 .. Cell.Row + 1 loop
         if Row in Valid_Row then
            Count_Columns :
            for Column in Cell.Column - 1 .. Cell.Column + 1 loop
               if Column in Valid_Column and then Field.Mine_Field (Row, Column).State = Marked then
                  Result := Result + 1;
               end if;
            end loop Count_Columns;
         end if;
      end loop Count_Rows;

      return Result;
   end Num_Marked_Neighbors;

   function Mark_Count_Satisfied
     (Field : Field_Info;
      Cell  : Cell_Location)
      return Boolean
   is
      -- null;
   begin -- Mark_Count_Satisfied
      return Field.Mine_Field (Cell.Row, Cell.Column).Count = Num_Marked_Neighbors (Field, Cell);
   end Mark_Count_Satisfied;

   procedure Auto_Step
     (Field : in out Field_Info;
      Cell  : in     Cell_Location)
   is -- Doug's version
   -- Automatically step on any (unstepped-upon) neighbors of Cell if:
   --   (1) Cell has as many marked neighbors its count, or
   --   (2) the neighbor has as many marked neighbors as its count.

      Cell_Satisfied : constant Boolean := Mark_Count_Satisfied (Field, Cell);
   begin -- Auto_Step
      Step_Rows :
      for Row in Cell.Row - 1 .. Cell.Row + 1 loop
         if Row in Valid_Row then
            Step_Columns :
            for Column in Cell.Column - 1 .. Cell.Column + 1 loop
               if Column in Valid_Column and then Field.Mine_Field (Row, Column).State /= Marked then
                  if Cell_Satisfied or Mark_Count_Satisfied (Field, (Row => Row, Column => Column)) then
                     Step (Field => Field, Cell => (Row => Row, Column => Column));
                  end if;
               end if;
            end loop Step_Columns;
         end if;
      end loop Step_Rows;
   end Auto_Step;

   procedure Mark
     (Field : in out Field_Info;
      Cell  : in     Cell_Location)
   is
      Old_State : constant State_Id := Field.Mine_Field (Cell.Row, Cell.Column).State;
   begin -- Mark
      if Field.Dead then
         return;
      end if;

      if Stepped_On_Neighbor (Field, Cell) or else Marked_Neighbor (Field, Cell) then
         Field.Mine_Field (Cell.Row, Cell.Column).State := Marked; -- Force detect to count cell's neighbors

         Count_Rows :
         for Row in Cell.Row - 1 .. Cell.Row + 1 loop -- Automatically detect around marked cell
            if Row in Valid_Row then
               Count_Columns :
               for Column in Cell.Column - 1 .. Cell.Column + 1 loop
                  if Column in Valid_Column then
                     Detect (Field => Field, Cell => Cell_Location'(Row => Row, Column => Column));
                  end if;
               end loop Count_Columns;
            end if;
         end loop Count_Rows;

         Field.Mine_Field (Cell.Row, Cell.Column).State := Old_State;

         case Old_State is
            when Normal => -- Mark it
               Field.Mine_Field (Cell.Row, Cell.Column).State := Marked;
               User_IF.Display_Mark (Data => Field.App_Data, Cell => Cell);
               Field.To_Mark := Field.To_Mark - 1;
            when Marked => -- Unmark it
               Field.Mine_Field (Cell.Row, Cell.Column).State := Normal;

               User_IF.Display_Count
                 (Data    => Field.App_Data, Count => Field.Mine_Field (Cell.Row, Cell.Column).Count,
                  Stepped => Field.Mine_Field (Cell.Row, Cell.Column).State = Stepped_On, Cell => Cell);

               Field.To_Mark := Field.To_Mark + 1;
            when Stepped_On =>
               null; -- Can't marked a stepped-on cell
         end case;

         User_IF.Display_To_Go (Data => Field.App_Data, To_Go => Field.To_Mark);

         if User_IF.Extended_Stepping (Field.App_Data) then
            Auto_Step (Field => Field, Cell => Cell);
         end if;
      end if;
   end Mark;

   procedure Step
     (Field : in out Field_Info;
      Cell  : in     Cell_Location)
   is
      function Num_Normal_Neighbors
        (Cell : Cell_Location)
         return Valid_Count
      is
         Result : Valid_Count := 0;
      begin -- Num_Normal_Neighbors
         Count_Rows :
         for Row in Cell.Row - 1 .. Cell.Row + 1 loop
            if Row in Valid_Row then
               Count_Columns :
               for Column in Cell.Column - 1 .. Cell.Column + 1 loop
                  if Column in Valid_Column and then Field.Mine_Field (Row, Column).State = Normal then
                     Result := Result + 1;
                  end if;
               end loop Count_Columns;
            end if;
         end loop Count_Rows;

         return Result;
      end Num_Normal_Neighbors;
   begin -- Step
      if Field.Dead then
         return;
      end if;

      if Field.Mine_Field (Cell.Row, Cell.Column).State = Marked then
         User_IF.Display_Mark (Data => Field.App_Data, Cell => Cell);

         return;
      end if;

      if Field.Mine_Field (Cell.Row, Cell.Column).Stepped then -- Avoid inifinite recursion.
         return;
      end if;

      if not Stepped_On_Neighbor (Field, Cell) and then not Marked_Neighbor (Field, Cell) then
         User_IF.Display_Blank (Data => Field.App_Data, Cell => Cell);
      else
         Field.Step_Count                                 := Field.Step_Count + 1;
         Field.Mine_Field (Cell.Row, Cell.Column).State   := Stepped_On;
         Field.Mine_Field (Cell.Row, Cell.Column).Stepped := True;

         Count_Rows :
         for Row in Cell.Row - 1 .. Cell.Row + 1 loop -- Automatically detect around stepped-on cell
            if Row in Valid_Row then
               Count_Columns :
               for Column in Cell.Column - 1 .. Cell.Column + 1 loop
                  if Column in Valid_Column then
                     Detect (Field => Field, Cell => Cell_Location'(Row => Row, Column => Column));
                  end if;
               end loop Count_Columns;
            end if;
         end loop Count_Rows;

         if Field.Mine_Field (Cell.Row, Cell.Column).Mine then -- Stepped on a mine!
            Field.Dead := True;
            User_IF.Display_Mine (Data => Field.App_Data, Cell => Cell);

            return;
         end if;

         User_IF.Display_Count
           (Data    => Field.App_Data, Count => Field.Mine_Field (Cell.Row, Cell.Column).Count,
            Stepped => Field.Mine_Field (Cell.Row, Cell.Column).State = Stepped_On, Cell => Cell);

         Auto_Step (Field => Field, Cell => Cell);

         if Field.Dead then
            return;
         end if;

         if User_IF.Auto_Marking (Field.App_Data) then
            -- See if stepping here has created any normal cells that obviously contain mines;
            -- if so, mark them.
            if Field.Mine_Field (Cell.Row, Cell.Column).Count - Num_Marked_Neighbors (Field, Cell) =
              Num_Normal_Neighbors (Cell)
            then
               Mark_Rows :
               for Row in Cell.Row - 1 .. Cell.Row + 1 loop
                  Mark_Columns :
                  for Column in Cell.Column - 1 .. Cell.Column + 1 loop
                     if Field.Mine_Field (Row, Column).State = Normal then
                        Mark (Field => Field, Cell => (Row => Row, Column => Column));
                     end if;
                  end loop Mark_Columns;
               end loop Mark_Rows;
            end if;
         end if;

         Field.Step_Count := Field.Step_Count - 1;

         if Field.Step_Count <= 0 then
            Release_Rows :
            for Row in Valid_Row loop
               Release_Columns :
               for Column in Valid_Column loop
                  Field.Mine_Field (Row, Column).Stepped := False;
               end loop Release_Columns;
            end loop Release_Rows;
         end if;
      end if;
   end Step;

   -- The game is Lost when a mine has been stepped on, Won when all mines have been marked & all other cells stepped on,
   -- and In_Progress otherwise
   function Game_State
     (Field : Field_Info)
      return Game_State_ID
   is
      -- null;
   begin -- Game_State
      if Field.Dead then -- A mine has been stepped on
         return Lost;
      end if;

      Check_Rows :
      for Row in Valid_Row loop
         Check_Columns :
         for Column in Valid_Column loop
            if Field.Mine_Field (Row, Column).State = Normal
              or else (Field.Mine_Field (Row, Column).State = Marked) /= Field.Mine_Field (Row, Column).Mine
            then
               return In_Progress;
            end if;
         end loop Check_Columns;
      end loop Check_Rows;

      return Won;
   end Game_State;
end Field.Operations;
--
-- This is free software; you can redistribute it and/or modify it under
-- terms of the GNU General Public License as published by the Free Software
-- Foundation; version 2.
-- This software is distributed in the hope that it will be useful, but WITH
-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-- for more details. Free Software Foundation, 59 Temple Place - Suite
-- 330, Boston, MA 02111-1307, USA.

user_if.ads

-- Mine Detector Game
-- Copyright (C) 2014 by PragmAda Software Engineering.  All rights reserved.
-- **************************************************************************
--
-- Provide the user interface
--
-- V7.0 2014 Dec 01          First Gnoga version
--
with Field;

with Gnoga.Types;

package User_IF is
   procedure Display_Count
     (Data    : in Gnoga.Types.Pointer_to_Connection_Data_Class;
      Count   : in Field.Valid_Count;
      Stepped : in Boolean;
      Cell    : in Field.Cell_Location);

   procedure Display_Mark
     (Data : in Gnoga.Types.Pointer_to_Connection_Data_Class;
      Cell : in Field.Cell_Location);
   -- Display a marked cell

   procedure Display_Mine
     (Data : in Gnoga.Types.Pointer_to_Connection_Data_Class;
      Cell : in Field.Cell_Location);
   -- Display a mine.

   procedure Display_Blank
     (Data : in Gnoga.Types.Pointer_to_Connection_Data_Class;
      Cell : in Field.Cell_Location);
   -- Display a blank cell

   procedure Display_To_Go
     (Data  : in Gnoga.Types.Pointer_to_Connection_Data_Class;
      To_Go : in Integer);
   -- Display # of mines still to mark; can be negative

   procedure Reset_Screen (Data : in Gnoga.Types.Pointer_to_Connection_Data_Class); -- Return to start of game condition

   function Auto_Marking
     (Data : Gnoga.Types.Pointer_to_Connection_Data_Class)
      return Boolean; -- Get auto-marking state

   function Extended_Stepping
     (Data : in Gnoga.Types.Pointer_to_Connection_Data_Class)
      return Boolean;
   -- Get extended-stepping (after mark) state
end User_IF;
--
-- This is free software; you can redistribute it and/or modify it under
-- terms of the GNU General Public License as published by the Free Software
-- Foundation; version 2.
-- This software is distributed in the hope that it will be useful, but WITH
-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-- for more details. Free Software Foundation, 59 Temple Place - Suite
-- 330, Boston, MA 02111-1307, USA.

user_if.adb

-- Mine Detector Game
-- Copyright (C) 2016 by PragmAda Software Engineering.  All rights reserved.
-- **************************************************************************
--
-- v7.5 2016 May 01          Used some colors; better name Stepped in Display
-- V7.4 2016 Feb 15          Cleaned up unreferenced packages and variables that are not modified
-- V7.3 2015 Jun 15          Changed from Docker to Grid and added touch-screen support
-- V7.2 2015 Jan 01          Improved "termination" screen
-- V7.1 2014 Dec 10          Protected field-updating operations
-- V7.0 2014 Dec 01          First Gnoga version
--

with Ada.Characters.Wide_Wide_Latin_1;

with Field.Operations;
pragma Elaborate (Field.Operations);

with Gnoga.Application.Multi_Connect;
with Gnoga.Gui.Base;
with Gnoga.Gui.Element.Common;
with Gnoga.Gui.Element.Form;
with Gnoga.Gui.View.Grid;
with Gnoga.Gui.Window;
with Gnoga.Types.Colors;

use Ada;
use Ada.Characters;

package body User_IF is
   use Gnoga;
   use all type Gnoga.String;

   subtype String is Gnoga.String;

   Gray : constant Gnoga.Types.RGBA_Type := (Red => 224, Green => 224, Blue => 224, Alpha => 1.0);

   type Button_Set is array (Field.Valid_Row, Field.Valid_Column) of Gnoga.Gui.Element.Common.Button_Type;

   type Action_ID is (Button_Press, Right_Click, Restart, Quit);

   type Atomic_Boolean is new Boolean;
   pragma Atomic (Atomic_Boolean);

   type App_Info;
   type App_Ptr is access all App_Info;

   protected type Sequentialize is
      entry Respond
        (Action   : in Action_ID;
         App_Data : in App_Ptr;
         Cell     : in Field.Cell_Location := (Row => 1, Column => 1));
   end Sequentialize;

   type App_Info is new Gnoga.Types.Connection_Data_Type with record
      Field                     : Standard.Field.Field_Info (App_Data => App_Info'Unchecked_Access);
      Window                    : Gnoga.Gui.Window.Pointer_To_Window_Class;
      Big_View                  : Gnoga.Gui.View.Grid.Grid_View_Type;
      Left_View                 : aliased Gnoga.Gui.View.View_Type;
      Right_View                : aliased Gnoga.Gui.View.View_Type;
      Mines_Left                : Gnoga.Gui.Element.Common.Span_Type;
      Button                    : Button_Set;
      Restart_Button            : Gnoga.Gui.Element.Common.Button_Type;
      Level_Form                : Gnoga.Gui.Element.Form.Form_Type;
      Level                     : Gnoga.Gui.Element.Form.Selection_Type;
      Mark_Form                 : Gnoga.Gui.Element.Form.Form_Type;
      Mark_Check                : Gnoga.Gui.Element.Form.Check_Box_Type;
      Mark_Label                : Gnoga.Gui.Element.Form.Label_Type;
      Step_Form                 : Gnoga.Gui.Element.Form.Form_Type;
      Step_Check                : Gnoga.Gui.Element.Form.Check_Box_Type;
      Step_Label                : Gnoga.Gui.Element.Form.Label_Type;
      Rules                     : Gnoga.Gui.Element.Common.Button_Type;
      About                     : Gnoga.Gui.Element.Common.Button_Type;
      Quit                      : Gnoga.Gui.Element.Common.Button_Type;
      Game_Over                 : Gnoga.Gui.Element.Common.Span_Type;
      Mode_Form                 : Gnoga.Gui.Element.Form.Form_Type;
      Mode_Check                : Gnoga.Gui.Element.Form.Check_Box_Type;
      Mode_Label                : Gnoga.Gui.Element.Form.Label_Type;
      Auto_Marking_Desired      : Atomic_Boolean := False;
      Extended_Stepping_Desired : Atomic_Boolean := False;
      Sequentializer            : Sequentialize;
   end record;

   You_Won_Message  : constant String := "You Won";
   You_Lost_Message : constant String := "BOOM!";
   Exploded         : constant String := "X";

   type Level_Info is record
      Name  : String;
      Mines : Natural;
   end record;

   type Level_List is array (Positive range <>) of Level_Info;

   Levels : constant Level_List :=
     (1 => (Name => " 50", Mines => 50), 2 => (Name => "100", Mines => 100), 3 => (Name => "150", Mines => 150),
      4 => (Name => "200", Mines => 200), 5 => (Name => "250", Mines => 250));

   Default_Level : constant := 2;

   subtype Cell_String is String;

   procedure Show_Game_Over (App_Data : in App_Ptr) is
      -- null;
   begin -- Show_Game_Over
      case Field.Operations.Game_State (App_Data.Field) is
         when Field.Operations.Won =>
            App_Data.Game_Over.Text (Value => You_Won_Message);
         when Field.Operations.Lost =>
            App_Data.Game_Over.Text (Value => You_Lost_Message);
         when Field.Operations.In_Progress =>
            null;
      end case;
   end Show_Game_Over;
   pragma Inline (Show_Game_Over);

   use type Field.Operations.Game_State_ID;

   Button_Size : constant := 30;

   procedure Display
     (App_Data : in App_Ptr;
      Cell     : in Field.Cell_Location;
      Text     : in Cell_String;
      Stepped  : in Boolean)
   is
      -- null;
   begin -- Display
      App_Data.Button (Cell.Row, Cell.Column).Text (Value => Text);

      if not Stepped then
         App_Data.Button (Cell.Row, Cell.Column).Background_Color (Enum => Gnoga.Types.Colors.Light_Green);
         App_Data.Button (Cell.Row, Cell.Column).Shadow_None;
      else
         if Text = Exploded then
            App_Data.Button (Cell.Row, Cell.Column).Background_Color (Enum => Gnoga.Types.Colors.Red);
         else
            App_Data.Button (Cell.Row, Cell.Column).Background_Color (RGBA => Gray);
         end if;

         App_Data.Button (Cell.Row, Cell.Column).Shadow
           (Horizontal_Position => "1px", Vertical_Position => "1px", Inset_Shadow => True);
      end if;

      if Field.Operations.Game_State (App_Data.Field) /= Field.Operations.In_Progress then
         Show_Game_Over (App_Data => App_Data);
      end if;
   end Display;
   pragma Inline (Display);

   procedure Display_Blank
     (Data : in Gnoga.Types.Pointer_to_Connection_Data_Class;
      Cell : in Field.Cell_Location)
   is
      App_Data : constant App_Ptr := App_Ptr (Data);
   begin -- Display_Blank
      Display (App_Data => App_Data, Cell => Cell, Text => " ", Stepped => False);
   end Display_Blank;

   procedure Display_Count
     (Data    : in Gnoga.Types.Pointer_to_Connection_Data_Class;
      Count   : in Field.Valid_Count;
      Stepped : in Boolean;
      Cell    : in Field.Cell_Location)
   is
      Zero_Pos : constant := Character'Pos ('0');

      App_Data : constant App_Ptr := App_Ptr (Data);
   begin -- Display_Count
      Display
        (App_Data => App_Data, Cell => Cell, Text => From_ASCII (Character'Val (Zero_Pos + Count)), Stepped => Stepped);
   end Display_Count;

   procedure Display_Mark
     (Data : in Gnoga.Types.Pointer_to_Connection_Data_Class;
      Cell : in Field.Cell_Location)
   is
      App_Data : constant App_Ptr := App_Ptr (Data);
   begin -- Display_Mark
      Display (App_Data => App_Data, Cell => Cell, Text => "M", Stepped => False);
   end Display_Mark;

   procedure Display_Mine
     (Data : in Gnoga.Types.Pointer_to_Connection_Data_Class;
      Cell : in Field.Cell_Location)
   is
      App_Data : constant App_Ptr := App_Ptr (Data);
   begin -- Display_Mine
      Display (App_Data => App_Data, Cell => Cell, Text => Exploded, Stepped => True);
   end Display_Mine;

   procedure Display_To_Go
     (Data  : in Gnoga.Types.Pointer_to_Connection_Data_Class;
      To_Go : in Integer)
   is
      Image : constant String := Gnoga.Image (To_Go);

      App_Data : constant App_Ptr := App_Ptr (Data);
   begin -- Display_To_Go
      App_Data.Mines_Left.Text (Value => Image);
   end Display_To_Go;

   procedure Reset_Screen (Data : in Gnoga.Types.Pointer_to_Connection_Data_Class) is
      App_Data : constant App_Ptr := App_Ptr (Data);
   begin -- Reset_Screen
      App_Data.Mines_Left.Text (Value => "0");
      App_Data.Game_Over.Text (Value => "");

      Button_Row :
      for Row in Field.Valid_Row loop
         Button_Column :
         for Column in Field.Valid_Column loop
            Display_Blank (Data => Data, Cell => (Row => Row, Column => Column));
         end loop Button_Column;
      end loop Button_Row;
   end Reset_Screen;

   function Auto_Marking
     (Data : Gnoga.Types.Pointer_to_Connection_Data_Class)
      return Boolean
   is
      App_Data : constant App_Ptr := App_Ptr (Data);
   begin -- Auto_Marking
      return Boolean (App_Data.Auto_Marking_Desired);
   end Auto_Marking;

   function Extended_Stepping
     (Data : in Gnoga.Types.Pointer_to_Connection_Data_Class)
      return Boolean
   is
      App_Data : constant App_Ptr := App_Ptr (Data);
   begin -- Extended_Stepping
      return Boolean (App_Data.Extended_Stepping_Desired);
   end Extended_Stepping;

   procedure When_Close (Object : in out Gnoga.Gui.Base.Base_Type'Class) is
      App_Data : constant App_Ptr := App_Ptr (Object.Connection_Data);
   begin -- When_Close
      App_Data.Sequentializer.Respond (Action => Quit, App_Data => App_Data);
   end When_Close;

   procedure Mark_Toggle (Object : in out Gnoga.Gui.Base.Base_Type'Class) is
      App_Data : constant App_Ptr := App_Ptr (Object.Connection_Data);
   begin -- Mark_Toggle
      App_Data.Auto_Marking_Desired := Atomic_Boolean (App_Data.Mark_Check.Checked);
   end Mark_Toggle;

   procedure Step_Toggle (Object : in out Gnoga.Gui.Base.Base_Type'Class) is
      App_Data : constant App_Ptr := App_Ptr (Object.Connection_Data);
   begin -- Step_Toggle
      App_Data.Extended_Stepping_Desired := Atomic_Boolean (App_Data.Step_Check.Checked);
   end Step_Toggle;

   procedure Button_Press (Object : in out Gnoga.Gui.Base.Base_Type'Class) is
      Name : constant String := Object.ID;

      Row    : constant Field.Valid_Row    := Value (Name.Slice (Name.First, Name.First + 1));
      Column : constant Field.Valid_Column := Value (Name.Slice (Name.Last - 1, Name.Last));

      App_Data : constant App_Ptr := App_Ptr (Object.Connection_Data);
   begin -- Button_Press
      App_Data.Sequentializer.Respond
        (Action => Button_Press, App_Data => App_Data, Cell => (Row => Row, Column => Column));
   end Button_Press;

   procedure Right_Click (Object : in out Gnoga.Gui.Base.Base_Type'Class) is
      Name : constant String := Object.ID;

      Row    : constant Field.Valid_Row    := Value (Name.Slice (Name.First, Name.First + 1));
      Column : constant Field.Valid_Column := Value (Name.Slice (Name.Last - 1, Name.Last));

      App_Data : constant App_Ptr := App_Ptr (Object.Connection_Data);
   begin -- Right_Click
      App_Data.Sequentializer.Respond
        (Action => Right_Click, App_Data => App_Data, Cell => (Row => Row, Column => Column));
   end Right_Click;

   procedure When_Restart_Button (Object : in out Gnoga.Gui.Base.Base_Type'Class) is
      App_Data : constant App_Ptr := App_Ptr (Object.Connection_Data);
   begin -- When_Restart_Button
      App_Data.Sequentializer.Respond (Action => Restart, App_Data => App_Data);
   end When_Restart_Button;

   procedure Rules_Pressed (Object : in out Gnoga.Gui.Base.Base_Type'Class) is
      App_Data : constant App_Ptr := App_Ptr (Object.Connection_Data);

      Rules : constant String :=
        "The object of the game is to mark all cells containing " &
        "mines and to step on all cells that do not contain a " & "mine." & Wide_Wide_Latin_1.LF &
        Wide_Wide_Latin_1.LF & "The game is played on a rectangular field of 16 x 30 " &
        "cells. A number of mines are hidden within the field." & Wide_Wide_Latin_1.LF & Wide_Wide_Latin_1.LF &
        "Some of the cells have numbers on them. The numbers represent " &
        "the total number of mines in that cell and its " &
        "immediate neighbors. As you play the game, additional cells " & "will become numbered." &
        Wide_Wide_Latin_1.LF & Wide_Wide_Latin_1.LF &
        "You step on a cell by clicking on it. You mark a cell by right " &
        "clicking on it. A marked cell has an M on it. Marking a " &
        "marked cell unmarks it. You can only mark or step " & "on a cell with a number on it." & Wide_Wide_Latin_1.LF &
        Wide_Wide_Latin_1.LF & "When you step on a cell, an auto-stepping algorithm " &
        "automatically steps on any of its neighbors that " & "obviously do not contain mines. Since this is then " &
        "done for the neighbors of the stepped-on neighbors, " &
        "the auto-stepping algorithm will spread across areas " &
        "of the field that obviously do not contain mines. The " &
        "auto-stepping algorithm is invoked even if the cell is " &
        "already stepped on. This can be useful to clear around " & "a new mark." & Wide_Wide_Latin_1.LF &
        Wide_Wide_Latin_1.LF & "If you step on a cell containing a mine, either " &
        "directly or indirectly through the auto-stepping " & "algorithm, the cell shows an X, and the game is over." &
        Wide_Wide_Latin_1.LF & Wide_Wide_Latin_1.LF & "The game is over when you step on a mine, or when you " &
        "have marked all mines and stepped on all other cells. " & "If you win, '" & You_Won_Message &
        "' appears below the " & "'Quit' button. If you lose, '" & You_Lost_Message & "' appears there." &
        Wide_Wide_Latin_1.LF & Wide_Wide_Latin_1.LF & "At the top right of the field is a number. At the " &
        "start of a game this is the number of mines in the " & "field. Each time you mark a cell, this number is " &
        "decreased by one. Each time you unmark a marked cell, " &
        "this number is increased by one. If you successfully " & "complete a game, this number will be zero." &
        Wide_Wide_Latin_1.LF & Wide_Wide_Latin_1.LF & "The 'New Game' button starts a new game. Any game in " &
        "progress is abandoned." & Wide_Wide_Latin_1.LF & Wide_Wide_Latin_1.LF &
        "The level drop-down allows you to choose how many mines " &
        "will be in the field at the start of the next game. You " & "can choose from" & Levels (Levels'First).Name &
        " to " & Levels (Levels'Last).Name & " mines. This goes into effect " &
        "the next time you start a new game. At higher numbers of " &
        "mines, it may not be possible to win the game without luck." & Wide_Wide_Latin_1.LF & Wide_Wide_Latin_1.LF &
        "The 'Auto Mark' check box enables an auto-marking " &
        "algorithm that marks any cells that obviously contain " &
        "a mine. At lower levels, the game does not present much " &
        "of an intellectual challenge with this option. At higher " &
        "levels, it's very difficult to play without this option." & Wide_Wide_Latin_1.LF & Wide_Wide_Latin_1.LF &
        "The 'Auto Step after Mark' check box enables the auto-" &
        "stepping algorithm after a cell is marked, either " & "directly or indirectly through the auto-marking " &
        "algorithm." & Wide_Wide_Latin_1.LF & Wide_Wide_Latin_1.LF &
        "The 'Mark' check box is for use with touch screens or other " &
        "systems for which right clicking is difficult or impossible. " &
        "When this box is not checked, clicking on a cells steps on the " &
        "cell. When this box is checked, clicking on a cell marks or " & "unmarks the cell.";
   begin -- Rules_Pressed
      App_Data.Window.Alert (Message => Rules);
   end Rules_Pressed;

   procedure About_Pressed (Object : in out Gnoga.Gui.Base.Base_Type'Class) is
      App_Data : constant App_Ptr := App_Ptr (Object.Connection_Data);
   begin -- About_Pressed
      App_Data.Window.Alert
        (Message =>
           "Mine Detector" & Wide_Wide_Latin_1.LF & "Copyright (C) 2015 by" & Wide_Wide_Latin_1.LF &
           "PragmAda Software Engineering" & Wide_Wide_Latin_1.LF & "Released as Free Software under the terms" &
           Wide_Wide_Latin_1.LF & "of the GNU Public License" & Wide_Wide_Latin_1.LF & '"' & "Ada Inside" & '"');
   end About_Pressed;

   function Image
     (Row    : Field.Valid_Row;
      Column : Field.Valid_Column)
      return String
   is
   -- Returns a 4-Character String of the form "RRCC", where
   --    RR is the zero-filled image of Row
   --    CC is the zero-filled image of Column
      Row_Image    : String   := Image (Row, Prefix => ' ');
      Column_Image : String   := Image (Column, Prefix => ' ');
      Row_First    : Positive := Row_Image.First;
      Column_First : Positive := Column_Image.First;
   begin -- Image
      Row_Image.Replace_Unicode (Row_Image.First, '0');
      Column_Image.Replace_Unicode (Column_Image.First, '0');

      if Row >= 10 then
         Row_First := Row_First + 1;
      end if;

      if Column >= 10 then
         Column_First := Column_First + 1;
      end if;

      return Row_Image.Slice (Row_First, Row_Image.Last) & Column_Image.Slice (Column_First, Column_Image.Last);
   end Image;

   procedure Create_Level_Option_Menu (App_Data : in out App_Info) is
      -- null;
   begin -- Create_Level_Option_Menu
      Add_Options :
      for I in Levels'range loop
         App_Data.Level.Add_Option (Value => Levels (I).Name, Text => Levels (I).Name);
      end loop Add_Options;

      App_Data.Level.Selected (Index => Default_Level);
   end Create_Level_Option_Menu;

   procedure On_Connect
     (Main_Window : in out Gnoga.Gui.Window.Window_Type'Class;
      Connection  :        access Gnoga.Application.Multi_Connect.Connection_Holder_Type)
   is
      App_Data : constant App_Ptr := new App_Info;
   begin -- On_Connect
      App_Data.Window := Main_Window'Unchecked_Access;
      Main_Window.Connection_Data (Data => App_Data);
      Field.Operations.Set_Mine_Count (Field => App_Data.Field, New_Mine_Count => Levels (Default_Level).Mines);
      Main_Window.Buffer_Connection;
      App_Data.Big_View.Create
        (Parent => Main_Window, Layout => Gnoga.Gui.View.Grid.Horizontal_Split, Set_Sizes => False);
      App_Data.Big_View.Background_Color (Enum => Gnoga.Types.Colors.Light_Blue);
      App_Data.Left_View.Create (Parent => App_Data.Big_View.Panel (1, 1).all);
      App_Data.Left_View.Hidden;
      App_Data.Left_View.Background_Color (Enum => Gnoga.Types.Colors.Light_Blue);

      Button_Row :
      for Row in App_Data.Button'Range (1) loop
         Button_Column :
         for Column in App_Data.Button'Range (2) loop
            App_Data.Button (Row, Column).Create
              (Parent => App_Data.Left_View, Content => " ", ID => User_IF.Image (Row, Column));
            App_Data.Button (Row, Column).Overflow (Value => Gnoga.Gui.Element.Hidden);
            App_Data.Button (Row, Column).Vertical_Align (Value => Gnoga.Gui.Element.Middle);
            App_Data.Button (Row, Column).Minimum_Width (Value => Button_Size);
            App_Data.Button (Row, Column).Maximum_Width (Value => Button_Size);
            App_Data.Button (Row, Column).Minimum_Height (Value => Button_Size);
            App_Data.Button (Row, Column).Maximum_Height (Value => Button_Size);
            App_Data.Button (Row, Column).Text_Alignment (Value => Gnoga.Gui.Element.Center);
            App_Data.Button (Row, Column).Margin (Top => "1px", Right => "1px", Bottom => "1px", Left => "1px");
            App_Data.Button (Row, Column).Border (Width => "thin");
            App_Data.Button (Row, Column).On_Click_Handler (Handler => Button_Press'Access);
            App_Data.Button (Row, Column).On_Context_Menu_Handler (Handler => Right_Click'Access);
         end loop Button_Column;

         App_Data.Left_View.Put_HTML (HTML => "<br />");
      end loop Button_Row;

      App_Data.Left_View.Hidden (Value => False);

      App_Data.Right_View.Create (Parent => App_Data.Big_View.Panel (1, 2).all);
      App_Data.Right_View.Background_Color (Enum => Gnoga.Types.Colors.Light_Blue);
      App_Data.Mines_Left.Create (Parent => App_Data.Right_View, Content => "0");
      App_Data.Mines_Left.Width (Value => 100);
      App_Data.Mines_Left.Text_Alignment (Value => Gnoga.Gui.Element.Center);
      App_Data.Mines_Left.Display (Value => "block");
      App_Data.Restart_Button.Create (Parent => App_Data.Right_View, Content => "New Game");
      App_Data.Restart_Button.Display (Value => "block");
      App_Data.Restart_Button.On_Click_Handler (Handler => When_Restart_Button'Access);
      App_Data.Level_Form.Create (Parent => App_Data.Right_View);
      App_Data.Level_Form.Display (Value => "block");
      App_Data.Level.Create (Form => App_Data.Level_Form);
      App_Data.Level.Width (Value => 57);
      Create_Level_Option_Menu (App_Data => App_Data.all);
      App_Data.Mark_Form.Create (Parent => App_Data.Right_View);
      App_Data.Mark_Form.Display (Value => "block");
      App_Data.Mark_Check.Create (Form => App_Data.Mark_Form);
      App_Data.Mark_Check.Checked (Value => False);
      App_Data.Mark_Check.On_Click_Handler (Handler => Mark_Toggle'Access);
      App_Data.Mark_Label.Create
        (Form => App_Data.Mark_Form, Label_For => App_Data.Mark_Check, Content => "Auto Mark", Auto_Place => False);
      App_Data.Step_Form.Create (Parent => App_Data.Right_View);
      App_Data.Step_Form.Display (Value => "block");
      App_Data.Step_Check.Create (Form => App_Data.Step_Form);
      App_Data.Step_Check.Checked (Value => False);
      App_Data.Step_Check.On_Click_Handler (Handler => Step_Toggle'Access);
      App_Data.Step_Label.Create
        (Form       => App_Data.Step_Form, Label_For => App_Data.Step_Check, Content => "Auto Step after Mark",
         Auto_Place => False);
      App_Data.Rules.Create (Parent => App_Data.Right_View, Content => "Rules");
      App_Data.Rules.Display (Value => "block");
      App_Data.Rules.On_Click_Handler (Handler => Rules_Pressed'Access);
      App_Data.About.Create (Parent => App_Data.Right_View, Content => "About");
      App_Data.About.Display (Value => "block");
      App_Data.About.On_Click_Handler (Handler => About_Pressed'Access);
      App_Data.Quit.Create (Parent => App_Data.Right_View, Content => "Quit");
      App_Data.Quit.Display (Value => "block");
      App_Data.Quit.On_Click_Handler (Handler => When_Close'Access);
      App_Data.Mode_Form.Create (Parent => App_Data.Right_View);
      App_Data.Mode_Form.Display (Value => "block");
      App_Data.Mode_Check.Create (Form => App_Data.Mode_Form);
      App_Data.Mode_Check.Checked (Value => False);
      App_Data.Mode_Label.Create
        (Form => App_Data.Mode_Form, Label_For => App_Data.Mode_Check, Content => "Mark", Auto_Place => False);
      App_Data.Game_Over.Create (Parent => App_Data.Right_View, Content => You_Won_Message);
      App_Data.Game_Over.Width (Value => 100);
      App_Data.Game_Over.Text_Alignment (Value => Gnoga.Gui.Element.Center);
      App_Data.Game_Over.Display (Value => "block");
      Main_Window.Buffer_Connection (Value => False);
      Field.Operations.Reset (Field => App_Data.Field);
   end On_Connect;

   End_Message : constant String := "Mine Detector ended.";

   protected body Sequentialize is
      entry Respond
        (Action   : in Action_ID;
         App_Data : in App_Ptr;
         Cell     : in Field.Cell_Location := (Row => 1, Column => 1)) when Standard.True
      is
         View : Gnoga.Gui.View.View_Type;
      begin -- Respond
         case Action is
            when Button_Press =>
               if Field.Operations.Game_State (App_Data.Field) /= Field.Operations.In_Progress then
                  Show_Game_Over (App_Data => App_Data);
               elsif App_Data.Mode_Check.Checked then
                  Field.Operations.Mark (Field => App_Data.Field, Cell => Cell);
               else
                  Field.Operations.Step (Field => App_Data.Field, Cell => Cell);
               end if;
            when Right_Click =>
               if Field.Operations.Game_State (App_Data.Field) /= Field.Operations.In_Progress then
                  Show_Game_Over (App_Data => App_Data);
               else
                  Field.Operations.Mark (Field => App_Data.Field, Cell => Cell);
               end if;
            when Restart =>
               Field.Operations.Set_Mine_Count
                 (Field => App_Data.Field, New_Mine_Count => Levels (App_Data.Level.Selected_Index).Mines);
               Field.Operations.Reset (Field => App_Data.Field);
            when Quit =>
               App_Data.Big_View.Remove;
               View.Create (Parent => App_Data.Window.all);
               View.Put_Line (Message => End_Message);
               App_Data.Window.Close;
               App_Data.Window.Close_Connection;
         end case;
      end Respond;
   end Sequentialize;
begin -- User_IF
   Gnoga.Application.Title (Name => "Mine Detector");
   Gnoga.Application.HTML_On_Close (HTML => End_Message);
   Gnoga.Application.Multi_Connect.Initialize;
   Gnoga.Application.Multi_Connect.On_Connect_Handler (Event => On_Connect'Access, Path => "default");
   Gnoga.Application.Multi_Connect.Message_Loop;
end User_IF;
--
-- This is free software; you can redistribute it and/or modify it under
-- terms of the GNU General Public License as published by the Free Software
-- Foundation; version 2.
-- This software is distributed in the hope that it will be useful, but WITH
-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-- for more details. Free Software Foundation, 59 Temple Place - Suite
-- 330, Boston, MA 02111-1307, USA.

connectfour.properties

#Connect Four en
ADPT=Adapted for GNOGA by Pascal Pignard (20150613).
APPE=Application ended.
CPYR=Connect Four (TM) by Barry Fagin and Martin Carlisle
DEVP=Developed by Barry Fagin and Martin Carlisle, US Air Force Academy.
IAMT=I am thinking...
INFO=This Connect Four (TM) game was initially coded in Ada 2005 and compiled with the JVM-GNAT compiler.
IWIN=I win\! - Press left mouse button
TIEG=Tie Game\! - Press Left Mouse Button
YWIN=You win\! - Press left mouse button
TITL=Connect Four (TM)

mine_detector.adb

-- Mine Detector Game
-- Copyright (C) 2014 by PragmAda Software Engineering.  All rights reserved.
-- **************************************************************************
--
-- V7.0 2014 Dec 01          First Gnoga version
--
with User_IF;
procedure Mine_Detector is
   -- null;
begin -- Mine_Detector
   null;
end Mine_Detector;
--
-- This is free software; you can redistribute it and/or modify it under
-- terms of the GNU General Public License as published by the Free Software
-- Foundation; version 2.
-- This software is distributed in the hope that it will be useful, but WITH
-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-- for more details. Free Software Foundation, 59 Temple Place - Suite
-- 330, Boston, MA 02111-1307, USA.

Project file

with "settings.gpr";
with "gnoga.gpr";

project Mine_Detector is

   for Object_Dir use Settings.Obj_Dir;
   for Exec_Dir use Settings.Exe_Dir;
   for Main use ("mine_detector.adb");
   for Create_Missing_Dirs use Settings'Create_Missing_Dirs;

   package Compiler is
      for Default_Switches ("Ada") use Settings.Compiler'Default_Switches ("Ada") & "-gnatyN";
   end Compiler;

   package Binder renames Settings.Binder;
   package Linker renames Settings.Linker;
   package Pretty_Printer renames Settings.Pretty_Printer;

end Mine_Detector;