Word Builder Game in React.js

Technology: React.js

Problem Statement

Develop a word game where users need to create words using a set of permitted characters within a time limit. The goal is to match the user’s words with a list of correct words, and the score is based on the length of the guessed word.

Note that:

  • If a user types in a non-permitted character, it should not be added to the input bar.
  • The Submit button will get disabled after the timeout and an alert with Total Score will appear.
  • Clicking on Reset will result in the game starting again from the beginning.
  • Guessing the same word multiple times will not result in increased score.

Solution

Checkout the video solution here.

  • App.jsx
  • WordInput.jsx
  • Score.jsx
  • Timer.jsx
import { useState } from "react";
import "./styles.css";
import WordInput from "./components/WordInput";
import Timer from "./components/Timer";
import Score from "./components/Score";

export default function App() {
  const [score, setScore] = useState(0);
  const [timer, setTimer] = useState(10);

  const allowedChar = ["R", "A", "N", "D", "T", "E"];
  const winningWords = ["RAND", "TED", "RAN", "NED", "NET", "NERD"];

  return (
    <div className="App">
      <Timer time={timer} settime={setTimer} score={score} />
      <Score score={score} />
      <WordInput
        chars={allowedChar}
        winwords={winningWords}
        time={timer}
        settime={setTimer}
        setscore={setScore}
      />
    </div>
  );
}
import { useState } from "react";

export default function WordInput({
  chars,
  winwords,
  time,
  settime,
  setscore,
}) {
  const [guessword, setGuessword] = useState("");
  const [guessed, setGuessed] = useState([]);

  function submitWord(e) {
    e.preventDefault();

    const won = guessed.includes(guessword)
      ? false
      : winwords.includes(guessword);

    if (won) {
      const count = guessword.length;
      setscore((prevScore) => prevScore + count);
      setGuessed((prev) => [...prev, guessword]);
      setGuessword("");
    }
  }

  function validateChar(e) {
    const val = e.target.value.toUpperCase();
    const currChar = val !== "" ? val.slice(-1) : "";
    const permissible = chars.includes(currChar) || val === "";

    if (!permissible) {
      return;
    }

    setGuessword(val);
  }

  function reset() {
    settime(10);
    setscore(0);
    setGuessword("");
    setGuessed([]);
  }

  return (
    <>
      <p>Allowed Characters: {chars.join(", ")}</p>
      <form onSubmit={submitWord}>
        <input
          type="text"
          name="guessword"
          value={guessword}
          onChange={validateChar}
        />
        <input type="submit" value="Submit" disabled={!time} />
        <button onClick={reset}>Reset</button>
      </form>
    </>
  );
}
export default function Score({ score }) {
  return <h3>Score: {score}</h3>;
}
import { useEffect } from "react";

export default function Timer({ time, settime, score }) {
  useEffect(() => {
    let timer = setInterval(() => {
      settime((prev) => {
        if (prev === 0) {
          return alert(`Score is: ${score}`);
        }
        return prev - 1;
      });
    }, 1000);

    return () => clearInterval(timer);
  }, [score]);

  return <h2>{time ? time : "Time Over"}</h2>;
}

For visual step-by-step explanation, you can check out the following video: VIDEO_LINK.