Debugging tests
This commit is contained in:
@@ -158,7 +158,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.republicate.kson</groupId>
|
<groupId>com.republicate.kson</groupId>
|
||||||
<artifactId>essential-kson-jvm</artifactId>
|
<artifactId>essential-kson-jvm</artifactId>
|
||||||
<version>2.3</version>
|
<version>2.4</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- charset detection
|
<!-- charset detection
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@@ -14,13 +14,13 @@ data class BaseCritParams(
|
|||||||
val dupWeight: Double = MAX_AVOIDDUPGAME,
|
val dupWeight: Double = MAX_AVOIDDUPGAME,
|
||||||
val random: Double = 0.0,
|
val random: Double = 0.0,
|
||||||
val deterministic: Boolean = true,
|
val deterministic: Boolean = true,
|
||||||
val colorBalance: Double = MAX_COLOR_BALANCE
|
val colorBalanceWeight: Double = MAX_COLOR_BALANCE
|
||||||
) {
|
) {
|
||||||
init {
|
init {
|
||||||
if (nx1 < 0.0 || nx1 > 1.0) throw Error("invalid standardNX1Factor")
|
if (nx1 < 0.0 || nx1 > 1.0) throw Error("invalid standardNX1Factor")
|
||||||
if (dupWeight < 0.0 || dupWeight > MAX_AVOIDDUPGAME) throw Error("invalid avoidDuplGame value")
|
if (dupWeight < 0.0 || dupWeight > MAX_AVOIDDUPGAME) throw Error("invalid avoidDuplGame value")
|
||||||
if (random < 0.0 || random > MAX_RANDOM) throw Error("invalid random")
|
if (random < 0.0 || random > MAX_RANDOM) throw Error("invalid random")
|
||||||
if (colorBalance > 0.0 || colorBalance > MAX_COLOR_BALANCE) throw Error("invalid balanceWB")
|
if (colorBalanceWeight < 0.0 || colorBalanceWeight > MAX_COLOR_BALANCE) throw Error("invalid ColorBalanceWeight")
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@@ -189,14 +189,14 @@ fun BaseCritParams.Companion.fromJson(json: Json.Object) = BaseCritParams(
|
|||||||
dupWeight = json.getDouble("dupWeight") ?: default.dupWeight,
|
dupWeight = json.getDouble("dupWeight") ?: default.dupWeight,
|
||||||
random = json.getDouble("random") ?: default.random,
|
random = json.getDouble("random") ?: default.random,
|
||||||
deterministic = json.getBoolean("deterministic") ?: default.deterministic,
|
deterministic = json.getBoolean("deterministic") ?: default.deterministic,
|
||||||
colorBalance = json.getDouble("colorBalanceWeight") ?: default.colorBalance
|
colorBalanceWeight = json.getDouble("colorBalanceWeight") ?: default.colorBalanceWeight
|
||||||
)
|
)
|
||||||
|
|
||||||
fun BaseCritParams.toJson() = Json.Object(
|
fun BaseCritParams.toJson() = Json.Object(
|
||||||
"nx1" to nx1,
|
"nx1" to nx1,
|
||||||
"dupWeight" to dupWeight,
|
"dupWeight" to dupWeight,
|
||||||
"random" to random,
|
"random" to random,
|
||||||
"colorBalanceWeight" to colorBalance
|
"colorBalanceWeight" to colorBalanceWeight
|
||||||
)
|
)
|
||||||
|
|
||||||
fun MainCritParams.Companion.fromJson(json: Json.Object) = MainCritParams(
|
fun MainCritParams.Companion.fromJson(json: Json.Object) = MainCritParams(
|
||||||
|
@@ -3,7 +3,7 @@ package org.jeudego.pairgoth.pairing
|
|||||||
import org.jeudego.pairgoth.model.*
|
import org.jeudego.pairgoth.model.*
|
||||||
import org.jeudego.pairgoth.model.Game.Result.*
|
import org.jeudego.pairgoth.model.Game.Result.*
|
||||||
|
|
||||||
open class HistoryHelper(protected val history: List<List<Game>>, private val scores: Map<ID, Double>) {
|
open class HistoryHelper(protected val history: List<List<Game>>, scoresGetter: ()-> Map<ID, Double>) {
|
||||||
|
|
||||||
private val Game.blackScore get() = when (result) {
|
private val Game.blackScore get() = when (result) {
|
||||||
BLACK, BOTHWIN -> 1.0
|
BLACK, BOTHWIN -> 1.0
|
||||||
@@ -15,6 +15,8 @@ open class HistoryHelper(protected val history: List<List<Game>>, private val sc
|
|||||||
else -> 0.0
|
else -> 0.0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val scores by lazy(scoresGetter)
|
||||||
|
|
||||||
// Generic helper functions
|
// Generic helper functions
|
||||||
open fun playedTogether(p1: Pairable, p2: Pairable) = paired.contains(Pair(p1.id, p2.id))
|
open fun playedTogether(p1: Pairable, p2: Pairable) = paired.contains(Pair(p1.id, p2.id))
|
||||||
open fun colorBalance(p: Pairable) = colorBalance[p.id]
|
open fun colorBalance(p: Pairable) = colorBalance[p.id]
|
||||||
@@ -137,8 +139,8 @@ open class HistoryHelper(protected val history: List<List<Game>>, private val sc
|
|||||||
|
|
||||||
// CB TODO - a big problem with the current naive implementation is that the team score is -for now- the sum of team members individual scores
|
// CB TODO - a big problem with the current naive implementation is that the team score is -for now- the sum of team members individual scores
|
||||||
|
|
||||||
class TeamOfIndividualsHistoryHelper(history: List<List<Game>>, scores: Map<ID, Double>):
|
class TeamOfIndividualsHistoryHelper(history: List<List<Game>>, scoresGetter: () -> Map<ID, Double>):
|
||||||
HistoryHelper(history, scores) {
|
HistoryHelper(history, scoresGetter) {
|
||||||
|
|
||||||
private fun Pairable.asTeam() = this as TeamTournament.Team
|
private fun Pairable.asTeam() = this as TeamTournament.Team
|
||||||
|
|
||||||
|
@@ -20,7 +20,7 @@ class MacMahonSolver(round: Int,
|
|||||||
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() = TODO()
|
override val mainLimits get() = Pair(0.0, 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)
|
||||||
|
@@ -48,10 +48,8 @@ sealed class Solver(
|
|||||||
}
|
}
|
||||||
|
|
||||||
abstract val scores: Map<ID, Double>
|
abstract val scores: Map<ID, Double>
|
||||||
val historyHelper by lazy {
|
val historyHelper = if (pairables.first().let { it is TeamTournament.Team && it.teamOfIndividuals }) TeamOfIndividualsHistoryHelper(history) { scores }
|
||||||
if (pairables.first().let { it is TeamTournament.Team && it.teamOfIndividuals }) TeamOfIndividualsHistoryHelper(history, scores)
|
else HistoryHelper(history) { scores }
|
||||||
else HistoryHelper(history, scores)
|
|
||||||
}
|
|
||||||
|
|
||||||
// pairables sorted using overloadable sort function
|
// pairables sorted using overloadable sort function
|
||||||
private val sortedPairables by lazy {
|
private val sortedPairables by lazy {
|
||||||
@@ -139,8 +137,8 @@ sealed class Solver(
|
|||||||
if (potentialHd == 0) {
|
if (potentialHd == 0) {
|
||||||
val wb1: Int = p1.colorBalance
|
val wb1: Int = p1.colorBalance
|
||||||
val wb2: Int = p2.colorBalance
|
val wb2: Int = p2.colorBalance
|
||||||
if (wb1 * wb2 < 0) return colorBalance
|
if (wb1 * wb2 < 0) return colorBalanceWeight
|
||||||
else if (wb1 == 0 && abs(wb2) >= 2 || wb2 == 0 && abs(wb1) >= 2) return colorBalance / 2
|
else if (wb1 == 0 && abs(wb2) >= 2 || wb2 == 0 && abs(wb1) >= 2) return colorBalanceWeight / 2
|
||||||
}
|
}
|
||||||
return 0.0
|
return 0.0
|
||||||
}
|
}
|
||||||
@@ -239,7 +237,7 @@ sealed class Solver(
|
|||||||
|
|
||||||
// Same country
|
// Same country
|
||||||
val countryRatio = if (p1.country != p2.country && countryFactor != 0) {
|
val countryRatio = if (p1.country != p2.country && countryFactor != 0) {
|
||||||
min(countryFactor.toDouble() / placementScoreRange as Double, 1.0) // clamp to 1
|
min(countryFactor.toDouble() / placementScoreRange.toDouble(), 1.0) // clamp to 1
|
||||||
} else {
|
} else {
|
||||||
0.0
|
0.0
|
||||||
}
|
}
|
||||||
@@ -253,14 +251,14 @@ sealed class Solver(
|
|||||||
clubRatio = if (clubFactor == 0) {
|
clubRatio = if (clubFactor == 0) {
|
||||||
0.0
|
0.0
|
||||||
} else {
|
} else {
|
||||||
clubFactor.toDouble() / 2.0 / placementScoreRange as Double
|
clubFactor.toDouble() / 2.0 / placementScoreRange.toDouble()
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (!commonGroup && !commonClub) {
|
} else if (!commonGroup && !commonClub) {
|
||||||
clubRatio = if (clubFactor == 0) {
|
clubRatio = if (clubFactor == 0) {
|
||||||
0.0
|
0.0
|
||||||
} else {
|
} else {
|
||||||
clubFactor.toDouble() * 1.2 / placementScoreRange as Double
|
clubFactor.toDouble() * 1.2 / placementScoreRange.toDouble()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
clubRatio = min(clubRatio, 1.0)
|
clubRatio = min(clubRatio, 1.0)
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
package org.jeudego.pairgoth.pairing
|
package org.jeudego.pairgoth.pairing
|
||||||
|
|
||||||
import org.jeudego.pairgoth.model.*
|
import org.jeudego.pairgoth.model.*
|
||||||
|
import kotlin.properties.Delegates
|
||||||
|
|
||||||
class SwissSolver(round: Int,
|
class SwissSolver(round: Int,
|
||||||
history: List<List<Game>>,
|
history: List<List<Game>>,
|
||||||
@@ -11,8 +12,11 @@ class SwissSolver(round: Int,
|
|||||||
|
|
||||||
// In a Swiss tournament the main criterion is the number of wins and already computed
|
// In a Swiss tournament the main criterion is the number of wins and already computed
|
||||||
|
|
||||||
override val scores: Map<ID, Double>
|
override val scores by lazy {
|
||||||
get() = historyHelper.wins
|
historyHelper.wins
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// get() by lazy { historyHelper.wins }
|
||||||
|
|
||||||
override val mainLimits = Pair(0.0, round - 1.0)
|
override val mainLimits = Pair(0.0, round - 1.0)
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
package org.jeudego.pairgoth.test
|
package org.jeudego.pairgoth.test
|
||||||
|
|
||||||
import com.republicate.kson.Json
|
import com.republicate.kson.Json
|
||||||
|
import com.republicate.kson.toJsonObject
|
||||||
import org.jeudego.pairgoth.model.ID
|
import org.jeudego.pairgoth.model.ID
|
||||||
import org.junit.jupiter.api.MethodOrderer.MethodName
|
import org.junit.jupiter.api.MethodOrderer.MethodName
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
@@ -53,7 +54,7 @@ class BasicTests: TestBase() {
|
|||||||
),
|
),
|
||||||
"rounds" to 2,
|
"rounds" to 2,
|
||||||
"pairing" to Json.Object(
|
"pairing" to Json.Object(
|
||||||
"type" to "MACMAHON"
|
"type" to "MAC_MAHON"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -94,8 +95,10 @@ class BasicTests: TestBase() {
|
|||||||
val resp = TestAPI.get("/api/tour/$aTournamentID").asObject()
|
val resp = TestAPI.get("/api/tour/$aTournamentID").asObject()
|
||||||
assertEquals(aTournamentID, resp.getInt("id"), "First tournament should have id #$aTournamentID")
|
assertEquals(aTournamentID, resp.getInt("id"), "First tournament should have id #$aTournamentID")
|
||||||
// filter out "id", and also "komi", "rules" and "gobanSize" which were provided by default
|
// filter out "id", and also "komi", "rules" and "gobanSize" which were provided by default
|
||||||
val cmp = Json.Object(*resp.entries.filter { it.key !in listOf("id", "komi", "rules", "gobanSize") }.map { Pair(it.key, it.value) }.toTypedArray())
|
// also filter out "pairing", which is filled by all default values
|
||||||
assertEquals(aTournament.toString(), cmp.toString(), "tournament differs")
|
val cmp = Json.Object(*resp.entries.filter { it.key !in listOf("id", "komi", "rules", "gobanSize", "pairing") }.map { Pair(it.key, it.value) }.toTypedArray())
|
||||||
|
val expected = aTournament.entries.filter { it.key != "pairing" }.map { Pair(it.key, it.value) }.toMap().toJsonObject()
|
||||||
|
assertEquals(expected.toString(), cmp.toString(), "tournament differs")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@@ -216,7 +216,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.republicate.kson</groupId>
|
<groupId>com.republicate.kson</groupId>
|
||||||
<artifactId>essential-kson-jvm</artifactId>
|
<artifactId>essential-kson-jvm</artifactId>
|
||||||
<version>2.3</version>
|
<version>2.4</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- charset detection
|
<!-- charset detection
|
||||||
<dependency>
|
<dependency>
|
||||||
|
Reference in New Issue
Block a user