-
Notifications
You must be signed in to change notification settings - Fork 0
/
draw.adb
83 lines (81 loc) · 3.06 KB
/
draw.adb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
------------------------------------------------------------------------
-- draw.adb - draw random numbers
------------------------------------------------------------------------
-- Author:
-- Erich H. Rast <[email protected]>
--
-- License: This program is free software licensed under GNU Lesser
-- General Public License version 3. Please read the accompanying
-- License.Txt text for more Information. This program and
-- its packages come with ABSOLUTELY NO WARRANTY.
------------------------------------------------------------------------
with Draw;
package body draw is
--------------------------------------------------------------------------
-- draw one number using the pseudo-random
-- number generator and return it
function Draw1 (Total : in Lottery_Number) return Lottery_Number is
begin
return Lottery_Number ((Float'Floor
(Float_Random.Random (G) *
(Float (Total)) +
1.0)));
end Draw1;
--------------------------------------------------------------------------
-- the good old slow bubblesort!
procedure Sort (Draw : in out Full_Draw; Max : in Draw_Number) is
Buffer : Lottery_Number;
Swapped : Boolean;
begin
loop
Swapped := False;
for i in 2 .. Max loop
if Draw (i - 1) > Draw (i) then
Buffer := Draw (i);
Draw (i) := Draw (i - 1);
Draw (i - 1) := Buffer;
Swapped := True;
end if;
end loop;
exit when Swapped = False;
end loop;
end Sort;
--------------------------------------------------------------------------
-- draw all the numbers and return the result
-- in a Full_Draw array
procedure Draw_Numbers
(Num : in Draw_Number;
Total : in Lottery_Number;
Result : in out Full_Draw)
is
Buffer : Lottery_Number;
Unique_Draw : Boolean;
begin
if not Initialized then
Float_Random.Reset (G);
Initialized := True;
end if;
Result (1) := Draw1 (Total);
for i in 2 .. Num loop
check_loop : loop
Unique_Draw := True;
Result (i) := Draw1 (Total);
inner_for_loop : for j in 1 .. i - 1 loop
if Result (j) = Result (i) then
Unique_Draw := False;
exit inner_for_loop;
elsif j > 1 and then Result (j - 1) > Result (j) then
-- we presort the array as much as possible
-- in the hope of speeding up final sorting
Buffer := Result (j);
Result (j) := Result (j - 1);
Result (j - 1) := Buffer;
end if;
end loop inner_for_loop;
exit check_loop when Unique_Draw = True;
end loop check_loop;
end loop;
Sort (Result, Num);
end Draw_Numbers;
--------------------------------------------------------------------------
end draw;