我对Scala / Akka很陌生,这是我第一次尝试写一个演员。
我想要完成的任务是:给定一个足球比赛序列,根据足球的一般规则生成一个排名(胜利者得到3分,输家得到0分,平局时每个人得到1分)。
以下是我目前的角色演员:
package soccerLeague.akka
import akka.actor.Actor
import soccerLeague.common.{LeagueRules, MatchResult, TeamWithPoints}
// Stateful Ranker actor that maintains a rank.
// The rank gets updated every time a MatchResult message is received.
class RankerActor(rules: LeagueRules) extends Actor {
private var rank: Seq[TeamWithPoints] = List()
private var rankMap = Map[String, Int]()
def receive = {
case MatchResult(team1, score1, team2, score2) => {
updateRank(MatchResult(team1, score1, team2, score2))
sender ! rank
}
case Message("getRank") => {
sender ! rank
}
}
private def updateRank(matchRes: MatchResult): Unit = {
def calcDeltaPoints(score1: Int, score2: Int): Int = {
if(score1 == score2) rules.drawScore
else if(score1 > score2) rules.winScore
else rules.lossScore
}
val newPoints1 = rankMap.getOrElse(matchRes.team1, 0) + calcDeltaPoints(matchRes.score1, matchRes.score2)
val newPoints2 = rankMap.getOrElse(matchRes.team2, 0) + calcDeltaPoints(matchRes.score2, matchRes.score1)
rankMap += (matchRes.team1 -> newPoints1, matchRes.team2 -> newPoints2)
// Sort by score, in reverse order (i.e. the team with most points is first).
// Teams that have the same score are sorted in alphabetical order.
// TODO: this *can* be improved by only moving around the two teams that are changing.
rank = rankMap.toSeq
.map { case (t, s) => new TeamWithPoints(t, s) }
.sortBy { case TeamWithPoints(team, points) => (-points, team) }
}
}我有几门辅助性案例课:
case class MatchResult(team1: String, score1: Int, team2: String, score2: Int)
case class LeagueRules(winScore: Int, drawScore: Int, lossScore: Int)
case class TeamWithPoints(team: String, points: Int)receive方法中),然后当我想将它传递给updateRank方法时,再重新构造它?发布于 2017-03-15 20:40:39
首先,您可以尝试向Actor发送命令,而不是名词(源: Actor模型的反应性消息传递模式)。
有关命名命令的信息,请参阅此线程。https://stackoverflow.com/questions/12510535/naming-convention-for-commands-events
https://codereview.stackexchange.com/questions/157857
复制相似问题