Fix tables numbers

This commit is contained in:
Claude Brisson
2024-01-20 12:38:35 +01:00
parent 48fc66ab52
commit fd1df8762a
7 changed files with 24 additions and 16 deletions

View File

@@ -23,7 +23,9 @@ object PairingHandler: PairgothApiHandler {
}.toSet() }.toSet()
val unpairables = tournament.pairables.values.filter { !it.final || it.skip.contains(round) }.sortedByDescending { it.rating }.map { it.id }.toJsonArray() val unpairables = tournament.pairables.values.filter { !it.final || it.skip.contains(round) }.sortedByDescending { it.rating }.map { it.id }.toJsonArray()
val pairables = tournament.pairables.values.filter { it.final && !it.skip.contains(round) && !playing.contains(it.id) }.sortedByDescending { it.rating }.map { it.id }.toJsonArray() val pairables = tournament.pairables.values.filter { it.final && !it.skip.contains(round) && !playing.contains(it.id) }.sortedByDescending { it.rating }.map { it.id }.toJsonArray()
val games = tournament.games(round).values val games = tournament.games(round).values.sortedBy {
if (it.table == 0) Int.MAX_VALUE else it.table
}
return Json.Object( return Json.Object(
"games" to games.map { it.toJson() }.toCollection(Json.MutableArray()), "games" to games.map { it.toJson() }.toCollection(Json.MutableArray()),
"pairables" to pairables, "pairables" to pairables,

View File

@@ -6,6 +6,7 @@ import org.jeudego.pairgoth.model.MainCritParams.SeedMethod.SPLIT_AND_SLIP
import org.jeudego.pairgoth.model.PairingType.* import org.jeudego.pairgoth.model.PairingType.*
import org.jeudego.pairgoth.pairing.solver.MacMahonSolver import org.jeudego.pairgoth.pairing.solver.MacMahonSolver
import org.jeudego.pairgoth.pairing.solver.SwissSolver import org.jeudego.pairgoth.pairing.solver.SwissSolver
import java.util.*
// base pairing parameters // base pairing parameters
data class BaseCritParams( data class BaseCritParams(
@@ -172,7 +173,7 @@ class Swiss(
): Pairing(SWISS, pairingParams, placementParams) { ): Pairing(SWISS, pairingParams, placementParams) {
companion object {} companion object {}
override fun pair(tournament: Tournament<*>, round: Int, pairables: List<Pairable>): List<Game> { override fun pair(tournament: Tournament<*>, round: Int, pairables: List<Pairable>): List<Game> {
return SwissSolver(round, tournament.historyBefore(round), pairables, pairingParams, placementParams).pair() return SwissSolver(round, tournament.historyBefore(round), pairables, pairingParams, placementParams, tournament.usedTables(round)).pair()
} }
} }
@@ -201,7 +202,7 @@ class MacMahon(
): Pairing(MAC_MAHON, pairingParams, placementParams) { ): Pairing(MAC_MAHON, pairingParams, placementParams) {
companion object {} companion object {}
override fun pair(tournament: Tournament<*>, round: Int, pairables: List<Pairable>): List<Game> { override fun pair(tournament: Tournament<*>, round: Int, pairables: List<Pairable>): List<Game> {
return MacMahonSolver(round, tournament.historyBefore(round), pairables, pairingParams, placementParams, mmFloor, mmBar).pair() return MacMahonSolver(round, tournament.historyBefore(round), pairables, pairingParams, placementParams, tournament.usedTables(round), mmFloor, mmBar).pair()
} }
} }

View File

@@ -7,6 +7,7 @@ import org.jeudego.pairgoth.api.ApiHandler.Companion.badRequest
import org.jeudego.pairgoth.pairing.solver.MacMahonSolver import org.jeudego.pairgoth.pairing.solver.MacMahonSolver
import org.jeudego.pairgoth.pairing.solver.SwissSolver import org.jeudego.pairgoth.pairing.solver.SwissSolver
import org.jeudego.pairgoth.store.Store import org.jeudego.pairgoth.store.Store
import java.util.*
import kotlin.math.roundToInt import kotlin.math.roundToInt
sealed class Tournament <P: Pairable>( sealed class Tournament <P: Pairable>(
@@ -68,13 +69,19 @@ sealed class Tournament <P: Pairable>(
else mutableMapOf<ID, Game>().also { games.add(it) } else mutableMapOf<ID, Game>().also { games.add(it) }
fun lastRound() = games.size fun lastRound() = games.size
fun usedTables(round: Int): BitSet =
games(round).values.map { it.table }.fold(BitSet()) { acc, table ->
acc.set(table)
acc
}
fun recomputeDUDD(round: Int, gameID: ID) { fun recomputeDUDD(round: Int, gameID: ID) {
// Instantiate solver with game history // Instantiate solver with game history
// TODO cleaner solver instantiation // TODO cleaner solver instantiation
val history = games.map { games -> games.values.toList() } val history = games.map { games -> games.values.toList() }
val solver = when (pairing.type) { val solver = when (pairing.type) {
PairingType.SWISS -> SwissSolver(round, history, pairables.values.toList(), pairing.pairingParams, pairing.placementParams) PairingType.SWISS -> SwissSolver(round, history, pairables.values.toList(), pairing.pairingParams, pairing.placementParams, usedTables(round))
PairingType.MAC_MAHON -> MacMahonSolver(round, history, pairables.values.toList(), pairing.pairingParams, pairing.placementParams, mmBar = 3, mmFloor = -20) PairingType.MAC_MAHON -> MacMahonSolver(round, history, pairables.values.toList(), pairing.pairingParams, pairing.placementParams, usedTables(round), mmBar = 3, mmFloor = -20)
else -> throw Exception("Invalid tournament type") else -> throw Exception("Invalid tournament type")
} }
// Recomputes DUDD // Recomputes DUDD

View File

@@ -134,11 +134,4 @@ abstract class BasePairingHelper(
open fun nameSort(p: Pairable, q: Pairable): Int { open fun nameSort(p: Pairable, q: Pairable): Int {
return if (p.name > q.name) 1 else -1 return if (p.name > q.name) 1 else -1
} }
val tables = history.mapTo(mutableListOf()) { games ->
games.map { it.table }.fold(BitSet()) { acc, table ->
acc.set(table)
acc
}
}
} }

View File

@@ -26,6 +26,7 @@ sealed class BaseSolver(
pairables: List<Pairable>, // All pairables for this round, it may include the bye player pairables: List<Pairable>, // All pairables for this round, it may include the bye player
pairing: PairingParams, pairing: PairingParams,
placement: PlacementParams, placement: PlacementParams,
val usedTables: BitSet
) : BasePairingHelper(history, pairables, pairing, placement) { ) : BasePairingHelper(history, pairables, pairing, placement) {
companion object { companion object {
@@ -532,7 +533,6 @@ sealed class BaseSolver(
} }
open fun games(black: Pairable, white: Pairable): List<Game> { open fun games(black: Pairable, white: Pairable): List<Game> {
// CB TODO team of individuals pairing // CB TODO team of individuals pairing
val usedTables = tables.getOrNull(round - 1) ?: BitSet().also { tables.add(it) }
val table = if (black.id == 0 || white.id == 0) 0 else usedTables.nextClearBit(1) val table = if (black.id == 0 || white.id == 0) 0 else usedTables.nextClearBit(1)
usedTables.set(table) usedTables.set(table)
return listOf(Game(id = Store.nextGameId, table = table, black = black.id, white = white.id, handicap = pairing.handicap.handicap(white, black), drawnUpDown = dudd(black, white))) return listOf(Game(id = Store.nextGameId, table = table, black = black.id, white = white.id, handicap = pairing.handicap.handicap(white, black), drawnUpDown = dudd(black, white)))

View File

@@ -1,6 +1,7 @@
package org.jeudego.pairgoth.pairing.solver package org.jeudego.pairgoth.pairing.solver
import org.jeudego.pairgoth.model.* import org.jeudego.pairgoth.model.*
import java.util.*
import kotlin.math.max import kotlin.math.max
import kotlin.math.min import kotlin.math.min
@@ -9,8 +10,9 @@ class MacMahonSolver(round: Int,
pairables: List<Pairable>, pairables: List<Pairable>,
pairingParams: PairingParams, pairingParams: PairingParams,
placementParams: PlacementParams, placementParams: PlacementParams,
usedTables: BitSet,
private val mmFloor: Int, private val mmBar: Int): private val mmFloor: Int, private val mmBar: Int):
BaseSolver(round, history, pairables, pairingParams, placementParams) { BaseSolver(round, history, pairables, pairingParams, placementParams, usedTables) {
override val scores: Map<ID, Double> by lazy { override val scores: Map<ID, Double> by lazy {
pairablesMap.mapValues { pairablesMap.mapValues {

View File

@@ -1,13 +1,16 @@
package org.jeudego.pairgoth.pairing.solver package org.jeudego.pairgoth.pairing.solver
import org.jeudego.pairgoth.model.* import org.jeudego.pairgoth.model.*
import java.util.*
class SwissSolver(round: Int, class SwissSolver(round: Int,
history: List<List<Game>>, history: List<List<Game>>,
pairables: List<Pairable>, pairables: List<Pairable>,
pairingParams: PairingParams, pairingParams: PairingParams,
placementParams: PlacementParams): placementParams: PlacementParams,
BaseSolver(round, history, pairables, pairingParams, placementParams) { usedTables: BitSet
):
BaseSolver(round, history, pairables, pairingParams, placementParams, usedTables) {
// In a Swiss tournament the main criterion is the number of wins and already computed // In a Swiss tournament the main criterion is the number of wins and already computed