Fix 9-hole course handicap formula to use HI÷2 per WHS spec

Dedicated 9-hole courses have 9-hole ratings and pars, so the WHS
formula is: round((HI÷2) × (slope/113) + (rating − par)).
The previous code used the full HI, giving roughly double the correct
result (e.g. 22 instead of 11 on Augwil White Male for HI 18).

The three cases are now handled correctly:
- Dedicated 9-hole course: HI÷2 with 9-hole ratings
- 9 holes on 18-hole course: full HI with 18-hole ratings, result halved
- Full 18 holes: full HI with 18-hole ratings

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Rolf
2026-03-23 21:51:49 +01:00
parent 26c3280a92
commit c298c473f4
2 changed files with 10 additions and 3 deletions
+5 -1
View File
@@ -331,11 +331,15 @@ async def create_game(request: Request, holes_count: int = Form(...),
playing_handicap = None
strokes_allocation_json = None
par_for_formula = course_par_played * 2 if nine_of_eighteen else course_par_played
# Dedicated 9-hole courses have 9-hole ratings: WHS uses HI÷2 in the formula.
# For 9-of-18 the full HI is used and the result halved instead.
nine_hole_dedicated = (holes_count == 9 and not nine_of_eighteen)
if hc is not None and tee_id and par_for_formula:
async with db.execute("SELECT slope, rating FROM course_tees WHERE id = ?", (tee_id,)) as c:
tee_row = await c.fetchone()
if tee_row:
ph = round(hc * (tee_row["slope"] / 113) + (tee_row["rating"] - par_for_formula))
hc_for_formula = hc / 2 if nine_hole_dedicated else hc
ph = round(hc_for_formula * (tee_row["slope"] / 113) + (tee_row["rating"] - par_for_formula))
playing_handicap = round(ph / 2) if nine_of_eighteen else ph
if hole_rank and playing_handicap > 0:
base, extra = divmod(playing_handicap, n_si)
+5 -2
View File
@@ -67,10 +67,13 @@
const course = COURSES_DATA.find(c => c.id === this.courseId);
if (!course || !tee || player.handicap == null) return null;
const nineOfEighteen = parseInt(this.holesCount) === 9 && course.holes === 18;
// For 9-of-18, use par_9×2 as the 18-hole par so back-nine holes don't need to be in DB.
const nineHoleDedicated = parseInt(this.holesCount) === 9 && course.holes === 9;
// For 9-of-18: use par_9×2 as the 18-hole par, compute full CH then halve.
// For dedicated 9-hole: WHS formula uses HI÷2 directly with 9-hole ratings.
const par = nineOfEighteen ? course.par_9 * 2 : course.par;
if (!par) return null;
const ph = Math.round(player.handicap * (tee.slope / 113) + (tee.rating - par));
const hcForFormula = nineHoleDedicated ? player.handicap / 2 : player.handicap;
const ph = Math.round(hcForFormula * (tee.slope / 113) + (tee.rating - par));
return nineOfEighteen ? Math.round(ph / 2) : ph;
},
goToConfirm() { this.step = 3; },