12

I want to create some letters boxed as in the Wordle game: screenshot from the wordle game: letters in colored square boxes But so far i have not found a tool that allows me to do it. I want to embed them both in the title and in the document. How would you make them?

1
  • Please edit the question to limit it to a specific problem with enough detail to identify an adequate answer.
    – Community Bot
    Commented Sep 28, 2022 at 15:00

6 Answers 6

22

Here is a possibility using tikz with the matrix library.

I defined three colors: great, good and bad, which you can adjust to your liking.

The wordle is a TikZ matrix with the nodes filled with bad by default, unless you include |[fill=<color>]| in the cell. To use in a title you must use ampersand replacement.

The node style is set globally using tikzset with the style wordlematrix. You can adjust the height, width, spacing and font there.

enter image description here

To save some typing, I made styles for fill=great and fill=good,

g/.style={fill=great}, h/.style={fill=good}

and added them to the tikzset. Here is the code:

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{matrix}
\tikzset{wordlematrix/.style={matrix of nodes, nodes={anchor=center, fill=bad, minimum height=1cm, minimum width=1cm}, column sep=2pt, row sep=2pt, color=white, font=\sffamily\Large\bfseries},
    g/.style={fill=great}, h/.style={fill=good},  n/.style={fill=none, color=black, draw=dark-border, thick,minimum size=1cm-\pgflinewidth}, e/.style={fill=none, color=black, draw=light-border, thick,minimum size=1cm-\pgflinewidth}}

\definecolor{great}{rgb}{0.416, 0.667, 0.392}
\definecolor{good}{rgb}{0.788, 0.706, 0.345}
\definecolor{bad}{rgb}{0.471, 0.486, 0.494}
\definecolor{light-border}{rgb}{0.827, 0.839, 0.855}
\definecolor{dark-border}{rgb}{0.529, 0.541, 0.549}
\definecolor{none}{rgb}{1,1,1}

\title{Here is a 
    \begin{tikzpicture}[baseline=-1.5mm]
    \matrix(titlewordle)[wordlematrix, ampersand replacement=\&]{ 
    W \& |[g]|O \& |[g]|R \& D \& |[h]|L \& E\\
    };
    \end{tikzpicture}
    in a title}
\author{Sandy G}

\begin{document}
\maketitle

Here is a wordle in the document:
\[
\begin{tikzpicture}
\matrix(example)[wordlematrix]{ 
G & |[g]|R & |[g]|A & I & L\\
T & |[g]|R & |[g]|A & |[h]|C & K\\
|[g]|C & |[g]|R & |[g]|A & M & P\\
|[g]|C & |[g]|R & |[g]|A & B & S\\
|[g]|C & |[g]|R & |[g]|A & |[g]|Z & Y\\
|[g]|C & |[g]|R & |[g]|A & |[g]|Z & |[g]|E\\
};
\end{tikzpicture}
\]
Here is a wordle to complete:
\[
\begin{tikzpicture}
\matrix(example)[wordlematrix]{ 
W & R & O & N & G\\
T & |[g]|R & |[g]|A & |[h]|C & K\\
|[n]|T&|[n]|R&|[n]|Y&|[n]|M&|[n]|E\\
|[e]|& |[e]| & |[e]|& |[e]| & |[e]|\\
|[e]|& |[e]| & |[e]|& |[e]| & |[e]|\\
};
\end{tikzpicture}
\]
I did it!

\end{document}
2
  • This works great for me! Thanks. I've made some changes to the colors and added some option, both for not-yet-checked words and for empty boxes Commented Sep 29, 2022 at 10:29
  • I've submitted an edit with the changes and new image Commented Sep 29, 2022 at 10:45
15

Welcome to tex.stackexchange!

I just finished a project using Tikz's chains library. So, like the man with a hammer that views the world as a nail, I suggest using the chains library for this:

\documentclass{article}

\usepackage{xcolor}
\usepackage{tikz}

\usetikzlibrary{positioning,chains}

%% |=====8><-----| %%

\newcounter{wrownum}

%% |=====8><-----| %%

\NewDocumentEnvironment{wordframe}{}{% six rows, six chains
    \setcounter{wrownum}{0}%
    \begin{tikzpicture}[
        start chain=1 going right,
        start chain=2 going right,
        start chain=3 going right,
        start chain=4 going right,
        start chain=5 going right,
        start chain=6 going right,
        node distance=1mm]  
}{%
    \end{tikzpicture}%
}

\tikzset{wbox/.style={%
        text=white,font=\sffamily\bfseries,minimum size=2em,
    }
}

%% color shorthand -- change at will
\colorlet{gr}{gray}
\colorlet{gn}{green!80!blue}
\colorlet{yl}{yellow!80!orange}

\NewDocumentCommand{\wrow}{m}{%
    \stepcounter{wrownum}
    \foreach \L/\C in {#1}{% TikZ foreach: Letter/color
        \ifnum\thewrownum=1
            \node[wbox,fill=\C,on chain=\thewrownum]{\L};
        \else
            \node[wbox,fill=\C,
            below=1mm of \the\numexpr\thewrownum-1\relax-1,
            on chain=\thewrownum] {\L};
        \fi
    }%
}

\parindent0pt

\begin{document}

\noindent This is a frame \begin{wordframe}\wrow{W/gr,O/gr,R/gn,D/gr,L/yl,E/gn}\end{wordframe} in a sentence.

\bigskip

\begin{wordframe}
    \wrow{G/gr,R/gn,A/gn,I/gr,L/gr}
    \wrow{T/gr,R/gn,A/gn,C/yl,K/gr}
    \wrow{C/gn,R/gn,A/gn,M/gr,P/gr}
    \wrow{C/gn,R/gn,A/gn,B/gr,S/gr}
    \wrow{C/gn,R/gn,A/gn,Z/gn,Y/gr}
    \wrow{C/gn,R/gn,A/gn,Z/gn,E/gn}
\end{wordframe}

\end{document}

enter image description here

Update

I've made both the entry of data a bit easier (I hate to type). Also there are a few additional options (via `keyval.sty) which are demonstrated in the examples.

\documentclass{article}

\usepackage{xcolor,xparse,tikz,keyval}

\usetikzlibrary{positioning,chains,backgrounds}

%% |=====8><-----| %%

\newcounter{wrownum}
\newlength{\wboxsep}
\newlength{\wboxsize}
\newlength{\wboxrcwd}
\newif\ifmkwframe
\newif\ifwdrawbox

%% |=====8><-----| %% keyval defaults -- change to suit %% |=====8><-----| %%

\setlength{\wboxsep}{1mm}%% <<<=>>> horizontal/vertical space between boxes
\setlength{\wboxsize}{2em}% default size of box; sets TikZ `minimum size'
\setlength{\wboxrcwd}{0pt}% default rounded cornet size; set to 0pt for no rounded corners
\def\wboxfontsize{\normalsize}% uses standard LaTeX sizes, e.g. \tiny, \small, \normalsize, \large...
\colorlet{wframefill}{white}


\makeatletter
\define@key{wrdlbox}{wboxsep}{\setlength{\wboxsep}{#1}}
\define@key{wrdlbox}{wboxrcwd}{\setlength{\wboxrcwd}{#1}}
\define@key{wrdlbox}{wboxsize}{\setlength{\wboxsize}{#1}}
\define@key{wrdlbox}{wboxfontsize}{\def\wboxfontsize{#1}}
\define@key{wrdlbox}{mkwframe}[true]{\csname mkwframe#1\endcsname}
\define@key{wrdlbox}{wdrawbox}[true]{\csname wdrawbox#1\endcsname}
\define@key{wrdlbox}{wframefill}{\colorlet{wframefill}{#1}}
\makeatother

%% |=====8><-----| %%
%% keyval ootions: wboxsep, wboxrcwd, wboxsize, wboxfontsize, mkwframe, wframefill, wdrawbox
\NewDocumentEnvironment{wordframe}{O{}}{% six rows, six chains; more rows? just add more chains
    \setkeys{wrdlbox}{#1}%
    \setcounter{wrownum}{0}%
    \begin{tikzpicture}[
        start chain=1 going right,
        start chain=2 going right,
        start chain=3 going right,
        start chain=4 going right,
        start chain=5 going right,
        start chain=6 going right,
        node distance=\wboxsep,outer sep=0pt]   
}{%
        \ifmkwframe
            \begin{scope}[on background layer]
                \draw[fill=wframefill,thick]
                ([xshift=-\wboxsep,yshift=-\wboxsep]current bounding box.south west)
                rectangle
                ([xshift=\wboxsep,yshift=\wboxsep]current bounding box.north east);
            \end{scope}
        \fi
    \end{tikzpicture}%
}

\tikzset{wbox/.style={%
        text=white,
        font=\sffamily\bfseries\wboxfontsize,
        minimum size=\wboxsize,
        fill=\C,
        rounded corners=\wboxrcwd,
        \ifwdrawbox draw\fi
    }%
}

%% color shorthand -- alter, change or enlarge at will
\colorlet{gr}{gray}
\colorlet{gn}{green!80!blue}
\colorlet{yl}{yellow!80!orange}

\NewDocumentCommand{\wrow}{u{>}}{% comma-separated values: Letter/color; 'u' requires xparse.sty
    \stepcounter{wrownum}
    \foreach \L/\C in {#1}{% TikZ foreach: Letter/color
        \ifnum\thewrownum=1
            \node[wbox,on chain=\thewrownum]{\L};
        \else
            \node[wbox,below=\wboxsep of \the\numexpr\thewrownum-1\relax-1,on chain=\thewrownum] {\L};
        \fi
    }%
}

\catcode`<=\active
\let<=\wrow

