% lottery(Tot, Type): lotto 649 simulator % Tot = number of games to play % Type = random1 (generate 1 list for user) % = random2 (generate new list per game for user) % = list (user-supplied list of numbers) % % This simulation uses "old" $1 games and winnings estimates. % Double these for the newer $2 games. % Note: must load in file 'lotto649' as well (done at bottom). % Note: entire program is done without cuts or other control directives. lottery(Tot, random1) :- lotto649(UserNums), lotto_sim(Tot, UserNums). lottery(Tot, random2) :- lotto_sim(Tot, random2). lottery(Tot, UserNums) :- test_legal(UserNums), lotto_sim(Tot, UserNums). % verify that user's 6 numbers are all unique integers between 1 and 49 test_legal(UserNums) :- remove_dups(UserNums, UserNums), length(UserNums, 6), test_lotto_vals(UserNums). test_lotto_vals([]). test_lotto_vals([N|R]) :- integer(N), N >= 1, N =< 49, test_lotto_vals(R). test_lotto_vals([N|_]) :- write(N), write(' is illegal!'), nl, fail. % Do the simulation... lotto_sim(Tot, Type) :- lotto_loop(1, Tot, Type, 0, 0, 0, 0, 0, 0). % lotto_loop(K, Tot, Type, W2, W3, W4, W5, W6, Pot): % K = current game number % Tot = total games to play % Type = type of game (random2 = generate user numbers every game; % List = list of user numbers) % W2,...,W6 = number of games matching 2 through 6 numbers respectively % Pot = total pot won % % This does the lottery simulation loop. % For every game, numbers are generated and matched, tallies are done, and % counts are updated. Upon termination, a summary is printed. lotto_loop(K, Tot, _, W2, W3, W4, W5, W6, Total) :- K > Tot, Net is Total - Tot, writelist([nl,'Total games: ', Tot, nl, 'Total 2-matches: ', W2, nl, 'Total 3-matches: ', W3, nl, 'Total 4-matches: ', W4, nl, 'Total 5-matches: ', W5, nl, 'Total 6-matches: ', W6, nl, 'Total winnings: $', Total, nl, 'Net winnings: $', Net, nl, nl]). lotto_loop(K, Tot, random2, W2, W3, W4, W5, W6, Total) :- lotto649(UserNums), lotto649(GameNums), intersection(UserNums, GameNums, Matches), length(Matches, NumMatches), winnings(NumMatches, Prize), Total2 is Total+Prize, writelist(['#',K, ': ', 'user -> ',UserNums, ' game -> ',GameNums,nl, ' ', NumMatches, ' matches -> ', Matches, nl, ' Prize = $',Prize, ', Total win = $', Total2, nl,nl]), K2 is K+1, update_counters(NumMatches,W2, W2b, W3, W3b, W4, W4b, W5, W5b, W6, W6b), lotto_loop(K2, Tot, random2, W2b, W3b, W4b, W5b, W6b, Total2). lotto_loop(K, Tot, Type, W2, W3, W4, W5, W6, Total) :- Type \= random2, cond_generate_nums(Type, UserNums), lotto649(GameNums), intersection(UserNums, GameNums, Matches), length(Matches, NumMatches), winnings(NumMatches, Prize), Total2 is Total+Prize, writelist(['#',K, ': ', 'user -> ',UserNums, ' game -> ',GameNums,nl, ' ', NumMatches, ' matches -> ', Matches, nl, ' Prize = $',Prize, ', Total win = $', Total2, nl,nl]), K2 is K+1, update_counters(NumMatches,W2, W2b, W3, W3b, W4, W4b, W5, W5b, W6, W6b), lotto_loop(K2, Tot, Type, W2b, W3b, W4b, W5b, W6b, Total2). % either generate numbers for user (random2) or use given list... cond_generate_nums(random2, UserNums) :- lotto649(UserNums). cond_generate_nums([H|T], [H|T]). % winnings(N, Prize) is a table of winnings and prize values winnings(0, 0). winnings(1, 0). winnings(2, 1). winnings(3, 10). winnings(4, 80). winnings(5, 2000). winnings(6, 2000000). % update_counters(N, A, A2, B, B2, C, C2, D, D2, E, E2) updates the appropriate % counter based on the number of matches update_counters(2, A, A2, B, B, C, C, D, D, E, E) :- A2 is A+1. update_counters(3, A, A, B, B2, C, C, D, D, E, E) :- B2 is B+1. update_counters(4, A, A, B, B, C, C2, D, D, E, E) :- C2 is C+1. update_counters(5, A, A, B, B, C, C, D, D2, E, E) :- D2 is D+1. update_counters(6, A, A, B, B, C, C, D, D, E, E2) :- E2 is E+1. update_counters(_, A, A, B, B, C, C, D, D, E, E). % intersection(A, B, C) where C is the intersection of A and B intersection([], _, []). intersection([X|R], Y, [X|Z]) :- member(X, Y), intersection(R, Y, Z). intersection([X|R], Y, Z) :- \+ member(X, Y), intersection(R, Y, Z). % remove_dups(A, B) removes all duplicates from list A, resulting in B. remove_dups([], []). remove_dups([A|R], S) :- member(A, R), remove_dups(R, S). remove_dups([A|R], [A|S]) :- \+ member(A, R), remove_dups(R, S). % standard member/2 definition... member(A, [A|_]). member(A, [_|B]) :- member(A, B). % writelist(L) writes each entry in L. 'nl' is caught. writelist([]). writelist([nl|R]) :- nl, writelist(R). writelist([A|R]) :- \+ (A=nl), write(A), writelist(R). ?- [lotto649].