Introduction

A few years ago, my wife started playing the Anagrams game from the Hoyle Word Games CD. The game presents you with a scrambled 6-letter word, and presents you with an opportunity to find 10-20 words that exist within the original word in a short amount of time. All the while, a pair of off-screen cannibals try to distract you with witty remarks, questions about your computer system, word suggestions (that are never right for the scramble you're currently working with), and sometimes, outright taunting.

While somewhat amusing (based solely on what the off-screen cannibals might be saying), the game is severely limited in its scope, and in my humble opinion, arbitrarily so. First, your scrambled word is never comprised of more than six letters, making for a limited dictionary. Second, the number of words are radically fewer than what actually exist in the scrambled word. Mind you, I'm not talking about obscure and rarely used words, but plain English stuff that any person with even just a mediocre vocabulary would see.

Note: This is not a complex game, and the code certainly doesn't explore or exercise any of the .NET Framework's more esoteric functionality. I simply wrote the game to help me learn .NET (I've only been coding in C# since August of 2007). There is no fancy interface, no amazing 3-D effects, and no attempts to dazzle anyone. It is what it is.

What I Did

After becoming sufficiently annoyed with the game, I decided it wouldn't be too awful hard to duplicate the game, but I wanted to include a much more far-reaching dictionary. So, I searched the web for lists of words of various lengths, from three to ten characters long. I also wanted to make sure I included as many valid words as possible. So, I figured I need to find lists of words that were legal in the game Scrabble. What better source of words than the most famous and popular word game in the world? In no time, I'd gathered a collection of over 125,000 words.

The Word Dictionary

Now that I had a sufficient list of words from which to bamboozle the user, I needed a way to load them all into memory at the same time. I created a "dictionary" class which created a word list object for each set of words based on their character counts.

Remember, we had words with from three to ten letters. As most of us already know, C# lists are zero-based. To make accessing the word lists a little easier to maintain, the dictionary creates 11 word lists, with list index 0 through 2 not being used to store dictionary words. However, there was a use for at least one of these unused list indexes.

Other dictionary functionality includes the ability to mark a word as having been used (so that the user won't see the same scrambled word until all of the other words in that letter group have been seen). When all of the words in a group have been seen, only a percentage of the words are marked as not having been used. This reduces the change that a recently used word will be presented again too soon after its last use.

While the dictionary object makes it easy to manage all of the word lists in a single location, the real use of the dictionary is to allow the program to discover and track words that are contained WITHIN the scrambled word.

Possible Words

Part of the game play support, the program has to be able to quickly identify words that are indeed found within the scrambled word. It would be impractical to search all 120,000+ words to see if one of them was a valid one. So, the program takes the scrambled word, and searches all of the word lists as soon as the scrambled word is available. To store these possible words, we use the 0th index in the list of word list objects.

Finally, we use the numerous dictionary object methods to find and update this possible words object. This includes marking possible words as already having been found and making the validation of user-submitted words much simpler.

Game Configuration

I provided a bit of configuration capability regarding how many letters to allow in the scrambled words, how much time is allotted to play a round, how much bonus time to allow, whether or not to play the game sounds, and whether or not to allow repeating words. These settings are saved via the GameConfig.cs file. Here's the dialog box:

The Game Panel

This is nothing but a Windows Forms application. I had to play some tricks to get the panel to react the way I wanted it to. I needed a way for the user to be able to just hit the enter key and have it submit the typed word. To do this, I created and hid a Submit button and made it the "default" button. With the Submit button taken care of, I had to find a way to illustrate the time left to the user for the current round.

I wanted to display the time remaining inside a progress bar, but I couldn't find a way to do that with the standard progress bar control (which probably means it's there, I just didn't find it). So, I found a control class called SmoothProgressBar (I don't remember where I found it, but I didn't write it), and it allowed the text in bar. As the timer winds down, the progress bar and the text are updated to reflect the amount of time remaining.

The Word List

I wanted a way to show the user what he'd typed, so I decided on a list box. As the program validates and accepts submitted words, they are added to the list box (sorted alphabetically). Then, when the user clicked Solve or the round expired naturally, I wanted to show all of the words that were possible, yet show the words that the user had submitted in such a way as to highlight those words.

To accomplish this, I set the list box's DrawMode property to be OwnerDrawFixed, and then overrode the DrawItem behavior. This allowed me to draw certain items with different appearances. I settled on dark gray text for words that were not discovered by the player, and bold red italic text for words the user found.

Statistics

I made a half-hearted attempt at providing a minimal set of statistics in the game. These stats aren't cataloged, but it wouldn't be hard to expand and thereby provide graphed results and game-play histories. I might even do that a little later.

The Sounds

Yeah, they suck. If you want to replace them with something else, go ahead. In fact, if you know anyone with a clear speaking voice (preferably a soft-spoken yet sultry female), have her record the appropriate vocal indicators and let me know you have a new set of files.

In Closing

I fail to understand why Hoyle imposed arbitrary restrictions on their version of the game. Maybe they wanted to keep the game to a limited intellectual level - I don't know. I find the game to be quite addictive because the rounds are short, and you tend to start saying to yourself, "Just one more round before I go to work..."

Share

About the Author

I've been paid as a programmer since 1982 with experience in Pascal, and C++ (both self-taught), and began writing Windows programs in 1991 using Visual C++ and MFC. In the 2nd half of 2007, I started writing C# Windows Forms and ASP.Net applications, and have since done WPF, Silverlight, WCF, web services, and Windows services.

My weakest point is that my moments of clarity are too brief to hold a meaningful conversation that requires more than 30 seconds to complete. Thankfully, grunts of agreement are all that is required to conduct most discussions without committing to any particular belief system.

Click the New Game button, and then start entering words. You can use the configuration form to modify the playing style (I personally set it to not have a time limit). When you get tire of trying to find words, you can click the Solve button and it will show you all of the words you didn't find.

.45 ACP - because shooting twice is just silly-----"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997-----"The staggering layers of obscenity in your statement make it a work of art on so many levels." - J. Jystad, 2001

I'm glad you're enjoying the game. I was working on a network version, but I kinda got side-tracked onto something else, but I will eventually get back to it, hopefully in the next month or so.

"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997-----"...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001

"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997-----"...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001

I've started working on the network version, and the code is getting REAL interesting. I've decided to provide three styles of play via three combined Windows Services. The idea will be that you have a game server that provides one or more of the play styles (that you can choose via an app.config file setting). If you don't want to run the server via services, there will also be a server console available in the form of a WinForms application. This console will allow you to turn on/off play styles at will. Having a game server separate from the client code will allow each player an equal latency where updates are concerned (since this is a timed game).

At this time, I've only got a TCP/IP transport layer going, but I might also try to provide a WCF layer as well.

"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997-----"...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001

As far as I know, the app will only work on Windows (you need .Net 2.0). It should work if you install XP into a VM, and then run the app in the VM.

"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997-----"...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001

I googled things like "3-letter words", and found scrabble-allowed lists of words. I was lucky enough to find them already sorted and space delimited.

I could do more letters if I wanted to, but I figured 10 letters should provide about 300-400 words, and there was no way in hell someone is gonna be able to find all of those.

"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997-----"...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001

You saved me the trouble man. My kid brother was about to have one written for him by yours truly to help him improve his spelling.

I'll have fun with this one I can tell you that

"Every time Lotus Notes starts up, somewhere a puppy, a kitten, a lamb, and a baby seal are killed. Lotus Notes is a conspiracy by the forces of Satan to drive us over the brink into madness. The CRC-32 for each file in the installation includes the numbers 666." Gary Wheeler

"The secret to a long and healthy life is simple. Don't get ill and don't die." Pete O'Hanlon, courtesy of Rama

"I realised that all of my best anecdotes started with "So there we were, pissed". Pete O'Hanlon

It really isn't that fancy. In fact, I think labeling "intermediate" may be a bit over the top. The code is fully commented, and like I stated in the article, this is not a complex program and doesn't really demonstrate anything of interest regarding the .Net framework.

I may add network play and the historical tracking stuff in the future. (Of course, I might not, too. )

"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997-----"...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001