MakeWords: Implementing a Classic Pen & Paper Game in Google Sheets

Make Words Game:

Implementing a Classic Pen & Paper Game in Google Sheets

Introduction

Word games have always been a popular form of entertainment and education, with classics like Boggle, Scrabble, and the New York Times’ Spelling Bee captivating word enthusiasts worldwide. Growing up, I played these games with my family using paper and pencil, which created wonderful memories and a love for word puzzles. Inspired by these timeless games, I set out to create MakeWords, a Google Sheets-based game that brings the excitement of word puzzles into a digital and easily accessible format. This game isn’t just a fun way to pass time; it’s also a valuable educational tool, particularly for ESL and ELL students.

Project Overview

Objective: Form as many smaller words as possible from a given longer word.

Rules: Players are given a long word and must form as many valid smaller words as possible using the letters from the long word.

Video Preview

Educational Benefits

  • Vocabulary Expansion: Players are encouraged to think of and form longer, more complex words, helping them expand their vocabulary.
  • Strategic Thinking: The exponential scoring encourages strategic thinking, as players need to weigh the benefits of finding longer words against the time it takes to think of them.
  • Engagement: The increasing points for longer words make the game more exciting and competitive, which can help maintain students’ interest and engagement.
  • Reinforcement of Spelling: Regularly forming and validating words helps reinforce correct spelling and word usage.

Gamifying Learning

MakeWords is a powerful tool for engaging students through gamification. Teachers assigning this game are leveraging the principles of gamification to make learning fun and interactive. Here’s how:

Engaging Through Gamification

  1. Making Learning Fun: By turning word practice and spelling into a game, students are more likely to enjoy the learning process. The competitive element, where students aim to find as many words as possible from a given word, and the longer the word, the more points are awarded.
  2. Attention to Detail: The game requires students to pay close attention to the letters in the given long word. They need to ensure they are using the letters correctly, checking for duplicates, and verifying the validity of the words. This meticulous approach enhances their attention to detail and spelling accuracy.
  3. Fostering a Competitive Learning Environment: By choosing the same starting long word,and playing simultaneously, users can compete to see who can get the most points in the given time. This healthy competition can drive players to improve their word recall and spelling skills as they strive to outperform their peers.

Tracking Performance and Growth

  1. Timestamps for Tracking Progress: Each game session is automatically named and saved with a timestamp. This feature allows teachers and parents to track the progress of students over time. They can see how students are improving in their ability to recall and form words.
  2. Performance Review: By reviewing past game sessions, shared with teachers or parents, it’s easy to identify patterns in a student’s performance. Teachers can see which types of words students struggle with and provide targeted support to help them improve.
  3. Growth in Word Recall and Retrieval: As students play more games, their ability to recall and retrieve words is likely to improve. Teachers can use the timestamps and saved game sessions to monitor this growth, providing evidence of learning progress over time.
  4. Data-Driven Insights: The structured data from each game session offers valuable insights into a student’s learning journey. Teachers can analyze this data to understand individual strengths and weaknesses, adapting their teaching strategies to better support each student.

Practical Implementation

Assigning the Game: Teachers can easily assign MakeWords to students in Google Classroom. The game is accessible and straightforward, making it easy for students to start playing and learning immediately. Teachers can keep track of usage; this shared access ensures that those involved in the student’s education can see their progress and provide encouragement or additional support as needed.

Encouraging Continuous Improvement: With each game saved and accessible, students can see their own improvement over time. This visibility can be a powerful motivator, encouraging them to keep practicing and improving their word skills.

Technical Setup – Google Sheet Structure

Dictionary Sheet: Contains a list of long words organized alphabetically into columns (A-Z). 

This structure significantly improves efficiency by limiting the search space. Instead of searching through one long column containing the entire dictionary, the search is confined to a single column corresponding to the first letter of the word, making lookups faster and less resource-intensive.

Game Sheet: The gameplay takes place here, where players enter their words and see their scores.

