Table renumbering ; various bugfixes and enhancements
This commit is contained in:
@@ -16,7 +16,7 @@ interface PairgothApiHandler: ApiHandler {
|
||||
fun Tournament<*>.dispatchEvent(event: Event, data: Json? = null) {
|
||||
Event.dispatch(event, Json.Object("tournament" to id, "data" to data))
|
||||
// when storage is not in memory, the tournament has to be persisted
|
||||
if (event != Event.tournamentAdded && event != Event.tournamentDeleted)
|
||||
if (event != Event.TournamentAdded && event != Event.TournamentDeleted)
|
||||
Store.replaceTournament(this)
|
||||
}
|
||||
|
||||
|
@@ -7,7 +7,6 @@ import org.jeudego.pairgoth.model.Game
|
||||
import org.jeudego.pairgoth.model.getID
|
||||
import org.jeudego.pairgoth.model.toID
|
||||
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.HttpServletResponse
|
||||
@@ -59,7 +58,7 @@ object PairingHandler: PairgothApiHandler {
|
||||
}
|
||||
val games = tournament.pair(round, pairables)
|
||||
val ret = games.map { it.toJson() }.toJsonArray()
|
||||
tournament.dispatchEvent(gamesAdded, Json.Object("round" to round, "games" to ret))
|
||||
tournament.dispatchEvent(GamesAdded, Json.Object("round" to round, "games" to ret))
|
||||
return ret
|
||||
}
|
||||
|
||||
@@ -78,6 +77,7 @@ object PairingHandler: PairgothApiHandler {
|
||||
game.black = payload.getID("b") ?: badRequest("missing black player id")
|
||||
game.white = payload.getID("w") ?: badRequest("missing white player id")
|
||||
tournament.recomputeDUDD(round, game.id)
|
||||
val previousTable = game.table;
|
||||
// temporary
|
||||
payload.getInt("dudd")?.let { game.drawnUpDown = it }
|
||||
val black = tournament.pairables[game.black] ?: badRequest("invalid black player id")
|
||||
@@ -90,10 +90,15 @@ object PairingHandler: PairgothApiHandler {
|
||||
if (playing.contains(white.id)) badRequest("white is already in another game")
|
||||
if (payload.containsKey("h")) game.handicap = payload.getString("h")?.toIntOrNull() ?: badRequest("invalid handicap")
|
||||
if (payload.containsKey("t")) {
|
||||
// TODO CB - update *all* tables numbers accordingly
|
||||
game.table = payload.getString("t")?.toIntOrNull() ?: badRequest("invalid table number")
|
||||
}
|
||||
tournament.dispatchEvent(gameUpdated, Json.Object("round" to round, "game" to game.toJson()))
|
||||
tournament.dispatchEvent(GameUpdated, Json.Object("round" to round, "game" to game.toJson()))
|
||||
if (game.table != previousTable && tournament.renumberTables(round, game)) {
|
||||
val games = tournament.games(round).values.sortedBy {
|
||||
if (it.table == 0) Int.MAX_VALUE else it.table
|
||||
}
|
||||
tournament.dispatchEvent(TablesRenumbered, Json.Object("round" to round, "games" to games.map { it.toJson() }.toCollection(Json.MutableArray())))
|
||||
}
|
||||
return Json.Object("success" to true)
|
||||
}
|
||||
|
||||
@@ -111,7 +116,7 @@ object PairingHandler: PairgothApiHandler {
|
||||
payload.forEach {
|
||||
val id = (it as Number).toInt()
|
||||
val game = tournament.games(round)[id] ?: throw Error("invalid game id")
|
||||
if (game.result != Game.Result.UNKNOWN) {
|
||||
if (game.result != Game.Result.UNKNOWN && game.black != 0 && game.white != 0) {
|
||||
ApiHandler.logger.error("cannot unpair game id ${game.id}: it has a result")
|
||||
// we'll only skip it
|
||||
// throw Error("cannot unpair ")
|
||||
@@ -120,7 +125,7 @@ object PairingHandler: PairgothApiHandler {
|
||||
}
|
||||
}
|
||||
}
|
||||
tournament.dispatchEvent(gamesDeleted, Json.Object("round" to round, "games" to payload))
|
||||
tournament.dispatchEvent(GamesDeleted, Json.Object("round" to round, "games" to payload))
|
||||
return Json.Object("success" to true)
|
||||
}
|
||||
}
|
||||
|
@@ -5,7 +5,6 @@ import com.republicate.kson.toJsonArray
|
||||
import org.jeudego.pairgoth.api.ApiHandler.Companion.badRequest
|
||||
import org.jeudego.pairgoth.model.Player
|
||||
import org.jeudego.pairgoth.model.fromJson
|
||||
import org.jeudego.pairgoth.server.Event
|
||||
import org.jeudego.pairgoth.server.Event.*
|
||||
import javax.servlet.http.HttpServletRequest
|
||||
import javax.servlet.http.HttpServletResponse
|
||||
@@ -25,7 +24,7 @@ object PlayerHandler: PairgothApiHandler {
|
||||
val payload = getObjectPayload(request)
|
||||
val player = Player.fromJson(payload)
|
||||
tournament.players[player.id] = player
|
||||
tournament.dispatchEvent(playerAdded, player.toJson())
|
||||
tournament.dispatchEvent(PlayerAdded, player.toJson())
|
||||
return Json.Object("success" to true, "id" to player.id)
|
||||
}
|
||||
|
||||
@@ -36,7 +35,7 @@ object PlayerHandler: PairgothApiHandler {
|
||||
val payload = getObjectPayload(request)
|
||||
val updated = Player.fromJson(payload, player)
|
||||
tournament.players[updated.id] = updated
|
||||
tournament.dispatchEvent(playerUpdated, player.toJson())
|
||||
tournament.dispatchEvent(PlayerUpdated, player.toJson())
|
||||
return Json.Object("success" to true)
|
||||
}
|
||||
|
||||
@@ -44,7 +43,7 @@ object PlayerHandler: PairgothApiHandler {
|
||||
val tournament = getTournament(request)
|
||||
val id = getSubSelector(request)?.toIntOrNull() ?: badRequest("missing or invalid player selector")
|
||||
tournament.players.remove(id) ?: badRequest("invalid player id")
|
||||
tournament.dispatchEvent(playerDeleted, Json.Object("id" to id))
|
||||
tournament.dispatchEvent(PlayerDeleted, Json.Object("id" to id))
|
||||
return Json.Object("success" to true)
|
||||
}
|
||||
}
|
||||
|
@@ -24,7 +24,7 @@ object ResultsHandler: PairgothApiHandler {
|
||||
val payload = getObjectPayload(request)
|
||||
val game = tournament.games(round)[payload.getInt("id")] ?: badRequest("invalid game id")
|
||||
game.result = Game.Result.fromSymbol(payload.getChar("result") ?: badRequest("missing result"))
|
||||
tournament.dispatchEvent(Event.resultUpdated, Json.Object("round" to round, "data" to game))
|
||||
tournament.dispatchEvent(Event.ResultUpdated, Json.Object("round" to round, "data" to game))
|
||||
return Json.Object("success" to true)
|
||||
}
|
||||
}
|
||||
|
@@ -4,7 +4,6 @@ import com.republicate.kson.Json
|
||||
import com.republicate.kson.toJsonArray
|
||||
import org.jeudego.pairgoth.api.ApiHandler.Companion.badRequest
|
||||
import org.jeudego.pairgoth.model.TeamTournament
|
||||
import org.jeudego.pairgoth.server.Event
|
||||
import org.jeudego.pairgoth.server.Event.*
|
||||
import javax.servlet.http.HttpServletRequest
|
||||
import javax.servlet.http.HttpServletResponse
|
||||
@@ -26,7 +25,7 @@ object TeamHandler: PairgothApiHandler {
|
||||
val payload = getObjectPayload(request)
|
||||
val team = tournament.teamFromJson(payload)
|
||||
tournament.teams[team.id] = team
|
||||
tournament.dispatchEvent(teamAdded, team.toJson())
|
||||
tournament.dispatchEvent(TeamAdded, team.toJson())
|
||||
return Json.Object("success" to true, "id" to team.id)
|
||||
}
|
||||
|
||||
@@ -38,7 +37,7 @@ object TeamHandler: PairgothApiHandler {
|
||||
val payload = getObjectPayload(request)
|
||||
val updated = tournament.teamFromJson(payload, team)
|
||||
tournament.teams[updated.id] = updated
|
||||
tournament.dispatchEvent(teamUpdated, team.toJson())
|
||||
tournament.dispatchEvent(TeamUpdated, team.toJson())
|
||||
return Json.Object("success" to true)
|
||||
}
|
||||
|
||||
@@ -47,7 +46,7 @@ object TeamHandler: PairgothApiHandler {
|
||||
if (tournament !is TeamTournament) badRequest("tournament is not a team tournament")
|
||||
val id = getSubSelector(request)?.toIntOrNull() ?: badRequest("missing or invalid team selector")
|
||||
tournament.teams.remove(id) ?: badRequest("invalid team id")
|
||||
tournament.dispatchEvent(teamDeleted, Json.Object("id" to id))
|
||||
tournament.dispatchEvent(TeamDeleted, Json.Object("id" to id))
|
||||
return Json.Object("success" to true)
|
||||
}
|
||||
}
|
||||
|
@@ -11,7 +11,6 @@ import org.jeudego.pairgoth.model.fromJson
|
||||
import org.jeudego.pairgoth.model.toJson
|
||||
import org.jeudego.pairgoth.store.Store
|
||||
import org.jeudego.pairgoth.server.ApiServlet
|
||||
import org.jeudego.pairgoth.server.Event
|
||||
import org.jeudego.pairgoth.server.Event.*
|
||||
import org.w3c.dom.Element
|
||||
import javax.servlet.http.HttpServletRequest
|
||||
@@ -44,7 +43,7 @@ object TournamentHandler: PairgothApiHandler {
|
||||
else -> badRequest("missing or invalid payload")
|
||||
}
|
||||
Store.addTournament(tournament)
|
||||
tournament.dispatchEvent(tournamentAdded, tournament.toJson())
|
||||
tournament.dispatchEvent(TournamentAdded, tournament.toJson())
|
||||
return Json.Object("success" to true, "id" to tournament.id)
|
||||
}
|
||||
|
||||
@@ -64,14 +63,14 @@ object TournamentHandler: PairgothApiHandler {
|
||||
clear()
|
||||
putAll(tournament.games(round))
|
||||
}
|
||||
updated.dispatchEvent(tournamentUpdated, updated.toJson())
|
||||
updated.dispatchEvent(TournamentUpdated, updated.toJson())
|
||||
return Json.Object("success" to true)
|
||||
}
|
||||
|
||||
override fun delete(request: HttpServletRequest): Json {
|
||||
val tournament = getTournament(request)
|
||||
Store.deleteTournament(tournament)
|
||||
tournament.dispatchEvent(tournamentDeleted, Json.Object("id" to tournament.id))
|
||||
tournament.dispatchEvent(TournamentDeleted, Json.Object("id" to tournament.id))
|
||||
return Json.Object("success" to true)
|
||||
}
|
||||
}
|
||||
|
@@ -90,6 +90,23 @@ sealed class Tournament <P: Pairable>(
|
||||
val blackplayer = solver.pairables.find { p-> p.id == game.black }!!
|
||||
game.drawnUpDown = solver.dudd(blackplayer, whiteplayer)
|
||||
}
|
||||
|
||||
fun renumberTables(round: Int, pivot: Game? = null): Boolean {
|
||||
var changed = false
|
||||
var nextTable = 1
|
||||
games(round).values.filter{ game -> pivot?.let { pivot.id != game.id } ?: true }.sortedBy { game ->
|
||||
val whiteRank = pairables[game.white]?.rating ?: Int.MIN_VALUE
|
||||
val blackRank = pairables[game.black]?.rating ?: Int.MIN_VALUE
|
||||
-(2 * whiteRank + 2 * blackRank) / 2
|
||||
}.forEach { game ->
|
||||
if (pivot != null && nextTable == pivot.table) {
|
||||
++nextTable
|
||||
}
|
||||
changed = changed || game.table != nextTable
|
||||
game.table = nextTable++
|
||||
}
|
||||
return changed
|
||||
}
|
||||
}
|
||||
|
||||
// standard tournament of individuals
|
||||
|
@@ -4,19 +4,20 @@ import info.macias.sse.events.MessageEvent
|
||||
import java.util.concurrent.atomic.AtomicLong
|
||||
|
||||
enum class Event {
|
||||
tournamentAdded,
|
||||
tournamentUpdated,
|
||||
tournamentDeleted,
|
||||
playerAdded,
|
||||
playerUpdated,
|
||||
playerDeleted,
|
||||
teamAdded,
|
||||
teamUpdated,
|
||||
teamDeleted,
|
||||
gamesAdded,
|
||||
gamesDeleted,
|
||||
gameUpdated,
|
||||
resultUpdated,
|
||||
TournamentAdded,
|
||||
TournamentUpdated,
|
||||
TournamentDeleted,
|
||||
PlayerAdded,
|
||||
PlayerUpdated,
|
||||
PlayerDeleted,
|
||||
TeamAdded,
|
||||
TeamUpdated,
|
||||
TeamDeleted,
|
||||
GamesAdded,
|
||||
GamesDeleted,
|
||||
GameUpdated,
|
||||
ResultUpdated,
|
||||
TablesRenumbered
|
||||
;
|
||||
|
||||
companion object {
|
||||
|
Reference in New Issue
Block a user