Skip to content

Commit 40e25b3

Browse files
ejmccalla4607claude
andcommitted
Add winner indicator to match planner for played matches
Show actual blue/red scores and a BLUE WIN / RED WIN badge for played matches. Falls back to estimated scores (muted) for unplayed matches, and a PLAYED badge if actual scores aren't in TBA yet. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 18dfabc commit 40e25b3

2 files changed

Lines changed: 33 additions & 4 deletions

File tree

src/scouting_analysis/frc2026_picklist_runner.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,8 @@ def main():
154154
matches[int(row["match_number"])] = {
155155
"blue": [int(t[3:]) for t in alliances["blue"]["team_keys"]],
156156
"red": [int(t[3:]) for t in alliances["red"]["team_keys"]],
157+
"blue_score": alliances["blue"].get("score", -1),
158+
"red_score": alliances["red"].get("score", -1),
157159
}
158160

159161
# Build a lookup from picklist
@@ -233,12 +235,16 @@ def get_stat(team, col):
233235
num = int(parts[0].replace("Match ", ""))
234236
alliance = parts[1].strip() if len(parts) > 1 else ""
235237
current_match = str(num)
238+
blue_score = matches.get(num, {}).get("blue_score", -1)
239+
red_score = matches.get(num, {}).get("red_score", -1)
236240
match_data[current_match] = {
237241
"num": num,
238242
"alliance": alliance,
239243
"played": num in played_match_nums,
240244
"blueTotal": float(row.iloc[3]) if row.iloc[3] != "" else 0,
241245
"redTotal": float(row.iloc[7]) if row.iloc[7] != "" else 0,
246+
"blueActual": blue_score if isinstance(blue_score, int) and blue_score >= 0 else None,
247+
"redActual": red_score if isinstance(red_score, int) and red_score >= 0 else None,
242248
"rows": [],
243249
}
244250
elif current_match and first not in ("", "blue1"):

webapp/planner.html

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,14 @@
139139
color: #facc15; border: 1px solid #facc15; border-radius: 3px;
140140
padding: 0px 4px; margin-left: 4px;
141141
}
142+
.win-badge {
143+
font-family: var(--mono); font-size: 9px; letter-spacing: 1px;
144+
border-radius: 3px; padding: 1px 6px; font-weight: bold;
145+
}
146+
.win-badge.blue { color: var(--blue); border: 1px solid var(--blue); }
147+
.win-badge.red { color: var(--red); border: 1px solid var(--red); }
148+
.score-actual { font-family: var(--mono); font-size: 18px; }
149+
.score-est { font-family: var(--mono); font-size: 14px; color: var(--muted); }
142150
</style>
143151
</head>
144152
<body>
@@ -206,17 +214,32 @@ <h1 id="page-title">Match Planner</h1>
206214
const allianceColor = m.alliance === 'BLUE' ? 'var(--blue)' : 'var(--red)';
207215
const allianceBg = m.alliance === 'BLUE' ? '#0d2040' : '#2a0d0d';
208216
const playedClass = m.played ? 'played' : '';
209-
const playedBadge = m.played ? '<span class="played-badge">✓ PLAYED</span>' : '';
217+
218+
const hasActual = m.blueActual != null && m.redActual != null;
219+
const winner = hasActual
220+
? (m.blueActual > m.redActual ? 'blue' : m.redActual > m.blueActual ? 'red' : 'tie')
221+
: null;
222+
223+
const winBadge = winner && winner !== 'tie'
224+
? `<span class="win-badge ${winner}">${winner.toUpperCase()} WIN</span>`
225+
: m.played ? '<span class="played-badge">✓ PLAYED</span>' : '';
226+
227+
const blueScoreHtml = hasActual
228+
? `<span class="score-actual" style="color:var(--blue)">${m.blueActual}</span>`
229+
: `<span class="score-est" style="color:var(--blue)">${parseFloat(m.blueTotal).toFixed(1)}</span>`;
230+
const redScoreHtml = hasActual
231+
? `<span class="score-actual" style="color:var(--red)">${m.redActual}</span>`
232+
: `<span class="score-est" style="color:var(--red)">${parseFloat(m.redTotal).toFixed(1)}</span>`;
210233

211234
return `
212235
<div class="match-card ${playedClass}" id="mc-${m.num}" style="animation-delay:${idx * 0.02}s">
213236
<div class="match-header" onclick="toggle('mc-${m.num}')">
214237
<div class="match-num">Q${m.num}</div>
215-
${playedBadge}
238+
${winBadge}
216239
<div style="font-family:var(--mono);font-size:11px;padding:3px 8px;border-radius:3px;background:${allianceBg};color:${allianceColor};letter-spacing:2px;">${m.alliance}</div>
217240
<div class="alliance-totals">
218-
<div class="alliance-total blue"><span class="value">${parseFloat(m.blueTotal).toFixed(1)}</span></div>
219-
<div class="alliance-total red"><span class="value">${parseFloat(m.redTotal).toFixed(1)}</span></div>
241+
<div class="alliance-total blue">${blueScoreHtml}</div>
242+
<div class="alliance-total red">${redScoreHtml}</div>
220243
</div>
221244
<div class="chevron">▾</div>
222245
</div>

0 commit comments

Comments
 (0)