diff --git a/api-webapp/src/main/kotlin/org/jeudego/pairgoth/ext/OpenGotha.kt b/api-webapp/src/main/kotlin/org/jeudego/pairgoth/ext/OpenGotha.kt
index b1a81b7..4c7186d 100644
--- a/api-webapp/src/main/kotlin/org/jeudego/pairgoth/ext/OpenGotha.kt
+++ b/api-webapp/src/main/kotlin/org/jeudego/pairgoth/ext/OpenGotha.kt
@@ -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}"/>
diff --git a/api-webapp/src/main/kotlin/org/jeudego/pairgoth/model/Pairing.kt b/api-webapp/src/main/kotlin/org/jeudego/pairgoth/model/Pairing.kt
index 0cf8fbe..9f52d14 100644
--- a/api-webapp/src/main/kotlin/org/jeudego/pairgoth/model/Pairing.kt
+++ b/api-webapp/src/main/kotlin/org/jeudego/pairgoth/model/Pairing.kt
@@ -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,
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 dcc0e6e..76e4f43 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
@@ -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
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 a97e8f5..44de378 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
@@ -60,6 +60,15 @@ open class HistoryHelper(protected val history: List>, scoresGetter:
}
}
+ // Set of all implied players for each round
+ val playersPerRound = history.map {
+ it.fold(mutableSetOf()) { acc, next ->
+ acc.add(next.white)
+ acc.add(next.black)
+ acc
+ }
+ }
+
val wins: Map by lazy {
mutableMapOf().apply {
history.flatten().forEach { game ->
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 a6265b3..4bee2ff 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
@@ -15,7 +15,9 @@ class MacMahonSolver(round: Int,
override val scores: Map 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
}
}
}