1

I am currently working through John English' "Ada 95: The Craft of Object-Oriented Programming". I am at task 5.1:

Write a program to play a simple guessing game. Define an integer type with a range of values from 1 to 1000 and declare a secret value as a constant of this type, and then give the user ten chances to guess its value.

What I wrote (as a stub) was now

procedure je_5_1 is
  type guess_value is new Integer range 1..1000;
  secret : guess_value;
  package random_guess_value is new Ada.Numerics.Discrete_Random(guess_value);
  Gen : random_guess_value.Generator;
begin
  random_guess_value.Reset(Gen);
  secret := random_guess_value.Random(Gen);
end je_5_1;

Obviously this does not implement the requirement to declare a secret value as a constant. But since I have to call Reset(Gen) before I can assign a randomly generated value to secret, I cannot define the variable secret as a constant before begin.

Is it still possible to define secret as a random constant?

alex
  • 1,277
  • 3
  • 14
  • 30

3 Answers3

2

Use a "declare" to open new scope. For example:

with Ada.Text_IO; use Ada.Text_IO;

procedure Example is

   package Integer_Text_IO is new Integer_IO (Integer);
   use Integer_Text_IO;

   A : Integer;

begin

   Get(A);

   declare
      C : constant Integer := A; 
   begin
      Put(C);
   end;

end Example;

I think that what the text says is that you should choose the secret value when you write your code and insert it "hard coded" into the source.

Artium
  • 5,147
  • 8
  • 39
  • 60
  • Yes, that worked! But no, the (complete) exercise explicitly says to use a RNG. I just truncated the text to focus on my main problem. Thanks! – alex Apr 25 '15 at 05:17
2

The exercise later suggests that you "Modify the program so that the value to be guessed is chosen at random each time the program is run." This requires that the Generator be initialized before the secret value is established. One approach is to encapsulate the secret value in an Abstract State Machine, illustrated here. In the example below, an instance of the Generator is Reset and used to initialize Secret in a sequence of statements that is executed when the package is elaborated, as discussed here and illustrated here.

package Game_Model is
   subtype Guess_Value is Integer range 1 .. 1000;
   function Check(value : Guess_Value) return Boolean;
end Game_Model;

package body Game_Model is
   package Guess_Generator is new Ada.Numerics.Discrete_Random(Guess_Value);
   G: Guess_Generator.Generator;
   Secret : Guess_Value;

   function Check(Value : Guess_Value) return Boolean is
   begin
      return Value = Secret;
   end;

begin
   Guess_Generator.Reset(G);
   Secret := Guess_Generator.Random(G);
end Game_Model;

Given a guessed Value, you can Check it as required in your program.

Value : Game_Model.Guess_Value;
…
Ada.Text_IO.Put_Line(Boolean'Image(Game_Model.Check(Value)));
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
2

You might create another procedure inside the declaration part of the main procedure that would return the random number.

procedure je_5_1 is
  type guess_value is new Integer range 1..1000;

  function get_random return guess_value
  is
     package random_guess_value is new Ada.Numerics.Discrete_Random(guess_value);
     Gen : random_guess_value.Generator;
  begin
     random_guess_value.Reset(Gen);
     return random_guess_value.Random(Gen);
  end get_random;

  secret : constant guess_value := get_random;
begin
   --do your 10 chance loop
end je_5_1;
Pedro Witzel
  • 368
  • 3
  • 14