在掷骰子应用程序中,前两个计数器永远不会增加

Ada*_*ace 3 ada

我正在编写一个程序,掷两个骰子,并使用一组计数器来显示每个总数显示的次数。我的代码编译良好并且确实运行,但由于某种原因,前两个计数器从未增加,并且似乎按数字升序打印 - 对我来说,这听起来像是我的随机数函数的问题。但我不太明白我哪里出了问题。它也永远不会迭代正确的次数,实际上大约是一半。这是我的代码。

    with Ada.Text_IO; use Ada.Text_IO;
    with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
    with Ada.Numerics.Discrete_Random;
    
    -- procedure main - begins program execution
    procedure main is
    
        dice1, dice2, diceTotal : Integer;
    
        type Count_Array is array(1 .. 11) of Integer;
        intArray : Count_Array;
    
        -- function returnRand - produces a random number and returns it
        function returnRand return Integer is
    
            type magicNumber is new Integer range 2 .. 12;
            package Rand_Number is new Ada.Numerics.Discrete_Random(magicNumber);
            use Rand_Number;
            theNumber : magicNumber;
            g : Generator;
    
        begin
            Reset(g);
    
            theNumber := Random(g);
    
            return Integer(theNumber);
        end returnRand;
    
        -- procedure rollDice - rolls two dice 36000 times and tallys the totals
        procedure rollDice(dice1 : out Integer; dice2 : out Integer;
                     diceTotal : out Integer; intArray : in out Count_Array) is
        begin
            for I in 1 .. 36000 loop
                dice1 := returnRand;
                dice2 := returnRand;
                diceTotal := dice1 + dice2;
    
                if diceTotal = 2 then
                    intArray(1) := intArray(1) + 1;
                elsif diceTotal = 3 then
                    intArray(2) := intArray(2) + 1;
                elsif diceTotal = 4 then
                    intArray(3) := intArray(3) + 1;
                elsif diceTotal = 5 then
                    intArray(4) := intArray(4) + 1;
                elsif diceTotal = 6 then
                    intArray(5) := intArray(5) + 1;
                elsif diceTotal = 7 then
                    intArray(6) := intArray(6) + 1;
                elsif diceTotal = 8 then
                    intArray(7) := intArray(7) + 1;
                elsif diceTotal = 9 then
                    intArray(8) := intArray(8) + 1;
                elsif diceTotal = 10 then
                    intArray(9) := intArray(9) + 1;
                elsif diceTotal = 11 then
                    intArray(10) := intArray(10) + 1;
                elsif diceTotal = 12 then
                    intArray(11) := intArray(11) + 1;
                end if;
            end loop;
        end rollDice;
    
        -- procedure printResults - prints out the totals of each dice throw
        procedure printResults(intArray : in Count_Array) is
        begin
            Put_Line("Dice Total          Tally");
    
            for I in Count_Array'Range loop
               -- Set_Col(2);
               -- Put(integer'image(I));
               -- Set_Col(23);
                Put(integer'image(intArray(I)));
                New_Line;
            end loop;
        end printResults;
    
    begin
        New_Line;
    
        intArray := (0,0,0,0,0,0,0,0,0,0,0);
    
        rollDice(dice1, dice2, diceTotal, intArray);
        printResults(intArray);
    
       New_Line;
    end main;
Run Code Online (Sandbox Code Playgroud)

egi*_*lhh 9

您掷出两个 D11(范围 2..12),而不是 D6,因此当您将它们加在一起时,您得到的范围为 4..24,而不是预期的 2..12。

如果您使用类型系统对问题进行建模,则会检测到以下情况:

    type Count_Array is array(2 .. 12) of Integer;
Run Code Online (Sandbox Code Playgroud)

然后你的 if..elsif 构造可能只是:

    intArray(diceTotal) := intArray(diceTotal) + 1;

Run Code Online (Sandbox Code Playgroud)

将 magicNumber 更改为 1..6 范围以滚动 D6。

此外,无需在每次掷骰子时重置生成器。一次就够了。

编辑:

您还可以进一步使用类型系统,并执行以下操作:

with Ada.Text_IO; use Ada.Text_IO;
with Ada.Numerics.Discrete_Random;

procedure Main is
   Number_Of_Dice : constant := 2;

   type Die_Range is new Positive range 1 .. 6;
   subtype Sums_Range is Die_Range'Base 
      range Number_Of_Dice*Die_Range'First..Number_Of_Dice*Die_Range'Last;

   type Count_Array is array(Sums_Range) of Natural;

   package Random_Die is new Ada.Numerics.Discrete_Random(Die_Range);
   Die : Random_Die.Generator;

   function Roll(Die : Random_Die.Generator) return Die_Range 
      renames Random_Die.Random;

   procedure Roll_Dice(Sums : in out Count_Array) is
      Dice_Total : Sums_Range'Base; 
   begin
      for I in 1 .. 36_000 loop
         Dice_Total := Roll(Die);
         for I in 1..Number_Of_Dice-1 loop
            Dice_Total := Dice_Total + Roll(Die);
         end loop;
         Sums(Dice_Total) := Sums(Dice_Total) + 1;
      end loop;
   end Roll_Dice;

   procedure Print_Results(Sums : in Count_Array) is
   begin
      Put_Line("Dice Total          Tally");

      for I in Sums'Range loop
         Put(Sums(I)'Image);
         New_Line;
      end loop;
   end Print_Results;

   Sums : Count_Array;
begin
   Random_Die.Reset(Die);
   New_Line;

   Sums := (others => 0);

   Roll_Dice(Sums);
   Print_Results(Sums);
   New_Line;
end Main;
Run Code Online (Sandbox Code Playgroud)

请注意,当需求发生变化时,例如每次掷骰子的数量或骰子的类型(D4、D6、D8、D12 等),此代码将非常容易维护