fix tournament idle resign bug
parent
d98a6f954b
commit
0d132d0826
|
@ -342,6 +342,8 @@ case class DbGame(
|
|||
|
||||
def playerMoves(color: Color): Int = (turns + color.fold(1, 0)) / 2
|
||||
|
||||
def playerHasMoved(color: Color) = playerMoves(color) > 0
|
||||
|
||||
def playerBlurPercent(color: Color): Int = (turns > 5).fold(
|
||||
(player(color).blurs * 100) / playerMoves(color),
|
||||
0
|
||||
|
|
|
@ -33,4 +33,7 @@ object Pov {
|
|||
game player playerId map { p ⇒ new Pov(game, p.color) }
|
||||
}
|
||||
|
||||
case class PovRef(gameId: String, color: Color)
|
||||
case class PovRef(gameId: String, color: Color) {
|
||||
|
||||
def unary_! = PovRef(gameId, !color)
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ final class RoundEnv(
|
|||
playerTimeout = RoundPlayerTimeout
|
||||
)), name = ActorRoundHubMaster)
|
||||
|
||||
lazy val moveNotifier = new MoveNotifier(
|
||||
private lazy val moveNotifier = new MoveNotifier(
|
||||
siteHubName = ActorSiteHub,
|
||||
lobbyHubName = ActorLobbyHub,
|
||||
tournamentHubMasterName = ActorTournamentHubMaster,
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
package lila
|
||||
package tournament
|
||||
|
||||
import game.{ DbGame, DbPlayer, GameRepo, Pov }
|
||||
import chess.Color
|
||||
import game.{ DbGame, DbPlayer, GameRepo, Pov, PovRef }
|
||||
import user.User
|
||||
import round.Meddler
|
||||
|
||||
|
@ -16,6 +17,8 @@ final class GameJoiner(
|
|||
timelinePush: DbGame ⇒ IO[Unit],
|
||||
getUser: String ⇒ IO[Option[User]]) {
|
||||
|
||||
private val secondsToMove = 20
|
||||
|
||||
def apply(tour: Started)(pairing: Pairing): IO[DbGame] = for {
|
||||
user1 ← getUser(pairing.user1) map (_ err "No such user " + pairing)
|
||||
user2 ← getUser(pairing.user2) map (_ err "No such user " + pairing)
|
||||
|
@ -38,23 +41,31 @@ final class GameJoiner(
|
|||
_ ← gameRepo insert game
|
||||
_ ← gameRepo denormalizeStarted game
|
||||
_ ← timelinePush(game)
|
||||
_ ← scheduleIdleCheck(game.id)
|
||||
_ ← scheduleIdleCheck(PovRef(game.id, Color.White), secondsToMove)
|
||||
} yield game
|
||||
|
||||
private def scheduleIdleCheck(gameId: String) = io {
|
||||
Akka.system.scheduler.scheduleOnce(20 seconds)(idleCheck(gameId))
|
||||
}
|
||||
private def scheduleIdleCheck(povRef: PovRef, in: Int) = io {
|
||||
Akka.system.scheduler.scheduleOnce(in seconds)(idleCheck(povRef))
|
||||
} map (_ ⇒ ())
|
||||
|
||||
private def idleCheck(gameId: String) {
|
||||
private def idleCheck(povRef: PovRef) {
|
||||
(for {
|
||||
gameOption ← gameRepo game gameId
|
||||
_ ← gameOption.fold(
|
||||
game ⇒ game.playerWhoDidNotMove.fold(
|
||||
player ⇒ roundMeddler resign Pov(game, player),
|
||||
io()
|
||||
),
|
||||
io()
|
||||
)
|
||||
povOption ← gameRepo pov povRef
|
||||
_ ← povOption.filter(_.game.playable).fold(idleResult, io())
|
||||
} yield ()).unsafePerformIO
|
||||
}
|
||||
|
||||
private def idleResult(pov: Pov) = {
|
||||
val idle = !pov.game.playerHasMoved(pov.color)
|
||||
idle.fold(
|
||||
roundMeddler resign pov,
|
||||
(pov.color.white && !pov.game.playerHasMoved(Color.Black)).fold(
|
||||
scheduleIdleCheck(!pov.ref, pov.game.lastMoveTime.fold(
|
||||
lastMoveTime ⇒ lastMoveTime - nowSeconds + secondsToMove,
|
||||
secondsToMove
|
||||
)),
|
||||
io()
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ final class HubMaster(
|
|||
|
||||
case msg @ SendTo(_, _) ⇒ hubs.values foreach (_ ! msg)
|
||||
|
||||
case Forward(id, msg) ⇒ hubs.get(id).foreach(_ ! msg)
|
||||
case Forward(id, msg) ⇒ hubs get id foreach (_ ! msg)
|
||||
|
||||
case GetHub(id: String) ⇒ sender ! {
|
||||
(hubs get id) | {
|
||||
|
|
1
todo
1
todo
|
@ -49,7 +49,6 @@ tournament detect leavers and withdraw them (started) (also use force resign)
|
|||
-> or show current tournament on every page, with (join) and (redraw) buttons
|
||||
tournament warmup games
|
||||
send lobby new forum posts html through websockets
|
||||
BUG tournament idle resign: based on 20 seconds added time! can make black resign by playing after 19s
|
||||
AI thinks during your time (premove?) http://en.lichess.org/forum/lichess-feedback/y-u-so-greedy-with-time-stockfish#4
|
||||
- in fact it does not, but the UI clocks only update once the ai made the move
|
||||
- solution: do AI asynchronously. Send player move events right away,
|
||||
|
|
Loading…
Reference in New Issue