\parindent0pt

\begin{document}

\begin{wordframe}
    <G/gr,R/gn,A/gn,I/gr,L/gr>
    <T/gr,R/gn,A/gn,C/yl,K/gr>
    <C/gn,R/gn,A/gn,M/gr,P/gr>
    <C/gn,R/gn,A/gn,B/gr,S/gr>
    <C/gn,R/gn,A/gn,Z/gn,Y/gr>
    <C/gn,R/gn,A/gn,Z/gn,E/gn>
\end{wordframe}

\bigskip

\noindent This is a frame \begin{wordframe}<W/gr,O/gr,R/gn,D/gr,L/yl,E/gn>\end{wordframe} in a sentence.

\bigskip

\begin{wordframe}[wframefill=cyan!10,
    wboxsize=3em,wboxfontsize=\tiny,
    wboxsep=2mm,wboxrcwd=3pt,mkwframe]
    <G/gr,R/gn,A/gn,I/gr,L/gr>
    <T/gr,R/gn,A/gn,C/yl,K/gr>
    <C/gn,R/gn,A/gn,M/gr,P/gr>
    <C/gn,R/gn,A/gn,B/gr,S/gr>
    <C/gn,R/gn,A/gn,Z/gn,Y/gr>
    <C/gn,R/gn,A/gn,Z/gn,E/gn>
\end{wordframe}

\bigskip

\begin{wordframe}[wboxfontsize=\large,wboxsep=0pt,mkwframe,wdrawbox]
    <G/gr,R/gn,A/gn,I/gr,L/gr>
    <T/gr,R/gn,A/gn,C/yl,K/gr>
    <C/gn,R/gn,A/gn,M/gr,P/gr>
    <C/gn,R/gn,A/gn,B/gr,S/gr>
    <C/gn,R/gn,A/gn,Z/gn,Y/gr>
    <C/gn,R/gn,A/gn,Z/gn,E/gn>
\end{wordframe}

\end{document}

enter image description here

Update 2

At the risk of being tedious, but in the interest of simplest input, I offer the following. Output is exactly the same as previous. Added is filling the letter box with red if the tag is wrong.

\documentclass{article}

\usepackage{xcolor,xparse,tikz,keyval}

\usetikzlibrary{positioning,chains,backgrounds}

%% |=====8><-----| %%

\newcounter{wrownum}
\newlength{\wboxsep}
\newlength{\wboxsize}
\newlength{\wboxrcwd}
\newif\ifmkwframe
\newif\ifwdrawbox

%% |=====8><-----| %% keyval defaults -- change to suit %% |=====8><-----| %%

