Merge branch 'mms-limits' into 'pairing2'

Add mmsFloor and mmsBar parameters for initial MMS scores

See merge request tournois/pairgoth!3
This commit is contained in:
Claude BRISSON
2023-11-05 15:46:05 +00:00
4 changed files with 2111 additions and 1298 deletions

View File

@@ -116,8 +116,16 @@ object OpenGotha {
else -> throw Error("missing byoyomi type") else -> throw Error("missing byoyomi type")
}, },
pairing = when (handParams.hdCeiling) { pairing = when (handParams.hdCeiling) {
0 -> Swiss(pairingParams = pairgothPairingParams, placementParams = pairgothPlacementParams) 0 -> Swiss(
else -> MacMahon(pairingParams = pairgothPairingParams, placementParams = pairgothPlacementParams) pairingParams = pairgothPairingParams,
placementParams = pairgothPlacementParams
)
else -> MacMahon(
pairingParams = pairgothPairingParams,
placementParams = pairgothPlacementParams,
mmFloor = Pairable.parseRank(genParams.genMMFloor),
mmBar = Pairable.parseRank(genParams.genMMBar)
)
}, },
rounds = genParams.numberOfRounds rounds = genParams.numberOfRounds
) )
@@ -241,7 +249,15 @@ object OpenGotha {
TimeSystem.TimeSystemType.STANDARD -> "STDBYOYOMI" TimeSystem.TimeSystemType.STANDARD -> "STDBYOYOMI"
TimeSystem.TimeSystemType.CANADIAN -> "CANBYOYOMI" TimeSystem.TimeSystemType.CANADIAN -> "CANBYOYOMI"
TimeSystem.TimeSystemType.FISCHER -> "FISCHER" TimeSystem.TimeSystemType.FISCHER -> "FISCHER"
} }" director="" endDate="${tournament.endDate}" fischerTime="${tournament.timeSystem.increment}" genCountNotPlayedGamesAsHalfPoint="false" genMMBar="9D" genMMFloor="30K" 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}"/> } }" director="" endDate="${tournament.endDate}" fischerTime="${tournament.timeSystem.increment}" genCountNotPlayedGamesAsHalfPoint="false" genMMBar="${
displayRank(
if (tournament.pairing is MacMahon) tournament.pairing.mmBar else 8
).uppercase(Locale.ROOT)
}" genMMFloor="${
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}"/>
<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

@@ -180,11 +180,13 @@ class MacMahon(
), ),
placementParams: PlacementParams = PlacementParams( placementParams: PlacementParams = PlacementParams(
Criterion.NBW, Criterion.SOSW, Criterion.SOSOSW Criterion.NBW, Criterion.SOSW, Criterion.SOSOSW
) ),
var mmFloor: Int = -20,
var mmBar: Int = 0
): 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).pair() return MacMahonSolver(round, tournament.historyBefore(round), pairables, pairingParams, placementParams, mmFloor, mmBar).pair()
} }
} }
@@ -305,12 +307,15 @@ fun Pairing.Companion.fromJson(json: Json.Object): Pairing {
val placementParams = json.getArray("placement")?.let { PlacementParams.fromJson(it) } ?: defaultParams.placementParams val placementParams = json.getArray("placement")?.let { PlacementParams.fromJson(it) } ?: defaultParams.placementParams
return when (type) { return when (type) {
SWISS -> Swiss(pairingParams, placementParams) SWISS -> Swiss(pairingParams, placementParams)
MAC_MAHON -> MacMahon(pairingParams, placementParams) MAC_MAHON -> MacMahon(pairingParams, placementParams).also { mm ->
mm.mmFloor = json.getInt("mmFloor") ?: -20
mm.mmBar = json.getInt("mmBar") ?: 0
}
ROUND_ROBIN -> RoundRobin(pairingParams, placementParams) ROUND_ROBIN -> RoundRobin(pairingParams, placementParams)
} }
} }
fun Pairing.toJson() = Json.Object( fun Pairing.toJson(): Json.Object = Json.MutableObject(
"type" to type.name, "type" to type.name,
"base" to pairingParams.base.toJson(), "base" to pairingParams.base.toJson(),
"main" to pairingParams.main.toJson(), "main" to pairingParams.main.toJson(),
@@ -318,4 +323,9 @@ fun Pairing.toJson() = Json.Object(
"geo" to pairingParams.geo.toJson(), "geo" to pairingParams.geo.toJson(),
"handicap" to pairingParams.handicap.toJson(), "handicap" to pairingParams.handicap.toJson(),
"placement" to placementParams.toJson() "placement" to placementParams.toJson()
) ).also { ret ->
if (this is MacMahon) {
ret["mmFloor"] = mmFloor
ret["mmBar"] = mmBar
}
}

View File

@@ -1,12 +1,15 @@
package org.jeudego.pairgoth.pairing.solver package org.jeudego.pairgoth.pairing.solver
import org.jeudego.pairgoth.model.* import org.jeudego.pairgoth.model.*
import kotlin.math.max
import kotlin.math.min
class MacMahonSolver(round: Int, class MacMahonSolver(round: Int,
history: List<List<Game>>, history: List<List<Game>>,
pairables: List<Pairable>, pairables: List<Pairable>,
pairingParams: PairingParams, pairingParams: PairingParams,
placementParams: PlacementParams): placementParams: PlacementParams,
private val mmFloor: Int, private val mmBar: Int):
BaseSolver(round, history, pairables, pairingParams, placementParams) { BaseSolver(round, history, pairables, pairingParams, placementParams) {
override val scores: Map<ID, Double> by lazy { override val scores: Map<ID, Double> by lazy {
@@ -16,14 +19,18 @@ class MacMahonSolver(round: Int,
} }
} }
} }
val Pairable.mmBase: Double get() = rank + 30.0 // TODO use params val Pairable.mmBase: Double get() = min(max(rank, mmFloor), mmBar) + mmsZero
val Pairable.mms: Double get() = scores[id] ?: 0.0 val Pairable.mms: Double get() = scores[id] ?: 0.0
// CB TODO - configurable criteria // CB TODO - configurable criteria
override val mainLimits get() = Pair(0.0, 100.0) // TODO override val mainLimits get() = Pair(mmFloor.toDouble(), 100.0) // TODO ?
override fun evalCriterion(pairable: Pairable, criterion: Criterion) = when (criterion) { override fun evalCriterion(pairable: Pairable, criterion: Criterion) = when (criterion) {
Criterion.MMS -> pairable.mms Criterion.MMS -> pairable.mms
else -> super.evalCriterion(pairable, criterion) else -> super.evalCriterion(pairable, criterion)
} }
companion object {
const val mmsZero = 30.0
}
} }

File diff suppressed because it is too large Load Diff