Cowboy Programming

Game Development and General Hacking by the Old West

July 23rd, 2008

CheckWord Reviews

My Scrabble word checker “CheckWord” for the iPhone has got a surprisingly large number of reviews and comments for such a simple application. I think this is probably because it was a launch app, the the early adopters are just going through every single app they can get their hands on. Also early-adopters tend to be a bit nerdy, and hence more likely to play Scrabble.

Currently there are three video reviews, one of which is in Spanish, which almost makes me want to do a Spanish version of CheckWord.

And the Spanish one:

The third video review is on appstoreapps.com:
http://www.appstoreapps.com/2008/08/11/checkword/


There are also lots of web posts, most of which seem to be cut and paste from each other – probably mostly automatically in some kind of click mining operations.   I’ve tried to get the original sources below:

I make the top ten free utilities for the iPhone on this list, coming it at #8

http://www.extremetech.com/article2/0,2845,2325378,00.asp

Find out if a word is acceptable in games like Scrabble. CheckWord makes it fast and easy to find out if the word somebody is trying to use is real or if they made it all up. Don’t be cheated when playing Scrabble put CheckWord on your iPhone today.

http://www.appleiphoneschool.com/2008/07/14/checkword-10/

CheckWord is a simple application that allows you to check whether or not words are good or bad in games like Scrabble. I love the developer's description, "Quicker than using a dictionary, easier than using a computer." See, now that is why we love our iPhones! [...]This application is great for those of you who like to play Scrabble the correct way

http://macenstein.com/default/archives/1519

CheckWord is a Scrabble player's dream app

http://theapplife.com/2008/07/20/a-new-favorite-app-checkword-is-good/

A new favorite app. CHECKWORD is GOOD

http://inc.ongruo.us/2008/08/04/my-new-iphone-25-apps-in-10-days/

CheckWord (free): Very simple, very cool little app that simply tells you whether a word is good or bad in Scrabble. It uses the TWL (Tournament Word List) as opposed to the consumer dictionary, so “FUCK is GOOD”, which is just as it should be.

http://icali.tv/checkword-app-review

Overall, CheckWord is a valuable resource while playing games like Scrabble, whether you're on your iPhone/iPod Touch, or you're playing actual board games.

I also got some nice reviews on the App store, although several people there seemed to miss that point that this was a Scrabble word checker, and not a dictionary.

.

July 10th, 2008

CheckWord – My iPhone Scrabble word checker app

I’ve been working on a iPhone game (NineSpeed) on and off for a while – although recently it has been mostly off.  So when I got an email from Apple last Wednesday, telling me to submit my game by Monday to get in the app store for launch, then this spurred me into some kind of action.

Of course I was not going to finish the game by Monday, as I still had a load of UI stuff to do, and it was getting annoying, as I’d done everything in OpenGL up to that point, and starting to bolt on the necessary iPhone OS stuff (flipping views, saving states, entering text) was a bit intimidating.

So it struck me I could kill two birds with one stone – I could write a simple app for launch that would include all the UI elements I was lacking in NineSpeed.   I needed something simple that I could do in three days, but also something useful, so it would actually get published (although that did not turn out to be as big an issue as I thought it might).   And doing this would also let me go through the submission process, which might raise some issues in advance of me doing it for an app I hoped people would buy.

So I decided to do a Scrabble word checker.  It would just input a word and then tell you if it was good or bad to play in Scrabble.  There would also be an options screen where the user could change dictionaries.  The finshed app, “CheckWord” is now on the store:

http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=284938074&mt=8

STARTING FROM SCRATCH

iPhone development is done using two applications on the Mac:  XCode and Interface Builder.   These two apps are closely linked.   XCode lets you create, edit, build and test code.  Interface Builder lets you build pretty screens with buttons and suchlike, and link it up with the code you made in XCode.

XCode will make a basic iPhone application for you.  Simple choose “New Project”, and you get to pick from a few basic templates.  I chose “Utility Application”, which gives you two “views”, and a button that flips between them.

