Add pairing basic test

This commit is contained in:
Claude Brisson
2023-05-17 22:16:34 +02:00
parent 67fc65dada
commit b24948ba30
6 changed files with 24 additions and 11 deletions

View File

@@ -19,7 +19,8 @@ object PairingHandler: ApiHandler {
override fun get(request: HttpServletRequest): Json {
val tournament = getTournament(request)
val round = getSubSelector(request)?.toIntOrNull() ?: badRequest("invalid round number")
return tournament.pairables.values.filter { !it.skip.contains(round) }.map { it.toJson() }.toJsonArray()
val games = tournament.games.getOrNull(round)?.values ?: emptyList()
return games.map { it.toJson() }.toJsonArray()
}
override fun post(request: HttpServletRequest): Json {
@@ -38,7 +39,7 @@ object PairingHandler: ApiHandler {
if (it.skip.contains(round)) badRequest("pairable #$id does not play round $round")
} ?: badRequest("invalid pairable id: #$id")
}
// check players are not already implied in games
// check players are not already implied in games in this round
val pairablesIDs = pairables.map { it.id }.toSet()
tournament.games.getOrNull(round)?.let { games ->
games.values.mapNotNull { game ->

View File

@@ -28,6 +28,7 @@ object TournamentHandler: PairgothApiHandler {
}
override fun put(request: HttpServletRequest): Json {
// BC TODO - some checks are needed here (cannot lower rounds number if games have been played in removed rounds, for instance)
val tournament = getTournament(request) ?: badRequest("missing or invalid tournament id")
val payload = getObjectPayload(request)
// disallow changing type

View File

@@ -24,7 +24,7 @@ class Swiss(
var method: Method,
var firstRoundMethod: Method = method
): Pairing(SWISS) {
enum class Method { FOLD, RANDOM, SLIP }
enum class Method { SPLIT_AND_FOLD, SPLIT_AND_RANDOM, SPLIT_AND_SLIP }
override fun pair(tournament: Tournament, round: Int, pairables: List<Pairable>): List<Game> {
val actualMethod = if (round == 1) firstRoundMethod else method
val history =
@@ -66,7 +66,9 @@ fun Pairing.Companion.fromJson(json: Json.Object) = when (json.getString("type")
}
fun Pairing.toJson() = when (this) {
is Swiss -> Json.Object("type" to type.name, "method" to method.name, "firstRoundMethod" to firstRoundMethod.name)
is Swiss ->
if (method == firstRoundMethod) Json.Object("type" to type.name, "method" to method.name)
else Json.Object("type" to type.name, "method" to method.name, "firstRoundMethod" to firstRoundMethod.name)
is MacMahon -> Json.Object("type" to type.name, "bar" to bar, "minLevel" to minLevel)
is RoundRobin -> Json.Object("type" to type.name)
}

View File

@@ -16,6 +16,7 @@ data class Tournament(
val location: String,
val online: Boolean,
val timeSystem: TimeSystem,
val rounds: Int,
val pairing: Pairing,
val rules: Rules = Rules.FRENCH,
val gobanSize: Int = 19,
@@ -45,6 +46,7 @@ data class Tournament(
// Minimal check on round number.
// CB TODO - the complete check should verify, for each player, that he was either non pairable or implied in the previous round
if (round > games.size + 1) badRequest("previous round not paired")
if (round > rounds) badRequest("too many rounds")
val evenPairables =
if (pairables.size % 2 == 0) pairables
else pairables.toMutableList()?.also { it.add(ByePlayer) }
@@ -78,6 +80,7 @@ fun Tournament.Companion.fromJson(json: Json.Object, default: Tournament? = null
rules = json.getString("rules")?.let { Rules.valueOf(it) } ?: default?.rules ?: Rules.FRENCH,
gobanSize = json.getInt("gobanSize") ?: default?.gobanSize ?: 19,
timeSystem = json.getObject("timeSystem")?.let { TimeSystem.fromJson(it) } ?: default?.timeSystem ?: badRequest("missing timeSystem"),
rounds = json.getInt("rounds") ?: default?.rounds ?: badRequest("missing rounds"),
pairing = json.getObject("pairing")?.let { Pairing.fromJson(it) } ?: default?.pairing ?: badRequest("missing pairing")
)
@@ -95,5 +98,6 @@ fun Tournament.toJson() = Json.Object(
"rules" to rules.name,
"gobanSize" to gobanSize,
"timeSystem" to timeSystem.toJson(),
"rounds" to rounds,
"pairing" to pairing.toJson()
)

View File

@@ -32,6 +32,7 @@ sealed class Solver(private val history: List<Game>) {
val solution = matching.matching
val result = solution.map {
// CB TODO - choice of colors should be here
Game(Store.nextGameId, graph.getEdgeSource(it).id , graph.getEdgeTarget(it).id)
}
return result

View File

@@ -27,8 +27,10 @@ class BasicTests: TestBase() {
"mainTime" to 1200,
"increment" to 10
),
"rounds" to 2,
"pairing" to Json.Object(
"type" to "ROUNDROBIN"
"type" to "SWISS",
"method" to "SPLIT_AND_SLIP"
)
)
@@ -79,19 +81,21 @@ class BasicTests: TestBase() {
@Test
fun `004 modify user`() {
val resp = TestAPI.put("/api/tour/1/part/1", Json.Object("skip" to Json.Array(1))) as Json.Object
// remove player #1 from round #2
val resp = TestAPI.put("/api/tour/1/part/1", Json.Object("skip" to Json.Array(2))) as Json.Object
assertTrue(resp.getBoolean("success") == true, "expecting success")
val player = TestAPI.get("/api/tour/1/part/1") as Json.Object
assertEquals("[1]", player.getArray("skip").toString(), "First player should have id #1")
assertEquals("[2]", player.getArray("skip").toString(), "First player should have id #1")
}
@Test
fun `005 pair`() {
val resp = TestAPI.post("/api/tour/1/part", anotherPlayer) as Json.Object
assertTrue(resp.getBoolean("success") == true, "expecting success")
val pairable = TestAPI.get("/api/tour/1/pair/1")
logger.info(pairable.toString())
val games = TestAPI.post("/api/tour/1/pair/1", Json.Array("all"))
val possibleResults = setOf(
"[{\"id\":1,\"w\":1,\"b\":2,\"r\":\"?\"}]",
"[{\"id\":1,\"w\":2,\"b\":1,\"r\":\"?\"}]")
assertTrue(possibleResults.contains(games.toString()), "pairing differs")
}
}