Google Apps Script

  • Random Word Selection: The script draws a random long word from the “Dictionary” sheet.
  • Word Validation: Players enter their words in designated cells, and the script checks their validity, ensuring they can be formed from the letters of the long word.
  • Scoring System: The script calculates points based on the length of the words and handles duplicate entries and invalid words.

Feedback

Providing clear reasons why a word is invalid is vital feedback that enhances the learning experience in “Make Words.” When players receive specific feedback, such as a word being invalid due to incorrect letters or being a duplicate entry, they can quickly adjust their strategies and avoid making the same mistakes. This targeted feedback not only aids in faster learning but also keeps the game challenging and educational. Knowing why a word is invalid or seeing their scores improve encourages players to think more critically and enhances their problem-solving skills, making MakeWords both a fun and valuable educational tool.

A key feature of MakeWords is the use of toast notifications. These are small, non-intrusive pop-up messages that appear briefly at the bottom of the screen. The name “toast” comes from the way these notifications pop up like a slice of toasted bread. Toast notifications are particularly effective because they provide feedback without interrupting gameplay. Unlike traditional dialogue boxes or alerts that require user interaction to close, toast notifications allow players to continue playing seamlessly. Players are informed about the validity of their words and their points without having to click anything to dismiss the notification. This ensures a smooth and engaging gaming experience.

Toast notifications provide instant feedback on the validity of their words and the points they earn. This real-time response keeps students engaged and helps them learn from their mistakes without interrupting the flow of the game. Moreover, this immediate feedback is crucial for maintaining high levels of motivation and engagement, as it helps players understand the rules better and improve their word-forming skills dynamically.

Smart Scoring Method

One of the unique aspects of this game is its smart scoring method, designed to encourage players to find longer words. 

This exponential scoring system motivates players to find longer words, as each additional letter significantly increases the points earned. It turns the game into a more strategic and engaging activity.

Performance Optimization with Binary Search

One significant challenge was ensuring the game ran smoothly and updated scores correctly during fast play. This required an efficient way to validate words against a large dictionary.

Efficient Google Sheet Structure

  • Dictionary Sheet: Contains a list of long words organized alphabetically into columns (A-Z). This structure improves efficiency by limiting the search space. Instead of searching through one long column containing the entire dictionary, the search is confined to a single column corresponding to the first letter of the word, making lookups faster and less resource-intensive.

Why Binary Search?

Binary search is a powerful algorithm for finding an item in a sorted list in logarithmic time. Imagine you’re playing a number guessing game, where you have to guess a number between 1 and 100. Each time you make a guess, you’re told whether the number is higher or lower than your guess. You might start by guessing 50. If the number is higher, you then guess 75, and if it’s lower, you guess 25. By continually dividing the range in half, you quickly narrow down the possibilities.

Applying Binary Search to Word Validation

By organizing the dictionary sheet alphabetically into columns based on the first letter of each word, I leveraged binary search to quickly validate words. Here’s how:

  • Alphabetical Columns: The dictionary is divided into 26 columns (A-Z), each containing words that start with the corresponding letter.
  • Sorted Words: Within each column, the words are sorted alphabetically.

Example:

Suppose a player enters the word “cinema”. The script:

  • Locates the Column: Identifies the relevant column ‘C’ for words starting with ‘C’.
  • Performs Binary Search:
    1. Finds the middle word in the ‘C’ column. With 24,797 words, the middle word would be around the 12,399th word.
    2. Let’s assume the middle word in the 0 to 12,398 range is “cobra”.
    3. Compare “cinema” with “cobra”:
      • Since “cinema” comes before “cobra” alphabetically, search the first half of the column.
    4. Narrow the search range to 0 to 6,199.
    5. Find the new middle word in this range, let’s say it’s “cherry”.
    6. Compare “cinema” with “cherry”:
      • Since “cinema” comes after “cherry”, search the second half of this range.
    7. Narrow the search range to 3,100 to 6,199.
    8. Find the new middle word in this range, let’s say it’s “clementine”.
    9. Compare “cinema” with “clementine”:
      • Since “cinema” comes before “clementine”, search the first half of this range.
    10. Narrow the search range to 3,100 to 4,649.
    11. Find the new middle word in this range, let’s say it’s “cite”.
    12. Compare “cite” with “cinema”:
      • Since “cinema” comes before “cite”, search the first half of this range.
    13. Repeat this process until “cinema” is found or the range is exhausted.

