From 17697845fd1491b28d65afe0437a324bfc78048d Mon Sep 17 00:00:00 2001 From: Claude Brisson Date: Sat, 29 Nov 2025 22:00:31 +0100 Subject: [PATCH] Implement avoidSameFamily geographic criterion When enabled, avoid pairing players from the same club who have the same family name (surname). Uses existing player.name field. --- .../main/kotlin/org/jeudego/pairgoth/model/Pairing.kt | 1 + .../kotlin/org/jeudego/pairgoth/pairing/solver/Solver.kt | 9 ++++++++- view-webapp/src/main/webapp/js/tour-information.inc.js | 3 ++- view-webapp/src/main/webapp/tour-parameters.inc.html | 6 ++++++ 4 files changed, 17 insertions(+), 2 deletions(-) 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 968b3d2..a3ddb0d 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 @@ -87,6 +87,7 @@ data class GeographicalParams( val preferMMSDiffRatherThanSameClubsGroup: Int = 2, // Typically = 2 val preferMMSDiffRatherThanSameClub: Int = 3, // Typically = 3 val proportionMainClubThreshold: Double = 0.4, // If the biggest club has a proportion of players higher than this, the secondary criterium is not applied + val avoidSameFamily: Boolean = false, // When enabled, avoid pairing players from the same club with the same family name ) { companion object { val disabled = GeographicalParams(avoidSameGeo = 0.0) diff --git a/api-webapp/src/main/kotlin/org/jeudego/pairgoth/pairing/solver/Solver.kt b/api-webapp/src/main/kotlin/org/jeudego/pairgoth/pairing/solver/Solver.kt index 1034c57..92cb69d 100644 --- a/api-webapp/src/main/kotlin/org/jeudego/pairgoth/pairing/solver/Solver.kt +++ b/api-webapp/src/main/kotlin/org/jeudego/pairgoth/pairing/solver/Solver.kt @@ -504,7 +504,14 @@ sealed class Solver( // else: effectiveCommonClub = true → clubRatio stays 0 (no bonus for same club) clubRatio = min(clubRatio, 1.0) - // TODO Same family + // Same family: when enabled and players are from the same club, check if they have the same surname + // If so, remove the bonus to avoid pairing family members (even if local club logic gave them a bonus) + if (avoidSameFamily && commonClub) { + val sameFamily = p1.name.uppercase() == p2.name.uppercase() + if (sameFamily) { + clubRatio = 0.0 // No bonus for same family within same club + } + } // compute geoRatio val mainPart = max(countryRatio, clubRatio) diff --git a/view-webapp/src/main/webapp/js/tour-information.inc.js b/view-webapp/src/main/webapp/js/tour-information.inc.js index 673bf0b..710cdd5 100644 --- a/view-webapp/src/main/webapp/js/tour-information.inc.js +++ b/view-webapp/src/main/webapp/js/tour-information.inc.js @@ -247,7 +247,8 @@ onLoad(() => { }, geo: { mmsDiffCountry: form.val('mmsDiffCountry'), - mmsDiffClub: form.val('mmsDiffClub') + mmsDiffClub: form.val('mmsDiffClub'), + avoidSameFamily: form.val('avoidSameFamily') }, handicap: { useMMS: form.val('useMMS'), diff --git a/view-webapp/src/main/webapp/tour-parameters.inc.html b/view-webapp/src/main/webapp/tour-parameters.inc.html index a22e9ae..9ca9121 100644 --- a/view-webapp/src/main/webapp/tour-parameters.inc.html +++ b/view-webapp/src/main/webapp/tour-parameters.inc.html @@ -142,6 +142,12 @@ rather than pairing players of the same club. +
+ +
Handicap parameters