为了学习斯卡拉和阿卡,我正在写一个战舰游戏。我还没有开始编写任何代码,我只是在考虑事情是如何运作的。
我有船只和球员队的代理人,以及诸如“射击”,“击中”,“未命中”,“所有船只被杀”等消息。我的第一个绊脚石是,当玩家1射击时会产生一系列事件,而玩家2必须等到所有人都已经安定下来然后才能轮到他。我怎样才能确定?我想也许我总是发送一个回复,无论如何,然后计算一个发送者收到与发送的消息完全一样多的答案。也许Battleship不是代理商的最佳候选应用程序。
这也带来了一个问题:在没有接收答案之间做出区别,因为消息尚未处理,代理没有回复任何内容,或者代理人死亡。但是我会把它保存下来。
答案 0 :(得分:1)
您可能希望在此处执行以下操作:
让第一个演员收到对其每条消息的回复,然后将你的回合消息发送给第二个演员
向第二个演员发送消息,指出必须接收给定回合中的事件数量
这些可以实现如下:
import akka.pattern._
(d1 ? m1) zip (d2 ? m2) pipeTo that
在上面的示例中,d1/2
是目标actor,m1/2
是要发送的消息。这些演员的回复被压缩在一起(进入Tuple2
)并转发给第二个演员(示例中为that
)
第二种机制涉及更多;我用SyncPoints
写了类似的东西。所以,像这样:
case class SyncPoint(id: UUID, participants: ActorRef*)
object SyncPoint {
def newFor(participants: ActorRef*) = SyncPoint(UUID.createRandomUUID, participants)
}
然后,消息的创建者首先向最终观察者发送一个SyncPoint
val sync = SyncPoint.newFor(d1, d2)
that ! sync
现在终极接收者知道每个参与者都希望在此SyncPoint
上留言。
d1 ! SyncPart(m1, sync)
d2 ! SyncPart(m2, sync)
哪里
case class SyncPart(msg: Any, sync: SyncPoint)
演员d1
和d2
会在处理完消息后转发that
。
case class SyncPartial(sync: SyncPoint, participant: ActorRef)
通过这种方式,that
知道它期待来自多个参与者的消息,然后可以跟踪这些参与者何时执行了他们的处理。