CSA FRQ #2

Directions:

SHOW ALL YOUR WORK. REMEMBER THAT PROGRAM SEGMENTS ARE TO BE WRITTEN IN JAVA.

Notes:

  • Assume that the classes listed in the Java Quick Reference have been imported where appropriate.
  • Unless otherwise noted in the question, assume that parameters in method calls are not null and that methods are called only when their preconditions are satisfied.
  • In writing solutions for each question, you may use any of the accessible methods that are listed in classes defined in that question. Writing significant amounts of code that can be replaced by a call to one of these methods will not receive full credit.

Consider a guessing game in which a player tries to guess a hidden word. The hidden word contains only capital letters and has a length known to the player. A guess contains only capital letters and has the same length as the hidden word.

After a guess is made, the player is given a hint that is based on a comparison between the hidden word and the guess. Each position in the hint contains a character that corresponds to the letter in the same position in the guess. The following rules determine the characters that appear in the hint.

image

A table is shown with two columns titled If the letter in the guess is… on the left and the corresponding character in the hint is on the right. The first row reads also in the same position in the hidden word on the left, and the matching letter on the right. The second row reads also in the hidden word but in a different position on the left, and a plus sign on the right. The third row reads not in the hidden word on the left, and an asterisk on the right.

The HiddenWord class will be used to represent the hidden word in the game. The hidden word is passed to the constructor. The class contains a method, getHint, that takes a guess and produces a hint.

For example, suppose the variable puzzle is declared as follows.

HiddenWord puzzle = new HiddenWord(“HARPS”);

The following table shows several guesses and the hints that would be produced.

image

A table is shown with two columns titled Call to getHint on the left and String returned on the right. The first row reads puzzle dot getHint open parentheses “AAAAA” close parentheses on the left, and “plus A plus plus plus” on the right. The second row reads puzzle dot getHint open parentheses “HELLO” close parentheses on the left, and “H asterisk asterisk asterisk asterisk” on the right. The third row reads puzzle dot getHint open parentheses “HEART” close parentheses on the left, and “H asterisk plus plus asterisk” on the right. The fourth row reads puzzle dot getHint open parentheses “HARMS” close parentheses on the left, and “HAR asterisk S” on the right. The fifth row reads puzzle dot getHint open parentheses “HARPS” close parentheses on the left, and “HARPS” on the right.

Write the complete HiddenWord class, including any necessary instance variables, its constructor, and the method, getHint, described above. You may assume that the length of the guess is the same as the length of the hidden word.

Static way of how code works

public class HiddenWord {
    private String hiddenWord;

    public HiddenWord(String word) { // Constructor
        this.hiddenWord = word;
    }

    public String getHint(String guess) {// Method to get the hint based on the guess
        StringBuilder hint = new StringBuilder();

        for (int i = 0; i < hiddenWord.length(); i++) {// Check each letter in the guess against the hidden word
            char guessChar = guess.charAt(i);
            char hiddenChar = hiddenWord.charAt(i);

            if (guessChar == hiddenChar) { // If the letter is in the same position, append the letter
                hint.append(hiddenChar);
            } else if (hiddenWord.indexOf(guessChar) != -1) {
                hint.append("+");// If the letter is in a different position, append a plus sign
            } else {
                hint.append("*"); //if the letter is not in the hidden word, append an asterisk
            }
        }

        return hint.toString();
    }

    public static void main(String[] args) {
        HiddenWord puzzle = new HiddenWord("HARPS");

        System.out.println(puzzle.getHint("AAAAA"));  
        System.out.println(puzzle.getHint("HELLO"));  
        System.out.println(puzzle.getHint("HEART")); 
        System.out.println(puzzle.getHint("HARMS"));
        System.out.println(puzzle.getHint("HARPS"));   
    }
}

HiddenWord.main(null);
+A+++
H****
H*++*
HAR*S
HARPS

User input with scanner

import java.util.Scanner;

public class HiddenWord {
    private String hiddenWord;

    public HiddenWord(String word) { //constructor
        this.hiddenWord = word;
    }

    // Method to get the hint based on the guess
    public String getHint(String guess) {
        String hint = "";

        // Check each letter in the guess against the hidden word
        for (int i = 0; i < hiddenWord.length(); i++) {
            char guessChar = guess.charAt(i);
            char hiddenChar = hiddenWord.charAt(i);

            hint += getHintCharacter(guessChar, hiddenChar);
        }
        return hint;
    }

    // Helper method to determine the hint character for a pair of characters
    private String getHintCharacter(char guessChar, char hiddenChar) {
        if (guessChar == hiddenChar) {
            return String.valueOf(hiddenChar);
        } 
        else if (hiddenWord.indexOf(guessChar) != -1) {
            return "+";
        } 
        else {
            return "*";
        }
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        // Take input for the hidden word
        System.out.print("Enter the hidden word: ");
        String hiddenWord = scanner.next().toUpperCase(); // Convert to uppercase for consistency
        HiddenWord puzzle = new HiddenWord(hiddenWord);

        // Take multiple guesses until the correct word is guessed
        while (true) {
            System.out.print("Enter your guess: ");
            String guess = scanner.next().toUpperCase(); // Convert to uppercase for consistency

            if (guess.length() != hiddenWord.length()) {
                System.out.println("Please enter a guess with the same length as the hidden word.");
                continue; // Skip the rest of the loop and ask for another guess
            }

            String hint = puzzle.getHint(guess);
            System.out.println("Hint: " + hint);

            if (hint.equals(hiddenWord)) {
                System.out.println("Congratulations! You guessed the hidden word.");
                break; // Exit the loop if the correct word is guessed
            }
        }
        scanner.close();
    }
}

HiddenWord.main(null);
Enter the hidden word: Enter your guess: Hint: +A+++
Enter your guess: Hint: H****
Enter your guess: Hint: H*++*
Enter your guess: Hint: HAR*S
Enter your guess: Hint: HARPS
Congratulations! You guessed the hidden word.

Explanation and Reflection:

Compared to the first quesiton with arrays, I find this question a bit more trickier because it isn’t as straight forward. It may seem confusing to someone who hasn’t ever played this game. In question 1, it was just iterating through arrays and finding the sum of that array. Now, we are required to build classes with constructors and methods that iterate through for loops to find whether or not a character is valid.

When solving this question, the most important piece of code is:

public String getHint(String guess) {
        StringBuilder hint = new StringBuilder();

        for (int i = 0; i < hiddenWord.length(); i++) { //check each letter in the guess against the hidden word
            char guessChar = guess.charAt(i);
            char hiddenChar = hiddenWord.charAt(i);

            if (guessChar == hiddenChar) {
                hint.append(hiddenChar); //if the letter is in the same position, append the letter
            } 
            else if (hiddenWord.indexOf(guessChar) != -1) { // same thing but using a + sign if letter is in the word but not in the right spot
                hint.append("+");
            } 
            else { // If the letter is not in the hidden word, append an asterisk
                hint.append("*");
            }
        }
        return hint.toString();
    }

When first looking at the problem, it came to me that the question wanted me to build a program that is similar to Wordle. I was thinking about iterating through each character and then replacing the character based on if it was in the hidden word or not but that would be way too long and complicated. Instead, I used StringBuilder to easily modify the string after it has been constructed.