Back to AI Coding

Word Reveal

One way to clear each phase. Compare the approach with your own, then try the patterns yourself.

src/validator.py
"""Phase 1: Validator must accept both upper- and lowercase letters
because the game is case-insensitive."""


class Validator:
    """Enforces input rules for the Word Reveal game."""

    def is_valid(self, guess: str) -> bool:
        """A guess is valid if it is exactly one alphabetic character.
        Both 'A' and 'a' are acceptable."""
        if not isinstance(guess, str):
            return False
        if len(guess) != 1:
            return False
        # Bug fix: accept upper- AND lowercase. The original `'a' <= guess <= 'z'`
        # rejected every uppercase guess in a "case-insensitive" game.
        return ('a' <= guess <= 'z') or ('A' <= guess <= 'Z')
src/reveal_state.py
"""Phase 1: case-insensitive secret matching + corrected `is_complete`."""

from typing import List


class RevealState:
    """Hidden-word state, Hangman-style."""

    def __init__(self, secret: str):
        if not secret:
            raise ValueError("secret must be non-empty")
        self._secret = secret
        self._revealed: List[str] = ['_' for _ in secret]

    def apply(self, letter: str) -> int:
        """Reveal every position of `letter` in the secret.
        Returns the number of newly-revealed positions. Case-insensitive."""
        letter = letter.lower()
        count = 0
        for i, ch in enumerate(self._secret):
            # Bug fix: compare the secret in lowercase so uppercase
            # secrets ("APPLE") match lowercase guesses ("p").
            if ch.lower() == letter and self._revealed[i] == '_':
                self._revealed[i] = letter
                count += 1
        return count

    def display(self) -> str:
        """Visible state: revealed letters with underscores for unknown."""
        return ' '.join(self._revealed)

    def is_complete(self) -> bool:
        """True iff every position has been revealed."""
        # Bug fix: the original `'_' in self._revealed` returned True
        # exactly when the word still had blanks. Logic was inverted.
        return '_' not in self._revealed

    def secret(self) -> str:
        return self._secret

Discuss