Table numbers exclusion is functional
This commit is contained in:
@@ -3,6 +3,7 @@ package org.jeudego.pairgoth.api
|
||||
import com.republicate.kson.Json
|
||||
import com.republicate.kson.toJsonArray
|
||||
import org.jeudego.pairgoth.api.ApiHandler.Companion.badRequest
|
||||
import org.jeudego.pairgoth.api.TournamentHandler.dispatchEvent
|
||||
import org.jeudego.pairgoth.model.Game
|
||||
import org.jeudego.pairgoth.model.getID
|
||||
import org.jeudego.pairgoth.model.toID
|
||||
@@ -38,6 +39,7 @@ object PairingHandler: PairgothApiHandler {
|
||||
if (round > tournament.lastRound() + 1) badRequest("invalid round: previous round has not been played")
|
||||
val payload = getArrayPayload(request)
|
||||
if (payload.isEmpty()) badRequest("nobody to pair")
|
||||
// CB TODO - change convention to empty array for all players
|
||||
val allPlayers = payload.size == 1 && payload[0] == "all"
|
||||
//if (!allPlayers && tournament.pairing.type == PairingType.SWISS) badRequest("Swiss pairing requires all pairable players")
|
||||
val playing = (tournament.games(round).values).flatMap {
|
||||
@@ -57,6 +59,10 @@ object PairingHandler: PairgothApiHandler {
|
||||
} ?: badRequest("invalid pairable id: #$id")
|
||||
}
|
||||
val games = tournament.pair(round, pairables)
|
||||
|
||||
// always renumber table to take table exclusion into account
|
||||
tournament.renumberTables(round)
|
||||
|
||||
val ret = games.map { it.toJson() }.toJsonArray()
|
||||
tournament.dispatchEvent(GamesAdded, request, Json.Object("round" to round, "games" to ret))
|
||||
return ret
|
||||
@@ -122,6 +128,14 @@ object PairingHandler: PairgothApiHandler {
|
||||
return Json.Object("success" to true)
|
||||
} else {
|
||||
// without id, it's a table renumbering
|
||||
if (payload.containsKey("excludeTables")) {
|
||||
val tablesExclusion = payload.getString("excludeTables") ?: badRequest("missing 'excludeTables'")
|
||||
TournamentHandler.validateTablesExclusion(tablesExclusion)
|
||||
while (tournament.tablesExclusion.size < round) tournament.tablesExclusion.add("")
|
||||
tournament.tablesExclusion[round - 1] = tablesExclusion
|
||||
tournament.dispatchEvent(TournamentUpdated, request, tournament.toJson())
|
||||
}
|
||||
|
||||
val sortedPairables = tournament.getSortedPairables(round)
|
||||
val sortedMap = sortedPairables.associateBy {
|
||||
it.getID()!!
|
||||
|
@@ -91,7 +91,7 @@ object TournamentHandler: PairgothApiHandler {
|
||||
return Json.Object("success" to true)
|
||||
}
|
||||
|
||||
private fun validateTablesExclusion(exclusion: String) {
|
||||
internal fun validateTablesExclusion(exclusion: String) {
|
||||
if (!tablesExclusionValidator.matches(exclusion)) badRequest("invalid tables exclusion pattern")
|
||||
}
|
||||
|
||||
|
@@ -6,10 +6,12 @@ import com.republicate.kson.toJsonArray
|
||||
//import kotlinx.datetime.LocalDate
|
||||
import java.time.LocalDate
|
||||
import org.jeudego.pairgoth.api.ApiHandler.Companion.badRequest
|
||||
import org.jeudego.pairgoth.api.ApiHandler.Companion.logger
|
||||
import org.jeudego.pairgoth.store.nextPlayerId
|
||||
import org.jeudego.pairgoth.store.nextTournamentId
|
||||
import kotlin.math.max
|
||||
import java.util.*
|
||||
import java.util.regex.Pattern
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
sealed class Tournament <P: Pairable>(
|
||||
@@ -127,9 +129,12 @@ sealed class Tournament <P: Pairable>(
|
||||
fun renumberTables(round: Int, pivot: Game? = null, orderBY: (Game) -> Int = ::defaultGameOrderBy): Boolean {
|
||||
var changed = false
|
||||
var nextTable = 1
|
||||
val excluded = excludedTables(round)
|
||||
games(round).values.filter{ game -> pivot?.let { pivot.id != game.id } ?: true }.sortedBy(orderBY).forEach { game ->
|
||||
while (excluded.contains(nextTable)) ++nextTable
|
||||
if (pivot != null && nextTable == pivot.table) {
|
||||
++nextTable
|
||||
while (excluded.contains(nextTable)) ++nextTable
|
||||
}
|
||||
if (game.table != 0) {
|
||||
changed = changed || game.table != nextTable
|
||||
@@ -150,6 +155,22 @@ sealed class Tournament <P: Pairable>(
|
||||
"ready" to (games.getOrNull(index)?.values?.count { it.result != Game.Result.UNKNOWN } ?: 0)
|
||||
)
|
||||
}.toJsonArray()
|
||||
|
||||
fun excludedTables(round: Int): Set<Int> {
|
||||
if (round > tablesExclusion.size) return emptySet()
|
||||
val excluded = mutableSetOf<Int>()
|
||||
val parser = Regex("(\\d+)(?:-(\\d+))?")
|
||||
parser.findAll(tablesExclusion[round - 1]).forEach { match ->
|
||||
val left = match.groupValues[1].toInt()
|
||||
val right = match.groupValues[2].let { if (it.isEmpty()) left else it.toInt() }
|
||||
var t = left
|
||||
do {
|
||||
excluded.add(t)
|
||||
++t
|
||||
} while (t <= right)
|
||||
}
|
||||
return excluded
|
||||
}
|
||||
}
|
||||
|
||||
// standard tournament of individuals
|
||||
|
Reference in New Issue
Block a user