Ada掷骰子程序前两个计数器未增长、迭代次数异常问题求助
问题根源分析
- 计数器无累加问题:你定义的随机数生成函数
returnRand实际返回的是2~12区间的整数,两个该区间的数相加最小值为4,永远不会出现总和为2、3的情况,因此对应计数2的intArray(1)、计数3的intArray(2)永远不会被触发累加。 - 循环计数不足问题:两个212的数相加的结果范围是424,而你仅编写了总和2~12的计数分支,所有总和大于12的结果都不会被计入任何计数器,因此所有计数器的累加和仅为预期36000次的一半左右,看起来类似循环迭代次数不够。
额外隐藏问题
你将随机数生成器Generator的声明和Reset操作放在了returnRand函数内部,每次调用函数都会重新初始化生成器。如果调用间隔小于系统时钟精度,Reset会使用相同的时间种子,导致生成的随机数完全不符合均匀分布的要求,无法模拟真实掷骰子的结果。
修复后的代码
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 is dice1, dice2, diceTotal : Integer; type Count_Array is array(1 .. 11) of Integer; intArray : Count_Array; -- 随机数生成相关移到外部,仅初始化一次 type Dice_Point is new Integer range 1 .. 6; package Rand_Number is new Ada.Numerics.Discrete_Random(Dice_Point); use Rand_Number; g : Generator; -- 生成单个骰子的1-6随机数 function returnRand return Integer is theNumber : Dice_Point; begin theNumber := Random(g); return Integer(theNumber); end returnRand; 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(intArray : in Count_Array) is begin Put_Line("Dice Total Tally"); for I in Count_Array'Range loop Set_Col(2); Put(I + 1, 2); -- 数组索引+1对应实际骰子总和 Set_Col(23); Put(intArray(I)); New_Line; end loop; end printResults; begin New_Line; Reset(g); -- 全局仅初始化一次随机数生成器 intArray := (others => 0); rollDice(dice1, dice2, diceTotal, intArray); printResults(intArray); New_Line; end main;
内容的提问来源于stack exchange,提问作者Ada Lovelace
相关产品推荐
相关产品推荐

