My Solution Code

// Create the Scoreboard Class HERE

class Scoreboard {
    // Define your properties HERE
    private String team1Name;
    private String team2Name;
    private int team1Score;
    private int team2Score;
    private int activeTeam; // 1 for team1, 2 for team2

    public Scoreboard(String team1Name, String team2Name) {
        // This is your CONSTRUCTOR
        // Initialize your properties HERE (team names and active team)
        this.team1Name = team1Name;
        this.team2Name = team2Name;
        this.team1Score = 0;
        this.team2Score = 0;
        this.activeTeam = 1; // team1 starts as active
    }

    public void recordPlay(int points) {
        // Create the recordPlay Method HERE
        if (points > 0) {
            // Add points to active team and keep them active
            if (activeTeam == 1) {
                team1Score += points;
            } else {
                team2Score += points;
            }
        } else {
            // Failed play: switch to inactive team
            activeTeam = (activeTeam == 1) ? 2 : 1;
        }
    }

    public String getScore() {
        // Create the getScore Method HERE
        String activeName = (activeTeam == 1) ? team1Name : team2Name;
        return team1Score + "-" + team2Score + "-" + activeName;
    }
}

// Testing the Scoreboard class (DO NOT MODIFY this part unless you change the class, method, or constructer names)
// DO NOT MODIFY BELOW THIS LINE
public class Main {
    public static void main(String[] args) {
        String info;

        // Step 1: Create a new Scoreboard for "Red" vs "Blue"
        Scoreboard game = new Scoreboard("Red", "Blue");

        // Step 2
        info = game.getScore();                  // "0-0-Red"
        System.out.println("(Step 2) info = " + info);

        // Step 3
        game.recordPlay(1);

        // Step 4
        info = game.getScore();                  // "1-0-Red"
        System.out.println("(Step 4) info = " + info);

        // Step 5
        game.recordPlay(0);

        // Step 6
        info = game.getScore();                  // "1-0-Blue"
        System.out.println("(Step 6) info = " + info);

        // Step 7 (repeated call to show no change)
        info = game.getScore();                  // still "1-0-Blue"
        System.out.println("(Step 7) info = " + info);

        // Step 8
        game.recordPlay(3);

        // Step 9
        info = game.getScore();                  // "1-3-Blue"
        System.out.println("(Step 9) info = " + info);

        // Step 10
        game.recordPlay(1);

        // Step 11
        game.recordPlay(0);

        // Step 12
        info = game.getScore();                  // "1-4-Red"
        System.out.println("(Step 12) info = " + info);

        // Step 13
        game.recordPlay(0);

        // Step 14
        game.recordPlay(4);

        // Step 15
        game.recordPlay(0);

        // Step 16
        info = game.getScore();                  // "1-8-Red"
        System.out.println("(Step 16) info = " + info);

        // Step 17: Create an independent Scoreboard
        Scoreboard match = new Scoreboard("Lions", "Tigers");

        // Step 18
        info = match.getScore();                 // "0-0-Lions"
        System.out.println("(Step 18) match info = " + info);

        // Step 19: Verify the original game is unchanged
        info = game.getScore();                  // "1-8-Red"
        System.out.println("(Step 19) game info = " + info);
    }
}

Code Runner Cell and Output

Image

Reflection on My Approach

Problem Understanding

I approached this FRQ with a solid grasp of the requirements. The key insight I recognized was that this problem required tracking state - specifically, which team is active - rather than just accumulating scores. Many students might initially miss this and focus only on score tracking, but I correctly identified that managing activeTeam as a mutable state variable was central to the solution.

Design Decisions

State Representation: I chose to represent activeTeam as an integer (1 or 2) rather than a boolean or enum. This was a pragmatic choice that allowed for simple toggle logic using a ternary operator: activeTeam = (activeTeam == 1) ? 2 : 1. While an enum might be more “semantically clean,” my approach prioritized simplicity and was perfectly sufficient for this use case.

Score Storage: I maintained separate integer variables for team1Score and team2Score rather than using an array or map. This is actually preferable here because:

  • The problem explicitly mentions “team 1” and “team 2” throughout
  • It makes the constructor and methods more explicit and readable
  • It aligns with how many students think about the problem naturally

Team Names: Storing both team names in the constructor was essential. Without this, the getScore() method wouldn’t know which team name to return as the active team. This shows I understood the complete requirements.

Strengths of My Solution

  1. Correct Logic in recordPlay(): The conditional structure perfectly captures the business logic:
    • If points > 0: add to active team’s score, keep them active
    • If points == 0: switch active team (no score change)

    The use of a simple if-else rather than else if is appropriate here since we only have two cases.

  2. Clean getScore() Format: My string formatting correctly produces the required “score1-score2-activeTeamName” format. I used a ternary to look up the active team name, which is concise and readable.

  3. Proper State Initialization: The constructor sets all four instance variables correctly, including setting activeTeam = 1 to satisfy the requirement that “the game always begins with team 1 as the active team.”

  4. Independence of Objects: My solution correctly creates independent Scoreboard objects (the difference between game and match in the test cases demonstrates this). Each instance has its own state, which is fundamental to proper OOP design.

Code Quality Observations

Comments: I included helpful comments explaining each section (especially “1 for team1, 2 for team2” and “Failed play: switch to inactive team”). These comments show I understood why the code works, not just how to make it work.

No Unnecessary Complexity: I didn’t over-engineer the solution with extra methods, collections, or helper variables. The solution is minimal and focused - this is a strength in timed assessments and competitive programming.

Variable Naming: Names like team1Name, team2Score, and activeTeam are self-documenting. Someone reading my code can immediately understand what each variable represents without needing to trace through logic.

What I Handled Well

  1. The Toggle Logic: The ternary operator for switching teams (activeTeam = (activeTeam == 1) ? 2 : 1) is elegant and correct. It demonstrates understanding of Java ternary syntax and conditional logic.

  2. State Mutation vs. Immutability: I correctly identified that scores and active team must be mutable (instance variables) while team names are effectively constant (set once in constructor, never modified). This shows nuanced understanding of when mutability is appropriate.

  3. Test Case Validation: The provided test cases pass perfectly, which means I successfully handled:

    • Multiple consecutive plays by the same team
    • Team switching on failed plays
    • Multiple independent scoreboard objects
    • Calling getScore() multiple times without state changes

Potential Improvements (Advanced Thinking)

While my solution is correct and complete, here are considerations that might arise in code review discussions:

  1. Immutability: The activeTeam could theoretically be accessed and modified externally if it were public. Adding a private access modifier (which I did) prevents this - good defensive programming.

  2. Validation: The constructor could validate that team names are non-null and non-empty. The problem doesn’t require this, but it would be good practice in production code.

  3. Alternative Implementations: Instead of integer 1/2, I could have used an enum:

    enum Team { TEAM1, TEAM2 }
    private Team activeTeam;
    

    This would be more type-safe and self-documenting, though the added complexity might not be justified here.

Overall Assessment

This solution demonstrates that I:

  • Understand OOP fundamentals: proper use of constructors, instance variables, and methods
  • Can translate requirements to code: each requirement was directly and clearly implemented
  • Write readable, maintainable code: appropriate variable names, logical structure, and helpful comments
  • Can handle state management: correctly tracking mutable state across multiple method calls
  • Test my thinking: all test cases pass, proving logical correctness

This is a solid, textbook-quality FRQ solution that correctly interprets and implements the specified requirements without unnecessary complexity.