Benefits of This Structure:

Notice how, in just 4-5 comparisons, we got down to less than 1,000 options from the over 24,000 words starting with C. Compare this method to going through the entire dictionary of over 150,000 words every time we want to validate a word! Binary search can reduce the search space significantly, making it ideal for handling large datasets and ensuring quick word validation even during fast-paced play.

Code Snippet for Binary Search:

  • arr: The array (list) of sorted words being searched.

  • target: The word you’re looking for.

  • left and right: The starting and ending indices of the current search range.

  • mid: The middle index of the current search range.

  • midValue: The word at the middle index, compared to the target word.

Implementation Details

Step-by-Step Guide

  1. Set up the Google Sheets: Create a “Dictionary” sheet and a “Make Words Game” sheet.
  2. Google Apps Script: Implement the script to handle word selection, validation, and scoring. Here’s a key snippet from the script:
  3. Start Playing: Draw a random word and begin forming smaller words. The script will handle validation and scoring in real-time.

    Breakdown of the Scoring Formula

    The formula used in cell F2 to calculate the total score is:

    =SUMPRODUCT(IF(ISNUMBER(B4:B45), B4:B45, 0)) + SUMPRODUCT(IF(ISNUMBER(D4:D45), D4:D45, 0)) + SUMPRODUCT(IF(ISNUMBER(F4:F45), F4:F45, 0))

    How It Works:

    • SUMPRODUCT Function: This function multiplies corresponding components in the given arrays and then sums the results. It’s used here to handle both numeric and text entries.
    • IF Function: IF(ISNUMBER(B4:B45), B4:B45, 0) checks each cell in the range B4. If the cell contains a number, it returns that number; otherwise, it returns 0. This ensures that only valid points (numbers) are included in the sum.
    • ISNUMBER Function: This function checks whether each cell contains a number. It’s essential for filtering out non-numeric values like text or empty cells.
    • Sum Calculation: The formula does this for three ranges: B4, D4, and F4. It sums the valid numeric values from these ranges separately and then adds the results together to get the total score.

    This formula efficiently calculates the total points from multiple columns, ensuring that only numeric values are considered, which is particularly useful during fast-paced play.

    Conclusion

    The MakeWords game is a fantastic way to bring the joy of classic word games into the digital age, using tools like Google Sheets and Google Apps Script. Whether you’re an educator looking for a fun classroom activity or a word enthusiast, this game offers endless possibilities for learning and enjoyment. I invite you to try creating your own version and share your experiences!

    Explanation of Functions

    1. Initial Setup Functions
      • onOpen: This function adds a custom menu item to the Google Sheets UI when the spreadsheet is opened.
      • newGame: This function sets up a new game session, renaming the current game sheet with a timestamp, deleting any existing game sheet, duplicating a past game sheet if available, and initializing a new game sheet.
    2. Helper Functions
      • getLetterCount: This function counts the occurrences of each letter in a given word.
      • binarySearch: This function performs a binary search on a sorted array to efficiently find the target word.
    3. Core Game Functions
      • drawRandomWord: This function selects a random word from the dictionary sheet.
      • isRealWordLocal: This function checks if a word is real by performing a binary search in the dictionary sheet.
      • isValidWord: This function validates a word by comparing its letter counts with those of the given long word.
      • isDuplicateEntry: This function checks for duplicate word entries in the current game session.
      • updatePoints: This function updates the points in the adjacent cell based on the length of the word.
      • showToast: This function displays toast notifications within the spreadsheet.
    4. Event Handling Functions
      • onEdit: This function handles the onEdit event, validating the entered word and updating the game state accordingly.
      • processUpdateQueue: This function processes the update queue, ensuring smooth handling of word entries and validations.

    How to Play

    Click the MakeWords game to make your own template. A new menu item called ‘Make Words’ will be created. Select ‘New Game’ from that menu. If you encounter a problem, click on the ‘Extensions’ menu and choose ‘Apps Script’. Then, run the onOpen function from the script editor.

    Running the Google Apps Script shared is safe. Here’s what you can expect during the process:

    1. Authorization Request: When you run the script, you will encounter an authorization request. This is a standard procedure for the script to access specific data within your Google account.
    2. Clicking “Advanced”: During authorization, you will need to click on “Advanced” to review and understand the script’s permissions.
    3. Allowing the Script to Run: You might see a warning about the script being unverified. This is not indicative of any malicious activity. Simply select the option to allow the script to run. It’s important to note that this grants the script permission to read and modify the contents of cells in the sheet, which is necessary for it to perform the requested actions.I hope you find this tool to be a useful game-changer. Here’s to taking tournament management to the next level! Please enjoy these interactive tournament brackets. Play on!

    Full Code Base:

    Make Words Code.gs

A Wordle for Google Sheets Adventure

 

Introduction:

Creating a Wordle game in Google Sheets, with ChatGPT was a real back-and-forth. ChatGPT, with its vast pool of knowledge and ideas, was a huge help. But in the end, it was the practical skills—knowing what makes a good user experience and applying design thinking—that shaped the project. Every iteration brought new challenges and things to learn, highlighting the value of patience, persistence, and paying attention to the small stuff in making digital tools that people might enjoy using.

Inspiration and Research:

This project was part of my ongoing exploration of how to leverage AI for programming, education, and fun. My project was inspired by the widespread appeal of Josh Wardle’s original Wordle game. His creation showed how a straightforward concept could engage a wide audience, sparking my interest in developing something similar.

Two particular resources significantly shaped the direction of this project: Tyler Robertson’s Zapier article revealed the potential of Google Sheets to host a Wordle-like game without Google Apps Script (incredible!).  He creatively uses formulas, data validation, and conditional formatting, reinforcing my appreciation for Google Sheets as a versatile platform for creating interactive experiences.

Equally inspiring was Sajad Deyargaroo’s GitHub project, which uses Google Apps Script. I emulated his cell layout for the color-coded feedback keyboard. 


Software Development:

The script function selectRandomWord randomly selects a word from the ‘Words’ sheet to serve as the challenge for the game session. In terms of implementation, here’s a simplified pseudo-code representation of the selectRandomWord function:

In detail:

  • Accessing the Spreadsheet: The function begins by getting a handle on the active spreadsheet using SpreadApp.getActiveSpreadsheet(), which allows the script to interact with the spreadsheet content.
  • Locating the Words Sheet: It then identifies the specific sheet named ‘Words’ where the list of words is stored. This is done through getSheetByName(“Words”).
  • Random Word Selection: To select a random word, the function first determines the number of words available by finding the last row in the ‘Words’ sheet with getLastRow(). This is essential to ensure that the random selection is within the bounds of the word list.
  • Generating a Random Number: A random row number is generated within the range of available words. This is where Math.random() comes in, which generates a number between 0 and 1, and then it’s multiplied by the lastRow to scale it to the size of the word list. The Math.floor() function is used to round down to the nearest whole number, ensuring you get a valid row index.
  • Retrieving the Word: With the random row number in hand, the script retrieves the word from the “Words” sheet using getRange() and getValue(). The range is dynamically constructed using template literals to incorporate the row number.
  • Formatting the Word: Finally, the selected word is converted to uppercase with toUpperCase() to maintain consistency throughout the game, as user input will also be converted to uppercase for comparison purposes.

Version 1 of selectRandomWord:

At the start of each game or round, this function is called to set the challenge word that players will attempt to guess—more on how this function changed later when I discuss word categories.

User Experience:


I initially considered using a checkbox that, when checked, would trigger the onEdit function which calls the checkGuess function. However, this required the user to perform multiple actions: typing the guess, navigating to the checkbox, and then clicking it. This method, while functional, did not offer the most fluid experience.

The original onEdit trigger:

I didn’t want users to have to type a word and then click the mouse — I wanted to allow players to just type a word and press ‘Enter.’

To refine this, I made pressing ‘Enter’ trigger the onEdit function. This single-step interaction mimics the ease of the original Wordle game, where a guess is submitted with just a keystroke, thereby maintaining the user’s focus and flow (note that clicking outside of the edited cell would also trigger the function).

The enhanced onEdit trigger:

Incorporating this functionality reduces the cognitive load on the user, allowing them to remain engrossed in the game rather than the mechanics of the game’s interface. It’s an example of user experience (UX) design principles; by recognizing that minimizing the number of user actions leads to a more enjoyable and engaging experience, you’ve made the game more accessible and enjoyable, particularly for users who may not be as comfortable switching between keyboard and mouse actions.

Dealing with Duplicates

In creating Wordle in Google Sheets, a key challenge was managing duplicate letters—both in players’ guesses and the puzzle words. This required refining the updateUI function. Initially, it color-coded cells based on the correctness of guesses. The twist came with handling duplicates, where the game logic had to discern between excess and correctly placed letters.

The solution involved a dual-pass approach:

  • First pass: We mark the correctly placed letters and decrement their counts from the correctLetterCounts map.

Second pass: We deal with misplaced letters and excess letters. A letter is colored yellow if it’s in the correct word and we haven’t used up all its occurrences yet (as per the correctLetterCounts map). If it’s not in the correct word or we’ve used up all its occurrences, we color it gray.

However, this can cause the letters and their color coding not to be revealed from left to right. Adjusting the logic to reveal each letter from left to right, regardless of whether they’re correct, misplaced, or incorrect, required rethinking the two-pass approach. To achieve the sequential reveal effect similar to the real game, I had to integrate the logic for determining the color into a single pass. This way, each cell is updated one by one in order, maintaining the suspense of the game.

Modified updateUI function:

In this revised approach:

First Pass: Initial Coloring and Occurrence Tracking

In the first loop over the guessed word, the function performs several tasks for each letter:

  • Visual Update: It updates the corresponding cell in the Google Sheet with the guessed letter, setting its font size and weight for clarity.
  • Occurrence Tracking: It increments the count of each guessed letter in guessedLetterCounts.
  • Initial Coloring: It assigns an initial background color to each cell based on a simple check:
    • Green (#6aaa64) if the guessed letter is in the correct position.
    • Yellow (#c9b458) if the letter is present in the correct word but not necessarily in the right place or the right quantity.
    • Gray (#787c7e) if the letter is not present in the correct word at all.

After setting the initial color, it decrements the count in correctLetterCounts for green letters, acknowledging that one correct occurrence of the letter has been accounted for.

Second Pass: Correcting Colors for Misplaced vs. Excess Letters

The function’s second loop over the guessed word adjusts the initial color assumptions to handle the nuances of duplicate letters and their placements:

  • It reevaluates cells initially marked as yellow to determine if they represent misplaced letters or excess letters. This step is necessary because the first pass might incorrectly mark an excess letter (one that appears more times in the guess than in the correct word) as yellow.
  • For each guessed letter not in the correct position, the function checks if the number of guesses for that letter exceeds the number of occurrences in the correct word. If so, it changes the cell’s color to gray (#787c7e), indicating an excess letter, and decrements guessedLetterCounts to reflect that one of the excess occurrences has been accounted for.

Key Mechanisms

  • Two-Pass Coloring Logic: This approach allows the function to initially mark potential matches as yellow and then refine those marks by distinguishing between correctly placed, misplaced, and excess letters. This is crucial for handling words with duplicate letters accurately.
  • Occurrence Tracking: By tracking the occurrences of each letter in both the guessed word and the correct word, the function can accurately determine when to mark a letter as excess (gray) rather than misplaced (yellow).
  • Delayed Visual Feedback: The SpreadsheetApp.flush() and Utilities.sleep(50. This was a design choice inspired by the original Wordle;  including a delay between the reveals of each letter as a UX consideration. By revealing each letter one by one, we allow for brain processing time, preventing cognitive overload, and mirror the pace at which the human brain processes information, creating suspense and drawing the player into the game experience, hopefully enhancing anticipation/drama/engagement/fun.  More on why this was removed later in the article.

In summary, the updateUI function adeptly handles the complexities of Wordle’s coloring rules, especially in the context of duplicate letters, through a methodical two-pass system that first assigns preliminary colors based on simple matches and then refines those colors to accurately reflect the actual state of the game.

First Pass: All letters are placed and initially colored. Correctly placed letters are immediately marked green. Letters that exist in the word are temporarily marked as yellow, and incorrect letters are marked gray. This creates the left-to-right reveal effect.

Second Pass: Adjusts the color of letters marked as yellow if they are found to be excess. This pass refines the initial guesswork by turning excess letters gray.


Accessibility

Introduction of Categories:

To diversify the Wordle game, I decided to introduce categories, allowing players to choose words from specific themes like Animals and Cities. By importing different word lists by category, I could potentially broaden the game’s educational scope, using it as a tool for language learning. This necessitated modifications in how words were selected based on the user’s chosen category. Here’s a summary of the process.

Word List Organization:

The ‘Words‘ sheet was organized with different categories in separate columns: Column A for all words, Column B for Animals, and Column C for Cities. Each column had a header indicating the category, facilitating easy identification and selection of words from the desired category.

Conceptualization:

  • Category Selection: The first step was selecting broad categories with ample five-letter words. Categories such as Animals, Cities, Foods, Colors, Tools, Sports, Music, and Brands were chosen for their rich vocabulary and accessibility to a diverse audience.
  • Word Sources: For each category, legitimate sources were identified to compile the words. These included online dictionaries, encyclopedias (e.g. Wikipedia), GitHub repositories, educational resources, APIs (like Datamuse for programmatically fetching words), and community contributions.

Implementation:

  • Removing Duplicates: An optimized script function removeDuplicatesOptimized was developed to process large datasets efficiently, ensuring that unique words remained. This script employs batch processing techniques, significantly reducing execution time compared to row-by-row operations.
  • Filtering Five-Letter Words: A script filterFiveLetterWords was created to cleanse the imported lists, removing any words not exactly five letters long or that were compound words. This script streamlined the process of preparing category-specific word lists for the game.
  • Loading Category Words: The loadCategoryWords function was introduced to dynamically load words from the specified category into the game, enhancing the game’s flexibility. This function used the spreadsheet headers to identify the correct column for each category, loading the words into an in-memory cache for quick access.
  • Category-Specific Gameplay: Functions like playWordleAnimals, playWordleCities, etc., were implemented to allow players to start games with words from their chosen categories, enriching the gameplay experience with variety and customization.
  • Changes to selectRandomWord: The key improvement here is the dynamic determination of the word list based on the given category, allowing the game to draw from different sets of words depending on the user’s choice. This not only diversified the gameplay but also showcased the flexibility of Google Apps Script in handling data dynamically in Google Sheets.
  • Using a helper function, columnToLetter, I converted column indices to letters, enabling the script to work with the A1 notation that Google Sheets requires. This utility function was essential in mapping the 1-indexed category position to the corresponding column letter in the sheet.

Current version of selectRandomWord:

 


Efficiency and Optimization:

  • Batch Processing: Emphasized throughout the implementation was the use of batch processing for reading and writing data to Google Sheets, significantly enhancing performance, especially for large word lists.
  • Cache Utilization: The strategic use of a cache (categoryWordsCache) minimized repetitive reads from the spreadsheet, further optimizing the game’s responsiveness and efficiency.

Function Modifications for Category Selection:

Given the need for functions that would select a random word from the user’s desired category, I modified the existing selectRandomWord function to accept a category parameter. This adjustment allowed for dynamic word selection based on the category chosen by the user.

Incorporating User Selection through UI:

To enable users to choose a category directly from the Google Sheets UI, I added a custom menu with options for each category, using Google Apps Script:

Dynamic Range Calculation:

To accurately select a random word from the desired category, it was essential to calculate the last row for each specific column, addressing the varying lengths of each category. ChatGPT suggested an updated selectRandomWord function that dynamically calculates the range for the specified category column:

Handling Function Overloading:

In Google Apps Script, which adheres to JavaScript’s limitations, the concept of function overloading—where multiple functions with the same name differ only by their parameters—is not supported. Initially, this project included two distinct functions for the selectRandomWord task: one without parameters for selecting a default word, and another accepting a category parameter for category-specific selections. Due to the scripting environment’s constraints, attempting to use both functions led to a TypeError when the no-parameter version was called, highlighting the limitations of function overloading in this context.

To overcome this, the solution was to merge these functions into a single, versatile selectRandomWord(category) function. This unified function adeptly checks for the presence of a category argument. Based on whether a category is provided, it either executes category-specific logic for word selection or falls back to a default operation, typically selecting words from a predefined column (e.g., column A) when no category is specified:

This approach ensures a single selectRandomWord function can handle both scenarios: selecting words from a specific category or a default list, enhancing the script’s manageability and user experience.

Moreover, the playWordle function was refined to accommodate an optional category parameter. This modification enables dynamic category selection for the game. If a category is provided, playWordle invokes selectRandomWord with the given category; otherwise, it defaults to the general word list. This flexibility is crucial for supporting a variety of word categories without the need for separate functions for each category type:

This code structure not only simplifies adding new categories by merely adding a new column to the ‘Words’ sheet but also enhances the game’s versatility. Players can now enjoy a tailored game experience with categories ranging from “Animals” to “Cities,” facilitated by the dynamically adjusted playWordle and selectRandomWord functions. To reflect these changes and new category options in the Google Sheets UI, users must refresh the UI after script updates, ensuring the custom menu accurately presents the new categories available for gameplay. This design philosophy promotes ease of expansion and user engagement by seamlessly integrating new word categories into the game.

Why I removed Utilities.sleep

Earlier, I discussed delayed visual feedback as a design choice, including a delay between the reveals of each letter to allow for brain processing time, suspense, and engagement. In practice, I noticed that it was not necessary given the latency already occurring. Google Apps Script runs on Google’s servers, meaning that every operation, especially those that modify a Google Sheet, requires communication between the user’s device and the server. This communication incurs a natural latency that can vary based on several factors, including network speed, server load, and the complexity of the operations being performed. Human perception of delays in user interfaces is an important factor to consider. Research in human-computer interaction suggests that users can perceive delays as short as 100 milliseconds and that delays of around 200-300 milliseconds are generally perceived as instantaneous. Given the natural latency involved in the script’s execution and the UI’s update process, these delays might be sufficient to create a staggered update effect without the need for additional artificial delays introduced by Utilities.sleep().

 

SpreadsheetApp.flush() is a method that forces the execution of all pending changes in the script to be applied to the spreadsheet immediately. Normally, Google Apps Script batches changes and applies them at the end of the script execution to optimize performance and reduce the number of calls to the server. By calling flush(), you are explicitly telling the script to apply all queued changes up to that point, which can be used to create a real-time update effect in the spreadsheet.

If you were to remove SpreadsheetApp.flush() from the script, Google Apps Script would revert to its default behavior of applying all changes at once, at the end of the script’s execution. This means the entire word’s color coding would appear simultaneously, removing the sequential reveal of each letter’s status. The removal of flush() would effectively batch all updates together, which might be less engaging for users who expect a more dynamic interaction, akin to the original Wordle game experience. Removing Utilities.sleep while keeping SpreadsheetApp.flush() creates a balance between responsiveness and the dynamic reveal of updates, leveraging Google Apps Script’s server-side execution model. This setup offers a practical compromise between performance and user experience, demonstrating the nuanced interplay between script execution speed, network latency, and UI update mechanisms within Google Sheets.

 


Extensibility

This code structure allows users to add categories by simply adding a new column to the ‘Words‘ sheet, updating the onOpen function, and creating a new playWordleCategory function, mirroring the structure of the existing category functions:

Challenge: Try to add your own category of words to your copy of Wordle for Google Sheets!

  • Adding a New Category Column: In Wordle for Google Sheets: Add a new column to your ‘Words’ sheet. Let’s say you’re passionate about ‘Plants’. Rename the ‘Your Category’ header as ‘Plants’ and fill the column with relevant five-letter words like ‘tulip’ or ‘ferns’, one word per cell.


  • In the script: You’ll need to update the onOpen function to include your new category in the custom menu.  The first quoted phrase is what appears in the Wordle menu in the sheet.  The second quoted phrase is the function name.

Also in the script: you’ll need to add a function with the exact function name you chose to add to the onOpen function.

  • Refresh the Sheet: After saving your script, refresh the spreadsheet for the new menu item to appear in the Wordle menu.

By carefully following these steps and ensuring that function names and sheet headers match, you can add endless categories to your game, making it a customized, robust educational tool. The addition of each new category not only expands the vocabulary but also the breadth of knowledge that players can gain from engaging with your Wordle game.

Conclusion:

The development of Wordle in Google Sheets illustrates the practical application of computer science principles and design thinking in an educational setting. This project underscores the iterative nature of design and the effective use of Google Apps Script to elevate teaching tools within a platform that’s familiar to both students and educators.

Educational Value: This project not only provides a fun and engaging game but also serves as a practical example of applying computer science concepts such as data structures, algorithms, and optimization techniques.

Design Thinking: Students and educators are encouraged to think critically about user experience and game design, considering aspects such as category selection, user interface, and gameplay dynamics.

Customizability: Allowing users to edit/add new words/categories fosters a collaborative environment, providing a platform for students and educators to contribute creatively to the game’s development.

Collaborating with AI, particularly through exchanges with ChatGPT, is akin to having a skilled partner. I directed the project, while the AI provided support with code suggestions and troubleshooting. To conclude, this Wordle project is a testament to the potential of conversational coding and instructional design. It demonstrates how Google Apps Script can be an excellent resource for educators introducing interactive coding projects. Innovating within Google Sheets offers a myriad of opportunities for those aiming to blend coding and app development into their curriculum. This endeavor goes beyond coding; it fosters a design-centric mindset for problem-solving that I hope my students will use in their future projects.

 

Spelling Bee in Scratch



Inspired by the NY Times Spelling Bee, I challenged myself to create a Scratch version of this game.
Rules: Words must be at least 4 letters long, and must contain the yellow center letter. Letters do not have to be adjacent to each other, and duplicating letter is allowed. I created the background hexagons with Google Drawings and Inkscape. In Scratch, I created a “dictionary” based on English word list from: http://www.mediafire.com/file/5cy3vcsag29ic43/Word_List.txt/file
I also created letter frequencies based the following sources:
https://www3.nd.edu/~busiforc/handouts/cryptography/letterfrequencies.html
https://en.wikipedia.org/wiki/Scrabble_letter_distributions
https://en.wikipedia.org/wiki/Letter_frequency

I got a great suggestion from Nirmala Sankaran, Co-Founder of HeyMath, to include the total possible words for a given board. This required iterating over the dictionary and checking if each word is valid for each board, given the game rules.

You can find the original code here: https://scratch.mit.edu/projects/603333011