More team tournaments debugging
This commit is contained in:
@@ -4,6 +4,8 @@ import com.republicate.kson.Json
|
|||||||
import com.republicate.kson.toJsonArray
|
import com.republicate.kson.toJsonArray
|
||||||
import org.jeudego.pairgoth.api.ApiHandler.Companion.badRequest
|
import org.jeudego.pairgoth.api.ApiHandler.Companion.badRequest
|
||||||
import org.jeudego.pairgoth.model.Game
|
import org.jeudego.pairgoth.model.Game
|
||||||
|
import org.jeudego.pairgoth.model.TeamTournament
|
||||||
|
import org.jeudego.pairgoth.model.TeamTournament.Team
|
||||||
import org.jeudego.pairgoth.model.toJson
|
import org.jeudego.pairgoth.model.toJson
|
||||||
import org.jeudego.pairgoth.server.Event
|
import org.jeudego.pairgoth.server.Event
|
||||||
import javax.servlet.http.HttpServletRequest
|
import javax.servlet.http.HttpServletRequest
|
||||||
@@ -22,8 +24,11 @@ object ResultsHandler: PairgothApiHandler {
|
|||||||
val tournament = getTournament(request)
|
val tournament = getTournament(request)
|
||||||
val round = getSubSelector(request)?.toIntOrNull() ?: badRequest("invalid round number")
|
val round = getSubSelector(request)?.toIntOrNull() ?: badRequest("invalid round number")
|
||||||
val payload = getObjectPayload(request)
|
val payload = getObjectPayload(request)
|
||||||
val game = tournament.games(round)[payload.getInt("id")] ?: badRequest("invalid game id")
|
val game = tournament.individualGames(round)[payload.getInt("id")] ?: badRequest("invalid game id")
|
||||||
game.result = Game.Result.fromSymbol(payload.getChar("result") ?: badRequest("missing result"))
|
game.result = Game.Result.fromSymbol(payload.getChar("result") ?: badRequest("missing result"))
|
||||||
|
if (tournament is TeamTournament && tournament.type.individual) {
|
||||||
|
tournament.propagateIndividualResult(round, game)
|
||||||
|
}
|
||||||
tournament.dispatchEvent(Event.ResultUpdated, request, Json.Object("round" to round, "data" to game))
|
tournament.dispatchEvent(Event.ResultUpdated, request, Json.Object("round" to round, "data" to game))
|
||||||
return Json.Object("success" to true)
|
return Json.Object("success" to true)
|
||||||
}
|
}
|
||||||
@@ -31,9 +36,12 @@ object ResultsHandler: PairgothApiHandler {
|
|||||||
override fun delete(request: HttpServletRequest, response: HttpServletResponse): Json {
|
override fun delete(request: HttpServletRequest, response: HttpServletResponse): Json {
|
||||||
val tournament = getTournament(request)
|
val tournament = getTournament(request)
|
||||||
val round = getSubSelector(request)?.toIntOrNull() ?: badRequest("invalid round number")
|
val round = getSubSelector(request)?.toIntOrNull() ?: badRequest("invalid round number")
|
||||||
for (game in tournament.games(round).values) {
|
for (game in tournament.individualGames(round).values) {
|
||||||
game.result = Game.Result.UNKNOWN
|
game.result = Game.Result.UNKNOWN
|
||||||
}
|
}
|
||||||
|
if (tournament is TeamTournament && tournament.type.individual) {
|
||||||
|
tournament.propagateIndividualResults(round)
|
||||||
|
}
|
||||||
tournament.dispatchEvent(Event.ResultsCleared, request, Json.Object("round" to round))
|
tournament.dispatchEvent(Event.ResultsCleared, request, Json.Object("round" to round))
|
||||||
return Json.Object("success" to true)
|
return Json.Object("success" to true)
|
||||||
}
|
}
|
||||||
|
@@ -16,6 +16,7 @@ import org.jeudego.pairgoth.util.mutableBiMultiMapOf
|
|||||||
import kotlin.math.max
|
import kotlin.math.max
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.regex.Pattern
|
import java.util.regex.Pattern
|
||||||
|
import kotlin.collections.get
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
sealed class Tournament <P: Pairable>(
|
sealed class Tournament <P: Pairable>(
|
||||||
@@ -276,10 +277,15 @@ class TeamTournament(
|
|||||||
if (type.individual) {
|
if (type.individual) {
|
||||||
games.forEach { game ->
|
games.forEach { game ->
|
||||||
individualGames.computeIfAbsent(game.id) { id ->
|
individualGames.computeIfAbsent(game.id) { id ->
|
||||||
|
// Here white and black just denote the first board color
|
||||||
val whitePlayers = teams[game.white]!!.activePlayers(round)
|
val whitePlayers = teams[game.white]!!.activePlayers(round)
|
||||||
val blackPlayers = teams[game.black]!!.activePlayers(round)
|
val blackPlayers = teams[game.black]!!.activePlayers(round)
|
||||||
whitePlayers.zip(blackPlayers).map {
|
whitePlayers.zip(blackPlayers).mapIndexed { i, players ->
|
||||||
Game(nextGameId, game.table, it.first.id, it.second.id)
|
// alternate colors in the following boards
|
||||||
|
if ((i % 2) == 0)
|
||||||
|
Game(nextGameId, game.table, players.first.id, players.second.id)
|
||||||
|
else
|
||||||
|
Game(nextGameId, game.table, players.second.id, players.first.id)
|
||||||
}.toMutableSet()
|
}.toMutableSet()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -355,6 +361,40 @@ class TeamTournament(
|
|||||||
it.playerIds.addAll(teamPlayersIds)
|
it.playerIds.addAll(teamPlayersIds)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun propagateIndividualResult(round: Int, game: Game) {
|
||||||
|
val inverseMap = individualGames.inverse.map { it.key.id to it.value }.toMap()
|
||||||
|
val teamGameID = inverseMap[game.id]
|
||||||
|
val score = individualGames[teamGameID]?.sumOf { game ->
|
||||||
|
when (game.result) {
|
||||||
|
Game.Result.WHITE -> 1
|
||||||
|
Game.Result.BLACK -> -1
|
||||||
|
else -> 0
|
||||||
|
} as Int
|
||||||
|
} ?: error("Team game not found: $teamGameID")
|
||||||
|
val teamGame = games[round - 1].get(teamGameID) ?: error("Team game not found: $teamGameID")
|
||||||
|
teamGame.result =
|
||||||
|
if (score < type.playersNumber / 2.0) Game.Result.BLACK
|
||||||
|
else if (score > type.playersNumber / 2.0) Game.Result.WHITE
|
||||||
|
else Game.Result.UNKNOWN
|
||||||
|
}
|
||||||
|
|
||||||
|
fun propagateIndividualResults(round: Int) {
|
||||||
|
for (teamGame in games(round).values) {
|
||||||
|
val score = individualGames[teamGame.id]?.sumOf { game ->
|
||||||
|
when (game.result) {
|
||||||
|
Game.Result.WHITE -> 1
|
||||||
|
Game.Result.BLACK -> -1
|
||||||
|
else -> 0
|
||||||
|
} as Int
|
||||||
|
} ?: error("Team game not found: $teamGame.id")
|
||||||
|
val teamGame = games[round - 1].get(teamGame.id) ?: error("Team game not found: $teamGame.id")
|
||||||
|
teamGame.result =
|
||||||
|
if (score < type.playersNumber / -2.0) Game.Result.BLACK
|
||||||
|
else if (score > type.playersNumber / 2.0) Game.Result.WHITE
|
||||||
|
else Game.Result.UNKNOWN
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Pairable.asPlayer() = this as? Player
|
fun Pairable.asPlayer() = this as? Player
|
||||||
@@ -406,7 +446,7 @@ fun Tournament.Companion.fromJson(json: Json.Object, default: Tournament<*>? = n
|
|||||||
pairing = json.getObject("pairing")?.let { Pairing.fromJson(it, default?.pairing) } ?: default?.pairing ?: badRequest("missing pairing"),
|
pairing = json.getObject("pairing")?.let { Pairing.fromJson(it, default?.pairing) } ?: default?.pairing ?: badRequest("missing pairing"),
|
||||||
tablesExclusion = json.getArray("tablesExclusion")?.map { item -> item as String }?.toMutableList() ?: default?.tablesExclusion ?: mutableListOf(),
|
tablesExclusion = json.getArray("tablesExclusion")?.map { item -> item as String }?.toMutableList() ?: default?.tablesExclusion ?: mutableListOf(),
|
||||||
individualGames = json.getObject("individualGames")?.entries?.flatMap {
|
individualGames = json.getObject("individualGames")?.entries?.flatMap {
|
||||||
(key, value) -> (value as Json.Array).map { game -> Game.fromJson(game as Json.Object) }.map { Pair(key.toID(), it) }
|
(key, value) -> (value as Json.Array).map { game -> Game.fromJson(game as Json.Object) }.map { key.toID() to it }
|
||||||
}?.let {
|
}?.let {
|
||||||
mutableBiMultiMapOf<ID, Game>(*it.toTypedArray())
|
mutableBiMultiMapOf<ID, Game>(*it.toTypedArray())
|
||||||
} ?: (default as? TeamTournament)?.individualGames ?: mutableBiMultiMapOf<ID, Game>()
|
} ?: (default as? TeamTournament)?.individualGames ?: mutableBiMultiMapOf<ID, Game>()
|
||||||
|
Reference in New Issue
Block a user