The next example is an experiment on playing Lotto. In this simplified version of Lotto you have to guess seven different numbers in the interval from 1 to 34. You may submit one bet each week. At the end of the week the Lotto system chooses randomly seven different winner numbers, and the winning players are those that have submitted a bet with these winner numbers.
We use a MonitorSystem
to represent the players and the Lotto. Lotto is represented by an object with MonitorProcess
as superclass. A player is represented by an instance of class Player
that is a subclass of MonitorProcess
.
The Lotto
system has the following overall structure:
LottoExperiment: obj MonitorSystem
mnoOfPlayers: val 500
betSize: val 7
class Hand:
:::
class Bet(thePlayer: ref Player, theHand: ref Hand):
:::
class Player(inx: var integer): MonitorProcess
:::
Lotto: obj MonitorProcess
:::
Lotto.start
generatePlayers: do
...
LottoExperiment
has the following main attributes:
- Constants
noOfPlayers
andbetSize
, which defines the number ofPlayer
objects and the size of aHand
in aBet
. - Class
Hand
which represents a hand of seven numbers. - Class
Bet
which represents a bet. It has parametersthePlayer
, which is thePlayer
that has submitted theBet
andtheHand
, which is theHand
of theBet
. - Class
Player
which represents a player. - An object
Lotto
, which represents the Lotto. - A statement that starts the
Lotto
process. - An object
generatePlayers
which is an object that generates the players.
Class Player
has the following structure:
class Player: MonitorProcess
cycle
Lotto.submit(Bet(this(Player),Hand)
doSomethingElse
- A
Player
repeatedly submits aBet
by invokingLotto.submit
. - The argument of
submit
is the objectBet(this(Player), Hand)
. - The first argument of
Bet
is a reference to thePlayer
submitting theBet
. - The second argument of
Bet
is aHand
which randomly generates 7 numbers. - After submitting a
Bet
, it executesdoSomethingElse
before playing the next time;doSomethingElse
is not specified here.
The Lotto is represented by an object Lotto
. This object keeps the bets being submitted, it has the winning bet, and the deadline for submitting bets. As players in parallel submit bets by calling the method submit
, the Lotto
object is defined as a MonitorProcess
with
as an entry method — similar to en submit
entry
-method of a Monitor
object.
The structure of Lotto
is as follows:
Lotto: obj MonitorProcess
submit(B: ref Bet): entry
bets.insert(B)
clearBets:
bets.clear
findWinningBets:
:::
bets: obj Set(#Bet)
:::
Lotto
has the following attributes:
- An
entry
-methodsubmit
, which may be used byPlayer
objects tosubmit
bets. As mentioned, it works in the same way as anentry
method of aMonitor
. This means that at most onesubmit
method may be executed at a given time. - The
Bets
being submitted are stored inbets
which is aSet
. - Methods
clearBets
andfindWinningBets
that are private toLotto
in the sense that they may not be invoked by objects (herePlayers
) outsideLotto
. As forMonitor
, only methods being submethods ofentry
may be invoked from outsideLotto
.
As said, a Lotto-period is a week. During a week the Players
may submit bets. At the end of a week, Lotto stops accepting Bets
via submit
. It then invokes findWinningBets
to find the possible winners of the week.
When possible winners have been found, Lotto
informs the winners. It invokes clearBets
to remove all elements from bets
and open up for a new round of submissions. This is represented by the following statements of Lotto
:
Lotto: obj MonitorProcess
-"-
run: do
waitAndAccept(aWeek)
findWinningBets
clearBets
restart(run)
The object run
is executed forever:
- When a
MonitorProcess
(hereLotto
) is executing, it is not possible to execute anentry
-method from outside. - The method
waitAndAccept
is defined as an attribute ofMonitorProcess
. - When
waitAndAccept(aWeek)
, theMonitorProcess
(Lotto
) waits for a period – here defined byaWeek
and while waiting it acceptsentry
-methods likesubmit
. - When
Lotto
has waited for a week,waitAndAccept
resumes execution and closes for execution ofentry
-methods likesubmit
. - It then executes
findWinningBets
followed byclearBets
.
When Lotto
executes waitAndAccept
, there may be Players
that have invoked Lotto.submit
. These invocations may be executed before waitAndAccept
closes for execution of entry
-methods. This means that a Player
may submit a Bet
after a week has passed. From a modeling point-of-view this may be ok since the invocation of submit
has happened before a week has passed. If one does not consider this to be ok, the implementation of waitAndSubmit
has to be able to block Players
waiting to execute a submit
.
We now show the details of findWinningBets
:
findWinningBets:
winningBet := Bet(Player("Winner"), Hand)
bets.scan
if (current.equal(winningBet)) :then
"Winner: ".print +++ måske inform winner?
current.print
newline
- As mentioned, it starts by assigning
possibleToSubmit
to false. - It then generates a
winningBet
with a hypotheticalPlayer
called “Winner” and aHand
with seven random numbers as arguments - It then scans the submitted bets in
bets
and checks whether or not the currentBet
is equal to thewinningBet
- If a winner is found, the
Player
of thisBet
is printed.
Finally we show the structure of class Hand
and class Bet
:
class Hand:
numbers: obj Array(betSize,#integer)
for (1):to(betSize):repeat
numbers.put(random(1,34)):at[inx]
class Bet(thePlayer: ref Player, theHand: ref Hand):
equal(aBet ref Bet) -> B: var boolean:
...
- Class
Hand
has an arraynumbers
that contains the seven random numbers of theHand
. - It uses a
for:to:repeat
to generate and store seven random numbers innumbers
. - Class
Bet
has anequal
method in addition to its two parameters.
For completeness, all the code for the Lotto example is shown below:
LottoExperiment: obj MonitorSystem
mnoOfPlayers: val 500
betSize: val 7
class Hand:
numbers: obj Array(betSize,#integer)
for (1):to(betSize):repeat
numbers.put(random(1,34)):at[inx]
class Bet(thePlayer: ref Player, theHand: ref Hand):
equal(aBet ref Bet) -> B: var boolean:
...
class Player(inx: var integer): MonitorProcess
cycle
Lotto.submit(Bet(this(Player),Hand)
doSomethingElse
Lotto: obj MonitorProcess
submit(B: ref Bet): entry
bets.insert(B)
clearBets:
bets.clear
findWinningBets:
winningBet := Bet(Player("Winner"), Hand)
bets.scan
if (current.equal(winningBet)) :then
"Winner: ".print +++ måske inform winner?
current.print
newline
bets: obj Set(#Bet)
run: do
waitAndAccept(aWeek)
findWinningBets
clearBets
restart(run)
Lotto.start
generatePlayers: do
...