我需要在Scala中编写一个程序,它有3个actor和一个object-ball。一个演员必须把球传给另一个。 Actor的构造函数必须包含两个参数:
class Player(val num: Int, val players: Array[ActorRef]) extends Actor { … }
这是我的问题:如何调用此构造函数来组成三个actor并同时将它们的数组传递给所有actor?
以下是我的其余代码:
case class Ball(count: Int)
class Player(val num: Int, val players: Array[ActorRef]) extends Actor {
def receive = {
case Ball(count) =>
println("I've got a ball!")
var nextPlayer = self
do {
nextPlayer = players((Math.random() * 3).toInt)
} while(nextPlayer == self)
self.tell(Ball(count + 1), nextPlayer)
}
}
答案 0 :(得分:0)
我说你的整个逻辑有点破碎。简单的解决方案是让一个父母演员称为例如Game
。逻辑上,多个Player's
可以参与单个游戏。所以,看起来应该是这样的:
import akka.actor.{ Actor, ActorLogging, ActorRef, Props }
object Game {
final case class StartGame(playerCount: Int)
def apply() = Props(new Game)
}
final class Game extends Actor with ActorLogging {
import Game._
var players = Set.empty[ActorRef]
override def receive: Receive = {
case StartGame(playerCount) =>
for (i <- 1 to playerCount) {
players = players + context.actorOf(Player.apply(playerCount), i.toString)
}
case (ball: Player.Ball, playerId: Int) =>
context.child(playerId.toString) match {
case Some(actorRef) => actorRef ! ball
case None => log.warning("Player not found!")
}
}
}
object Player {
case class Ball(count: Int = 0)
def apply(playerCount: Int) = Props(new Player(playerCount))
}
final class Player(playerCount: Int) extends Actor with ActorLogging {
import Player._
override def receive: Receive = {
case Ball(count) =>
log.info(s"Player with id: ${self.path.name} has the ball --- Ball count: $count")
context.parent ! (Ball(count + 1), 1 + (Math.random() * playerCount).toInt)
}
}
因此,相反,每个Player
actor都有对其他actor的引用,Game
父actor将拥有Player
个actor的集合。当每个Player
&#34;踢出&#34; Ball
,消息被发送到父actor,然后调度下一个选定的actor。
答案 1 :(得分:0)
演员将用来互相交谈的合约,
case object StartTheGame
case object StopTheGame
case class PlayerJoin(player: ActorRef)
case class PlayerLeave(player: ActorRef)
case class GetNextPlayer(player: ActorRef)
case class Ball(count: Int)
case class BallThrow(ball: Ball)
球员演员,
class Player extends Actor with ActorLogging {
override def receive = {
case Ball(count) => {
log.info("player has caught the ball - {}", self)
sender() ! BallThrow(Ball(count + 1))
log.info("player has thrown the ball - {}", self)
}
}
}
object Player {
def props: Props = Props(classOf[Player])
}
游乐场,
class PlayGround extends Actor with ActorLogging {
var players = Set.empty[ActorRef]
var gameOnGoing = false
def passBallToNextPlayer(player: ActorRef, ball: Ball): Unit = {
if (gameOnGoing) {
getRandomNextPlayer(sender()) ! ball
}
else {
log.info("Game has stopped. Ball is falling to the ground.")
}
}
def getRandomNextPlayer(player: ActorRef): ActorRef = {
val otherPlayers = (players - player).toVector
val otherPlayersCount = otherPlayers.size
if (otherPlayersCount > 0) {
otherPlayers((Math.random() * (otherPlayersCount - 1)).toInt)
}
else {
player
}
}
override def receive = {
case StartTheGame => startTheGame()
case StopTheGame => stopTheGame()
case PlayerJoin(player) => {
log.info("A new player has joined the game - {}", player)
players = players + player
}
case PlayerLeave(player) => {
log.info("A player has left the game - {}", player)
players = players - player
}
case BallThrow(ball) => passBallToNextPlayer(sender(), ball)
}
def startTheGame(): Unit = {
gameOnGoing = true
players.head ! Ball(0)
}
def stopTheGame(): Unit = {
gameOnGoing = false
}
}
object PlayGround {
def props: Props = Props(classOf[PlayGround])
}
游戏,
object Akka1 {
def main(args: Array[String]): Unit = {
val actorSystem = ActorSystem("game_system")
val playGround = actorSystem.actorOf(PlayGround.props)
playGround ! PlayerJoin(actorSystem.actorOf(Player.props))
playGround ! PlayerJoin(actorSystem.actorOf(Player.props))
playGround ! PlayerJoin(actorSystem.actorOf(Player.props))
playGround ! StartTheGame
}
}