Handling of half MMS point for missed rounds

This commit is contained in:
Claude Brisson
2023-12-26 11:04:54 +01:00
parent 70270bd528
commit b69b5cc0a6
5 changed files with 40 additions and 6 deletions

View File

@@ -10,6 +10,7 @@ import org.jeudego.pairgoth.store.Store
import org.w3c.dom.Element import org.w3c.dom.Element
import java.util.* import java.util.*
import javax.xml.datatype.XMLGregorianCalendar import javax.xml.datatype.XMLGregorianCalendar
import kotlin.math.roundToInt
private const val MILLISECONDS_PER_DAY = 86400000 private const val MILLISECONDS_PER_DAY = 86400000
fun XMLGregorianCalendar.toLocalDate() = LocalDate(year, month, day) fun XMLGregorianCalendar.toLocalDate() = LocalDate(year, month, day)
@@ -67,7 +68,11 @@ object OpenGotha {
seedSystem1 = parseSeedSystem(pairParams.paiMaSeedSystem1), seedSystem1 = parseSeedSystem(pairParams.paiMaSeedSystem1),
seedSystem2 = parseSeedSystem(pairParams.paiMaSeedSystem2 ?: "SPLITANDSLIP"), seedSystem2 = parseSeedSystem(pairParams.paiMaSeedSystem2 ?: "SPLITANDSLIP"),
additionalPlacementCritSystem1 = Criterion.valueOf(pairParams.paiMaAdditionalPlacementCritSystem1.uppercase()), additionalPlacementCritSystem1 = Criterion.valueOf(pairParams.paiMaAdditionalPlacementCritSystem1.uppercase()),
additionalPlacementCritSystem2 = Criterion.valueOf(pairParams.paiMaAdditionalPlacementCritSystem2.uppercase().replace("NULL", "NONE")) additionalPlacementCritSystem2 = Criterion.valueOf(pairParams.paiMaAdditionalPlacementCritSystem2.uppercase().replace("NULL", "NONE")),
nbwValueAbsent = genParams.genNBW2ValueAbsent.toDouble() / 2.0,
nbwValueBye = genParams.genNBW2ValueBye.toDouble() / 2.0,
mmsValueAbsent = genParams.genMMS2ValueAbsent.toDouble() / 2.0,
mmsValueBye = genParams.genMMS2ValueBye.toDouble() / 2.0,
), ),
secondary = SecondaryCritParams( secondary = SecondaryCritParams(
barThresholdActive = pairParams.paiSeBarThresholdActive.toBoolean(), barThresholdActive = pairParams.paiSeBarThresholdActive.toBoolean(),
@@ -262,7 +267,15 @@ object OpenGotha {
displayRank( displayRank(
if (tournament.pairing is MacMahon) tournament.pairing.mmFloor else -30 if (tournament.pairing is MacMahon) tournament.pairing.mmFloor else -30
).uppercase(Locale.ROOT) ).uppercase(Locale.ROOT)
}" genMMS2ValueAbsent="1" genMMS2ValueBye="2" genMMZero="30K" genNBW2ValueAbsent="0" genNBW2ValueBye="2" genRoundDownNBWMMS="true" komi="${tournament.komi}" location="${tournament.location}" name="${tournament.name}" nbMovesCanTime="${tournament.timeSystem.stones}" numberOfCategories="1" numberOfRounds="${tournament.rounds}" shortName="${tournament.shortName}" size="${tournament.gobanSize}" stdByoYomiTime="${tournament.timeSystem.byoyomi}"/> }" genMMS2ValueAbsent="${
(tournament.pairing.pairingParams.main.mmsValueAbsent * 2).roundToInt()
}" genMMS2ValueBye="${
(tournament.pairing.pairingParams.main.mmsValueBye * 2).roundToInt()
}" genMMZero="30K" genNBW2ValueAbsent="${
(tournament.pairing.pairingParams.main.nbwValueAbsent * 2).roundToInt()
}" genNBW2ValueBye="${
(tournament.pairing.pairingParams.main.nbwValueBye * 2).roundToInt()
}" genRoundDownNBWMMS="true" komi="${tournament.komi}" location="${tournament.location}" name="${tournament.name}" nbMovesCanTime="${tournament.timeSystem.stones}" numberOfCategories="1" numberOfRounds="${tournament.rounds}" shortName="${tournament.shortName}" size="${tournament.gobanSize}" stdByoYomiTime="${tournament.timeSystem.byoyomi}"/>
<HandicapParameterSet hdBasedOnMMS="${tournament.pairing.pairingParams.handicap.useMMS}" hdCeiling="${tournament.pairing.pairingParams.handicap.ceiling}" hdCorrection="${tournament.pairing.pairingParams.handicap.correction}" hdNoHdRankThreshold="${displayRank(tournament.pairing.pairingParams.handicap.rankThreshold)}"/> <HandicapParameterSet hdBasedOnMMS="${tournament.pairing.pairingParams.handicap.useMMS}" hdCeiling="${tournament.pairing.pairingParams.handicap.ceiling}" hdCorrection="${tournament.pairing.pairingParams.handicap.correction}" hdNoHdRankThreshold="${displayRank(tournament.pairing.pairingParams.handicap.rankThreshold)}"/>
<PlacementParameterSet> <PlacementParameterSet>
<PlacementCriteria> <PlacementCriteria>

View File

@@ -48,6 +48,10 @@ data class MainCritParams(
val seedSystem2: SeedMethod = SeedMethod.SPLIT_AND_FOLD, val seedSystem2: SeedMethod = SeedMethod.SPLIT_AND_FOLD,
val additionalPlacementCritSystem1: Criterion = Criterion.RATING, val additionalPlacementCritSystem1: Criterion = Criterion.RATING,
val additionalPlacementCritSystem2: Criterion = Criterion.NONE, val additionalPlacementCritSystem2: Criterion = Criterion.NONE,
val nbwValueAbsent: Double = 0.0,
val nbwValueBye: Double = 1.0,
val mmsValueAbsent: Double = 0.5,
val mmsValueBye: Double = 1.0
) { ) {
enum class DrawUpDown { TOP, MIDDLE, BOTTOM } enum class DrawUpDown { TOP, MIDDLE, BOTTOM }
enum class SeedMethod { SPLIT_AND_FOLD, SPLIT_AND_RANDOM, SPLIT_AND_SLIP } enum class SeedMethod { SPLIT_AND_FOLD, SPLIT_AND_RANDOM, SPLIT_AND_SLIP }
@@ -239,8 +243,12 @@ fun MainCritParams.Companion.fromJson(json: Json.Object, localDefault: MainCritP
seedSystem1 = json.getString("firstSeed")?.let { MainCritParams.SeedMethod.valueOf(it) } ?: localDefault?.seedSystem1 ?: default.seedSystem1, seedSystem1 = json.getString("firstSeed")?.let { MainCritParams.SeedMethod.valueOf(it) } ?: localDefault?.seedSystem1 ?: default.seedSystem1,
seedSystem2 = json.getString("secondSeed")?.let { MainCritParams.SeedMethod.valueOf(it) } ?: localDefault?.seedSystem2 ?: default.seedSystem2, seedSystem2 = json.getString("secondSeed")?.let { MainCritParams.SeedMethod.valueOf(it) } ?: localDefault?.seedSystem2 ?: default.seedSystem2,
additionalPlacementCritSystem1 = json.getString("firstSeedAddCrit")?.let { Criterion.valueOf(it) } ?: localDefault?.additionalPlacementCritSystem1 ?: default.additionalPlacementCritSystem1, additionalPlacementCritSystem1 = json.getString("firstSeedAddCrit")?.let { Criterion.valueOf(it) } ?: localDefault?.additionalPlacementCritSystem1 ?: default.additionalPlacementCritSystem1,
additionalPlacementCritSystem2 = json.getString("secondSeedAddCrit")?.let { Criterion.valueOf(it) } ?: localDefault?.additionalPlacementCritSystem2 ?: default.additionalPlacementCritSystem2 additionalPlacementCritSystem2 = json.getString("secondSeedAddCrit")?.let { Criterion.valueOf(it) } ?: localDefault?.additionalPlacementCritSystem2 ?: default.additionalPlacementCritSystem2,
) nbwValueAbsent = json.getDouble("nbwValueAbsent") ?: localDefault?.nbwValueAbsent ?: default.nbwValueAbsent,
nbwValueBye = json.getDouble("nbwValueBye") ?: localDefault?.nbwValueBye ?: default.nbwValueBye,
mmsValueAbsent = json.getDouble("mmsValueAbsent") ?: localDefault?.mmsValueAbsent ?: default.mmsValueAbsent,
mmsValueBye = json.getDouble("mmsValueBye") ?: localDefault?.mmsValueBye ?: default.mmsValueBye
)
fun MainCritParams.toJson() = Json.Object( fun MainCritParams.toJson() = Json.Object(
"catWeight" to categoriesWeight, "catWeight" to categoriesWeight,

View File

@@ -89,7 +89,9 @@ abstract class BasePairingHelper(
val Pairable.sosos: Double get() = historyHelper.sosos[id] ?: 0.0 val Pairable.sosos: Double get() = historyHelper.sosos[id] ?: 0.0
val Pairable.sodos: Double get() = historyHelper.sodos[id] ?: 0.0 val Pairable.sodos: Double get() = historyHelper.sodos[id] ?: 0.0
val Pairable.cums: Double get() = historyHelper.cumScore[id] ?: 0.0 val Pairable.cums: Double get() = historyHelper.cumScore[id] ?: 0.0
fun Pairable.missedRounds(upToRound: Int): Int = (1..upToRound).map { round ->
if (historyHelper.playersPerRound.getOrNull(round)?.contains(id) == true) 0 else 1
}.sum()
fun Pairable.eval(criterion: Criterion) = evalCriterion(this, criterion) fun Pairable.eval(criterion: Criterion) = evalCriterion(this, criterion)
open fun evalCriterion(pairable: Pairable, criterion: Criterion) = when (criterion) { open fun evalCriterion(pairable: Pairable, criterion: Criterion) = when (criterion) {
Criterion.NONE -> 0.0 Criterion.NONE -> 0.0

View File

@@ -60,6 +60,15 @@ open class HistoryHelper(protected val history: List<List<Game>>, scoresGetter:
} }
} }
// Set of all implied players for each round
val playersPerRound = history.map {
it.fold(mutableSetOf<ID>()) { acc, next ->
acc.add(next.white)
acc.add(next.black)
acc
}
}
val wins: Map<ID, Double> by lazy { val wins: Map<ID, Double> by lazy {
mutableMapOf<ID, Double>().apply { mutableMapOf<ID, Double>().apply {
history.flatten().forEach { game -> history.flatten().forEach { game ->

View File

@@ -15,7 +15,9 @@ class MacMahonSolver(round: Int,
override val scores: Map<ID, Double> by lazy { override val scores: Map<ID, Double> by lazy {
pairablesMap.mapValues { pairablesMap.mapValues {
it.value.let { it.value.let {
pairable -> pairable.mmBase + pairable.nbW // TODO take tournament parameter into account pairable -> pairable.mmBase +
pairable.nbW + // TODO take tournament parameter into account
pairable.missedRounds(round) * pairingParams.main.mmsValueAbsent
} }
} }
} }