-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathMultiplayer.scala
52 lines (46 loc) · 1.86 KB
/
Multiplayer.scala
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
package com.michalplachta.freeprisoners.free.programs
import cats.free.Free
import com.michalplachta.freeprisoners.PrisonersDilemma._
import com.michalplachta.freeprisoners.free.algebras.DecisionRegistryOps.DecisionRegistry
import com.michalplachta.freeprisoners.free.algebras.MatchmakingOps.Matchmaking
import com.michalplachta.freeprisoners.free.algebras.TimingOps.Timing
import com.michalplachta.freeprisoners.free.programs.tools.DeferredRetry
import scala.concurrent.duration._
object Multiplayer {
val deferredRetry = new DeferredRetry(100, 1.second)
import deferredRetry._
def findOpponent[S[_]](player: Prisoner)(
implicit matchmakingOps: Matchmaking.Ops[S],
timingOps: Timing.Ops[S]): Free[S, Option[Prisoner]] = {
import matchmakingOps._
for {
_ <- unregisterWaiting(player)
waitingPlayers <- getWaitingPlayers()
maybeOpponent <- waitingPlayers.headOption
.map(joinWaitingPlayer(player, _))
.getOrElse(waitForOpponent(player))
} yield maybeOpponent
}
def waitForOpponent[S[_]](player: Prisoner)(
implicit matchmakingOps: Matchmaking.Ops[S],
timingOps: Timing.Ops[S]): Free[S, Option[Prisoner]] = {
import matchmakingOps._
for {
_ <- registerAsWaiting(player)
maybeOpponent <- retry[S, Option[Prisoner]](checkIfOpponentJoined(player),
until = _.isDefined)
_ <- unregisterWaiting(player)
} yield maybeOpponent
}
def getRemoteOpponentDecision[S[_]](opponent: Prisoner)(
implicit gameOps: DecisionRegistry.Ops[S],
timingOps: Timing.Ops[S]): Free[S, Option[Decision]] = {
import gameOps._
for {
maybeOpponentDecision <- retry[S, Option[Decision]](
getRegisteredDecision(opponent),
until = _.isDefined)
_ <- clearRegisteredDecision(opponent)
} yield maybeOpponentDecision
}
}