skip to Main Content

I am trying to create a word search puzzle, but I am encountering some issues that for the life of me, I can’t seem to figure out. I’m just starting out with JS so be gentle, and any help is greatly appreciated.

Also, here is the fiddle with all the files: https://jsfiddle.net/jruiztt/3xgL7wzh/

As far as I can tell, here are the issues:

Puzzle Squares Coloring Issue:

Puzzle squares containing letters from the defined keywords are not changing their background color to red and text color to white when clicked.

Solve Puzzle Button Coloring Issue:

When the "Solve Puzzle" button is clicked, the background color and text color of the keywords in the puzzle are not changing to red and white, respectively.

Checkmark Legend Issue:

The legend checkboxes for keywords are not getting checked off when all the letters corresponding to a keyword are clicked in the puzzle.

Game Completion Check Issue:

The "Claim Prize" button is not being enabled even after all the checkboxes in the legend are checked, and all keywords in the puzzle are marked as completed.

JavaScript Error:

An error occurs in the console: "Uncaught ReferenceError: words is not defined" when attempting to solve the puzzle.

document.addEventListener('DOMContentLoaded', function() {
  const words = ["happy", "birthday", "to", "you"];
  const directions = ["horizontal", "vertical", "diagonal"];

  // Generate a random word search puzzle
  const puzzle = generatePuzzle(words, directions);

  // Render the puzzle on the page
  renderPuzzle(puzzle);

  // Add event listeners to squares for clicking
  const squares = document.querySelectorAll('.square');
  squares.forEach(square => {
    square.addEventListener('click', () => {
      checkWord(square);
    });
  });

  // Add event listener to the "Solve Puzzle" button
  const solveButton = document.getElementById('solveButton');
  solveButton.addEventListener('click', solvePuzzle);

  // Add event listener to the "Claim Prize" button
  const claimPrizeButton = document.getElementById('claimPrizeButton');
  claimPrizeButton.addEventListener('click', claimPrize);
});

function generatePuzzle(words, directions) {
  const gridSize = 10;
  const puzzle = Array.from({
    length: gridSize
  }, () => Array(gridSize).fill(''));

  // Place words in the puzzle
  words.forEach(word => {
    let placed = false;
    while (!placed) {
      const direction = directions[Math.floor(Math.random() * directions.length)];
      const row = Math.floor(Math.random() * gridSize);
      const col = Math.floor(Math.random() * gridSize);

      placed = placeWordInGrid(word.toUpperCase(), puzzle, row, col, direction);
    }
  });

  // Fill empty squares with random letters
  puzzle.forEach((row, rowIndex) => {
    row.forEach((cell, colIndex) => {
      if (cell === '') {
        const randomLetter = String.fromCharCode(65 + Math.floor(Math.random() * 26));
        puzzle[rowIndex][colIndex] = randomLetter;
      }
    });
  });

  return puzzle;
}

function placeWordInGrid(word, puzzle, startRow, startCol, direction) {
  const wordLength = word.length;
  const gridSize = puzzle.length;

  let endRow, endCol;

  switch (direction) {
    case 'horizontal':
      endRow = startRow;
      endCol = startCol + wordLength - 1;
      break;
    case 'vertical':
      endRow = startRow + wordLength - 1;
      endCol = startCol;
      break;
    case 'diagonal':
      endRow = startRow + wordLength - 1;
      endCol = startCol + wordLength - 1;
      break;
  }

  if (endRow >= gridSize || endCol >= gridSize) {
    return false;
  }

  for (let i = 0; i < wordLength; i++) {
    if (puzzle[startRow][startCol] !== '' && puzzle[startRow][startCol] !== word[i]) {
      return false;
    }

    puzzle[startRow][startCol] = word[i];

    switch (direction) {
      case 'horizontal':
        startCol++;
        break;
      case 'vertical':
        startRow++;
        break;
      case 'diagonal':
        startRow++;
        startCol++;
        break;
    }
  }

  return true;
}

function renderPuzzle(puzzle) {
  const container = document.getElementById('wordSearchContainer');
  container.innerHTML = '';

  puzzle.forEach((row, rowIndex) => {
    row.forEach((letter, colIndex) => {
      const square = document.createElement('div');
      square.className = 'square';
      square.textContent = letter;
      square.dataset.row = rowIndex;
      square.dataset.col = colIndex;
      container.appendChild(square);
    });
  });
}

