swiss WIP

This commit is contained in:
Thibault Duplessis 2020-05-07 13:24:34 -06:00
parent 9091390541
commit a04f80506f
5 changed files with 41 additions and 27 deletions

View file

@ -61,11 +61,7 @@ object tournaments {
" • ",
if (s.variant.exotic) s.variant.name else s.perfType.map(_.trans),
" • ",
(if (s.settings.rated) trans.casualTournament else trans.ratedTournament)(),
" • ",
s.round.value,
"/",
s.settings.nbRounds
(if (s.settings.rated) trans.casualTournament else trans.ratedTournament)()
)
)
)

View file

@ -40,7 +40,7 @@ case class Swiss(
def allRounds: List[SwissRound.Number] = (1 to round.value).toList.map(SwissRound.Number.apply)
def finishedRounds: List[SwissRound.Number] = (1 to (round.value - 1)).toList.map(SwissRound.Number.apply)
def guessNbRounds = (nbPlayers - 1) atMost settings.nbRounds
def guessNbRounds = (nbPlayers - 1) atMost settings.nbRounds atLeast 2
def actualNbRounds = if (isFinished) round.value else guessNbRounds
def startRound =

View file

@ -82,27 +82,44 @@ final class SwissJson(
def fetchMyInfo(swiss: Swiss, me: User): Fu[Option[MyInfo]] =
colls.player.byId[SwissPlayer](SwissPlayer.makeId(swiss.id, me.id).value) flatMap {
_ ?? { player =>
SwissPairing.fields { f =>
(swiss.nbOngoing > 0)
.?? {
colls.pairing
.find(
$doc(f.swissId -> swiss.id, f.players -> player.number, f.status -> SwissPairing.ongoing),
$doc(f.id -> true).some
)
.sort($sort desc f.date)
.one[Bdoc]
.dmap { _.flatMap(_.getAsOpt[Game.ID](f.id)) }
}
.flatMap { gameId =>
getOrGuessRank(swiss, player) dmap { rank =>
MyInfo(rank + 1, gameId, me, player).some
updatePlayerRating(swiss, player, me) >>
SwissPairing.fields { f =>
(swiss.nbOngoing > 0)
.?? {
colls.pairing
.find(
$doc(f.swissId -> swiss.id, f.players -> player.number, f.status -> SwissPairing.ongoing),
$doc(f.id -> true).some
)
.sort($sort desc f.date)
.one[Bdoc]
.dmap { _.flatMap(_.getAsOpt[Game.ID](f.id)) }
}
}
}
.flatMap { gameId =>
getOrGuessRank(swiss, player) dmap { rank =>
MyInfo(rank + 1, gameId, me, player).some
}
}
}
}
}
private def updatePlayerRating(swiss: Swiss, player: SwissPlayer, user: User): Funit =
swiss.perfType
.ifTrue(swiss.settings.rated)
.map(user.perfs.apply)
.filter(_.intRating != player.rating)
.?? { perf =>
SwissPlayer.fields { f =>
colls.player.update
.one(
$id(SwissPlayer.makeId(swiss.id, user.id)),
$set(f.rating -> perf.intRating, f.provisional -> perf.provisional)
)
.void
}
}
// if the user is not yet in the cached ranking,
// guess its rank based on other players scores in the DB
private def getOrGuessRank(swiss: Swiss, player: SwissPlayer): Fu[Int] =

View file

@ -51,7 +51,6 @@ object SwissPairing {
}
def fields[A](f: Fields.type => A): A = f(Fields)
// assumes that pairings are already sorted by round (probably by the DB query)
def toMap(pairings: List[SwissPairing]): PairingMap =
pairings.foldLeft[PairingMap](Map.empty) {
case (acc, pairing) =>

View file

@ -12,8 +12,7 @@ final class SwissScoring(
def recompute(swiss: Swiss): Funit = {
for {
prevPlayers <- fetchPlayers(swiss)
pairings <- fetchPairings(swiss)
(prevPlayers, pairings) <- fetchPlayers(swiss) zip fetchPairings(swiss)
pairingMap = SwissPairing.toMap(pairings)
sheets = SwissSheet.many(swiss, prevPlayers, pairingMap)
withPoints = (prevPlayers zip sheets).map {
@ -42,9 +41,12 @@ final class SwissScoring(
_ <- SwissPlayer.fields { f =>
prevPlayers
.zip(players)
.filter {
case (a, b) => a != b
}
.map {
case (prev, player) =>
(prev.score != player.score) ?? colls.player.update
colls.player.update
.one(
$id(player.id),
$set(