FRQ
› csapa
Scoreboard: 2024 FRQ 2
A step-by-step solution to the 2024 AP CSA FRQ 2 (Scoreboard), covering designing a class from scratch around an alternating-turn state machine in Java.
Two teams trading turns back and forth is the scenario behind this AP Computer Science A free-response question — you design an entire class from a plain-English description of the rules, with no starter code given at all.
What This FRQ Tests
- AP CSA units: Unit 5 (Writing Classes)
- Core skill: designing instance variables that track both accumulated state (scores) and a single piece of "which team's turn is it" state, from nothing but a rules description
- Secondary skill: building a formatted
Stringthat reports several pieces of state at once - Official category: "Classes" — always FRQ 2 on the AP CSA exam
The Setup
- No class skeleton is provided — the entire
Scoreboardclass, including its fields, is up to you to design. - Behavior is fully specified by the constructor and two methods:
Scoreboard(String team1Name, String team2Name)— team 1 always starts as the active teamvoid recordPlay(int points)— a play that scorespoints > 0keeps the same team active and adds to its score; a play of exactly0ends that team's turn and switches which team is activeString getScore()— returns"<team1Score>-<team2Score>-<activeTeamName>"
- The question includes a full worked execution sequence (reproduced below), and the finished class must return every value in it exactly.
Building the Scoreboard Class
Step-by-Step Approach
- Decide what state needs to persist between calls: both team names, both scores, and which team is currently active.
- In the constructor, store both names, initialize both scores to
0, and set team 1 as active. - In
recordPlay, branch on whetherpointsis0. If it's0, flip which team is active. Otherwise, addpointsto whichever team's score is currently active — and leave the active team unchanged. - In
getScore, figure out the active team's name based on the stored active-team state, then concatenate the two scores and that name with hyphens in between.
The Code
public class Scoreboard
{
private String name1;
private String name2;
private int score1;
private int score2;
private boolean team1Active;
public Scoreboard(String team1Name, String team2Name)
{
name1 = team1Name;
name2 = team2Name;
score1 = 0;
score2 = 0;
team1Active = true;
}
public void recordPlay(int points)
{
if (points == 0)
{
team1Active = !team1Active;
}
else
{
if (team1Active)
{
score1 = score1 + points;
}
else
{
score2 = score2 + points;
}
}
}
public String getScore()
{
String activeName;
if (team1Active)
{
activeName = name1;
}
else
{
activeName = name2;
}
return score1 + "-" + score2 + "-" + activeName;
}
}
Why Each Piece Matters
- A single
boolean team1Activefield, rather than aStringnaming the active team — since there are only ever two teams and they strictly alternate, a boolean fully captures "which one" without needing to store or compare names. team1Active = !team1Active— flipping a boolean is the simplest way to express "switch to whichever team isn't currently active," and it works correctly regardless of which team was active beforehand.- The
if (points == 0)check comes first, before anything about scoring — the entire method branches on this one condition, with scoring only happening in theelse. - The active team never changes when
points > 0— the rule says the team "remains active" after a successful play, so nothing aboutteam1Activeis touched in that branch.
Tracing the Example
Using the question's own execution sequence, game = new Scoreboard("Red", "Blue"):
| Call | team1Active |
score1 |
score2 |
getScore() |
|---|---|---|---|---|
| (after construction) | true | 0 | 0 | "0-0-Red" |
recordPlay(1) |
true | 1 | 0 | "1-0-Red" |
recordPlay(0) |
false | 1 | 0 | "1-0-Blue" |
recordPlay(3) |
false | 1 | 3 | "1-3-Blue" |
recordPlay(1) |
false | 1 | 4 | — |
recordPlay(0) |
true | 1 | 4 | "1-4-Red" |
recordPlay(0) |
false | 1 | 4 | — |
recordPlay(4) |
false | 1 | 8 | — |
recordPlay(0) |
true | 1 | 8 | "1-8-Red" |
Every value matches the question's table exactly, including a brand-new Scoreboard object (match) created partway through the sequence returning "0-0-Lions" independently, without disturbing game's own state at all — confirming that each Scoreboard object tracks its own fields separately.
Common Mistakes to Avoid
- Flipping
team1Activeon every call, not just whenpoints == 0. A successful scoring play must leave the active team unchanged. - Adding points to the wrong team's score — always double check that points go to whichever team
team1Activecurrently says is active, not a fixed team. - Building the returned
Stringin the wrong order. The rule is specifically team 1's score, then team 2's score, then the active team's name — not the active team's score first. - Forgetting that a new
Scoreboardobject needs its own independent fields. Each object should track its own scores and active team, unaffected by any otherScoreboardobject's state.
Key Takeaways
- When a class needs to track "which of exactly two things is currently true," a single
booleanis simpler and safer than storing a name or index to compare against later. - Toggling state with
flag = !flagis the standard way to express "switch to the other one" without anif/else. - When no class skeleton is given, work backward from the method signatures and any worked example table — they tell you exactly what state the class needs to hold.