finish games when tournament ends

This commit is contained in:
Thibault Duplessis 2012-09-16 20:14:52 +02:00
parent 50615e538d
commit 52a76cf0d0
10 changed files with 51 additions and 7 deletions

View file

@ -107,6 +107,7 @@ final class CoreEnv private (application: Application, val settings: Settings) {
flood = security.flood,
siteSocket = site.socket,
lobbyNotify = lobby.socket.reloadTournaments,
abortGame = round.forceAbort.apply,
mongodb = mongodb.apply _)
lazy val analyse = new lila.analyse.AnalyseEnv(

View file

@ -32,6 +32,10 @@ final class Finisher(
if (pov.game.abortable) finish(pov.game, Aborted)
else !!("game is not abortable")
def forceAbort(game: DbGame): ValidIOEvents =
if (game.playable) finish(game, Aborted)
else !!("game is not playable, cannot be force aborted")
def resign(pov: Pov): ValidIOEvents =
if (pov.game.resignable) finish(pov.game, Resign, Some(!pov.color))
else !!("game is not resignable")

View file

@ -0,0 +1,26 @@
package lila
package round
import game.{ DbGame, GameRepo }
import scalaz.effects._
final class ForceAbort(
gameRepo: GameRepo,
finisher: Finisher,
socket: Socket) {
def apply(id: String): IO[Unit] = for {
gameOption gameRepo game id
_ gameOption.fold(
game (finisher forceAbort game).fold(
err putStrLn(err.shows),
ioEvents for {
events ioEvents
_ io { socket.send(game.id, events) }
} yield ()
),
putStrLn("Cannot abort missing game " + id)
)
} yield ()
}

View file

@ -92,4 +92,9 @@ final class RoundEnv(
lazy val watcherRoomRepo = new WatcherRoomRepo(
mongodb(RoundCollectionWatcherRoom))
lazy val forceAbort = new ForceAbort(
gameRepo = gameRepo,
finisher = finisher,
socket = socket)
}

View file

@ -9,7 +9,8 @@ import scalaz.effects._
final class Queue(collection: MongoCollection) {
def enqueue(game: DbGame): IO[Unit] = enqueue(game.id)
def enqueue(game: DbGame): IO[Unit] =
game.finished.fold(enqueue(game.id), io())
def enqueue(id: String): IO[Unit] = io {
collection += DBObject("_id" -> id)

View file

@ -17,7 +17,10 @@ final class DataForm(isDev: Boolean) {
val clockIncrementDefault = 0
val clockIncrementChoices = options(clockIncrements, "%d second{s}")
val minutes = 10 to 60 by 5
val minutes = isDev.fold(
(1 to 9) ++ (10 to 60 by 5),
10 to 60 by 5
)
val minuteDefault = 30
val minuteChoices = options(minutes, "%d minute{s}")

View file

@ -149,11 +149,13 @@ case class Started(
def clockStatus = "%02d:%02d".format(remainingSeconds / 60, remainingSeconds % 60)
def userCurrentPov(userId: String): Option[PovRef] = {
pairings filter (_.playing) map { _ povRef userId }
playingPairings map { _ povRef userId }
}.flatten.headOption
def userCurrentPov(user: Option[User]): Option[PovRef] =
user.fold(u userCurrentPov(u.id), none)
def playingPairings = pairings filter (_.playing)
def finish = refreshPlayers |> { tour
Finished(
id = tour.id,

View file

@ -17,7 +17,8 @@ final class TournamentApi(
getUser: String IO[Option[User]],
socket: Socket,
siteSocket: site.Socket,
lobbyNotify: String IO[Unit]) {
lobbyNotify: String IO[Unit],
abortGame: String IO[Unit]) {
def makePairings(tour: Started, pairings: NonEmptyList[Pairing]): IO[Unit] =
(tour addPairings pairings) |> { tour2
@ -58,6 +59,7 @@ final class TournamentApi(
_ repo saveIO started.finish
_ socket reloadPage started.id
_ reloadSiteSocket
_ (started.playingPairings map (_.gameId) map abortGame).sequence
} yield ()) doIf started.readyToFinish
def join(tour: Created, me: User): Valid[IO[Unit]] = for {

View file

@ -24,6 +24,7 @@ final class TournamentEnv(
flood: Flood,
siteSocket: site.Socket,
lobbyNotify: String IO[Unit],
abortGame: String IO[Unit],
mongodb: String MongoCollection) {
implicit val ctx = app
@ -41,7 +42,8 @@ final class TournamentEnv(
timelinePush = timelinePush,
socket = socket,
siteSocket = siteSocket,
lobbyNotify = lobbyNotify)
lobbyNotify = lobbyNotify,
abortGame = abortGame)
lazy val roomRepo = new RoomRepo(
collection = mongodb(TournamentCollectionRoom)

2
todo
View file

@ -44,9 +44,7 @@ make hand and finisher actors to avoid racing conditions
tournament crowd
tournament monitor
all hub members should use userIds rather than usernames
finish games when tournament is over
add opera to list of supported browsers (with websocket trick)
tournament ties
tournament detect leavers and withdraw them (started) (also use force resign)
tournament end when all but one players resigned
send lobby new forum posts html through websockets