Ada:如何定义一个随机常数?

Ada: How to define a random constant?

我目前正在通过 John English' "Ada 95: The Craft of Object-Oriented Programming" 工作。我在 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.

我写的(作为存根)现在是

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;

显然这没有实现 declare a secret value as a constant 的要求。但是由于我必须先调用 Reset(Gen) 才能将随机生成的值分配给 secret,因此我无法在 begin 之前将变量 secret 定义为常量。

是否仍然可以将 secret 定义为随机常数?

使用"declare"打开新范围。例如:

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;

我认为文本所说的是您在编写代码时应该选择秘密值并将其插入 "hard coded" 到源代码中。

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;

给定一个猜测 Value,您可以 Check 根据您的程序的要求。

Value : Game_Model.Guess_Value;
…
Ada.Text_IO.Put_Line(Boolean'Image(Game_Model.Check(Value)));

您可以在主过程的声明部分创建另一个过程,该过程将 return 随机数。

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;