From eb81d8d2d26561750808015936e8e0986572f594 Mon Sep 17 00:00:00 2001 From: Theo Barollet Date: Thu, 28 Dec 2023 16:27:35 +0100 Subject: [PATCH 1/2] recomputing dudd when putting games --- .../org/jeudego/pairgoth/api/PairingHandler.kt | 1 + .../org/jeudego/pairgoth/model/Tournament.kt | 18 ++++++++++++++++++ .../pairgoth/pairing/solver/BaseSolver.kt | 13 +++++++++++-- 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/api-webapp/src/main/kotlin/org/jeudego/pairgoth/api/PairingHandler.kt b/api-webapp/src/main/kotlin/org/jeudego/pairgoth/api/PairingHandler.kt index 9fd8327..256490b 100644 --- a/api-webapp/src/main/kotlin/org/jeudego/pairgoth/api/PairingHandler.kt +++ b/api-webapp/src/main/kotlin/org/jeudego/pairgoth/api/PairingHandler.kt @@ -57,6 +57,7 @@ object PairingHandler: PairgothApiHandler { val game = tournament.games(round)[payload.getInt("id")] ?: badRequest("invalid game id") 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) if (payload.containsKey("h")) game.handicap = payload.getString("h")?.toIntOrNull() ?: badRequest("invalid handicap") tournament.dispatchEvent(gameUpdated, Json.Object("round" to round, "game" to game.toJson())) return Json.Object("success" to true) diff --git a/api-webapp/src/main/kotlin/org/jeudego/pairgoth/model/Tournament.kt b/api-webapp/src/main/kotlin/org/jeudego/pairgoth/model/Tournament.kt index 3f03473..19d456d 100644 --- a/api-webapp/src/main/kotlin/org/jeudego/pairgoth/model/Tournament.kt +++ b/api-webapp/src/main/kotlin/org/jeudego/pairgoth/model/Tournament.kt @@ -4,6 +4,8 @@ import com.republicate.kson.Json import com.republicate.kson.toJsonArray import kotlinx.datetime.LocalDate import org.jeudego.pairgoth.api.ApiHandler.Companion.badRequest +import org.jeudego.pairgoth.pairing.solver.MacMahonSolver +import org.jeudego.pairgoth.pairing.solver.SwissSolver import org.jeudego.pairgoth.store.Store import kotlin.math.roundToInt @@ -65,6 +67,22 @@ sealed class Tournament ( if (round > games.size + 1) throw Error("invalid round") else mutableMapOf().also { games.add(it) } fun lastRound() = games.size + + fun recomputeDUDD(round: Int, gameID: ID) { + // Instantiate solver with game history + // TODO cleaner solver instantiation + val history = games.map { games -> games.values.toList() } + val solver = when (pairing.type) { + PairingType.SWISS -> SwissSolver(round, history, pairables.values.toList(), pairing.pairingParams, pairing.placementParams) + PairingType.MAC_MAHON -> MacMahonSolver(round, history, pairables.values.toList(), pairing.pairingParams, pairing.placementParams, mmBar = 3, mmFloor = -20) + else -> throw Exception("Invalid tournament type") + } + // Recomputes DUDD + val game = games(round)[gameID]!! + val whiteplayer = solver.pairables.find { p-> p.id == game.white }!! + val blackplayer = solver.pairables.find { p-> p.id == game.black }!! + game.drawnUpDown = solver.dudd(blackplayer, whiteplayer) + } } // standard tournament of individuals diff --git a/api-webapp/src/main/kotlin/org/jeudego/pairgoth/pairing/solver/BaseSolver.kt b/api-webapp/src/main/kotlin/org/jeudego/pairgoth/pairing/solver/BaseSolver.kt index a4b9528..7e6ad3b 100644 --- a/api-webapp/src/main/kotlin/org/jeudego/pairgoth/pairing/solver/BaseSolver.kt +++ b/api-webapp/src/main/kotlin/org/jeudego/pairgoth/pairing/solver/BaseSolver.kt @@ -428,7 +428,12 @@ sealed class BaseSolver( val placementScoreRange = groupsCount //val geoMaxCost = avoidSameGeo - val geoMaxCost = 100000000000.0 + // TODO Fix import of avoidSameGeo in opengotha so this is not needed + val geoMaxCost = if (avoidSameGeo == 0.0) { + 0.0 + } else { + 100000000000.0 + } val countryFactor = preferMMSDiffRatherThanSameCountry val clubFactor: Int = preferMMSDiffRatherThanSameClub @@ -533,9 +538,13 @@ sealed class BaseSolver( return scale * (1.0 - x) * (1.0 + k * x) } + fun dudd(black: Pairable, white: Pairable) : Int { + return white.group - black.group + } + open fun games(black: Pairable, white: Pairable): List { // CB TODO team of individuals pairing - return listOf(Game(id = Store.nextGameId, black = black.id, white = white.id, handicap = pairing.handicap.handicap(black, white), drawnUpDown = white.group-black.group)) + return listOf(Game(id = Store.nextGameId, black = black.id, white = white.id, handicap = pairing.handicap.handicap(black, white), drawnUpDown = dudd(black, white))) } } From ddd7e74c098266bd8b0fd8085ca44276fde4ca13 Mon Sep 17 00:00:00 2001 From: Theo Barollet Date: Thu, 28 Dec 2023 16:36:41 +0100 Subject: [PATCH 2/2] recomputing dudd when putting games --- .../main/kotlin/org/jeudego/pairgoth/api/PairingHandler.kt | 1 + .../kotlin/org/jeudego/pairgoth/pairing/solver/BaseSolver.kt | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/api-webapp/src/main/kotlin/org/jeudego/pairgoth/api/PairingHandler.kt b/api-webapp/src/main/kotlin/org/jeudego/pairgoth/api/PairingHandler.kt index 4e6b07c..ef15003 100644 --- a/api-webapp/src/main/kotlin/org/jeudego/pairgoth/api/PairingHandler.kt +++ b/api-webapp/src/main/kotlin/org/jeudego/pairgoth/api/PairingHandler.kt @@ -73,6 +73,7 @@ object PairingHandler: PairgothApiHandler { }.toSet() 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) // temporary payload.getInt("dudd")?.let { game.drawnUpDown = it } val black = tournament.pairables[game.black] ?: badRequest("invalid black player id") diff --git a/api-webapp/src/main/kotlin/org/jeudego/pairgoth/pairing/solver/BaseSolver.kt b/api-webapp/src/main/kotlin/org/jeudego/pairgoth/pairing/solver/BaseSolver.kt index e21cfc5..f49d819 100644 --- a/api-webapp/src/main/kotlin/org/jeudego/pairgoth/pairing/solver/BaseSolver.kt +++ b/api-webapp/src/main/kotlin/org/jeudego/pairgoth/pairing/solver/BaseSolver.kt @@ -527,11 +527,14 @@ sealed class BaseSolver( return scale * (1.0 - x) * (1.0 + k * x) } + fun dudd(black: Pairable, white: Pairable): Int { + return white.group - black.group + } open fun games(black: Pairable, white: Pairable): List { // 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) usedTables.set(table) - return listOf(Game(id = Store.nextGameId, table = table, black = black.id, white = white.id, handicap = pairing.handicap.handicap(white, black), drawnUpDown = white.group-black.group)) + return listOf(Game(id = Store.nextGameId, table = table, black = black.id, white = white.id, handicap = pairing.handicap.handicap(white, black), drawnUpDown = dudd(black, white))) } }