16. âą Line Win
â X number of matching symbols on adjacent columns
â Positions have to be a âlineâ
â Wild symbols substitute for other symbols
âą Scatter Win
â X number of matching symbols anywhere
â Triggers bonus game
17. What symbols should land?
Any special symbol wins?
Did the player win anything?
33. type Wager = int64<Pence>
type Multiplier = int
type Payout = Coins of Wager
| MultipliedCoins of Multiplier * Wager
| Multi of Payout list
| BonusGame
34. type Wager = int64<Pence>
type Multiplier = int
type Payout = Coins of Wager
| MultipliedCoins of Multiplier * Wager
| Multi of Payout list
| BonusGame
35. type Wager = int64<Pence>
type Multiplier = int
type Payout = Coins of Wager
| MultipliedCoins of Multiplier * Wager
| Multi of Payout list
| BonusGame
36. type State =
{
AvgWager : Wager
SpecialSymbol : Symbol
Collectables : Map<Collectable, Count>
}
57. The Actor Model
An actor is the fundamental unit of computation
which embodies the 3 things
âą Processing
âą Storage
âą Communication
that are essential to computation.
-Carl Hewitt*
* http://bit.ly/HoNHbG
58. The Actor Model
âą Everything is an actor
âą An actor has a mailbox
âą When an actor receives a message it can:
â Create new actors
â Send messages to actors
â Designate how to handle the next message
59. Stateful Server
âą Gatekeeper
â Manages the local list of active workers
â Spawns new workers
âą Worker
â Manages the states for a player
â Optimistic locking
â Persist state after period of inactivity
69. type Result<âT> =
| Success of âT
| Failure of Exception
type GetResult = Result<State * Version>
type PutResult = Result<unit>
70. type Agent<âT> = MailboxProcessor<âT>
type Message =
| Get of AsyncReplyChannel<GetResult>
| Put of State * Version * AsyncReplyChannel<PutResult>
71. type Agent<âT> = MailboxProcessor<âT>
type Message =
| Get of AsyncReplyChannel<GetResult>
| Put of State * Version * AsyncReplyChannel<PutResult>
72. type Worker (playerId) =
let agent = Agent<Message>.Start(fun inbox ->
let state = getCurrentState playerId
let rec workingState (state, version) =
async { ⊠}
and closedState () =
async { ⊠}
workingState (state, 1))
73. type Worker (playerId) =
let agent = Agent<Message>.Start(fun inbox ->
let state = getCurrentState playerId
let rec workingState (state, version) =
async { ⊠}
and closedState () =
async { ⊠}
workingState (state, 1))
74. type Worker (playerId) =
let agent = Agent<Message>.Start(fun inbox ->
let state = getCurrentState playerId
let rec workingState (state, version) =
async { ⊠}
and closedState () =
async { ⊠}
workingState (state, 1))
75. type Worker (playerId) =
let agent = Agent<Message>.Start(fun inbox ->
let state = getCurrentState playerId
let rec workingState (state, version) =
async { ⊠}
and closedState () =
async { ⊠}
workingState (state, 1))
76. type Worker (playerId) =
let agent = Agent<Message>.Start(fun inbox ->
let state = getCurrentState playerId
let rec workingState (state, version) =
async { ⊠}
and closedState () =
async { ⊠}
workingState (state, 1))
77. let rec workingState (state, version) =
async {
let! msg = inbox.TryReceive(60000)
match msg with
| None ->
do! persist state
return! closedState()
âŠ
}
78. let rec workingState (state, version) =
async {
let! msg = inbox.TryReceive(60000)
match msg with
| None ->
do! persist state
return! closedState()
âŠ
}
79. let rec workingState (state, version) =
async {
let! msg = inbox.TryReceive(60000)
match msg with
| None ->
do! persist state
return! closedState()
âŠ
}
81. let rec workingState (state, version) =
async {
let! msg = inbox.TryReceive(60000)
match msg with
| None ->
do! persist state
return! closedState()
âŠ
}
82. let rec workingState (state, version) =
async {
let! msg = inbox.TryReceive(60000)
match msg with
| None ->
do! persist state
return! closedState()
âŠ
}
83. let rec workingState (state, version) =
async {
let! msg = inbox.TryReceive(60000)
match msg with
âŠ
| Some(Get(reply)) ->
reply.Reply <| Success(state, version)
return! workingState(state, version)
âŠ
}
84. let rec workingState (state, version) =
async {
let! msg = inbox.TryReceive(60000)
match msg with
âŠ
| Some(Get(reply)) ->
reply.Reply <| Success(state, version)
return! workingState(state, version)
âŠ
}
type Message =
| Get of AsyncReplyChannel<GetResult>
| Put of State * Version * AsyncReplyChannel<PutResult>
85. let rec workingState (state, version) =
async {
let! msg = inbox.TryReceive(60000)
match msg with
âŠ
| Some(Get(reply)) ->
reply.Reply <| Success(state, version)
return! workingState(state, version)
âŠ
}
type GetResult = Result<State * Version>
type PutResult = Result<unit>
86. let rec workingState (state, version) =
async {
let! msg = inbox.TryReceive(60000)
match msg with
âŠ
| Some(Get(reply)) ->
reply.Reply <| Success(state, version)
return! workingState(state, version)
âŠ
}
87. let rec workingState (state, version) =
async {
let! msg = inbox.TryReceive(60000)
match msg with
âŠ
| Some(Put(newState, v, reply)) when version = v ->
reply.Reply <| Success()
return! workingState(newState, version+1)
âŠ
}
88. let rec workingState (state, version) =
async {
let! msg = inbox.TryReceive(60000)
match msg with
âŠ
| Some(Put(newState, v, reply)) when version = v ->
reply.Reply <| Success()
return! workingState(newState, version+1)
âŠ
}
type Message =
| Get of AsyncReplyChannel<GetResult>
| Put of State * Version * AsyncReplyChannel<PutResult>
89. let rec workingState (state, version) =
async {
let! msg = inbox.TryReceive(60000)
match msg with
âŠ
| Some(Put(newState, v, reply)) when version = v ->
reply.Reply <| Success()
return! workingState(newState, version+1)
âŠ
}
90. let rec workingState (state, version) =
async {
let! msg = inbox.TryReceive(60000)
match msg with
âŠ
| Some(Put(newState, v, reply)) when version = v ->
reply.Reply <| Success()
return! workingState(newState, version+1)
âŠ
}
91. let rec workingState (state, version) =
async {
let! msg = inbox.TryReceive(60000)
match msg with
âŠ
| Some(Put(_, v, reply)) ->
reply.Reply <| Failure(VersionMismatch(version, v))
return! workingState(state, version)
}
92. let rec workingState (state, version) =
async {
let! msg = inbox.TryReceive(60000)
match msg with
âŠ
| Some(Put(_, v, reply)) ->
reply.Reply <| Failure(VersionMismatch(version, v))
return! workingState(state, version)
} type Result<âT> =
| Success of âT
| Failure of Exception
93. let rec workingState (state, version) =
async {
let! msg = inbox.TryReceive(60000)
match msg with
| None -> âŠ
| Some(Get(reply)) -> âŠ
| Some(Put(newState, v, reply)) when version = v -> âŠ
| Some(Put(_, v, reply)) -> âŠ
}
197. select GameTitle, UserId, TopScore
from GameScores
where GameTitle = âStarship Xâ
and TopScore >= 1000
order desc
limit 3
with (NoConsistentRead, Index(GameTitleIndex, true))
204. SELECT * FROM GameScore
Abstract Syntax Tree (AST)
FParsec
205.
206. select GameTitle, UserId, TopScore
from GameScores
where GameTitle = âStarship Xâ
and TopScore >= 1000
order desc
limit 3
with (NoConsistentRead, Index(GameTitleIndex, true))