hardReact Native#131

Wordle (word guessing game)

Prompt

Implement the letter-scoring logic for a Wordle game.

Write function checkGuess(guess) that takes a 5-letter string and returns an array of { letter, color } objects:

  • Green (#4CAF50) for correct letter in correct position
  • Yellow (#FFC107) for correct letter in wrong position
  • Gray (#9E9E9E) for incorrect letter

The target word is "REACT". Max 6 attempts.

Solution

const TARGET = 'REACT'

function checkGuess(guess) {
  return guess.split('').map((letter, i) => {
    if (TARGET[i] === letter) return { letter, color: '#4CAF50' }
    if (TARGET.includes(letter)) return { letter, color: '#FFC107' }
    return { letter, color: '#9E9E9E' }
  })
}
Mentor's take

The design lesson is game-state purity: checkGuess is string in, data out — no setState, no rendering, no globals mutated. The component's job shrinks to mapping the returned array onto colored tiles, and the scoring logic becomes testable with plain assertions, no renderer required. Whenever an interview project contains rules (scoring, win detection, validation), extracting them as pure functions is the first structural move.

The algorithm is a two-tier check per position, ordered by precedence: exact match at index i wins green before the membership check can claim yellow — flip those branches and a correctly-placed letter turns yellow. map over split('') keeps it a single pass returning a same-length array, which is exactly the shape the tile row wants.

The trade-off to volunteer unprompted: duplicate letters. TARGET.includes(letter) marks every stray occurrence yellow — guess "EEEEE" against REACT and you get one green plus four yellows, where real Wordle yellows only as many copies as remain unmatched. The correct version is two passes with a letter-count map: consume greens first, then spend remaining counts on yellows. Naming that limitation, and its fix, is worth more than silently shipping either version.

Red flag: computing colors inline in JSX per tile. The logic becomes untestable, re-runs per tile per render, and duplicates the precedence rule in view code.

Say it: "Scoring is a pure function the UI just renders — and I'd flag that includes() over-yellows duplicate letters; the fix is a count-based two-pass."