A “view”, as it turns out, is nothing complicated.  It’s just a region of a window.  A window is just the entire iPhone screen – they are resizable on the Mac, but on the iPhone you can only rotate them.  It’s perhaps a little confusing.

First confusion is that there are actually three views:  Root, Main and Flipside.  There are also three “Root Controllers”, which are objects that control the views.  The template sets all these up so that it displays the main view with the root view overlaid on top of it, and you can press a button to flip to the flipside view.  So in theory all I had to do was add a text entry field and some text display fields to the main view, and hook them together with some code, and then add some options on the flipside screen.

FIDDLY

So that’s what I did.  It’s bit fiddly, and for reference I used the “Hello World” sample app that inputs some text and then displays it on screen.   So my app ended up being an amalgam of the two.  I started with “Utility Application”, and then pasted in bits of “Hello World”

That worked reasonably well for the code, but of the Interface Builder (IB) stuff, I had to go in and visually check each element to see how it was connected.    The connections between IB and the code are pretty simple.  There’s an IBOutlet, which is just a data field that refers to the button or label, or whatever. Then there’s an IBAction, which is a function you define that is called when some event occurs on an IB object.

To actually hook these up, you just define them in the code, then IB will detect them, and when you right click on the appropiate object you get a list of outlets and actions and can drag them to the required place.

It’s not quite that simple though, and for a first-timer like myself, it can be rather confusing.  You’ve got all your object, but you also have these other objects:  the “File’s owner”, the “First Responder” and sometimes the “App Delegate”.  The “File’s Owner” you have to hook up to the class of the correct object in your code.  If this object is an UIApplication, then there’s a ‘delegate’ outlet, which you set to the App Delegate object, which is set to the class of that object.   Then either the File’s Owner or its delegate will have the outlets, and the “First Reponder” will have the actions.

If that’s hard to understand, it’s because I don’t fully understand it, and so I can’t explain it very well.  I’m still at a relativly early stage of learning this particular model of programming, and it will take a while before I get the nuances.

ACTUAL CODE

So all that’s just setting up connections between IB and the code.  What about actual code for chcking words?  Well, it turns out that that’s the easiest code to write.  Not because it’s any simpler, but because I know EXACTLY what the code is doing, since it’s just some raw C++ whizzing though arrays of bytes and doing some comparisons, simple stuff like:

bool CWordList::IsValid(const char *p_word)
{
	if (strlen(p_word) <= 1)
		return false;
	for (int i=0;i < m_words;i++)
	{
		if (strcasecmp(p_word, mp_words[i]) == 0)
			return true;
	}
	return false;
}

Nothing complicated there, just some nice simple cowboy code :)

SUBMITTING

The process of submitting the app to the app store was actually fairly painless in comparison with some things I’ve had to do in the past.  There were lots of instructions, and while there were a few problems, if you simply follow the instructions, all will be well.  The one problem I had was that at some stage the distribution build had to actually be built before some signing thing could be changed, and then it had to be built again.

I packed it up, uploaded it with some screenshots, and a few hours later it was approved.  Nice.

Anyway, in closing, here’s a list of the various discreet things I learned how to do, mostly for my own reference.

LOAD A BINARY FILE

Add the binary file to your “Resources” in xcode so it goes into the “bundle”.  Then code to load “TWL06.txt” into some C++ style allocated memory is:

				NSString *filePath = [[NSBundle mainBundle] pathForResource:@"TWL06" ofType:@"txt"];
				NSData *fileContents = [NSData dataWithContentsOfFile:filePath];
				int len = fileContents.length;
				char *p_data = new char[len];
				[fileContents getBytes:p_data];

TEXT INPUT

Create a UITextField object in IB, and one one the view controller’s interface, which you have to also decorate with UITextFieldDelegate, like:

@interface MyViewController : UIViewController  {
	IBOutlet UITextField *textField;
...
@property (nonatomic, retain) UITextField *textField;

You then override textFieldShouldReturn to call resignFirstResponder and return YES if you want the keyboard to go away after text entry. In my case I wanted to it stay, and I also check the word as soon as the text is entered, so I have:

- (BOOL)textFieldShouldReturn:(UITextField *)theTextField {
	if (theTextField == textField) {
		//[textField resignFirstResponder];
		[self checkWord:nil];
	}
	return NO;
}

SAVING STATE

NSUserDefaults is what you want, it stores a dictionary of objects. In applicationDidFinishLaunching, you check for the existence of it, and create a default if needed:

NSString *kDictionaryIndexKey = @"dictionaryIndexKey";
NSString *kAcceptableSwitchKey = @"acceptableSwitchKey";
NSString *kNameKey = @"nameKey";
...
	NSString *testValue = [[NSUserDefaults standardUserDefaults] stringForKey:kNameKey];
	if (testValue == nil)
	{
		printf("Dictionary Index key not found, creating default defaults\n");
		// since no default values have been set (i.e. no preferences file created), create it here
		NSString *name = @"CheckWord";
		NSDictionary *appDefaults =  [NSDictionary dictionaryWithObjectsAndKeys:
									  name,kNameKey,
									  [NSNumber numberWithInt:0], kAcceptableSwitchKey,
									  [NSNumber numberWithInt:0], kDictionaryIndexKey,
									  nil];

		[[NSUserDefaults standardUserDefaults] registerDefaults:appDefaults];
		[[NSUserDefaults standardUserDefaults] synchronize];
	}

Then you read them like this:

	[acceptableSwitch setOn:[[NSUserDefaults standardUserDefaults] integerForKey:kAcceptableSwitchKey]];
	dictionary.selectedSegmentIndex = [[NSUserDefaults standardUserDefaults] integerForKey:kDictionaryIndexKey];

(That reading the options to set the switch the the multi-segment button used in the options screen)

And write them like this:

- (IBAction) changeDictionary:(id)sender
{
	dictionaryIndex = dictionary.selectedSegmentIndex;
    [[NSUserDefaults standardUserDefaults] setInteger:dictionaryIndex forKey:kDictionaryIndexKey];
}

That’s an Action that takes the dictionaryIndex from the multi-segment button, and stores it in the user defaults.

That’s it, the options will be saved, and persist between sessions, and power-downs.

FLIPPING THE SCREEN

Just use the “Utility” template code.

MAKING THE ‘i’ LESS FIDDLY

This was an annoying one. The ‘i’ button in the sample worked fine in the simulator, but on the actual iPhone, it was very fiddly, and often seemed not to work for some reason. To fix this, I made a custom button, and used a screen-grabbed image of the ‘i’ instead. I made this 44×44 pixels with a lot of transparency (although I think you can just re-size any custom button, regardless of the bitmap). This improved things a lot.

July 6th, 2008

CheckWord

UPDATE Nov 24th 2010: Checkword 1.4 is in now the Apple approval queue, and will fix the problem with no keyboard, as well as adding a “Words With Friends” specific word list, and using less memory thanks to better list compression. Hopefully should be getting out in a few days. Sorry I did not test it before iOS4.2 was released. My bad!

CheckWord is an iPhone/iPod Touch application that checks if a word is good or bad in games like Scrabble. Quicker than using a dictionary, easier than using a computer. Ideal for for both casual and tournament use. Now with an added word generator and wild-card pattern matcher.

FEATURES:

- Uses the latest official TWL or SOWPODS word lists
- TWL 2006, with 178,691 words for North America
- SOWPODS 2006, with 267,751 words for international play
- No internet connection needed, so you can be in airplane mode
- Instant results, just type in the word and hit the search button
- Judge multiple words at once, according to tournament rules.
- Generate words from your letters and a board letters
- Solve crosswords by entering in the known letters
- Make anagrams, find words and make word lists with wildcard searches

CHECKWORD INSTRUCTIONS

The main purpose of CheckWord is to see if words are good or bad for play in Scrabble and other similar games. Because of this it does not include proper nouns (names and other words that are normally capitalized), such as “MICHAEL” or “ARIZONA”. However, some proper nouns have other uses, such as “HOLLY” (a tree), and “TEXAS” (a part of a steamboat), and so are included. I did not make the word lists, they are official lists created by various Scrabble associations.

To check a word, type it in and touch “Search”. You will be told if the word is “Good” or “Bad” to play in Scrabble.

To clear the display, just touch “Search” again.

In the options, you can select “Use ‘Acceptable’” to change the messages to “Acceptable” and “Unacceptable”, as this is the language used in official Scrabble tournaments.

If you enter multiple words from a single play, like “AT AA TAN”, then CheckWord will report GOOD or ACCEPTABLE only if all the words are correct. If one or more words are incorrect, then CheckWord will report BAD or UNACCEPTABLE. The incorrect word will not be highlighted, according to official Scrabble tournament rules.

MAKEWORD INSTRUCTIONS

To toggle to MakeWord, touch the “MakeWord” button in the top left. Use the same button to return to CheckWord. In both CheckWord and MakeWord you can press the ‘i’ in the top right to go to the options and info screen.

You can enter the “Letters” in your rack and/or a “Pattern” to fit those letters to. Use the ‘.’ for a blank tile or empty space, and use ‘@’ to represent an unknown number of letters in the pattern (see below for examples).

Letters Only:
If you only enter Letters, then MakeWord will make all the possible words it can make with those letters (and blanks, if you enter any). Longest words will be shown first, including any full-length anagrams.

Letters Only Examples:
RETAINS = All words you can make with the letters of RETAINS (there are 262 in TWL, 343 in SOWPODS)
RETAI.. = All the words you can make with RETAI and two blanks
… = All the three and two letter words

Pattern Only:
If you only enter a pattern, then MakeWord will assume you have enough blanks to make any word that fits that pattern. You would use this to find words that fit a particular pattern of letters, such as in a crossword. You can also make quick word lists for practice. It’s very powerful, but easy to do the simple stuff.

Pattern Examples:
.. = All the two letter words
… = All the three letter words
P..TZ.L = Word with some letters missing (PRETZEL)
THW@ = All words starting with THW
@PS = All words ending in PS
@THP@ = All words that contain THP
THP = Shortcut for @THP@
@.THP.@ = All words that contain THP, but do not start or end with it
PR@NT = All words that start with PR and end with NT
PR…NT = All seven letter words that start with PR and end with NT
JO.. = All four letter words that starts with JO

Letters and Pattern:
If you both letters and pattern, then MakeWord will generate words that fit the pattern using just the letters and blanks you specify. You would use this to fit your rack to a specific place on the board, or to generate more specific word lists.

Letters and Pattern Examples:
RETAINS + @AB@ = All words fitting some letters from RETAINS before, after or around AB
RETAINS + AB = Shortcut for the above
RETAINS + @AB = All words fitting letters from RETAINS before AB
RETAINS + AB@ = All words fitting RETAINS after AB
RETAINS + @.AB.@ = All words fitting RETAINS around AB
RETAINS + …. = All four letter words made from RETAINS
Q… + …. = All four letter words containing a Q (A ‘Q’ with three blanks, fitted into four spaces)
AAA.. + ….. = Five letter words with 3 ‘A’s
NOOMTRS + A…….Y = A nine letter word with your rack between A and Y (ASTRONOMY)
A… + G…. = A five letter word starting with G that contains an A

If you have any problems with CheckWord, then post a comment here, or email me at: mick@cowboyprogramming.com

If you have a problem or suggestion, then a great way to letting me know what the issue is is to take a screenshot by pressing the home and power buttons together. The screen will flash white, and a screenshot will be saved in your photo roll. Then email it to me at:
mick@cowboyprogramming.com with a note explaining the problem/suggestion.

Possible future features:

  • French, Spanish and other language support.

I’m interested in supporting other language, but I need to find appropriate word lists, and possibly some help translating “Enter word(s), good/bad, acceptable/unacceptable”.  Let me know if you can help.

FAQ:

Q: How do I clear the display?
A: Just press search again.

Q: How do I restrict the length of words in MakeWords?
Enter a patter with the same number of dots as the length of word you want.  Add a ‘@’ to make that the minimum length.

|