function checkWord(square) {
  const wordList = document.getElementById('wordList');
  const words = Array.from(wordList.getElementsByTagName('li'));

  words.forEach(word => {
    const letters = word.textContent.split('');

    if (letters.includes(square.textContent.toUpperCase())) {
      square.classList.add('selected');
      const selectedSquares = document.querySelectorAll('.selected');
      const wordFound = letters.every(letter =>
        Array.from(selectedSquares).some(selectedSquare => selectedSquare.textContent === letter)
      );

      if (wordFound) {
        word.classList.add('completed');
        selectedSquares.forEach(selectedSquare => {
          selectedSquare.classList.remove('selected');
          selectedSquare.style.backgroundColor = 'red';
          selectedSquare.style.color = 'white';
        });
        checkGameCompletion();
      }
    }
  });
}

function solvePuzzle() {
  const squares = document.querySelectorAll('.square');
  const wordList = document.getElementById('wordList');
  const words = Array.from(wordList.getElementsByTagName('li'));

  words.forEach(word => word.classList.add('completed'));

  squares.forEach(square => {
    const isKeywordSquare = words.some(word =>
      Array.from(word.textContent).some(letter => letter === square.textContent.toUpperCase())
    );

    if (isKeywordSquare) {
      square.classList.add('selected');
      square.style.backgroundColor = 'red';
      square.style.color = 'white';
    }
  });

  checkGameCompletion();
}

function checkGameCompletion() {
  const wordList = document.getElementById('wordList');
  const completedWords = Array.from(wordList.getElementsByClassName('completed'));

  const claimPrizeButton = document.getElementById('claimPrizeButton');
  claimPrizeButton.disabled = completedWords.length !== words.length ? true : false;
}

function claimPrize() {
  alert("Congratulations! You've successfully solved the puzzle!");
}
body {
  font-family: 'Arial', sans-serif;
  margin: 0;
  padding: 20px;
}

#wordSearchContainer {
  display: grid;
  grid-template-columns: repeat(10, 1fr);
  gap: 5px;
  max-width: 400px;
  margin-bottom: 20px;
}

.square {
  width: 100%;
  padding: 10px;
  text-align: center;
  cursor: pointer;
  border: 1px solid #ccc;
  background-color: #fff;
  user-select: none;
}

.square.selected {
  background-color: red;
  color: white;
}

#legend {
  margin-bottom: 20px;
}

h2 {
  margin: 0;
  font-size: 18px;
}

#wordList {
  list-style: none;
  padding: 0;
}

li {
  margin-bottom: 5px;
  display: flex;
  align-items: center;
}

li::before {
  content: '';
  display: inline-block;
  width: 15px;
  height: 15px;
  margin-right: 5px;
  border: 2px solid #333;
}

li.completed::before {
  background-color: #333;
}

#buttons {
  display: flex;
  gap: 10px;
}

button {
  padding: 10px;
  font-size: 16px;
  cursor: pointer;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="test-style.css">
  <title>Word Search Puzzle</title>
</head>

<body>
  <div id="wordSearchContainer"></div>
  <div id="legend">
    <h2>Words to find</h2>
    <ul id="wordList">
      <li id="happy">happy</li>
      <li id="birthday">birthday</li>
      <li id="to">to</li>
      <li id="you">you</li>
    </ul>
  </div>
  <div id="buttons">
    <button id="solveButton">Solve Puzzle</button>
    <button id="claimPrizeButton" disabled>Claim Prize</button>
  </div>
  <script src="test-script.js"></script>
</body>

</html>

2

Answers


  1. Puzzle Squares Coloring Issue: The condition letters.includes(square.textContent.toUpperCase()) is not fulfilled and nothing happens after. You should convert square letter to lowercase one to find it in letters from the word, so .toLowerCase().

    Login or Signup to reply.
  2. The words array is defined in your DOMContentLoaded event listener function. The const declaration is block-scoped it isn’t available in your checkGameCompletion() function.

    You should pass the words array the same way you did with the generatePuzzle(words, directions) function.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search