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

时间:2015-04-24 13:14:41

标签: random constants ada

我目前正在通过John English' " Ada 95:面向对象编程的工艺"。我在task 5.1

  

编写一个程序来玩一个简单的猜谜游戏。定义一个整数类型,其值范围为1到1000,并将一个秘密值声明为此类型的常量,然后为用户提供十次猜测其值的机会。

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

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,因此我无法将变量secret定义为begin之前的常量。

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

3 个答案:

答案 0 :(得分:2)

使用“声明”打开新范围。例如:

class FileItemsController < AccountsController
  def index
    account = Account.includes(:credentials).find params[:account_id]
    @page = page_param.to_i
    @tab = 'Files'
    @credential = if params[:credential_id].blank?
                    account.credentials.first || nil
                  else
                    account.credentials.find(params[:credential_id])
                  end
    return unless  @credential
    file_items = FileItem.file_item_list(@credential.root_folder, sort_by)
    @total_count = file_items.count
    @max_per_page = file_items.count <= 15 ? 'all' : max_per_page.to_i
    file_items_scope = Kaminari.paginate_array(file_items.select(&:file?), total_count: file_items.count).page(page_param)
    @file_items = if max_per_page == 'all'
                    file_items_scope.per(file_items.count) || []
                  else
                    file_items_scope.per(max_per_page) || []
                  end
  end

  private

  def page_param
    params[:page] || 1
  end

  def max_per_page
    val = params[:per] || 15
    val.to_i < 15 ? 15 : val unless val == 'all'
  end

  def sort_by
    params[sort_by] || 'created_at'
  end
end

我认为文本所说的是你在编写代码时应该选择秘密值并将其“硬编码”插入源代码。

答案 1 :(得分:2)

exercise后来建议您“修改程序,以便每次运行程序时随机选择要猜测的值。”这要求在建立秘密值之前初始化Generator。一种方法是将秘密值封装在Abstract State Machine中,如图所示here。在下面的示例中,Generator的实例为Reset,用于在详细说明包时执行的语句序列中初始化Secret,如上所述here并说明了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)));

答案 2 :(得分:2)

您可以在主过程的声明部分内创建另一个返回随机数的过程。

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;