Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Solutions & Fixes

This section shows one set of possible fixes for the workshop exercises.
Your exact solutions may differ slightly as long as they:

  • Remove the crashes.
  • Produce correct behavior.
  • Keep the code readable.

Level 1 – Reading Errors

BuggyCalculator.divide

One reasonable fix:

public static int divide(int a, int b) {
    if (b == 0) {
        // FIX: prevent division by zero and return a safe default
        System.out.println("Cannot divide " + a + " by zero.");
        return 0; // or throw new IllegalArgumentException("b must not be zero");
    }
    return a / b;
}

BuggyCalculator.sumFirstThree

Handle short arrays safely:

public static int sumFirstThree(int[] numbers) {
    if (numbers == null || numbers.length == 0) {
        // FIX: handle null or empty arrays without throwing an exception
        return 0;
    }

    int limit = Math.min(3, numbers.length);
    int total = 0;
    for (int i = 0; i < limit; i++) {
        // FIX: stop before we run past the end of the array
        total += numbers[i];
    }
    return total;
}

BuggyLoop.countUpTo

If the intent is to count how many numbers from 1 to n (inclusive):

public static int countUpTo(int n) {
    int count = 0;
    for (int i = 1; i <= n; i++) {
        // FIX: loop up to and including n so the count matches the intent
        count++;
    }
    return count;
}

Level 2 – Debugger Basics

The key fixes here are the same as Level 1, but discovered using:

  • Breakpoints.
  • Stepping.
  • Variable inspection.

See the Level 1 solutions above.


Level 3 – Multi‑File Debugging

ScoreUtils.averageScore

Correct the average calculation:

public static double averageScore(int[] scores) {
    if (scores == null || scores.length == 0) {
        // FIX: avoid dividing by zero and define a default average
        return 0.0;
    }

    int total = 0;
    for (int score : scores) {
        total += score;
    }
    // FIX: divide by the correct length to get an accurate average
    return (double) total / scores.length;
}

ScoreUtils.bestScore

Handle empty arrays and negative scores:

public static int bestScore(int[] scores) {
    if (scores == null || scores.length == 0) {
        // FIX: define behavior for empty or null score lists
        return 0; // or throw an exception, depending on requirements
    }

    int best = scores[0];
    for (int i = 1; i < scores.length; i++) {
        // FIX: compare all elements starting from index 1
        if (scores[i] > best) {
            best = scores[i];
        }
    }
    return best;
}

ScoreUtils.totalScore

Defensive null handling:

public static int totalScore(Player player) {
    if (player == null || player.getScores() == null) {
        // FIX: return a safe default when player or scores are missing
        return 0;
    }

    int sum = 0;
    for (int s : player.getScores()) {
        sum += s;
    }
    return sum;
}

Level 4 – Layered Bugs

InputParser.parseLevel

A safer implementation:

public static int parseLevel(String input) {
    if (input == null) {
        // FIX: handle null input by falling back to level 1
        return 1; // default level
    }

    String trimmed = input.trim(); // e.g., "level: 4"
    String[] parts = trimmed.split(":");
    if (parts.length < 2) {
        // FIX: validate the basic "label:number" format
        return 1; // or throw new IllegalArgumentException("Invalid level format");
    }

    String numberPart = parts[1].trim();

    try {
        // FIX: trim and safely parse the numeric part
        return Integer.parseInt(numberPart);
    } catch (NumberFormatException e) {
        // FIX: use a safe default when parsing fails instead of crashing
        return 1;
    }
}

LevelLoader.loadEnemiesForLevel

Return a non‑null array:

public static int[] loadEnemiesForLevel(int level) {
    if (level == 1) {
        return new int[] {2, 3};
    } else if (level == 2) {
        return new int[] {4, 4, 5};
    } else if (level == 3) {
        return new int[] {10};
    } else {
        // FIX: return an empty array instead of null for unknown levels
        return new int[0];
    }
}

LevelLoader.computeDifficulty

Fix the off‑by‑one and null handling:

public static int computeDifficulty(int[] enemies) {
    if (enemies == null || enemies.length == 0) {
        // FIX: define a difficulty of 0 when there are no enemies
        return 0;
    }

    int difficulty = 0;
    for (int i = 0; i < enemies.length; i++) {
        // FIX: stop at enemies.length - 1 to avoid going out of bounds
        difficulty += enemies[i] * (i + 1);
    }
    return difficulty;
}

Putting it all together

After applying these fixes:

  • The programs should compile and run without exceptions.
  • The scoreboard should report sensible averages, best scores, and totals.
  • The level loader should parse inputs, avoid null issues, and compute difficulty correctly.

If your results differ, use the debugger again to:

  • Set breakpoints in the fixed methods.
  • Step through and verify that variable values match your expectations.