FINAL

Ampscript
%%[
/* Calculate how much time is left to show this in the interface */
set @now = Now()
set @tomorrow = DateAdd(FormatDate(@now, 'yyyy-MM-dd'), 1, 'D')
set @timeLeft = DateDiff(@now, @tomorrow, 'MI')
set @timeLeftMinutes = Mod(@timeLeft, 60)
set @timeLeftHours = Divide(Subtract(@timeLeft, @timeLeftMinutes), 60)

/* Build the text string with hours AND minutes (IF they are bigger than 0) */
set @timeLeftString = 'The word resets in '

/* Hours */
IF
    @timeLeftHours >= 2
        THEN
            set @timeLeftString = Concat(@timeLeftString, @timeLeftHours, ' hours ')
ELSEIF
    @timeLeftHours == 1
        THEN
            set @timeLeftString = Concat(@timeLeftString, @timeLeftHours, ' hour ')
ENDIF

/* IF both numbers of hours AND minuter are mentioned place an 'AND' string between them */
IF 
    @timeLeftHours >= 1
    AND
    @timeLeftMinutes >= 1
        THEN
            set @timeLeftString = Concat(@timeLeftString, ' AND ')
ENDIF

/* Minutes */
IF
    @timeLeftMinutes >= 2
        THEN
            set @timeLeftString = Concat(@timeLeftString, @timeLeftMinutes, ' minutes ')
ELSEIF
    @timeLeftMinutes == 1
        THEN
            set @timeLeftString = Concat(@timeLeftString, @timeLeftMinutes, ' minute ')
ELSEIF
    @timeLeftHours == 0
    AND
    @timeLeftMinutes == 0
        THEN
            set @timeLeftString = Concat(@timeLeftString, 'less than a minute ')
ENDIF

/* Proper Wordle Stuff */

/* Select the word for the day in the encoded form */
set @words = 'U1RFQU0=|T1BFUkE=|Q0xPQUs=|Q0xFQVI=|TklHSFQ=|R0hPU1Q=|U1RBRkY=|U1RPVVQ=|UElMT1Q=|S0VCQUI=|QUJZU1M=|Uk9VR0U=|U0hBUkU=|V09STEQ=|UVVFUlk=|VUxDRVI=|U0lFR0U=|QkxPS0U=|RlJBTUU=|Q0hFQVQ=|RVBPQ0g=|U1BJQ1k=|RUxERVI=|RkVJR04=|Q1JBVEU=|VElNSUQ=|U1BJTEw=|QlJFQUs=|UEFVU0U=|R1JJTUU=|Q0hBTVA='

set @rowset = BuildRowsetFromString(@words, '|')
set @day = DatePart(@now, 'D')
set @row  = Row(@rowset, @day)
set @theWordEncoded = Field(@row, 1)

set @theWord = Base64Decode(@theWordEncoded, 'UTF-8')

/* Get the submitted values AND calculate how many attempts are left*/
set @previousWord = RequestParameter('previousWord')
set @lastGuess = Uppercase(RequestParameter('lastGuess'))
set @guesses = UpperCase(RequestParameter('guesses'))

/* Debug value capture before processing */
set @debug1 = Concat('{',
                        '"@case": "', @case, '",',
                        '"@feedback": "', @feedback, '",',
                        '"@previousWord": "', @previousWord, '",',
                        '"@theWordEncoded": "', @theWordEncoded, '",',  
                        '"@lastGuess": "', @lastGuess, '",',
                        '"@guesses": "', @guesses, '",',
                        '"@alphabet": "', @alphabet, '",',
                        '"@evaluation": "', @evaluation, '",',
                        '"@evaluation2": null,',
                        '"@evaluation3": ""',
                    '}')

/* Check IF the last word has expired */
IF 
    Empty(@previousWord) == false
    AND
    @theWord != Base64Decode(@previousWord)
    THEN 
        set @feedback = 'The daily word has reset'
        set @guesses = ''
        set @lastGuess = ''
ENDIF

/* Calculation of left attempts */
set @guessLimit = 6
set @guessRowset = BuildRowsetFromString(@guesses, '|')
set @guessesMade = RowCount(@guessRowset)
set @guessesLeft = Subtract(@guessLimit, @guessesMade)

set @feedback = ''

/* Validation of incoming words*/
IF 
    IndexOf(@guesses, @lastGuess) < 1
    AND
    Empty(@lastGuess) == false
        THEN
            set @lookup = RowCount(LookupRows('Wordle - Allowed Word List', 'Word', @lastGuess))

            IF 
                @lookup == 1
                AND
                Empty(@guesses) == true
                THEN
                    set @guesses = @lastGuess
            ELSEIF 
                @lookup == 1
                AND
                Empty(@guesses) == false
                THEN
                    set @guesses = Concat(@guesses, '|', @lastGuess)
            ELSE
                    set @feedback = Concat("'", @lastGuess, "' is not an allowed word")
            ENDIF
ELSEIF
    IndexOf(@guesses, @lastGuess) > 0
        THEN
            set @feedback = 'Repeat guesses are not allowed'
ENDIF

/* Calculation of left attempts */
set @guessLimit = 6
set @guessRowset = BuildRowsetFromString(@guesses, '|')
set @guessesMade = RowCount(@guessRowset)
set @guessesLeft = Subtract(@guessLimit, @guessesMade)

/* Check IF the player has won */ 
IF 
    @lastGuess == @theWord
    THEN
        set @input = ''
        set @feedback = '🎉 VICTORY ACHIEVED 🎉'
ELSEIF
    @guessesLeft > 0
    THEN
        set @input = '<input name="lastGuess" type="text" class="mainInput" pattern="[A-Za-z]{5}" title="This needs to be a 5-letter word" id="main"><br>'
        set @guessesLeft = Subtract(@guessesLeft, 1)
ENDIF

/* This will determine the colors assigned to each letter for the bottom keyboard output */ 
set @alphabet   = 'QWERTYUIOPASDFGHJKLZXCVBNM'
set @evaluation = '--------------------------'

set @guessesHtml = ''
set @cellTemplate = '<div class="cell {class}">{letter}</div>'

/* Iterate through each letter of the @guesses string */
FOR @i = 1 TO Length(@guesses) DO
    set @letter = Substring(@guesses, @i, 1)
    IF 
        @letter == '|'
        THEN
            set @guessesHtml = Concat(@guessesHtml, "<br>")
    ELSE

        /* Find the correct class to assign */
        IF
            Substring(@theWord, Mod(@i, 6), 1) == @letter
            THEN
                set @class = 'c' /* Correct letter in the right spot */
        ELSEIF
            IndexOf(@theWord, @letter) > 0
            THEN
                set @class = 'm' /* Misplaced letter */
        ELSE
                set @class = 'w' /* Wrong letter */
        ENDIF
        
        /* Modify the @cellTemplate */
        set @cell = Replace(@cellTemplate, "{letter}", @letter)
        set @cell = Replace(@cell, "{class}", @class)
        set @guessesHtml = Concat(@guessesHtml, @cell)

        /* Only change the color IF the letter was not in the correct position already */
        set @index = IndexOf(@alphabet, @letter)
        
        IF Substring(@evaluation, @index, 1) != 'c'
            THEN
                set @evaluation = Concat(
                    Substring(@evaluation, 1, Subtract(@index, 1)),
                    @class,
                    Substring(@evaluation, Add(1, @index))
                )
        ENDIF
    ENDIF
NEXT @i

/* Build the rows with empty cells to visualize remaining guesses */
FOR @i = 1 TO @guessesLeft DO
    set @cell = Replace(@cellTemplate, "{letter}", ' ')
    set @cell = Replace(@cell, "{class}", '')
    set @remainingHtml = Concat(@remainingHtml, @cell, @cell, @cell, @cell, @cell, "<br>")
NEXT @i

/* Bottom keyboard output */ 
set @letters = ''
set @letterTemplate = '<div class="letter {class}" name="letter">{letter}</div>'

FOR @i = 1 TO Length(@alphabet) DO
    set @instance = @letterTemplate
    set @instance = Replace(@instance, '{class}', Substring(@evaluation, @i, 1))
    set @instance = Replace(@instance, '{letter}', Substring(@alphabet, @i, 1))
    set @instance = Replace(@instance, ' -', '')
    set @letters = Concat(@letters, @instance)

    IF 
        @i == 10
        or
        @i == 19
        THEN
             set @letters = Concat(@letters, "<br>")
    ENDIF
NEXT @i

/* Debugging */
set @debug2 = Concat('{',
                        '"@case": "', @case, '",',
                        '"@feedback": "', @feedback, '",',
                        '"@previousWord": "', @previousWord, '",',
                        '"@theWordEncoded": "', @theWordEncoded, '",',
                        '"@lastGuess": "', @lastGuess, '",',
                        '"@guesses": "', @guesses, '",',
                        '"@alphabet": "', @alphabet, '",',
                        '"@evaluation": "', @evaluation, '",',
                    '}')
]%%
HTML + JavaScript
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>Ampscript Wordle by Rafal Wolsztyniak</title>
    <meta name="description" content="">
    <meta name="viewport" content="width=device-width, initial-scale=0.86, user-scalable=no, minimum-scale=0.86">
    <link rel="stylesheet" href="">
    <meta name="robots" content="noindex" />
    <meta name="AdsBot-Google" content="noindex" />
    <meta name="googlebot" content="noindex">
    <meta name="googlebot-news" content="nosnippet">
    <link rel="icon" href="https://sfmc.quest/img/sfmc.quest.favicon.ico" crossorigin>
    <link href="https://sfmc.quest/wordle/wordle-style.css" rel="stylesheet" rel="preconnect" crossorigin>

    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Roboto&family=Roboto+Mono&family=Roboto+Slab&display=swap" rel="stylesheet"> 

    <script>
        console.table(%%=v(@debug1)=%%)
        console.table(%%=v(@debug2)=%%)
    </script>
