Overview
The Cricket Score Board app is a live, interactive scoring solution designed for cricket matches, enabling scorers to track every ball, player performance, extras, wickets, and match progress in real-time. It supports player tracking with live statistics, extras such as wides and no-balls, wickets with dismissal types, speed warnings, and celebrations for milestones. It features a live stats popup for quick insights and supports both portrait and landscape orientations, ensuring seamless scoring experiences.
Within ScoreBoardView.swift, users interact primarily through a dynamic deliveries scroller that visually represents each ball bowled, including run deliveries like • and special tokens such as W, W+3, NB, and NB+2. This presentation enhances real-time comprehension and assists in quick verification of match progress.
The architecture ensures responsive updates to the UI as the underlying state changes — facilitating accurate player tracking and intuitive match management even during complex scoring scenarios involving extras and warnings.
Goals
- Accurate, real-time scoring of cricket matches including runs, extras, wickets, and penalties.
- Intuitive user interface optimized for both portrait and landscape device layouts.
- Track individual player performance for batsmen and bowlers throughout the innings and match.
- Support innings and match flow management, including target inputs and match completion logic.
- Provide undo and history functionality for error correction during scoring.
- Incorporate haptics and visual celebrations for key events such as boundaries and wickets.
ScoreBoardView.swift integrates these goals by leveraging Swift state management and NotificationCenter broadcasts to reflect changes immediately. The goals also extend to handling tokenized deliveries such as Warn and Bon+2, ensuring all scoring nuances are captured properly and players receive accurate credit.
The app is designed to scale flexibly, supporting edge cases like penalty balls (P5, P10) and complex wicket interactions (Wk, Wk+4), guaranteeing consistent and robust scoring workflows.
Features
- Run Inputs — Buttons for runs 0 through 6, with visual highlights for 4s and 6s to enhance quick scoring.
- Extras Handling
- Wides (
W) and No-Balls (NB) that add bonus runs. - Extras with bonus runs, e.g.,
W+3,NB+2where extra runs are added.
- Wides (
- Penalties — Penalty inputs of -5 (
P5) and -10 (P10) runs, with associated ball and wicket consumption rules. - Wicket Entry Popup
- Allows selection of dismissal type (e.g. bowled, caught, run-out).
- Optionally add runs on wicket balls.
- Speed Warnings
- First tap toggles a warning flag (
Warn). - Second tap prompts a dialog to add dead-ball runs.
- First tap toggles a warning flag (
- Live Stats Popup — Displays aggregated player and match statistics.
- Over Management & Bowler Selection — Automatic end-of-over prompts for bowler selection and strike swapping.
- Innings & Match Completion Logic — Automated detection and prompts for innings end and match completion according to targets and overs.
- Bonus Runs — Runs that do not consume a ball (
Bon+2), added via dialog. - Ball-by-Ball Deliveries Display — Visual list of deliveries for the current over, showing runs and extras.
- Swap Striker — Manual toggle to switch striker and non-striker positions.
- Retire Batsmen — Accessibility-labeled actions to retire batsmen appropriately.
- Undo & Reset Controls — Undo last scoring action and reset scoreboard or end innings/match.
- Target Chase Helpers — Display of required run rate, runs and balls remaining for second innings.
- Broadcast Strip in Landscape Mode — Live score strip optimized for landscape orientation.
The deliveries scroller showcases tokens such as • for dot balls, W and W+3 for wides, NB and NB+2 for no-balls, Warn and Warn+3 for warnings, Bon+2 for bonuses, P5 and P10 for penalties, and Wk and Wk+4 for wickets with runs. Each token is color-coded for quick visual recognition, improving scorer efficiency and accuracy during matches.
This fine-grained feedback mechanism ensures clear communication of match events and supports rapid decision-making through a user-friendly interface.
Planning
- MVP — Basic scoring including runs, wickets, extras, ball count and overs, basic player selection.
- Persistence — Save and restore player stats and match state for continuity.
- Advanced Extras & Warnings — Implement wide/no-ball bonus runs, speed warnings with dead-ball runs input.
- UI Polish & Animations — Add haptic feedback on key events, celebratory animations for boundaries and wickets.
- Landscape Layout — Support alternate layouts with broadcast strip and statistics panel.
- Stats Popup — Detailed player and match performance popup with navigation.
- QA & Edge Cases — Cover chase completion logic, max overs, innings transitions, and player selection safety.
In ScoreBoardView.swift, planning emphasizes modular design to support nuanced delivery tokens such as Warn+3 and Bon+2. This permits scalable code evolution and robust integration of scoring complexities, ensuring maintainability and testing ease.
Strategic use of Swift Concurrency and NotificationCenter facilitates responsiveness and user feedback, helping to meet aggressive UI/UX goals while ensuring data integrity throughout innings and match transitions.
Tools
- SwiftUI — Declarative UI framework for flexible interfaces.
- Swift Concurrency — Asynchronous handling for UI updates and notifications where applicable.
- NotificationCenter — For broadcasting and listening to quick scoring actions and UI events.
- Haptics — iOS native support for tactile feedback on scoring milestones.
- Color/Theme System — Supports light and dark mode with consistent color palette.
- Testing Framework — Swift Testing recommended for unit and UI test coverage.
- Xcode — Developed and maintained using Xcode 26.x.
ScoreBoardView.swift leverages these tools to implement a modern, accessible, and performant scoring app. The combination of SwiftUI and Swift Concurrency powers reactive UI elements, while NotificationCenter facilitates decoupled, event-driven state management.
Haptics and theming support deliver a polished user experience, and the testing framework enables comprehensive validation of features including delivery tokens and complex scoring paths.
Architecture
The app structure is divided into several key components to maintain separation of concerns and clarity.
- ScoreBoardView — Main SwiftUI view orchestrating UI and subviews, handling user interaction.
- ScoreboardStateManager — The single source of truth for current score, wickets, balls, overs, scoring history, innings selection, target input, max overs, and match completion state.
- MatchPerformanceTracker — Tracks individual batsman and bowler performances, manages striker/non-striker logic, current bowler, extras, and scoring methods including
endOver,recordRuns,recordDotBall,recordWicket, andswitchStrike. - PlayerManager — Manages the team players, updating and providing player statistics and availability for selection.
The architecture enforces a clear separation between the view layer and state/logic. Dialogs and popups are implemented as sheets/modal views. Quick scoring actions are dispatched via NotificationCenter to decouple UI components and allow centralized state updates.
ScoreBoardView.swift processes delivery tokens such as Wk+4 and Warn+3 within these components, coordinating state updates with real-time UI feedback and ensuring scalable, testable code.
Data Model
The ScoreboardGameState struct acts as a snapshot of the entire game state used for the undo functionality. It contains:
score— Total runs.wickets— Total wickets fallen.balls— Total legal deliveries bowled.overs— Completed overs count.history— Array of ball-by-ball delivery details.innings— Current innings number.target— Run target for innings 2.maxOvers— Maximum overs allowed.players— Player state and stats snapshot.
Additionally, the BatsmanPerformance struct holds key data:
- Runs scored, balls faced.
- Count of fours and sixes.
- Out status and dismissal type.
The BowlerPerformance struct tracks:
- Overs bowled and balls in the current over.
- Runs conceded and wickets taken.
- Bowling economy rate.
Team player ID lists are used to filter available players for selecting striker, non-striker, and bowlers.
Delivery tokens like P5, P10, and Bon+2 are integrated into the data model as non-ball-consuming extras and penalties, reflecting in player stats and overall match progression.
Overs Calculation
Overs are calculated by integer division of balls by 6. Each set of 6 legal deliveries increments the over count.
Legal vs Illegal Deliveries
- Legal balls increment the ball count.
- Illegal deliveries such as wides (
W), no-balls (NB), warnings (Warn), and bonuses (Bon+2) do not count as legal deliveries.
Strike Switching
Strike switches automatically on odd run totals and certain extras which award runs but don't consume a ball, including odd bonus runs on wides/no-balls. At the end of an over, strike switches automatically and a bowler selection prompt is displayed.
Warning Behavior
- First warning tap toggles a flag
Warnfor the bowler. - Second tap displays a dialog for dead-ball run additions, allowing scorers to add runs without incrementing balls.
- Warnings are treated as dead-ball deliveries in the logic.
Penalty Behavior
P5(-5 runs) consumes a legal ball.P10(-10 runs) consumes a legal ball and records a wicket (Wk).
Wicket Replacement Role Logic
When a wicket falls, the replacement batsman role depends on whether the over is completed or not:
- End of over: Striker changes, new batsman goes to non-striker.
- Mid-over wicket: New batsman becomes striker.
Match Completion Rules
- In innings 1, completion is triggered when all wickets fall or max overs are bowled.
- In innings 2, completion occurs on reaching or surpassing the target or end of all overs or wickets.
Required Run Rate Calculation
Calculated dynamically based on runs remaining and balls left in the innings during a chase, presented to assist scorers with pacing information.
ScoreBoardView.swift processes tokens such as Warn+3 and Wk+4 within the state logic to ensure accurate strike rotation and performance tracking, reflecting these in the UI and match state cohesively.
UI / UX
- Portrait vs Landscape — Portrait mode prioritizes control buttons and player cards. Landscape adds a broadcast strip and live stats side panel for enhanced viewing.
- Broadcast Strip — Displays current score, wickets, overs, and target in landscape with large readable text.
- Current Players Card — Shows striker, non-striker, and current bowler with stats and accessibility labels.
- Run, Extras, Penalty, and Wicket Controls — Large tap targets with distinct colors and icons for quick scoring.
- Undo & Warning Controls — Undo last scoring action and toggle warnings or add dead-ball runs.
- Bonus & Reset Buttons — Add bonus runs without consuming a ball and reset or end innings buttons clearly marked.
- Deliveries Scroller — Horizontal scroll showing ball-by-ball deliveries with run type indicators.
- Celebrations & Haptics — Visual and tactile feedback for 4s, 6s, and wickets.
- Accessibility — Retire batsmen buttons and key controls have descriptive labels for screen readers.
- Color Usage — Consistent color scheme highlighting scoring states, warnings, and penalties, with dark mode support.
The deliveries scroller presents tokens like W, NB, P5, P10, and Wk+4 with distinctive colors and icons, ensuring users can quickly identify delivery types and their impact on the match.
Haptic feedback is integrated to celebrate boundary milestones and wickets, making the scoring experience tactile and engaging, while accessibility labels ensure screen readers can convey all key interactions.
Implementation
The implementation centers on SwiftUI and the ScoreboardStateManager coordinating state changes triggered by UI inputs or internal logic.
// Save state for undo
private func saveState() {
let tracker = stateManager.currentPerformanceTracker
history.append(ScoreboardGameState(
score: score,
wickets: wickets,
balls: balls,
speedWarningGivenForCurrentOver: speedWarningGivenForCurrentOver,
deliveries: deliveries,
inningsSelection: inningsSelection,
targetInput: targetInput,
strikerId: tracker.striker?.playerId,
nonStrikerId: tracker.nonStriker?.playerId,
currentBowlerId: tracker.currentBowler?.playerId,
trackedBatsmen: tracker.allBatsmen,
trackedBowlers: tracker.allBowlers,
trackerExtras: tracker.extras,
trackerWides: tracker.wides,
trackerNoBalls: tracker.noBalls,
trackerByes: tracker.byes,
trackerLegByes: tracker.legByes
))
}
func addRuns(_ runs: Int) {
score += runs
balls += 1
if runs == 4 { triggerCelebration(type: "FOUR") }
if runs == 6 { triggerCelebration(type: "SIX") }
deliveries.append("\(runs)")
stateManager.currentPerformanceTracker.recordRuns(runs)
if var bowler = stateManager.currentPerformanceTracker.currentBowler {
bowler.runsConceded += runs
bowler.balls += 1
if bowler.balls >= 6 {
bowler.overs += 1
bowler.balls = 0
speedWarningGivenForCurrentOver = false
stateManager.currentPerformanceTracker.endOver()
showBowlerSelection = true
}
if let idx = stateManager.currentPerformanceTracker.allBowlers.firstIndex(where: { $0.id == bowler.id }) {
stateManager.currentPerformanceTracker.allBowlers[idx] = bowler
}
stateManager.currentPerformanceTracker.currentBowler = bowler
}
checkMatchCompletion()
}
private func addWide(bonusRuns: Int) {
let total = 1 + bonusRuns
score += total
deliveries.append(bonusRuns == 0 ? "W" : "W+\(bonusRuns)")
let tracker = stateManager.currentPerformanceTracker
tracker.extras += total
tracker.wides += total
if bonusRuns % 2 != 0 { tracker.switchStrike() }
if var bowler = tracker.currentBowler {
bowler.runsConceded += total
if let i = tracker.allBowlers.firstIndex(where: { $0.id == bowler.id }) { tracker.allBowlers[i] = bowler }
tracker.currentBowler = bowler
}
checkMatchCompletion()
}
private func addNoBall(bonusRuns: Int) {
let total = 1 + bonusRuns
score += total
deliveries.append(bonusRuns == 0 ? "NB" : "NB+\(bonusRuns)")
let tracker = stateManager.currentPerformanceTracker
tracker.extras += 1
tracker.noBalls += 1
if bonusRuns > 0, var striker = tracker.striker {
striker.runs += bonusRuns
if bonusRuns == 4 { striker.fours += 1 }
if bonusRuns == 6 { striker.sixes += 1 }
if let i = tracker.allBatsmen.firstIndex(where: { $0.id == striker.id }) { tracker.allBatsmen[i] = striker }
tracker.striker = striker
}
if bonusRuns % 2 != 0 { tracker.switchStrike() }
if var bowler = tracker.currentBowler {
bowler.runsConceded += total
if let i = tracker.allBowlers.firstIndex(where: { $0.id == bowler.id }) { tracker.allBowlers[i] = bowler }
tracker.currentBowler = bowler
}
checkMatchCompletion()
}
func speedWarningAction() {
guard !(isMaxOversReached || isChaseComplete || isChaseLost) else { return }
if !speedWarningGivenForCurrentOver {
saveState()
speedWarningGivenForCurrentOver = true
} else {
pendingWarningRuns = 0
showWarningEntry = true
}
}
private func applySecondWarningDecision(runs: Int) {
deliveries.append(runs == 0 ? "Warn" : "Warn+\(runs)")
guard runs > 0 else { return }
score += runs
recordDeadBallWarningRuns(runs)
checkMatchCompletion()
}
private func checkMatchCompletion() {
if inningsSelection == 1 {
if isFirstInningsComplete {
stateManager.triggerInningsComplete()
updatePlayerStatsForInnings()
}
} else if inningsSelection == 2 {
if isChaseComplete || isChaseLost {
updatePlayerStatsForInnings()
awardTopPerformanceMedals()
stateManager.completeMatch()
}
}
}
Testing
- Manual testing of scoring sequences: inputs for runs 0–6, extras, penalties, and wicket entries.
- Edge case tests for extras: wides with bonus runs, no-balls, warnings flow, and dead-ball run additions.
- Over rollover validation: automatic ball count to over progression and bowler selection prompts.
- Undo stack integrity: multiple undo operations in sequence and after innings transitions.
- Warnings flow: toggling first warning, opening dead-ball dialog on second tap, and undoing warnings.
- Wicket replacement roles logic: ensuring correct striker/non-striker assignment mid-over and end-of-over.
- Match completion logic: chase target met, all wickets fallen, max overs bowled.
- Player stats updates: verify batsman and bowler performance stats after runs, wickets, and extras.
- Persistence testing: save and restore state with all player stats and match data intact.
Example Swift Testing snippet skeleton:
import Testing
@Suite("Scoreboard basics")
struct ScoreboardBasics {
@Test("Dot ball increments balls only")
func dotBallIncrementsBalls() async throws {
let sm = ScoreboardStateManager()
let pm = PlayerManager()
let view = ScoreBoardView(stateManager: sm, playerManager: pm)
sm.balls = 0
sm.score = 0
view.addDotBall()
#expect(sm.balls == 1)
#expect(sm.score == 0)
}
@Test("Wide adds to score but not balls")
func wideDoesNotIncrementBalls() async throws {
let sm = ScoreboardStateManager()
let pm = PlayerManager()
let view = ScoreBoardView(stateManager: sm, playerManager: pm)
sm.balls = 0
sm.score = 0
view.addWide(bonusRuns: 0)
#expect(sm.balls == 0)
#expect(sm.score == 1)
}
}
Deployment
- Archive the app in Xcode targeting iOS 17.0+ and macOS 14.0+ (where applicable).
- Use Xcode's Organizer to export the app for App Store distribution or TestFlight beta testing.
- Note: Haptic feedback is available only on iOS devices supporting it.
- Prepare app icons in all required sizes for iOS and macOS.
- Ensure privacy compliance, especially if any user data is stored or transmitted.
Release builds generated by ScoreBoardView.swift workflows include embedded version metadata to aid support and diagnostics.
User Manual
Setup
- Select the Striker, Non-Striker, and Bowler from the player lists before starting.
- Set the maximum overs allowed for the innings.
- If in the second innings, input the target score to chase.
Scoring Runs
- Tap buttons labeled 0 through 6 to record runs scored on a ball.
- 4s and 6s are visually highlighted to assist quick recognition and celebrate boundaries.
Recording Extras
- Tap the
Wbutton to record a wide, which adds one or more bonus runs without consuming a ball. - Tap the
NBbutton to record a no-ball similarly. - Extras with additional bonus runs can be entered via a dialog, e.g.,
W+3orNB+2.
Wickets
- Tap the
Wkbutton to open the wicket entry popup. - Select dismissal type from the list.
- Optionally add runs scored on the wicket delivery.
Penalties
P5applies a -5 run penalty and consumes a legal ball.P10applies a -10 run penalty, consumes a ball, and records a wicket.
Warnings
- Tap the
Warnbutton once to toggle a warning flag for the current bowler. - Tap
Warna second time to open a dialog to add dead-ball runs. - Undo warnings anytime with the undo button.
Overs & Bowlers
- At the end of each over (6 legal balls), a prompt appears to select the next bowler.
- Strike switches automatically at over end.
- Manually change striker using the swap striker button.
Bonus Runs
- Add bonus runs via the bonus button. These runs add to the score but do not consume a ball.
Undo & Reset
- Undo the last scoring action with the undo button.
- Reset the scoreboard or end the innings/match using the reset/end button.
Live Stats
- Open the live stats popup to view current player performances and match summary metrics.
Landscape Mode Enhancements
- Landscape orientation displays a broadcast strip with live scores and overs.
- Also shows a side panel with detailed statistics for easy reference during scoring.
ScoreBoardView.swift's user manual ensures that scorers understand the function of delivery tokens such as Wk+4, Warn+3, and Bon+2 within scoring actions, promoting accuracy and ease of use for all scorer levels.
FAQ
-
What happens if only one batsman is available to bat?
The app disables non-striker selection and automatically assigns roles as needed. If no batsman is available for replacement, scoring is halted appropriately.
-
How do bonus runs affect the strike position?
Bonus runs do not consume balls and do not cause strike changes.
-
Why do some deliveries not count as legal balls?
Wides, no-balls, warnings, and bonus runs are extras or special cases that do not increment the legal ball count.
-
How is the required run rate calculated?
It divides the remaining runs by the number of balls remaining (converted into overs), updated live during the second innings chase.
-
Can I proceed without selecting a player as striker or bowler?
No, the app prompts for player selection before scoring to ensure accurate stats and role tracking.
-
How does the undo feature work with complex actions like wickets or penalties?
Undo restores the entire state snapshot to before the last action, including player stats and scores.
-
What if I make a mistake entering a warning or penalty?
Use the undo button to revert the last action safely.
-
Are haptics and celebrations available on all devices?
Haptics and animations are supported on iOS devices with hardware support, disabled on unsupported platforms.
-
Can I use the app offline?
Yes, the app runs fully offline with all data stored locally during the match.
-
How do I add bonus runs that do not consume a ball?
Use the bonus runs button which opens a dialog to add any amount of bonus runs.
These FAQs include clarifications on delivery token impacts and scoring flows to assist with common queries when operating ScoreBoardView.swift.
Workflows
The scoring logic and UI interactions follow optimized workflows that ensure smooth progress of the match.
graph TD
A[Start] --> B{Select Players?}
B -- Yes --> C[Start Innings]
B -- No --> B
C --> D{Ball Bowled}
D --> E{Type of Delivery?}
E -->|Run| F[Add Runs]
E -->|Wide| G[Add Wide]
E -->|No Ball| H[Add No Ball]
E -->|Wicket| I[Add Wicket]
F --> J{End of Over?}
G --> J
H --> J
I --> J
J -->|Yes| K[Select Next Bowler & Swap Strike]
J -->|No| D
K --> D
D --> L{Innings Complete?}
L -->|Yes| M[End Innings or Match]
L -->|No| D
M --> N[Reset or Next Innings]
Fallback ASCII workflow:
Start
|
Select Players? ---No---> (wait)
|
Yes
|
Start Innings
|
Ball Bowled
|
Type of Delivery? -> Run / Wide / No Ball / Wicket
|
Update Score, Deliveries, Stats
|
End of Over? --Yes--> Select Next Bowler & Swap Strike
| |
No------------------------------|
|
Innings Complete? --Yes--> End Innings or Match
| |
No--------------------------|
|
Repeat Ball Bowled
Quality Assurance
Quality is ensured via automated unit and integration tests covering all scoring paths, including edge cases for delivery tokens like Warn+3, Bon+2, and Wk+4.
Continuous integration pipelines run Swift Testing suites after each commit, guaranteeing that any regressions in ScoreBoardView.swift or state management are caught early.
Manual usability tests focus on UI responsiveness and accessibility, ensuring the app meets high standards across devices and orientations.
Performance
The app maintains smooth performance by minimizing unnecessary UI updates and leveraging SwiftUI's efficient diffing system.
Heavy operations such as state serialization for undo and player stats computation are optimized and performed asynchronously when possible.
The deliveries scroller efficiently handles large numbers of balls using lazy loading to maintain UI responsiveness.
Accessibility
Accessibility is a core consideration with labels on all buttons and dynamic content describing the current striker, bowler, and match status.
VoiceOver support includes descriptive announcements of deliveries, wickets, and warnings, with meaningful status updates for tokens such as P5 and Wk+4.
Color contrast and font sizing adhere to guidelines to ensure readability in all theme modes.
Security
All data is stored locally, with no network communication, ensuring user privacy and security.
Data persistence employs encryption where necessary and safeguards against data corruption on app suspension or termination.
User inputs are validated to prevent injection or malformed state updates that could corrupt match records.
Maintenance
The codebase is modular with well-documented methods, making additions like new delivery types or UI features straightforward.
ScoreBoardView.swift and associated state managers include comprehensive comments and structured tests to facilitate future developer onboarding and bug fixes.
Glossary
-
Delivery Token — a short string representing a ball outcome, e.g.,
Wfor wide,NBfor no-ball,•for dot ball. -
Speed Warning — a cautionary flag for the bowler, represented by
Warn, with optional run penalties. -
Bonus Runs — runs added without consuming a ball, represented as
Bon+X. -
Penalty Runs — negative runs with ball consumption,
P5andP10. -
Wicket with Runs — a wicket with runs scored on the ball, e.g.,
Wk+4.
These terms are used throughout ScoreBoardView.swift and documentation to concisely describe scoring events.