<commit_before>package org.jousse.bot
package system

import akka.actor._
import scala.concurrent.duration._
import scala.concurrent.ExecutionContext.Implicits.global
import scala.util.{ Try, Success, Failure }
import user.User

final class Server extends Actor with CustomLogging {

  import Server._

  val rounds = scala.collection.mutable.Map[GameId, ActorRef]()

  var nextArenaRoundId: Option[GameId] = None
  var nextArenaRoundClients: Int = 0

  def receive = akka.event.LoggingReceive {

    case RequestToPlayAlone(user, config) => {
      val replyTo = sender
      addRound(config) match {
        case Failure(e) => replyTo ! Status.Failure(e)
        case Success(round) => {
          round ! Round.Join(Right(user), Driver.Http, inputPromise(replyTo))
          (1 to 3) foreach { _ =>
            round ! Round.Join(Left("random"), Driver.Random, inputPromise(replyTo))
          }
        }
      }
    }

    case RequestToPlayArena(user) => {
      val replyTo = sender
      (nextArenaRoundId.flatMap(rounds.get) match {
        case Some(round) if nextArenaRoundClients < 4 => {
          nextArenaRoundClients = nextArenaRoundClients + 1
          Success(round)
        }
        case _ => addRound(Config.arena) map { round =>
          nextArenaRoundClients = 1
          round
        }
      }) match {
        case Failure(e)     => replyTo ! Status.Failure(e)
        case Success(round) => round ! Round.Join(Right(user), Driver.Http, inputPromise(sender))
      }
    }

    case Play(Pov(gameId, token), dir) => rounds get gameId match {
      case None        => sender ! notFound(s"Unknown game $gameId")
      case Some(round) => round.tell(Round.Play(token, dir), sender)
    }

    case Terminated(round) ⇒ {
      context unwatch round
      rounds filter (_._2 == round) foreach { case (id, _) ⇒ rounds -= id }
    }
  }

  def addRound(config: Config): Try[ActorRef] = config.make map { game =>
    val round = context.actorOf(Props(new Round(game)), name = game.id)
    rounds += (game.id -> round)
    context watch round
    round
  }
}

object Server {

  case class RequestToPlayAlone(user: User, config: Config)
  case class RequestToPlayArena(user: User)

  case class Play(pov: Pov, dir: String)

  import play.api.libs.concurrent.Akka
  import play.api.Play.current
  val actor = Akka.system.actorOf(Props[Server], name = "server")
}<commit_msg>fix arena round attribution<commit_after>package org.jousse.bot
package system

import akka.actor._
import scala.concurrent.duration._
import scala.concurrent.ExecutionContext.Implicits.global
import scala.util.{ Try, Success, Failure }
import user.User

final class Server extends Actor with CustomLogging {

  import Server._

  val rounds = scala.collection.mutable.Map[GameId, ActorRef]()

  var nextArenaRoundId: Option[GameId] = None
  var nextArenaRoundClients: Int = 0

  def receive = akka.event.LoggingReceive {

    case RequestToPlayAlone(user, config) => {
      val replyTo = sender
      addRound(config) match {
        case Failure(e) => replyTo ! Status.Failure(e)
        case Success((_, round)) => {
          round ! Round.Join(Right(user), Driver.Http, inputPromise(replyTo))
          (1 to 3) foreach { _ =>
            round ! Round.Join(Left("random"), Driver.Random, inputPromise(replyTo))
          }
        }
      }
    }

    case RequestToPlayArena(user) => {
      val replyTo = sender
      (nextArenaRoundId.flatMap(rounds.get) match {
        case Some(round) if nextArenaRoundClients < 4 => {
          nextArenaRoundClients = nextArenaRoundClients + 1
          Success(round)
        }
        case _ => addRound(Config.arena) map {
          case (id, round) => {
            nextArenaRoundId = Some(id)
            nextArenaRoundClients = 1
            round
          }
        }
      }) match {
        case Failure(e)     => replyTo ! Status.Failure(e)
        case Success(round) => round ! Round.Join(Right(user), Driver.Http, inputPromise(sender))
      }
    }

    case Play(Pov(gameId, token), dir) => rounds get gameId match {
      case None        => sender ! notFound(s"Unknown game $gameId")
      case Some(round) => round.tell(Round.Play(token, dir), sender)
    }

    case Terminated(round) ⇒ {
      context unwatch round
      rounds filter (_._2 == round) foreach { case (id, _) ⇒ rounds -= id }
    }
  }

  def addRound(config: Config): Try[(GameId, ActorRef)] = config.make map { game =>
    val round = context.actorOf(Props(new Round(game)), name = game.id)
    rounds += (game.id -> round)
    context watch round
    game.id -> round
  }
}

object Server {

  case class RequestToPlayAlone(user: User, config: Config)
  case class RequestToPlayArena(user: User)

  case class Play(pov: Pov, dir: String)

  import play.api.libs.concurrent.Akka
  import play.api.Play.current
  val actor = Akka.system.actorOf(Props[Server], name = "server")
}
{'fraction_non_alphanumeric': 0.11427989407211245, 'fraction_numerical': 0.002851904664901202, 'mean_word_length': 2.7509549274255156, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 34, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1743248', 'n_tokens_mistral': 1547, 'n_tokens_neox': 1496, 'n_words': 376}