\setlength{\wboxsep}{1mm}%% <<<=>>> horizontal/vertical space between boxes
\setlength{\wboxsize}{2em}% default size of box; sets TikZ `minimum size'
\setlength{\wboxrcwd}{0pt}% default rounded cornet size; set to 0pt for no rounded corners
\def\wboxfontsize{\normalsize}% uses standard LaTeX sizes, e.g. \tiny, \small, \normalsize, \large...
\colorlet{wframefill}{white}

\makeatletter
\define@key{wrdlbox}{wboxsep}{\setlength{\wboxsep}{#1}}
\define@key{wrdlbox}{wboxrcwd}{\setlength{\wboxrcwd}{#1}}
\define@key{wrdlbox}{wboxsize}{\setlength{\wboxsize}{#1}}
\define@key{wrdlbox}{wboxfontsize}{\def\wboxfontsize{#1}}
\define@key{wrdlbox}{mkwframe}[true]{\csname mkwframe#1\endcsname}
\define@key{wrdlbox}{wdrawbox}[true]{\csname wdrawbox#1\endcsname}
\define@key{wrdlbox}{wframefill}{\colorlet{wframefill}{#1}}
\makeatother

%% |=====8><-----| %%
%% keyval ootions: wboxsep, wboxrcwd, wboxsize, wboxfontsize, mkwframe, wframefill, wdrawbox
\NewDocumentEnvironment{wordframe}{O{}}{% six rows, six chains; more rows? just add more chains
    \setkeys{wrdlbox}{#1}%
    \setcounter{wrownum}{0}%
    \begin{tikzpicture}[%
        start chain=1 going right,
        start chain=2 going right,
        start chain=3 going right,
        start chain=4 going right,
        start chain=5 going right,
        start chain=6 going right,
        node distance=\wboxsep,outer sep=0pt]   
}{%
        \ifmkwframe
            \begin{scope}[on background layer]
                \draw[fill=wframefill,thick]
                    ([xshift=-\wboxsep,yshift=-\wboxsep]current bounding box.south west)
                    rectangle
                    ([xshift=\wboxsep,yshift=\wboxsep]current bounding box.north east);
            \end{scope}
        \fi
    \end{tikzpicture}%
}

\tikzset{wbox/.style={%
        text=white,
        font=\sffamily\bfseries\wboxfontsize,
        minimum size=\wboxsize,
        fill=\Clr,
        rounded corners=\wboxrcwd,
        \ifwdrawbox draw\fi
    }%
}

\def\dissect#1#2{% change colors to suit
    \def\Ltr{#1}%
    \if#2x
        \def\Clr{gray}% 'x' = gray = wrong letter
    \else
        \if#2!
            \def\Clr{green!80!blue}% '!' = green = right letter in right place
        \else
            \if#2?
                \def\Clr{yellow!80!orange}% '?' = yellow, right letter in wrong place
            \else
                \def\Clr{red}% incorrect letter tag, i.e., not "x" or "!" or "?"
            \fi
        \fi
    \fi 
}

\NewDocumentCommand{\wrow}{u{>}}{% comma-separated values: Letter/color; 'u' requires xparse.sty
    \stepcounter{wrownum}
    \foreach \X in {#1}{% TikZ foreach: Letter/color
        \expandafter\dissect\X
        \ifnum\thewrownum=1
            \node[wbox,on chain=\thewrownum]{\Ltr};
        \else
            \node[wbox,below=\wboxsep of \the\numexpr\thewrownum-1\relax-1,
                on chain=\thewrownum] {\Ltr};
        \fi
    }%
}

\catcode`<=\active
\let<=\wrow

\parindent0pt

\begin{document}

\begin{wordframe}
    <Gx,R!,A!,Ix,Lx>
    <Tx,R!,A!,C?,Kx>
    <C!,R!,A!,Mx,Px>
    <C!,R!,A!,Bx,Sx>
    <C!,R!,A!,Z!,Yx>
    <C!,R!,A!,Z!,E!>
\end{wordframe}

\bigskip

\noindent This is a frame \begin{wordframe}<Wx,Ox,R!,Dx,L?,E!>\end{wordframe} in a sentence.

\bigskip

\begin{wordframe}[wframefill=cyan!10,
    wboxsize=3em,wboxfontsize=\tiny,
    wboxsep=2mm,wboxrcwd=3pt,mkwframe]
    <Gx,R!,A!,Ix,Lx>
    <Tx,R!,A!,C?,Kx>
    <C!,R!,A!,Mx,Px>
    <C!,R!,A!,Bx,Sx>
    <C!,R!,A!,Z!,Yx>
    <C!,R!,A!,Z!,E!>
\end{wordframe}

\bigskip

\begin{wordframe}[wboxfontsize=\large,wboxsep=0pt,mkwframe,wdrawbox]
    <Gx,R!,A!,Ix,Lx>
    <Tx,R!,A!,C?,Kx>
    <C!,R!,A!,Mx,Px>
    <C!,R!,A!,Bx,Sx>
    <C!,R!,A!,Z!,Yx>
    <C!,R!,A!,Z!,E!>
