Video Tutorial | Word Game With AI Using Grok
Now that we have the basics of prompting, let’s move on to something a bit more interesting.
Word games are very popular amongst audiences aged 18 - 34. You, I, and every other person would have played ‘Scramble Words’. Today we will create an online version of the same using Grok AI.
Below, I have my idea for how the online version of the game should look. We will look at the idea, and then we will break it into steps for ChatGPT to perform.
The Idea
Imagine that you are given 7 letters at random from the English alphabet. There are empty spaces in front of you. As you are imagining words, you are typing those letters on the keyboard, or if you are on a mobile device, you are tapping on the letters as they are present on the screen. After you have typed in a valid word, you tap submit. Each letter equals a point, so for example, words that you create using the letters ‘M’, ‘A’, ‘K’, ‘I’, ‘E’. ‘R’, ‘G’ can be ‘MAKE’, ‘MAKING’, ‘MARKING’, and the score you get for these words can be MAKE, MAKING & MARKING. Some general rules that need to be followed are can be like Letters cannot be repeated. AI should be able to match the word against a list of valid words.
Note:- Unless we use an API, the word list will have to be fed in. We might need to refer to a dictionary and extract the list using AI. You can also search for the list online. We will cover this in future videos.
I did a quick search online and found this website - https://www.wordunscrambler.net (Disclaimer: This website does not sponsor this post in any way). It gives around 123 possible words that can be created using the letters ‘M’, ‘A’, ‘R’, ‘K’, ‘I’, ‘N’, ‘G’ (mind boggling right)!. We could go ahead with putting sounds like cheering or clapping and so on, but it will require us to extract .mp3 files of our choice and add so will keep basic sounds for now.
Since this idea makes sense, we will now break it into steps for Grok to perform. A brief on Grok from the internet, so you have context.
Grok is a conversational AI assistant chatbot developed by xAI, a company founded by Elon Musk. It's designed to engage in "serious and not-so-serious discussions," offering a more relaxed and witty approach to AI chatbots. Grok is known for its direct access to the X (formerly Twitter) social media platform, allowing it to provide real-time information and engage with users more dynamically.
The Steps
You can even get Grok to create the steps for you which you can feed it back to generate the HTML code. We can even feed it the idea and ask it to create HTML based on it but because we will be needing a validWordList for this game to work which we will be feeding it manually as it is not able to generate all the valid words itself, we will be giving it the steps manually. Also if you get the steps from Grok before feeding them back again to get the HTML, you can modify it and make it better.
Drop a ❤️ if this video helps and remember to subscribe to the YouTube channel for more tutorials.
Let us look at the steps to be fed to Grok. We will keep it a bit more detailed than the ‘Maths Game’ we created previously. -
Create a word-based game where the user is presented with 7 letters
The goal for the user is to make as many words as possible. Add a textbox titled ‘Rules’. Mention the rules in an unordered list based on the steps and prompt being fed.
Each letter in a valid word equals a point
This game is responsive and works well on both desktop and mobile.
Make sure that the keyboard is accessible on the desktop, and while using the keyboard, the user gets the impression that a letter has been typed in. When typing a letter, it the letter is from the list of letters shown to the user, make it dynamic so it looks like that letter has been selected or typed in.
On mobile, the user must be able to tap or click on a letter to use it to create a word.
These 7 letters presented to users will be ‘M’, ‘R’, ‘A’, ‘N’, ‘G’, ‘K’, ‘I’
There is a list of valid words that the user can create words from. Words outside this list will be invalid. List - ['MARKING', 'ARKING', 'ARMING', 'INGRAM', 'MAKING', 'MARGIN', 'RAKING', 'AGRIN', 'AKING', 'GAMIN', 'GARNI', 'GRAIN', 'INARM', 'KAING', 'KIANG', 'KRANG', 'MIKRA', 'MINAR', 'RAMIN', 'RANGI', 'AGIN', 'AIRN', 'AKIN', 'AMIN', 'AMIR', 'GAIN', 'GAIR', 'GARI', 'GINK', 'GIRN', 'GNAR', 'GRAM', 'GRAN', 'GRIM', 'GRIN', 'IKAN', 'KAIM', 'KAIN', 'KAMI', 'KANG', 'KARN', 'KINA', 'KING', 'KIRN', 'KNAG', 'KNAR', 'KRAI', 'MAGI', 'MAIK', 'MAIN', 'MAIR', 'MAKI', 'MANG', 'MANI', 'MARG', 'MARK', 'MINA', 'MING', 'MINK', 'MIRK', 'NAIK', 'NARK', 'NGAI', 'RAGI', 'RAIK', 'RAIN', 'RAKI', 'RAMI', 'RANG', 'RANI', 'RANK', 'RIMA', 'RING', 'RINK', 'AIM', 'AIN', 'AIR', 'AMI', 'ANI', 'ARK', 'ARM', 'GAK', 'GAM', 'GAN', 'GAR', 'GIN', 'ING', 'INK', 'IRK', 'KAI', 'KAM', 'KIN', 'KIR', 'MAG', 'MAK', 'MAN', 'MAR', 'MIG', 'MIR', 'MNA', 'NAG', 'NAM', 'NIM', 'RAG', 'RAI', 'RAM', 'RAN', 'RIA', 'RIG', 'RIM', 'RIN', 'AG', 'AI', 'AM', 'AN', 'AR', 'GI', 'IN', 'KA', 'KI', 'MA', 'MI', 'NA']
Once a word is submitted, it can either be valid or invalid. Show ‘Valid’ in green if the word is valid and ‘Invalid Word’ in red if the word is invalid. If a word is already created and submitted again, show ‘Word Already Exists’.
Enter equals submit on desktop. Similarly, on mobile, one needs to tap on submit.
Add a backspace button on mobile for the user. Put the Submit and Backspace buttons together on mobile under the text field.
If a user types in an invalid letter, show it slightly faded so they get a sense that the letter is not in the word list.
Keep showing the valid words in a list and the score achieved by the user for that word as they are being generated by the user. The list of words should be set in an order that they are created by the user. The list should be generated below the rules.
Depending on the longest possible word and the shortest possible word, allocate the created word into its own column, like ‘7-letter word’ or ‘2-letter words’. On desktop, they should appear in parallel columns, on mobile, they can be stacked.
Add a cool user user-friendly UI while creating this game.
Have the ‘Focus’ in the input field on desktop and mobile when the game loads.
Add comments after each line of code to help me understand it better.
Add a browser cookie that stores information about words created by the user, so if the page refreshes or they land on it again after exiting, it remembers what words they created. Refresh this cookie in 24 hours.
Generate this code while focusing on a modern UI.
Create a score bar at the top that uses the valid word list to have a maximum score, and keep increasing the user’s score as they make words, starting from 0.
Try adding sounds for valid, invalid, and repeated word creations to make this game attractive. Have a button that on clicking, reads out the rules to the user.
The code below is what I got. You can use the same or generate your own by using the steps above.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Word Game</title>
<script src="https://cdn.tailwindcss.com"></script>
<style>
body {
font-family: 'Inter', sans-serif;
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
}
.letter-btn {
transition: transform 0.2s, background-color 0.2s;
}
.letter-btn:active {
transform: scale(0.95);
}
.faded {
opacity: 0.5;
}
.score-bar {
transition: width 0.5s ease-in-out;
}
</style>
</head>
<body class="min-h-screen flex flex-col items-center justify-center p-4">
<div class="w-full max-w-4xl bg-white rounded-2xl shadow-2xl p-6">
<!-- Score Bar -->
<div class="mb-6">
<h2 class="text-2xl font-bold text-gray-800">Score: <span id="score">0</span>/<span id="maxScore">0</span></h2>
<div class="w-full bg-gray-200 rounded-full h-4">
<div id="scoreBar" class="score-bar bg-green-500 h-4 rounded-full" style="width: 0%"></div>
</div>
</div>
<!-- Letters Display -->
<div class="flex justify-center gap-2 mb-6">
<div id="letters" class="flex gap-2 flex-wrap justify-center"></div>
</div>
<!-- Input and Buttons -->
<div class="flex flex-col items-center mb-6">
<input id="wordInput" type="text" class="w-full max-w-md p-3 border-2 border-gray-300 rounded-lg focus:outline-none focus:border-blue-500" placeholder="Enter a word" autofocus>
<div id="mobileButtons" class="flex gap-2 mt-4 md:hidden">
<button id="submitBtn" class="px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600">Submit</button>
<button id="backspaceBtn" class="px-4 py-2 bg-gray-500 text-white rounded-lg hover:bg-gray-600">Backspace</button>
</div>
<p id="feedback" class="mt-2 text-lg font-semibold"></p>
</div>
<!-- Rules -->
<div class="mb-6">
<h2 class="text-xl font-bold text-gray-800 flex items-center">
Rules
<button id="readRulesBtn" class="ml-2 text-blue-500 hover:text-blue-700">
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15.75 10.5l4.72-4.72a.75.75 0 011.28.53v11.38a.75.75 0 01-1.28.53l-4.72-4.72M4.5 18.75h9a2.25 2.25 0 002.25-2.25v-9a2.25 2.25 0 00-2.25-2.25h-9A2.25 2.25 0 002.25 7.5v9a2.25 2.25 0 002.25 2.25z" />
</svg>
</button>
</h2>
<ul id="rules" class="list-disc pl-6 text-gray-600"></ul>
</div>
<!-- Word Lists -->
<div class="grid grid-cols-1 md:grid-cols-4 gap-4">
<div>
<h3 class="text-lg font-semibold text-gray-800">2-Letter Words</h3>
<ul id="words2" class="list-disc pl-6 text-gray-600"></ul>
</div>
<div>
<h3 class="text-lg font-semibold text-gray-800">3-Letter Words</h3>
<ul id="words3" class="list-disc pl-6 text-gray-600"></ul>
</div>
<div>
<h3 class="text-lg font-semibold text-gray-800">4-Letter Words</h3>
<ul id="words4" class="list-disc pl-6 text-gray-600"></ul>
</div>
<div>
<h3 class="text-lg font-semibold text-gray-800">5+ Letter Words</h3>
<ul id="words5" class="list-disc pl-6 text-gray-600"></ul>
</div>
</div>
</div>
<script>
const letters = ['M', 'R', 'A', 'N', 'G', 'K', 'I']; // Available letters
const validWords = ['MARKING', 'ARKING', 'ARMING', 'INGRAM', 'MAKING', 'MARGIN', 'RAKING', 'AGRIN', 'AKING', 'GAMIN', 'GARNI', 'GRAIN', 'INARM', 'KAING', 'KIANG', 'KRANG', 'MIKRA', 'MINAR', 'RAMIN', 'RANGI', 'AGIN', 'AIRN', 'AKIN', 'AMIN', 'AMIR', 'GAIN', 'GAIR', 'GARI', 'GINK', 'GIRN', 'GNAR', 'GRAM', 'GRAN', 'GRIM', 'GRIN', 'IKAN', 'KAIM', 'KAIN', 'KAMI', 'KANG', 'KARN', 'KINA', 'KING', 'KIRN', 'KNAG', 'KNAR', 'KRAI', 'MAGI', 'MAIK', 'MAIN', 'MAIR', 'MAKI', 'MANG', 'MANI', 'MARG', 'MARK', 'MINA', 'MING', 'MINK', 'MIRK', 'NAIK', 'NARK', 'NGAI', 'RAGI', 'RAIK', 'RAIN', 'RAKI', 'RAMI', 'RANG', 'RANI', 'RANK', 'RIMA', 'RING', 'RINK', 'AIM', 'AIN', 'AIR', 'AMI', 'ANI', 'ARK', 'ARM', 'GAK', 'GAM', 'GAN', 'GAR', 'GIN', 'ING', 'INK', 'IRK', 'KAI', 'KAM', 'KIN', 'KIR', 'MAG', 'MAK', 'MAN', 'MAR', 'MIG', 'MIR', 'MNA', 'NAG', 'NAM', 'NIM', 'RAG', 'RAI', 'RAM', 'RAN', 'RIA', 'RIG', 'RIM', 'RIN', 'AG', 'AI', 'AM', 'AN', 'AR', 'GI', 'IN', 'KA', 'KI', 'MA', 'MI', 'NA']; // Valid words list
const rules = [
"Use the 7 letters provided to form as many words as possible.",
"Each letter in a valid word counts as one point.",
"Letters cannot be repeated.",
"Word cannot be repeated"
]; // Game rules
let foundWords = []; // Track words found by user
let score = 0; // Current score
const maxScore = validWords.reduce((sum, word) => sum + word.length, 0); // Calculate max score
// Initialize sounds
const validSound = new Audio('https://www.soundjay.com/buttons/beep-01a.mp3'); // Valid word sound
const invalidSound = new Audio('https://www.soundjay.com/buttons/beep-02.mp3'); // Invalid word sound
const repeatSound = new Audio('https://www.soundjay.com/buttons/beep-03.mp3'); // Repeated word sound
// Cookie handling
function setCookie(name, value, hours) {
const date = new Date();
date.setTime(date.getTime() + (hours * 60 * 60 * 1000));
document.cookie = `${name}=${JSON.stringify(value)};expires=${date.toUTCString()};path=/`; // Set cookie with expiry
}
function getCookie(name) {
const value = `; ${document.cookie}`;
const parts = value.split(`; ${name}=`);
if (parts.length === 2) return JSON.parse(parts.pop().split(';').shift()); // Parse cookie value
return null;
}
// Load saved words from cookie
const savedWords = getCookie('foundWords');
if (savedWords) {
foundWords = savedWords;
updateWordLists();
updateScore();
}
// Display letters
const lettersDiv = document.getElementById('letters');
letters.forEach(letter => {
const btn = document.createElement('button');
btn.textContent = letter;
btn.className = 'letter-btn px-4 py-2 bg-blue-200 text-blue-800 rounded-lg hover:bg-blue-300';
btn.onclick = () => {
document.getElementById('wordInput').value += letter; // Add letter to input on click
btn.classList.add('bg-blue-400'); // Highlight selected letter
setTimeout(() => btn.classList.remove('bg-blue-400'), 200); // Remove highlight after animation
};
lettersDiv.appendChild(btn);
});
// Display rules
const rulesList = document.getElementById('rules');
rules.forEach(rule => {
const li = document.createElement('li');
li.textContent = rule;
rulesList.appendChild(li); // Add rule to list
});
// Read rules aloud
document.getElementById('readRulesBtn').onclick = () => {
const utterance = new SpeechSynthesisUtterance(rules.join(' '));
speechSynthesis.speak(utterance); // Speak rules
};
// Handle input
const wordInput = document.getElementById('wordInput');
wordInput.addEventListener('input', () => {
const value = wordInput.value.toUpperCase();
const lastChar = value.slice(-1);
if (lastChar && !letters.includes(lastChar)) {
wordInput.classList.add('faded'); // Fade input for invalid letter
} else {
wordInput.classList.remove('faded'); // Remove fade for valid letter
}
});
// Handle submit
function submitWord() {
const word = wordInput.value.toUpperCase().trim();
const feedback = document.getElementById('feedback');
if (!word) return;
// Validate word
const isValid = validWords.includes(word);
const isRepeated = foundWords.includes(word);
if (isValid && !isRepeated) {
feedback.textContent = 'Valid';
feedback.className = 'mt-2 text-lg font-semibold text-green-500';
foundWords.push(word);
score += word.length;
validSound.play(); // Play valid sound
setCookie('foundWords', foundWords, 24); // Save to cookie
updateWordLists();
updateScore();
} else if (isRepeated) {
feedback.textContent = 'Word Already Exists';
feedback.className = 'mt-2 text-lg font-semibold text-yellow-500';
repeatSound.play(); // Play repeat sound
} else {
feedback.textContent = 'Invalid Word';
feedback.className = 'mt-2 text-lg font-semibold text-red-500';
invalidSound.play(); // Play invalid sound
}
wordInput.value = ''; // Clear input
wordInput.classList.remove('faded');
}
// Desktop submit on Enter
wordInput.addEventListener('keydown', (e) => {
if (e.key === 'Enter') submitWord(); // Submit on Enter
});
// Mobile submit button
document.getElementById('submitBtn').onclick = submitWord;
// Mobile backspace button
document.getElementById('backspaceBtn').onclick = () => {
wordInput.value = wordInput.value.slice(0, -1); // Remove last character
wordInput.classList.remove('faded');
};
// Update word lists
function updateWordLists() {
const lists = {
2: document.getElementById('words2'),
3: document.getElementById('words3'),
4: document.getElementById('words4'),
5: document.getElementById('words5')
};
Object.values(lists).forEach(list => list.innerHTML = ''); // Clear lists
foundWords.forEach(word => {
const length = word.length;
const list = length <= 2 ? lists[2] : length === 3 ? lists[3] : length === 4 ? lists[4] : lists[5];
const li = document.createElement('li');
li.textContent = `${word} (${word.length} points)`;
list.appendChild(li); // Add word to appropriate list
});
}
// Update score and score bar
function updateScore() {
document.getElementById('score').textContent = score;
document.getElementById('maxScore').textContent = maxScore;
const percentage = (score / maxScore) * 100;
document.getElementById('scoreBar').style.width = `${percentage}%`; // Update score bar width
}
// Initialize score display
updateScore();
</script>
</body>
</html>