Skip to content

Instantly share code, notes, and snippets.

@huytd
Last active May 2, 2024 12:13
Show Gist options
  • Save huytd/6a1a6a7b34a0d0abcac00b47e3d01513 to your computer and use it in GitHub Desktop.
Save huytd/6a1a6a7b34a0d0abcac00b47e3d01513 to your computer and use it in GitHub Desktop.
Wordle in less than 50 lines of Bash

image

How to use:

./wordle.sh

Or try the unlimit mode:

./wordle.sh unlimit
words=($(grep '^\w\w\w\w\w$' /usr/share/dict/words | tr '[a-z]' '[A-Z]'))
actual=${words[$[$RANDOM % ${#words[@]}]]} end=false guess_count=0 max_guess=6
if [[ $1 == "unlimit" ]]; then
max_guess=999999
fi
while [[ $end != true ]]; do
guess_count=$(( $guess_count + 1 ))
if [[ $guess_count -le $max_guess ]]; then
echo "Enter your guess ($guess_count / $max_guess):"
read guess
guess=$(echo $guess | tr '[a-z]' '[A-Z]')
if [[ " ${words[*]} " =~ " $guess " ]]; then
output="" remaining=""
if [[ $actual == $guess ]]; then
echo "You guessed right!"
for ((i = 0; i < ${#actual}; i++)); do
output+="\033[30;102m ${guess:$i:1} \033[0m"
done
printf "$output\n"
end=true
else
for ((i = 0; i < ${#actual}; i++)); do
if [[ "${actual:$i:1}" != "${guess:$i:1}" ]]; then
remaining+=${actual:$i:1}
fi
done
for ((i = 0; i < ${#actual}; i++)); do
if [[ "${actual:$i:1}" != "${guess:$i:1}" ]]; then
if [[ "$remaining" == *"${guess:$i:1}"* ]]; then
output+="\033[30;103m ${guess:$i:1} \033[0m"
remaining=${remaining/"${guess:$i:1}"/}
else
output+="\033[30;107m ${guess:$i:1} \033[0m"
fi
else
output+="\033[30;102m ${guess:$i:1} \033[0m"
fi
done
printf "$output\n"
fi
else
echo "Please enter a valid word with 5 letters!";
guess_count=$(( $guess_count - 1 ))
fi
else
echo "You lose! The word is:"
echo $actual
end=true
fi
done
@BMDan
Copy link

BMDan commented Feb 9, 2022

As promised, the version without arrays. Also makes some minor stylistic changes, deletes an unnecessary loop, and adds an "abandon" feature (press CTRL-D at the prompt). 36 lines, total.

actual="$(sort -R /usr/share/dict/words | grep -xEm 1 '\w{5}' | tr '[:lower:]' '[:upper:]')"
guess_count=0 max_guess=6
[[ "${1//unlimit}" != "${1:-}" ]] && max_guess=999999
while true; do
    guess_count=$(( guess_count + 1 ))
    if [[ $guess_count -le $max_guess ]]; then
        while read -r -p "Enter your guess ($guess_count / $max_guess): " guess; do
            grep -ixF "${guess:-inv.alid}" /usr/share/dict/words | grep -xqE '\w{5}' && break
            [[ ${#guess} != 5 ]] && echo "Too short/long." && continue
            echo "Not a real word."
        done
        [ ${#guess} -eq 0 ] && echo && echo "Giving up so soon?  The answer was $actual." && break
        guess="$(tr '[:lower:]' '[:upper:]' <<<"$guess")"
        output="" remaining=""
        for ((i = 0; i < ${#actual}; i++)); do
            [[ "${actual:$i:1}" != "${guess:$i:1}" ]] && remaining+=${actual:$i:1}
        done
        for ((i = 0; i < ${#actual}; i++)); do
            if [[ "${actual:$i:1}" != "${guess:$i:1}" ]]; then
                if [[ "$remaining" == *"${guess:$i:1}"* ]]; then
                    output+="$(tput setaf 0)$(tput setab 11) ${guess:$i:1} $(tput sgr0)"
                    remaining=${remaining/"${guess:$i:1}"/}
                else
                    output+="$(tput setaf 0)$(tput setab 15) ${guess:$i:1} $(tput sgr0)"
                fi
            else
                output+="$(tput setaf 0)$(tput setab 10) ${guess:$i:1} $(tput sgr0)"
            fi
        done
        echo "$output"
        [ "$actual" = "$guess" ] && echo "You guessed right!" && break
    else
        echo "You lose!  The word was $(tput setaf 1)$(tput bold)$actual$(tput sgr0)."
        break
    fi
done

@kristinbell
Copy link

Here's a challenge for someone: Can we make a game that uses more than one language at a time? Would that just involve using two dictionaries? Or would the game need different rules?

@cjdinger
Copy link

I wrote a SAS version and placed it here sascommunities/wordle-sas. Uses the word lists from cfreshman (thanks) and arrays to check guesses.

example-game-dsobj

@aramvr
Copy link

aramvr commented Mar 18, 2022

I learned about this from an Oreilly blog post. Good job!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment