Handling of half MMS point for missed rounds
This commit is contained in:
@@ -10,6 +10,7 @@ import org.jeudego.pairgoth.store.Store
|
||||
import org.w3c.dom.Element
|
||||
import java.util.*
|
||||
import javax.xml.datatype.XMLGregorianCalendar
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
private const val MILLISECONDS_PER_DAY = 86400000
|
||||
fun XMLGregorianCalendar.toLocalDate() = LocalDate(year, month, day)
|
||||
@@ -67,7 +68,11 @@ object OpenGotha {
|
||||
seedSystem1 = parseSeedSystem(pairParams.paiMaSeedSystem1),
|
||||
seedSystem2 = parseSeedSystem(pairParams.paiMaSeedSystem2 ?: "SPLITANDSLIP"),
|
||||
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(
|
||||
barThresholdActive = pairParams.paiSeBarThresholdActive.toBoolean(),
|
||||
@@ -262,7 +267,15 @@ object OpenGotha {
|
||||
displayRank(
|
||||
if (tournament.pairing is MacMahon) tournament.pairing.mmFloor else -30
|
||||
).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)}"/>
|
||||
<PlacementParameterSet>
|
||||
<PlacementCriteria>
|
||||
|
@@ -48,6 +48,10 @@ data class MainCritParams(
|
||||
val seedSystem2: SeedMethod = SeedMethod.SPLIT_AND_FOLD,
|
||||
val additionalPlacementCritSystem1: Criterion = Criterion.RATING,
|
||||
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 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,
|
||||
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,
|
||||
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(
|
||||
"catWeight" to categoriesWeight,
|
||||
|
@@ -89,7 +89,9 @@ abstract class BasePairingHelper(
|
||||
val Pairable.sosos: Double get() = historyHelper.sosos[id] ?: 0.0
|
||||
val Pairable.sodos: Double get() = historyHelper.sodos[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)
|
||||
open fun evalCriterion(pairable: Pairable, criterion: Criterion) = when (criterion) {
|
||||
Criterion.NONE -> 0.0
|
||||
|
@@ -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 {
|
||||
mutableMapOf<ID, Double>().apply {
|
||||
history.flatten().forEach { game ->
|
||||
|
@@ -15,7 +15,9 @@ class MacMahonSolver(round: Int,
|
||||
override val scores: Map<ID, Double> by lazy {
|
||||
pairablesMap.mapValues {
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user