HiddenWord: 2015 FRQ 2
A step-by-step solution to the 2015 AP CSA FRQ 2 (HiddenWord), covering building a word-guessing game class that compares strings letter by letter in Java.
A word-guessing game with letter-by-letter feedback drives this AP Computer Science A free-response question — you build the entire class that compares a hidden word to a guess and produces a hint string, one character at a time.
What This FRQ Tests
- AP CSA units: Unit 5 (Writing Classes)
- Core skill: writing a complete class from a plain-English description, including its constructor and one method
- Secondary skill: comparing characters position-by-position across two equal-length strings, and checking whether a character shows up somewhere else in a string
- Official category: this year's FRQ 2 fits cleanly into the "Classes" category (Unit 5). Pre-2019 AP CSA exams didn't follow today's fixed FRQ-number-to-category order, but for 2015 this particular question happens to line up with what's now the modern FRQ-2 slot.
The Setup
- No class skeleton is given at all — the entire
HiddenWordclass is up to you to design - The constructor takes the hidden word as a
String(capital letters only) - One method:
getHint(String guess), whereguessis guaranteed to be the same length as the hidden word - The rule for each position in the returned hint:
- Guess letter matches the hidden word's letter at that exact position → that letter itself
- Guess letter appears somewhere in the hidden word, just not at that position →
"+" - Guess letter doesn't appear in the hidden word at all →
"*"
Building the HiddenWord Class
Step-by-Step Approach
- Store the hidden word in an instance variable — it's the only piece of state that needs to persist between calls to
getHint. - In
getHint, build the hint one character position at a time, inside a loop. - At each position, pull out the guess's letter and the hidden word's letter at that same index.
- If the two letters match, add that letter to the hint being built.
- If they don't match, check whether the guess's letter appears anywhere in the hidden word — if so, add
"+". - Otherwise, add
"*". - Return the finished hint after the loop completes.
The Code
public class HiddenWord
{
private String word;
public HiddenWord(String w)
{
word = w;
}
public String getHint(String guess)
{
String hint = "";
for (int i = 0; i < word.length(); i++)
{
String guessLetter = guess.substring(i, i + 1);
String wordLetter = word.substring(i, i + 1);
if (guessLetter.equals(wordLetter))
{
hint = hint + guessLetter;
}
else if (word.indexOf(guessLetter) != -1)
{
hint = hint + "+";
}
else
{
hint = hint + "*";
}
}
return hint;
}
}
Why Each Piece Matters
word.substring(i, i + 1)pulls out a single-characterStringat positioni— this is how the solution gets "the letter at positioni" while sticking to a method that's on the AP CSA Quick Reference sheet.charAtwould return that character more directly, but it isn't listed there (see the Notes section below for that version)..equals(), never==, for comparing the two single-character strings — two separately-builtStringobjects with identical characters aren't guaranteed to be the same object in memory.- Order matters: the exact-position check happens first, and the
indexOfcheck only runs when that first check has already failed. An exact match must never fall through and get reported as a"+"instead. word.indexOf(guessLetter) != -1, reached only after the exact-match check already failed, doesn't need to separately confirm the letter is at a different position — if it had been at the same position, the first check would already have caught it.
Tracing the Example
Using the question's own setup, puzzle = new HiddenWord("HARPS"), here's puzzle.getHint("HEART") traced position by position:
| Position | Guess letter | Word letter | Same-position match? | Appears elsewhere in word? | Hint character |
|---|---|---|---|---|---|
| 0 | H | H | yes | — | H |
| 1 | E | A | no | no | * |
| 2 | A | R | no | yes (A is at index 1) | + |
| 3 | R | P | no | yes (R is at index 2) | + |
| 4 | T | S | no | no | * |
Final result: "H*++*" — matches the question's table exactly.
The same position-by-position logic produces the rest of the question's examples too: "+A+++" for "AAAAA", "H****" for "HELLO", "HAR*S" for "HARMS", and "HARPS" for "HARPS" itself (every letter matching its own position).
Common Mistakes to Avoid
- Checking
indexOfbefore checking for an exact match. SinceindexOfwould still find the letter even when it's at the exact same position, checking it first would report every correctly-placed letter as a"+"instead of the letter itself. - Comparing the single-character strings with
==instead of.equals(). This is one of the most common AP CSA point losses anywhereStringcomparison shows up. - Building the hint as a
char[]and forgetting to convert it back to aString— the method's return type isString, notchar[]. - Looping over
guess.length()instead ofword.length(). The two are guaranteed equal here, but tying the loop bound to the object's own stored state (word) is the more defensible habit.
Notes: A Simpler Way to Grab a Single Character
public String getHint(String guess)
{
String hint = "";
for (int i = 0; i < word.length(); i++)
{
char guessLetter = guess.charAt(i);
char wordLetter = word.charAt(i);
if (guessLetter == wordLetter)
{
hint = hint + guessLetter;
}
else if (word.indexOf(guessLetter) != -1)
{
hint = hint + "+";
}
else
{
hint = hint + "*";
}
}
return hint;
}
charAt(i)returns the character at a position directly, instead of pulling out a one-characterStringwithsubstring(i, i + 1).charAtisn't listed on the AP CSA Quick Reference sheet, but that doesn't mean it's disallowed — AP CSA graders accept any correct Java, not just methods printed on the sheet. The real tradeoff is not being able to look its exact behavior up during the exam if you second-guess yourself, the way you could withsubstring.- Since
charis a primitive type,==correctly compares twocharvalues by content here — this is one of the few places in Java where==is genuinely the right choice, unlike comparingStringobjects.
Key Takeaways
- When a rule has multiple fallback conditions, check the most specific case (an exact match) before falling back to a more general one (appears anywhere) — checking out of order silently changes the answer.
substring(i, i + 1)is the Quick-Reference-safe way to pull a single character out of aStringwhencharAtisn't the method you want to rely on.- Building a
Stringpiece-by-piece inside a loop, then returning it once the loop finishes, is a pattern that shows up across many AP CSA FRQs well beyond this one.