\end{wordframe}

\end{document}
14

Quite similar to the other answer, but your question reminded me of a twitt of mine: https://twitter.com/CarLaTeXSE/status/1484979275598123015

\documentclass{standalone} 
\usepackage{xcolor}
\usepackage{tikz}
\usetikzlibrary{matrix}
\tikzset{
    mymatrix/.style={
        matrix of nodes,
        row sep=2pt,
        column sep=2pt,
        nodes={
            text width=10pt,
            text centered,
            text height=8pt,
            text depth=2pt
            }
        },
    greened/.style={fill=green},
    redded/.style={fill=red},
    yellowed/.style={fill=yellow},
    grayed/.style={fill=lightgray},
    }
\begin{document} 

\begin{tikzpicture}
\matrix[mymatrix] {
    |[grayed]|D&|[grayed]|U&|[grayed]|C&|[grayed]|K&|[grayed]|Y\\
    |[greened]|L&|[grayed]|I&|[grayed]|O&|[grayed]|N&|[grayed]|S\\
    |[greened]|L&|[yellowed]|E&|[yellowed]|A&|[grayed]|V&|[grayed]|E\\
    |[greened]|L&|[greened]|A&|[greened]|T&|[grayed]|I&|[grayed]|N\\
    |[greened]|L&|[greened]|a&|[greened]|T&|[greened]|e&|[greened]|X\\
    };
\end{tikzpicture}
\end{document}

enter image description here

3
  • I think the spacing is wrong in your last line ;-)
    – Sandy G
    Commented Sep 28, 2022 at 17:00
  • Just a joke—\LaTeX is typeset with negative space between its characters.
    – Sandy G
    Commented Sep 28, 2022 at 17:23
  • @SandyG Ah, OK, I didn't understand the joke :D
    – CarLaTeX
    Commented Sep 28, 2022 at 18:56
11
  1. Two modes:

    • mode = manual: the type (correct/wrong/almost/no eval/no letter) must be specified directly before the letter.

    • mode = pre: the types must be speciefied beforehand (with key pre) and then the words can be typed without any specifiers.

      • <text> can be used to escape the parser and all text will be treated as one letter.
      • For a position that didn't get predefined with pre the key letter/unknown = <L> will be executed (defaults to letter/no letter).
  2. Four styles:

    • style = plain: colored letters and typewriter font
    • style = plain-nott: colored letters of normal font but with fixed width
    • style = boxes: colored boxes, white letters
    • style = pgf: colored boxes, white letters but with PGF.

    pgf would look the same as boxes if it weren't for \pgfsetcornersarced ( rounded corners in TikZ) but allows for more custom boxes.

  3. Parsing a game:

    • Correct (green) letter: +
    • Wrong (gray) letter: -
    • “Almost” (yellow) letter: ~
    • Input letter (not yet evaluated): .
    • “No” letter (empty input box): ?
    • New line: ;
    • Spaces are ignored.

    More parsing characters can be defined with new parse = {<c>}{<key>} where <c> is the character and letter/<key> = <L> is the key that will called (see next).

  4. Every letter will be forwarded to a key according to its type:

    • every correct letter <L>: letter/correct = <L>,
    • every wrong letter <L>: letter/wrong = <L>,
    • every almost letter <L>: letter/almost = <L>,
    • every input letter <L>: letter/no eval = <L> and for
    • every no letter <L>: letter/no letter = <L>
  5. For every new line the key parser/new line will be executed when it is followed by more letters. (That means that the last line doesn't need to end with ; but it doesn't hurt, either.)

  6. Right before and right after the parser.

    • The value of at start will be executed right before the parsing starts.
    • The value of at end will be executed right after the parsing ends.
  7. \wordgame .W.O.R.D.L.E \endwordgame can't be used because the parser looks for \end. Technically, any \end{<stuff>} would end the wordgame environment because the parser replacoed \end{<stuff>} with \end{wordgame} but don't.

  8. [<options>] can be used inside the environment to set options (via \wordgameset).

In the code below all styles are used in the \title (but with only one line).

In the document itself, the three styles plain, boxes and pgf are used, once in manual mode, once in pre mode.

With this update, I've moved the previous version of the code to a package file wordgame.sty (the name Wordle is probably copyrighted somewhere) and made it available in a GitHub repo.

Code

\documentclass{article}
% https://github.com/Qrrbrbirlbel/latex-wordgame/blob/main/wordgame.sty
\usepackage{wordgame}

\usepackage{pgffor}
\wordgameset{
  ./.style={#1},
  mp/.style={
    at start/.prefix code=\minipage[t]{#1},
    at end/.append code=\endminipage}}
\newcommand*\srb[2]{\smash{\raisebox{#1}{#2}}}
\title{%
  \miniwordgame[style=plain]{-P~L+A~I-N}
  \miniwordgame[style=plain-nott]{-P~L+A~I-N}\\
  \miniwordgame[style=boxes]{-B~O+X~E-S}
  \miniwordgame[style=pgf]{-P~G+F}%
}
\author{Qrrbrbirlbel}
\begin{document}
\maketitle
\foreach \style/\mp in {plain/mp=2.6em, boxes/mp=8.3em, pgf/}{%
  \begin{center}
  \wordgameset{every wordgame/.append style={style=\style}}
  \begin{wordgame}[./.expand once=\mp]
  -W -R -O -N -G ;
  -T +R +A ~C -K ;
  .T .R .Y .M .E ;
  ?? ?? ?? ?? ?? ;
  ?? ?? ?? ?? ?? ;
  ?W ?{\srb{.5ex}{o}}
        ?R ?{\srb{-.5ex}{d}}
              ?L ;
  \end{wordgame}
  \quad
  \begin{wordgame}[
    pre=-----; -++~-; .....,
    ./.expand once=\mp]
  WRONG;
  TRACK;
  TRYME;
  ?????;
  ?????;
  W<\srb{.5ex}{o}>R<\srb{-.5ex}{d}>L;
  \end{wordgame}
  \end{center}
}
\end{document}

Output

enter image description here

3
  • +1 Nice! But surely a wrong letter should be -<L> ... and, although this is less clear cut, ~<L> should be an almost letter. Commented Sep 29, 2022 at 12:35
  • 1
    Well, the next step would be that it evaluates the letters on its own. Commented Sep 29, 2022 at 15:56
  • ...after your comment I could not help myself 🤔 Commented Sep 30, 2022 at 3:44
10

Here's a solution inspired by @Qrrbrbirlbel's reply to my comment on his post. It defines an environment, wordle, that takes one parameter, which is the correct answer to the wordle puzzle. The proposed solution to the puzzle is then given as words in the body of the environment. For example, for the puzzle in the question you would write:

\begin{wordle}{CRAZE}
  GRAIL TRACK CRAMP CRABS CRAZY CRAZE
\end{wordle}

to produce:

enter image description here

As in many of the solutions above, TikZ is used to print the letters but the bulk of the code is written in LaTeX3. There are comments in the code that briefly describe how it works.

EDIT The initial version of this code did not cope correctly with the cases where the words contained repeated letters. The updated version below does this correctly. To do this it is necessary to "process" each word twice, first counting the number of correctly placed letters after which it is possible to correctly "mark" the incorrectly placed repeated letters. This makes the code slightly more complicated, but not horrendously so -- although, I admit, this is subjective.

\documentclass{article}

\usepackage[svgnames]{xcolor}
\usepackage{tikz}
\tikzset{
  boxed letter/.style = {
    inner sep=1mm,
    rectangle,
    minimum width=4ex,
    minimum height=2ex,
    fill=#1,
    text=white,
    draw=white,
    thick
  }
}
\usepackage{expl3}
\ExplSyntaxOn

% print a letter in a box
\cs_new:Npn \l__boxed_letter:nn #1#2
{
  \tikz \node[boxed~letter=#1]{#2};
}

\seq_new:N \l_wordle_seq   % the answer
\prop_new:N \l_wordle_prop % count letters in wordle
\seq_new:N \l_words_seq    % list of all words
\prop_new:N \l_word_prop   % count letters in word
\int_new:N \l_letter_int   % index of current letter in word

% a conditional for nonnegative prop counter in \l_word_prop
\prg_new_protected_conditional:Npnn \if_wordle_letter_nonnegative:n #1 {TF}
{
    \prop_if_in:NnTF \l_word_prop {#1}
      { % letter in in prop
        \prop_get:NnN \l_word_prop {#1} \l_tmpa_tl
        \int_compare:nNnTF {\l_tmpa_tl} < {0}
          {\prg_return_false:} {\prg_return_true:}
      }
      {\prg_return_false:}
}

% a conditional for comparing letters
\prg_new_protected_conditional:Npnn \if_wordle_letters_agree:n #1 {T, TF}
{
    \str_set:Nx \l_tmpa_str {\seq_item:Nn \l_wordle_seq {\l_letter_int}}
    \str_if_eq:nVTF {#1} \l_tmpa_str {\prg_return_true:} {\prg_return_false:}
}

% add #3 to <prop=#1>.#2
\cs_new_protected:Npn \wordle__add_to_prop_counter:Nnn #1#2#3
{
    \prop_put_if_new:Nnn #1 {#2} {0}
    \prop_pop:NnN        #1 {#2} \l_tmp_a
    \prop_put:Nnx        #1 {#2} {\int_eval:n {#3+\l_tmp_a}}
}

% make \l_wordle_prop<x> = #x's in wordle_seq
\cs_new_protected:Npn \count_letters_in_wordle:n #1
{
    \wordle__add_to_prop_counter:Nnn \l_wordle_prop {#1} {1}
}

% first run: subtract correct matches from letter counts
\cs_new:Npn \count_letters_in_word:n #1
{
  \int_incr:N \l_letter_int
  \if_wordle_letters_agree:nT {#1}
     { \wordle__add_to_prop_counter:Nnn \l_word_prop {#1} {-1} }
}

% on the second run we print a coloured wordle word
\cs_new:Npn \write_letters_in_word:n #1
{
  \int_incr:N \l_letter_int
  \if_wordle_letters_agree:nTF {#1}
      { \l__boxed_letter:nn {ForestGreen}{#1} }
      {
         % subtract 1 from the prop counter
         \wordle__add_to_prop_counter:Nnn \l_word_prop {#1} {-1}
         % if the counter is non-negative this is a pseudo match
         \if_wordle_letter_nonnegative:nTF {#1}
            { \l__boxed_letter:nn {Goldenrod}{#1} }
            { \l__boxed_letter:nn {SlateGray}{#1} }
      }
}

\NewDocumentEnvironment{wordle}{ mb }
{
  \parindent=0pt
  % split the answer into letters
  \seq_set_split:Nnn \l_wordle_seq {} {#1}

  % we need to count the number of times each letter appears in \l_wordle_seq
  \prop_clear:N \l_wordle_prop
  \tl_map_function:nN {#1} \count_letters_in_wordle:n


  % split the solution into words
  \regex_split:nnN {\s} {#2} \l_words_seq


  % process the words
  \seq_map_inline:Nn \l_words_seq
  {
     \int_zero:N \l_letter_int
     \prop_set_eq:NN \l_word_prop \l_wordle_prop
     \tl_map_function:nN {##1} \count_letters_in_word:n
     \int_zero:N \l_letter_int
     \tl_map_function:nN {##1}  \write_letters_in_word:n
     \newline
  }

}{}

\ExplSyntaxOff

\begin{document}

\begin{wordle}{CRAZE}
  GRAIL TRACK CRAMP
  CRABS CRAZY CRAZE
\end{wordle}

\begin{wordle}{LILLY}
  TRACE LOUSY DIMLY HILLY FILLY LILLY
\end{wordle}

\begin{wordle}{LADLE}
   FLAIL LAPEL LADLE
\end{wordle}

\end{document}

In addition to the example above, the code also produces the two puzzles:

enter image description here

2
  • 3
    Wow. Very impressive.
    – sgmoye
    Commented Sep 30, 2022 at 9:15
  • 1
    This is crazy, congrats Commented Sep 30, 2022 at 9:32
2

Meanwhile there's the wordle package available, based on TikZ, providing some style options:

result

\documentclass{article}
\usepackage{wordle}

\begin{document}
 \begin{WordleGrid}{CRAZE}
    GRAIL
    TRACK
    CRAMP
    CRABS
    CRAZU
    CRAZE
 \end{WordleGrid}
\end{document}

P.S.: Seems to work with German language, too, unless you put an Umlaut (ÄÖÜ) ... German

1
  • 1
    Thanks for commenting @314159265358979323 . I recognized the similarities but couldn’t understand it.
    – MS-SPO
    Commented Aug 6 at 6:41

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .