From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Thread: 103376,8147387fe25d4e2a X-Google-NewGroupId: yes X-Google-Attributes: gida07f3367d7,domainid0,public,usenet X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news1.google.com!news3.google.com!fu-berlin.de!uni-berlin.de!individual.net!not-for-mail From: Niklas Holsti Newsgroups: comp.lang.ada Subject: Re: Random number generation Date: Thu, 30 Dec 2010 13:34:23 +0200 Organization: Tidorum Ltd Message-ID: <8o3920Fn0vU1@mid.individual.net> References: <864o9vbkwz.fsf@gareth.avalon.lan> Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Trace: individual.net wsoXf28CKM4uM2GvK3iSBQ6ctjUkB3GAQlwkouWiU4p5c/cBvs Cancel-Lock: sha1:JT/nNvcoT9xL1QrM1UCU4pr0ufo= User-Agent: Mozilla-Thunderbird 2.0.0.24 (X11/20100328) In-Reply-To: <864o9vbkwz.fsf@gareth.avalon.lan> Xref: g2news1.google.com comp.lang.ada:16248 Date: 2010-12-30T13:34:23+02:00 List-Id: Mart van de Wege wrote: > Beginner's question: I'm trying to implement a function that rolls a > number of dice and then adds a modifier. Somehow, it produces the same > number every time. I can't see where I'm going wrong. > > Here's the proof of concept code: > > with Ada.Numerics.Discrete_Random,Ada.Integer_Text_IO; > use Ada.Integer_Text_IO; > > procedure Rolltest is > function Roll ( Number : in Positive; > Size : in Positive; > Modifier : in Integer := 0 ) return Integer is > subtype Die_Size is Positive range 2..Size; > package Die is new Ada.Numerics.Discrete_Random( Die_Size ); > G : Die.Generator; > Result : Integer; > Temp : Integer; > begin > Die.Reset(G); This Reset operation is specified (in RM A.5.2(34)) to set the state of the generator G to a "time-dependent" state. If every call of Roll is returning the same results, perhaps the calls happen so rapidly that whatever discrete "time" source Reset uses is the same on each call, thus setting G to the same state on each call. Ordinarily I would suggest to call Reset just once, and then let the state of the generator evolve without Resets over all calls of Roll, but this cannot be done here because G is a local variable in Roll, and it must be so since the generic actual parameter depends on the Size parameter of Roll. Perhaps you should make another random Integer number generator IntGen, local to Rolltest but not to Roll, and use the generated Integer numbers to initialize Roll.G by a Reset call that has the random Integer as the second, state-determining "Initiator" parameter. The IntGen generator should be Reset in Rolltest, not in Roll, or left in its default initial state. If you leave a random-number generator with its default initial state (no Reset call), you get the same random-number sequence on every execution. If you use the single-parameter Reset (G) procedure, you get a sequence that is different for different executions, providing that the Resets are far enough apart in time to make a difference. > Result := 0; > for I in 1..Number loop > Temp := Die.Random(G); > Result := Result + Temp; > end loop; > Result := Result + Modifier; > return Result; > end Roll; > begin > for I in 1..10 loop > Put(Roll( Number => 3, Size => 6 )); > end loop; > end Rolltest; > > Anyone care to at least point me to some documentation that explains > what I'm doing wrong? > > Mart > -- Niklas Holsti Tidorum Ltd niklas holsti tidorum fi . @ .