</head>
<body>

<div style="text-align: center; width: 100%">
    <div>
        <header style="text-align: left">
        
            <img class="logo" src="https://image.s7.sfmc-content.com/lib/fe91137277600c7976/m/1/54db8ea4-2c41-4822-96bc-8189af38f833.png">
            <span class="title">Ampscript Wordle</span>
            <br>
            <ul class="info">
                <li>Developed by Rafał Wolsztyniak</li>
                <li>This is a tribute to <a href="https://www.nytimes.com/games/wordle/index.html" target="_blank">Wordle</a> by Josh Wardle</li>
                <li><a href="https://sfmc.quest">Click here to see how this game was made</a></li>
                <li>%%=v(@timeLeftString)=%%</li>
            </ul>    
        </header>
    </div>
    <!-- Standard Game -->

    <form method="post" action="#">
        <div class="board">
            <input name="previousWord" type="hidden" value="%%=v(@theWordEncoded)=%%">
            <input name="guesses" type="hidden" value="%%=v(@guesses)=%%">
            
            %%=v(@guessesHtml)=%% <br>
            %%=v(@input)=%% 
            %%=v(@remainingHtml)=%% <br>
        </div>
        <div class="feedback">
            <b>%%=v(@feedback)=%%</b>
        </div>
        <br>
        %%=v(@letters)=%%
        <br>
        <div>
            <input type="button" onclick="backspace()" value="←" class="letter control">
            <input type="submit" value="Enter" class="letter control" style="margin-top: 5px">
        </div>
    </form>

    <div class="hiddenInput">
        <!-- Board Reset -->
        <form method="post" action="" style="display:inline-block">
            <input name="previousWord" type="hidden" value="">
            <input name="guesses" type="hidden" value="">
            <input type="submit" value="Reset" class="letter control">
        </form>
    </div>
    <div class="info">
        How to play:
        <ul>
        <li>Each day a new word is selected for you to guess</li>
        <li>You have 6 attempts to find it</li>
        <li>After each attempt, the cells with letters will be styled to give you feedback IF they are used in the word </li>
        <li>It's possible for a letter to appear multiple times</li>
        </ul>
        Example:
        <ul>
        <li>The daily word is             
            <span class="mini">Q</span>
            <span class="mini">U</span>
            <span class="mini">E</span>
            <span class="mini">S</span>
            <span class="mini">T</span>
        </li>
        <li>You guess the word 
            <span class="mini">S</span>
            <span class="mini">W</span>
            <span class="mini">I</span>
            <span class="mini">F</span>
            <span class="mini">T</span>
            which will be styled this way:
            <span class="mini m">S</span>
            <span class="mini w">W</span>
            <span class="mini w">I</span>
            <span class="mini w">F</span>
            <span class="mini c">T</span>
        </li>
        <li>
            This gives you the following information:
            <ul>
            <li>
                <span class="mini c">T</span> is a letter in the correct spot of the word
            </li>
            <li>
                <span class="mini m">S</span> appears in the word at least once,<br>but is not in the right position
            </li>
            <li>
                <span class="mini w">W</span>, <span class="mini w">I</span> AND <span class="mini w">F</span> don't appear in the word
            </li>
            </ul>
        </li>
        
    </div>
<script>

inputNode = document.getElementById("main");

document.querySelectorAll('.letter').forEach(item => {
  item.addEventListener('click', event => {
      console.log(typeof item);
    IF(inputNode.value.length < 5){
        inputNode.value += event.target.innerText;
    }
  })
})

function backspace(){
    inputNode.value = inputNode.value.substr(0, inputNode.value.length-1);
}

</script>
</body>
</html>

Thank you for reading my thesis 😉