From 9c5eb1c333b28362b5504bfddf1e68afc7b67cb7 Mon Sep 17 00:00:00 2001 From: Claude Brisson Date: Fri, 9 Aug 2024 13:58:53 +0200 Subject: [PATCH] Add score X standings parameter --- .../kotlin/org/jeudego/pairgoth/api/ApiTools.kt | 16 ++++++++++++++-- .../org/jeudego/pairgoth/model/Placement.kt | 1 + .../pairgoth/pairing/BasePairingHelper.kt | 3 ++- .../jeudego/pairgoth/pairing/HistoryHelper.kt | 14 +++++++++++++- .../pairgoth/pairing/solver/MacMahonSolver.kt | 11 +++++++++++ .../pairgoth/pairing/solver/SwissSolver.kt | 3 +-- .../org/jeudego/pairgoth/view/PairgothTool.kt | 1 + 7 files changed, 43 insertions(+), 6 deletions(-) diff --git a/api-webapp/src/main/kotlin/org/jeudego/pairgoth/api/ApiTools.kt b/api-webapp/src/main/kotlin/org/jeudego/pairgoth/api/ApiTools.kt index ecbc176..fa49500 100644 --- a/api-webapp/src/main/kotlin/org/jeudego/pairgoth/api/ApiTools.kt +++ b/api-webapp/src/main/kotlin/org/jeudego/pairgoth/api/ApiTools.kt @@ -34,7 +34,9 @@ fun Tournament<*>.getSortedPairables(round: Int): List { else ceil(score - epsilon) } - val historyHelper = HistoryHelper(historyBefore(round + 1)) { + val historyHelper = HistoryHelper( + historyBefore(round + 1), + scoresGetter = { if (pairing.type == PairingType.SWISS) wins.mapValues { Pair(0.0, it.value) } else pairables.mapValues { it.value.let { pairable -> @@ -51,7 +53,16 @@ fun Tournament<*>.getSortedPairables(round: Int): List { ) } } - } + }, + scoresXGetter = { + if (pairing.type == PairingType.SWISS) wins.mapValues { it.value } + else pairables.mapValues { + it.value.let { pairable -> + roundScore(pairable.mmBase() + (nbW(pairable) ?: 0.0)) + } + } + } + ) val neededCriteria = ArrayList(pairing.placementParams.criteria) if (!neededCriteria.contains(Criterion.NBW)) neededCriteria.add(Criterion.NBW) if (!neededCriteria.contains(Criterion.RATING)) neededCriteria.add(Criterion.RATING) @@ -63,6 +74,7 @@ fun Tournament<*>.getSortedPairables(round: Int): List { Criterion.RATING -> pairables.mapValues { it.value.rating } Criterion.NBW -> historyHelper.wins Criterion.MMS -> historyHelper.mms + Criterion.SCOREX -> historyHelper.scoresX Criterion.STS -> StandingsHandler.nullMap Criterion.CPS -> StandingsHandler.nullMap diff --git a/api-webapp/src/main/kotlin/org/jeudego/pairgoth/model/Placement.kt b/api-webapp/src/main/kotlin/org/jeudego/pairgoth/model/Placement.kt index eb5f016..64b594b 100644 --- a/api-webapp/src/main/kotlin/org/jeudego/pairgoth/model/Placement.kt +++ b/api-webapp/src/main/kotlin/org/jeudego/pairgoth/model/Placement.kt @@ -12,6 +12,7 @@ enum class Criterion { MMS, // Macmahon score STS, // Strasbourg score CPS, // Cup score + SCOREX, // CB TODO - I'm adding this one for the congress, didn't find its name in OG after a quick check, needs a deeper investigation SOSW, // Sum of opponents NBW SOSWM1, //-1 diff --git a/api-webapp/src/main/kotlin/org/jeudego/pairgoth/pairing/BasePairingHelper.kt b/api-webapp/src/main/kotlin/org/jeudego/pairgoth/pairing/BasePairingHelper.kt index e52b502..39ba8b5 100644 --- a/api-webapp/src/main/kotlin/org/jeudego/pairgoth/pairing/BasePairingHelper.kt +++ b/api-webapp/src/main/kotlin/org/jeudego/pairgoth/pairing/BasePairingHelper.kt @@ -13,11 +13,12 @@ abstract class BasePairingHelper( ) { abstract val scores: Map> + abstract val scoresX: Map val historyHelper = if (pairables.first().let { it is TeamTournament.Team && it.teamOfIndividuals }) TeamOfIndividualsHistoryHelper( history ) { scores } - else HistoryHelper(history) { scores } + else HistoryHelper(history, scoresGetter = { scores }, scoresXGetter = { scoresX }) // Extend pairables with members from all rounds diff --git a/api-webapp/src/main/kotlin/org/jeudego/pairgoth/pairing/HistoryHelper.kt b/api-webapp/src/main/kotlin/org/jeudego/pairgoth/pairing/HistoryHelper.kt index d505aac..373954d 100644 --- a/api-webapp/src/main/kotlin/org/jeudego/pairgoth/pairing/HistoryHelper.kt +++ b/api-webapp/src/main/kotlin/org/jeudego/pairgoth/pairing/HistoryHelper.kt @@ -3,7 +3,15 @@ package org.jeudego.pairgoth.pairing import org.jeudego.pairgoth.model.* import org.jeudego.pairgoth.model.Game.Result.* -open class HistoryHelper(protected val history: List>, scoresGetter: HistoryHelper.()-> Map>) { +open class HistoryHelper( + protected val history: List>, + // scoresGetter() returns Pair(absentSosValueForOthers, score) where score is nbw for Swiss, mms for MM, ... + scoresGetter: HistoryHelper.()-> Map>, + // scoresXGetter(), defined by default as score + scoresXGetter: HistoryHelper.()-> Map = { + scoresGetter().mapValues { entry -> entry.value.second + } +}) { // List of all the pairables ID present in the history val allPairables = history.flatten() @@ -24,6 +32,10 @@ open class HistoryHelper(protected val history: List>, scoresGetter: scoresGetter() } + val scoresX by lazy { + scoresXGetter() + } + // Generic helper functions open fun playedTogether(p1: Pairable, p2: Pairable) = paired.contains(Pair(p1.id, p2.id)) open fun colorBalance(p: Pairable) = colorBalance[p.id] diff --git a/api-webapp/src/main/kotlin/org/jeudego/pairgoth/pairing/solver/MacMahonSolver.kt b/api-webapp/src/main/kotlin/org/jeudego/pairgoth/pairing/solver/MacMahonSolver.kt index 04566ba..c9c7503 100644 --- a/api-webapp/src/main/kotlin/org/jeudego/pairgoth/pairing/solver/MacMahonSolver.kt +++ b/api-webapp/src/main/kotlin/org/jeudego/pairgoth/pairing/solver/MacMahonSolver.kt @@ -33,6 +33,15 @@ class MacMahonSolver(round: Int, } } + override val scoresX: Map by lazy { + require (mmBar > mmFloor) { "MMFloor is higher than MMBar" } + pairablesMap.mapValues { + it.value.let { pairable -> + roundScore(pairable.mmBase + pairable.nbW) + } + } + } + override fun computeWeightForBye(p: Pairable): Double{ return 2*scores[p.id]!!.second } @@ -76,6 +85,7 @@ class MacMahonSolver(round: Int, val Pairable.mmBase: Double get() = min(max(rank, mmFloor), mmBar) + mmsZero + mmsCorrection // mms: current Mac-Mahon score of the pairable val Pairable.mms: Double get() = scores[id]?.second ?: 0.0 + val Pairable.scoreX: Double get() = scoresX[id] ?: 0.0 // CB TODO - configurable criteria val mainScoreMin = mmFloor + PLA_SMMS_SCORE_MIN - Pairable.MIN_RANK @@ -83,6 +93,7 @@ class MacMahonSolver(round: Int, override val mainLimits get() = Pair(mainScoreMin.toDouble(), mainScoreMax.toDouble()) override fun evalCriterion(pairable: Pairable, criterion: Criterion) = when (criterion) { Criterion.MMS -> pairable.mms + Criterion.SCOREX -> pairable.scoreX Criterion.SOSM -> pairable.sos Criterion.SOSOSM -> pairable.sosos Criterion.SOSMM1 -> pairable.sosm1 diff --git a/api-webapp/src/main/kotlin/org/jeudego/pairgoth/pairing/solver/SwissSolver.kt b/api-webapp/src/main/kotlin/org/jeudego/pairgoth/pairing/solver/SwissSolver.kt index 3497947..cf59bab 100644 --- a/api-webapp/src/main/kotlin/org/jeudego/pairgoth/pairing/solver/SwissSolver.kt +++ b/api-webapp/src/main/kotlin/org/jeudego/pairgoth/pairing/solver/SwissSolver.kt @@ -20,8 +20,7 @@ class SwissSolver(round: Int, historyHelper.wins.mapValues { Pair(0.0, it.value) } } - // - // get() by lazy { historyHelper.wins } + override val scoresX: Map get() = scores.mapValues { it.value.second } override val mainLimits = Pair(0.0, round - 1.0) } diff --git a/view-webapp/src/main/kotlin/org/jeudego/pairgoth/view/PairgothTool.kt b/view-webapp/src/main/kotlin/org/jeudego/pairgoth/view/PairgothTool.kt index d73e5de..d223089 100644 --- a/view-webapp/src/main/kotlin/org/jeudego/pairgoth/view/PairgothTool.kt +++ b/view-webapp/src/main/kotlin/org/jeudego/pairgoth/view/PairgothTool.kt @@ -26,6 +26,7 @@ class PairgothTool { "RATING" to "Rating", "NBW" to "Number of wins", // Number win "MMS" to "Mac Mahon score", // Macmahon score + "SCOREX" to "Score X", // Score X // TODO "STS" to "Strasbourg score", // Strasbourg score // TODO "CPS" to "Cup score", // Cup score