diff --git a/webapp/src/main/kotlin/org/jeudego/pairgoth/api/PairingHandler.kt b/webapp/src/main/kotlin/org/jeudego/pairgoth/api/PairingHandler.kt index 526eb0d..b6ff0c9 100644 --- a/webapp/src/main/kotlin/org/jeudego/pairgoth/api/PairingHandler.kt +++ b/webapp/src/main/kotlin/org/jeudego/pairgoth/api/PairingHandler.kt @@ -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 -> diff --git a/webapp/src/main/kotlin/org/jeudego/pairgoth/api/TournamentHandler.kt b/webapp/src/main/kotlin/org/jeudego/pairgoth/api/TournamentHandler.kt index e2028f1..2b35985 100644 --- a/webapp/src/main/kotlin/org/jeudego/pairgoth/api/TournamentHandler.kt +++ b/webapp/src/main/kotlin/org/jeudego/pairgoth/api/TournamentHandler.kt @@ -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 diff --git a/webapp/src/main/kotlin/org/jeudego/pairgoth/model/Pairing.kt b/webapp/src/main/kotlin/org/jeudego/pairgoth/model/Pairing.kt index 1bb5c43..eb3ea0f 100644 --- a/webapp/src/main/kotlin/org/jeudego/pairgoth/model/Pairing.kt +++ b/webapp/src/main/kotlin/org/jeudego/pairgoth/model/Pairing.kt @@ -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): List { 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) } diff --git a/webapp/src/main/kotlin/org/jeudego/pairgoth/model/Tournament.kt b/webapp/src/main/kotlin/org/jeudego/pairgoth/model/Tournament.kt index 66ef5ee..45afeda 100644 --- a/webapp/src/main/kotlin/org/jeudego/pairgoth/model/Tournament.kt +++ b/webapp/src/main/kotlin/org/jeudego/pairgoth/model/Tournament.kt @@ -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() ) diff --git a/webapp/src/main/kotlin/org/jeudego/pairgoth/pairing/Solver.kt b/webapp/src/main/kotlin/org/jeudego/pairgoth/pairing/Solver.kt index 8ba0bc2..382cc98 100644 --- a/webapp/src/main/kotlin/org/jeudego/pairgoth/pairing/Solver.kt +++ b/webapp/src/main/kotlin/org/jeudego/pairgoth/pairing/Solver.kt @@ -32,6 +32,7 @@ sealed class Solver(private val history: List) { 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 diff --git a/webapp/src/test/kotlin/BasicTests.kt b/webapp/src/test/kotlin/BasicTests.kt index 0405c2f..02690c2 100644 --- a/webapp/src/test/kotlin/BasicTests.kt +++ b/webapp/src/test/kotlin/BasicTests.kt @@ -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") } - - }