diff --git a/app/routers/games.py b/app/routers/games.py index 07e5fa7..9314e3d 100644 --- a/app/routers/games.py +++ b/app/routers/games.py @@ -292,7 +292,6 @@ async def create_game(request: Request, holes_count: int = Form(...), # Pre-fetch course holes for handicap calculation course_par_played = 0 # par for the holes being played - course_par_full = 0 # par for all holes on the course (needed for 9-of-18 halving) course_total_holes = holes_count # assume matches unless we find otherwise hole_stroke_indices: dict[int, int] = {} if course_id: @@ -305,14 +304,14 @@ async def create_game(request: Request, holes_count: int = Form(...), (course_id,), ) as c: for row in await c.fetchall(): - course_par_full += row["par"] or 0 if row["hole_number"] <= holes_count: course_par_played += row["par"] or 0 if row["stroke_index"] is not None: hole_stroke_indices[row["hole_number"]] = row["stroke_index"] # For a 9-hole game on an 18-hole course the tee ratings are 18-hole values. - # Per WHS: compute 18-hole course handicap, then halve it. + # Per WHS: compute 18-hole course handicap using played-par×2 as the 18-hole par, then halve. + # Using played-par×2 avoids relying on back-nine holes being present in course_holes. nine_of_eighteen = (holes_count == 9 and course_total_holes == 18) played_holes = list(range(1, holes_count + 1)) @@ -331,7 +330,7 @@ async def create_game(request: Request, holes_count: int = Form(...), playing_handicap = None strokes_allocation_json = None - par_for_formula = course_par_full if nine_of_eighteen else course_par_played + par_for_formula = course_par_played * 2 if nine_of_eighteen else course_par_played 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() diff --git a/app/templates/games/new_game.html b/app/templates/games/new_game.html index a9de23b..9dc54db 100644 --- a/app/templates/games/new_game.html +++ b/app/templates/games/new_game.html @@ -65,9 +65,12 @@ const player = this.getPlayer(uid); const tee = this.getTee(uid); const course = COURSES_DATA.find(c => c.id === this.courseId); - if (!course || !tee || player.handicap == null || !course.par) return null; + if (!course || !tee || player.handicap == null) return null; const nineOfEighteen = parseInt(this.holesCount) === 9 && course.holes === 18; - const ph = Math.round(player.handicap * (tee.slope / 113) + (tee.rating - course.par)); + // 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 par = nineOfEighteen ? course.par_9 * 2 : course.par; + if (!par) return null; + const ph = Math.round(player.handicap * (tee.slope / 113) + (tee.rating - par)); return nineOfEighteen ? Math.round(ph / 2) : ph; }, goToConfirm() { this.step = 3; },