48 - Hangman Game

Description

Build a Hangman game where players guess a hidden word letter by letter.

  • Generate a random word from a word list.

  • Show blanks or underscores representing the word's length.

  • Allow players to guess individual letters.

  • Reveal correctly guessed letters and update the blank spaces.

  • Track incorrect guesses and display a hangman graphic depending on the count.

  • Announce win or lose conditions, offering to play again.

Algorithm

Components:

  • GameBoard: Renders the hangman graphic, word blanks, guess input, and win/lose messages.

  • WordList: Holds an array of random words for selection.

  • LetterInput: Handles user input for guessing letters.

Data:

  • Store the chosen word, remaining guesses, and guessed letters in the GameBoard state.

  • Update the state based on user interactions and game logic.

Logic:

  • On guess attempt, check if the letter is present in the chosen word.

  • If correct, reveal the letter in the word blanks.

  • If incorrect, decrease remaining guesses and update the hangman graphic.

  • Check for win (all letters guessed) or lose (no more guesses) conditions.

  • After reaching an end state, offer a "Play Again" option.

Code

import React, { useState, useEffect } from 'react';
import WordList from './WordList';
import LetterInput from './LetterInput';

const GameBoard = () => {
  const [chosenWord, setChosenWord] = useState('');
  const [remainingGuesses, setRemainingGuesses] = useState(6);
  const [guessedLetters, setGuessedLetters] = useState([]);
  const [isWin, setIsWin] = useState(false);
  const [isLose, setIsLose] = useState(false);

  useEffect(() => {
    // Start a new game on component mount
    startNewGame();
  }, []);

  const startNewGame = () => {
    setChosenWord(WordList.getRandomWord());
    setRemainingGuesses(6);
    setGuessedLetters([]);
    setIsWin(false);
    setIsLose(false);
  };

  const handleGuess = (letter) => {
    if (isWin || isLose) return; // Do nothing if game is already over

    letter = letter.toUpperCase();

    if (guessedLetters.includes(letter)) return; // Already guessed this letter

    setGuessedLetters([...guessedLetters, letter]);

    if (chosenWord.includes(letter)) {
      // Correct guess
      const newWord = chosenWord.split('').map((char) =>
        guessedLetters.includes(char) ? char : '_'
      );
      setChosenWord(newWord.join(''));

      if (!newWord.includes('_')) {
        // All letters guessed correctly
        setIsWin(true);
      }
    } else {
      // Incorrect guess
      setRemainingGuesses(remainingGuesses - 1);
      if (remainingGuesses === 0) {
        setIsLose(true);
      }
    }
  };

  return (
    <div className="game-board">
      {/* Render hangman graphic here */}
      <p>Remaining guesses: {remainingGuesses}</p>
      <p>Word: {chosenWord.split('').map((char) => char === '_' ? ' _ ' : char).join('')}</p>
      <LetterInput onGuess={handleGuess} />
      {isWin && <p>Congratulations, you win!</p>}
      {isLose && <p>You lose! The word was {chosenWord}</p>}
      {isWin || isLose && <button onClick={startNewGame}>Play Again</button>}
    </div>
  );
};

export default GameBoard;
const words = [
  'apple',
  'banana',
  'computer',
  'guitar',
  'rainbow',
  'elephant',
  'butterfly',
  // Add more words here
];

export const getRandomWord = () => {
  return words[Math.floor(Math.random() * words.length)];
};
import React, { useState } from 'react';

const LetterInput = ({ onGuess }) => {
  const [inputValue, setInputValue] = useState('');

  const handleChange = (event) => {
    setInputValue(event.target.value.toUpperCase());
  };

  const handleSubmit = () => {
    if (inputValue.length === 1) {
      onGuess(inputValue);
      setInputValue('');
    }
  };

  return (
    <input
      type="text"
      placeholder="Guess a letter"
      value={inputValue}
      onChange={handleChange}
      onKeyUp={(e) => e.key === 'Enter' && handleSubmit()}
    />
  );
};

export default LetterInput;

Explanation

GameBoard.js:

  • Manages the main game state (chosen word, guesses, win/lose status).

  • Starts a new game on component mount.

  • Handles letter guesses, updating state accordingly.

  • Renders the game interface (hangman graphic, word, input, messages).

WordList.js:

  • Holds an array of words for the game.

  • Provides a function to randomly select a word.

LetterInput.js:

  • Handles user input for letter guesses.

  • Validates input to ensure single letters.

  • Triggers the onGuess function from GameBoard when a valid letter is entered.

Additional Notes

  • Hangman Graphic: The code currently includes a placeholder comment for rendering the hangman graphic. You'll need to implement this using an image or SVG elements.

  • CSS: Add basic CSS to style the game elements and make it visually appealing.

  • Difficulty Levels: Consider filtering words based on length or category for difficulty options.

  • Hints: Provide hints after a certain number of incorrect guesses or as a user-activated feature.

  • Visual Feedback: Highlight correct and incorrect letters differently for visual clarity.

  • Animation: Incorporate smooth transitions for the hangman graphic and element updates.

  • Sound Effects: Add sound effects for correct guesses, incorrect guesses, and game completion.

Last updated