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:
@@ -331,11 +331,15 @@ async def create_game(request: Request, holes_count: int = Form(...),
|
|||||||
playing_handicap = None
|
playing_handicap = None
|
||||||
strokes_allocation_json = None
|
strokes_allocation_json = None
|
||||||
par_for_formula = course_par_played * 2 if nine_of_eighteen else course_par_played
|
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:
|
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:
|
async with db.execute("SELECT slope, rating FROM course_tees WHERE id = ?", (tee_id,)) as c:
|
||||||
tee_row = await c.fetchone()
|
tee_row = await c.fetchone()
|
||||||
if tee_row:
|
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
|
playing_handicap = round(ph / 2) if nine_of_eighteen else ph
|
||||||
if hole_rank and playing_handicap > 0:
|
if hole_rank and playing_handicap > 0:
|
||||||
base, extra = divmod(playing_handicap, n_si)
|
base, extra = divmod(playing_handicap, n_si)
|
||||||
|
|||||||
@@ -67,10 +67,13 @@
|
|||||||
const course = COURSES_DATA.find(c => c.id === this.courseId);
|
const course = COURSES_DATA.find(c => c.id === this.courseId);
|
||||||
if (!course || !tee || player.handicap == null) return null;
|
if (!course || !tee || player.handicap == null) return null;
|
||||||
const nineOfEighteen = parseInt(this.holesCount) === 9 && course.holes === 18;
|
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;
|
const par = nineOfEighteen ? course.par_9 * 2 : course.par;
|
||||||
if (!par) return null;
|
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;
|
return nineOfEighteen ? Math.round(ph / 2) : ph;
|
||||||
},
|
},
|
||||||
goToConfirm() { this.step = 3; },
|
goToConfirm() { this.step = 3; },
|
||||||
|
|||||||
Reference in New Issue
Block a user