comp.lang.ada
 help / color / mirror / Atom feed
From: Jere <jhb.chat@gmail.com>
Subject: Re: Array of records with default values not propagating to array
Date: Sat, 3 Feb 2018 06:16:49 -0800 (PST)
Date: 2018-02-03T06:16:49-08:00	[thread overview]
Message-ID: <19b28472-5810-4306-b1b1-545cc7b6edcc@googlegroups.com> (raw)
In-Reply-To: <f326b46d-0ca2-45a8-94b7-bb27b52e54b9@googlegroups.com>

On Saturday, February 3, 2018 at 6:06:52 AM UTC-5, Bojan Bozovic wrote:
> When I defined a record, and set a default value for some of its components, these don't propagate when I make array of these records. Here is code that can be compiled, but I wonder do I need to explicitly assign value for 'others' in 'Initialize' procedure. This has nothing to do with Ada random number generation, I might have as well used Ada.Numerics.Float_Random, or the reusable code that was posted in another thread, with the same result, so I will post in this separate thread. When I omit "others =>" in Initialize, I get compilation errors at these lines both on FSF compiler and AdaCore GPL compiler on Windows. Is this intended behavior or I am missing something?
> 
> with Ada.Numerics.Discrete_Random;
> with Ada.Text_IO;
> with Ada.Text_IO.Unbounded_IO;
> with Ada.Strings;
> with Ada.Strings.Unbounded;
> 
> procedure Tarot1 is
> 
> Maximum_Deck_Length: constant integer := 78;
> subtype Card_Position is Positive range 1..Maximum_Deck_Length;
> type Card_Suits is (Cups,Pentacles,Swords,Wands);
> type Trump_Values is new Natural range 0..21;
> type Card_Values is (Two,Three,Four,Five,Six,Seven,Eight,Nine,Ten,Page,Knight,Queen,King,Ace);
> type Card_Info (Trump: Boolean := False) is record
> -- we will skip giving name and divinatory meaning to cards - its just ordinary assignment but for each card separately;
> -- PROBLEM: Assignment here does nothing, so I have to assign these values in Initialize procedure below as well
> 
> Name : Ada.Strings.Unbounded.Unbounded_String := Ada.Strings.Unbounded.Null_Unbounded_String;
> Divinatory_Meaning: Ada.Strings.Unbounded.Unbounded_String := Ada.Strings.Unbounded.Null_Unbounded_String;
> 
> case Trump is 
> 	when True => Trump_Value:Trump_Values;
> 	when False =>  Card_Value:Card_Values;
> 					Suit_Value:Card_Suits;
> end case;
> end record;
> type Deck is array (Card_Position) of Card_Info;
> package Card_Position_Random is new Ada.Numerics.Discrete_Random (Result_Subtype => Card_Position);
> 
> procedure Initialize ( TDeck : in out Deck) is
> 	Index: Card_Position := 1;
> 	begin
> 		-- first lay 22 trump cards in a deck
> 			for Index_1 in Trump_Values loop
> 			TDeck (Index) := (Trump => True, Trump_Value => Index_1, others => Ada.Strings.Unbounded.Null_Unbounded_String);
> 			Index := Index + 1;
> 			end loop;
> 		-- now lay 4 suits of 14 cards each;
> 		for Suit_Index in Card_Suits loop
> 			for Card_Index in Card_Values loop
> 			TDeck (Index) := (Trump => False, Card_Value => Card_Index, Suit_Value => Suit_Index, others => Ada.Strings.Unbounded.Null_Unbounded_String);
> 			exit when Index=Maximum_Deck_Length; -- preventing CONSTRAINT_ERROR;
> 			Index:=Index+1;
> 			end loop;
> 			end loop;
> end Initialize;
> 
>    procedure Shuffle (TDeck : in out Deck) is
>       Position_Gen   : Card_Position_Random.Generator;
>       Temporary_Data : Card_Info;
>       Index_Random   : Card_Position;
>    begin
>       Card_Position_Random.Reset (Gen => Position_Gen);
>       for Index in Card_Position loop
>          Index_Random         := Card_Position_Random.Random (Gen => Position_Gen);
>          Temporary_Data       := TDeck (Index);
>          TDeck (Index)        := TDeck (Index_Random);
>          TDeck (Index_Random) := Temporary_Data;
>       end loop;
>    end Shuffle;
>    Tarot_Deck : Deck;
>    begin
>    Initialize(Tarot_Deck);
>    Shuffle(Tarot_Deck);
>    for Index in Card_Position loop -- just print the deck as shuffled
>    if Tarot_Deck(Index).Trump then
> 	Ada.Text_IO.Put_Line("Major Arcana/Trump: "&Trump_Values'Image(Tarot_Deck(Index).Trump_Value));
> else
> 	Ada.Text_IO.Put_Line("Minor Arcana: "&Card_Values'Image(Tarot_Deck(Index).Card_Value)&" of "&Card_Suits'Image(Tarot_Deck(Index).Suit_Value));
> 	end if;
> 	end loop;
>    end Tarot1;
> 
> Thanks for help.

The big issue I see is not incrementing Index in the first loop.  As it
stands, you simply keep reassigning trumps to the same card over and over
again.  Since the type is uninitialized and the next for loop cannot fill
the deck, you get a constraint error later on in the print statement when
trying to print a minor arcana.  As a note, defaulting the variant portion
of the record definition did prevent the constraint error, though obviously
the results were wrong because Initialize did not initialize the whole deck.

Try:

with Ada.Numerics.Discrete_Random;
with Ada.Text_IO;
with Ada.Text_IO.Unbounded_IO;
with Ada.Strings;
with Ada.Strings.Unbounded; 

procedure Tarot1 is
   
   Maximum_Deck_Length: constant integer := 78;
   subtype Card_Position is Positive range 1..Maximum_Deck_Length;
   type Card_Suits is (Cups,Pentacles,Swords,Wands);
   type Trump_Values is new Natural range 0..21;
   type Card_Values is (Two,Three,Four,Five,Six,Seven,Eight,Nine,Ten,Page,Knight,Queen,King,Ace);
   type Card_Info (Trump: Boolean := False) is record
      -- we will skip giving name and divinatory meaning to cards - its just ordinary assignment but for each card separately;
      -- PROBLEM: Assignment here does nothing, so I have to assign these values in Initialize procedure below as well

      Name : Ada.Strings.Unbounded.Unbounded_String := Ada.Strings.Unbounded.Null_Unbounded_String;
      Divinatory_Meaning: Ada.Strings.Unbounded.Unbounded_String := Ada.Strings.Unbounded.Null_Unbounded_String;

      case Trump is
         when True =>
            Trump_Value:Trump_Values;
         when False =>
            Card_Value:Card_Values;
            Suit_Value:Card_Suits;
      end case;
   end record;
   type Deck is array (Card_Position) of Card_Info;
   package Card_Position_Random is new Ada.Numerics.Discrete_Random (Result_Subtype => Card_Position);

   procedure Initialize ( TDeck : in out Deck) is
      Index: Card_Position := 1;
   begin
      -- first lay 22 trump cards in a deck
      for Index_1 in Trump_Values loop
         TDeck (Index) := (Trump => True, Trump_Value => Index_1, others => <>);
         Index := Index + 1;  -- Jere:  I added this
      end loop;
      
      -- now lay 4 suits of 14 cards each;
      for Suit_Index in Card_Suits loop
         for Card_Index in Card_Values loop
            TDeck (Index) := (Trump => False, Card_Value => Card_Index, Suit_Value => Suit_Index, others => <>);
            exit when Index=Maximum_Deck_Length; -- preventing CONSTRAINT_ERROR;
            Index:=Index+1;
         end loop;
      end loop;
   end Initialize;

   procedure Shuffle (TDeck : in out Deck) is
      Position_Gen   : Card_Position_Random.Generator;
      Temporary_Data : Card_Info;
      Index_Random   : Card_Position;
   begin
      Card_Position_Random.Reset (Gen => Position_Gen);
      for Index in Card_Position loop
         Index_Random         := Card_Position_Random.Random (Gen => Position_Gen);
         Temporary_Data       := TDeck (Index);
         TDeck (Index)        := TDeck (Index_Random);
         TDeck (Index_Random) := Temporary_Data;
      end loop;
   end Shuffle;
   Tarot_Deck : Deck; 
   
begin
   
   Initialize(Tarot_Deck);
   Shuffle(Tarot_Deck);
   for Index in Card_Position loop -- just print the deck as shuffled
      Ada.Text_IO.put("Index = " & Card_Position'Image(Index) & " => ");
      if Tarot_Deck(Index).Trump then
         Ada.Text_IO.Put_Line("Major Arcana/Trump: "&Trump_Values'Image(Tarot_Deck(Index).Trump_Value));
      else
         Ada.Text_IO.Put_Line("Minor Arcana: "&Card_Values'Image(Tarot_Deck(Index).Card_Value)&" of "&Card_Suits'Image(Tarot_Deck(Index).Suit_Value));
      end if;
   end loop;
   
end Tarot1;

  reply	other threads:[~2018-02-03 14:16 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-02-03 11:06 Array of records with default values not propagating to array Bojan Bozovic
2018-02-03 14:16 ` Jere [this message]
2018-02-03 14:54   ` Bojan Bozovic
2018-02-03 15:26   ` Simon Wright
2018-02-03 16:07     ` Jere
2018-02-04  9:21     ` Niklas Holsti
2018-02-04  9:32       ` Simon Wright
2018-02-04  2:43 ` Robert Eachus
2018-02-04  4:59 ` Bojan Bozovic
2018-02-04  9:34   ` Simon Wright
2018-02-04 10:07   ` Niklas Holsti
2018-02-04 11:38     ` Bojan Bozovic
2018-02-04 10:19 ` Jeffrey R. Carter
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox