http://www.developer.com/ws/proto/article.php/1472181/Interactive-Fun-and-Games-with-WAP-and-WML.htm
This series of articles describes how to provide Webcontent to mobile devices through WML (Wireless Markup Language). This articlecovers creating an interactive game for deployment on mobile WML devices. Note: These articles cover WML and WMLScript version 1.1,which are supported by the majority of mobile devices in use today. Thearticles assume a working knowledge of HTML and general Web technologies, andfurther assume that you have read the previous article(s) in this series. Mobile devices are the most useful when they are connected to data sources and have the ability to deliver various data whenever needed. However, mobile devices are also very useful for entertainment purposes-I've spent many hours in airports with only my PDA and phone for company. Although WML doesn't lend itself to a complex gaming experience, it is fairly easy to create interactive entertainment. In this article I will lead you through the steps to create a rudimentary "hangman" game. Hangman is a straightforward game. For anyone unfamiliarwith the game, a word is shown as blanks and the player guesses letters thatmay be in the word. If a letter guessed is in the word, all instances of that letterare revealed. If a guessed letter is not in the word, part of a hanging stickfigure is drawn on a scaffold, at the end of a nooseusually starting with thehead, then the body, then the limbs (one at a time). The game ends when theword is guessed or the figure is completely drawn. In the former case theplayer wins, in the latter the player loses. The functionality for our project is as simple as the pen-and-paper version of the game: Once the functionality has been determined, the interface must be drafted. This project will utilize WML for the input and output andWMLScript for the behind-the-scenes processing. Because debugging tools forWMLScript are limited, we will build this project in small stages, addingfeatures only after the current feature set is solid. To start, we will create a simple deck of two cards. Thefirst card will call a WMLScript function to initialize the game's variables.The second card will then be displayed, showing the word as blanks and as plaintext (for debugging purposes). Our skeletal code looks like this: The first design decision is how to store the word list.Because standard WML technologies do not provide a convenient link to theoutside world (databases, etc.), the list has to be stored internally, withinthe script itself. The lack of true arrays in WMLScript contributes to theproblem as well. However, WMLScript's string handling solves the problem wellenoughthe words will be stored in delimited form within one long string (WMLSline 3). The String.elementAt function could then be used to parse one of thewords from the list (WMLS line 8). Next the "blank" template must be constructed forthe word (lines 9-12). At this point, the variable $word will contain theactual word, while $blank contains the blank representation. The variables arepushed out to the browser and the next card is displayed, showing all thevalues. Note: Even this partof the script was developed in pieces, though for the sake of brevity in thisarticle I've chosen to start with this chunk of code. Initially, I created thestub WML code to call the init function, which simply set a variable. Then Icreated the word list and randomized a word, which was displayed by the WML.Finally, I created the blanking code to create the blank word. Tip: The Openwave SDK provides a great environment todevelop applications in a stairstep method. Visit the developer site at Next we need to add the player entry code and the ability tocheck the entry against the word. The new code resembles the followinglistings: The new code (mostly the guess function, WMLS lines 15-33)accepts user input (WML line 18) and compares it to the letters in the word. A"temporary" word is built, revealing each matching letter and leavingthe rest of the word as revealed or hidden as it was before the guess. Thetemporary variable ($temp) is then passed back to the browser as the new $blankvariable. The new code allows for input and displays debugging output.Note that "a" was guessed in the previous round, revealing the 3 As Figure 8.1 shows, we are quickly running out of screenreal estate for our game. Since we are using text to depict our hanging man, wewill need 4-6 more lines to display him - and we obviously do not have enoughlines. Time for an interface change. Instead of putting the input on the same page as the status,we will move it to a "guess" card. It means more work for the user(he or she must select a "guess" button to display the input), butcleans up our interface. For the hanging man, we will use the following ASCIIrepresentation: He is crude but recognizable. We can break the man down intosix pieces: the head, torso, two arms, and two legs. If we get creative andtreat each piece as a string, we can add appropriate line breaks and print eachstring in sequence, effectively "building" the man. Consider thefollowing: Head: "<space>0<linebreak>" Arm1: "-" Torso: "|" Arm2: "-<linebreak>" Leg1: "/" Leg2: "<space>\" When printed in sequence, the hanging man is displayed. Ifwe print only the first three strings, only three pieces of the man (head, arm,torso) are displayed. Again, because WMLS lacks real arrays, we will build adelimited string that contains all the pieces: " , 0\r,-,|,-\r,/,\\\r" Note that a comma is used as the delimiting character, andthat we put a blank piece (a space) in the beginning to give the first realpiece an index of 1 instead of 0. Alsonote that we use escape codes for line breaks (\r = newline) and we must escapethe backslash. Because WML doesn't parse variables, using WML code for linebreaks would only result in the tags (such as "<br />") beingdisplayed as text instead of being interpreted as line breaks. Although it seems like there is a lot left to do, theproject is mopped up pretty quickly by doing the following: Most of these tasks revolve around counting the number ofguesses. The last task is the usual housekeeping that takes place at the end ofa project. The final code looks like this: The starting screen of the game, complete with hangman'snoose. Pressing the Accept key brings up the guessing card. As the player progresses, correct guesses are shown byrevealing characters in the word; incorrect guesses add to the hanging man. If the player guesses six incorrect letters, the game ends.Guessing all characters in the word, conversely, shows a "win"screen. Note the "Restart" function mapped to Accept. There's always room for improvement, especially inprogramming and interfaces. Given time, I'd add the following to the game: I'd also lengthen the word list and dynamically change itfrom time to time. One idea would be to run a script on the server that swapsdifferent versions of the WMLS file into place, each with a different wordlist. Another idea is to implement the entire game using PHP or another, morerobust scripting language that could tie into a massive word database. I'm interested in hearing what you need/want to do with WML.I'll use some of the more challenging or common ideas in upcoming articles.Send your ideas to the address below. Steve Schafer is president and CEO of Progeny Linux Systems,a Linux-based consulting company in Indianapolis, Indiana. He has writtenseveral technical books and articles and can be reached at sschafer@synergy-tech.com. # # #
Interactive Fun and Games with WAP and WML
September 27, 2002
Uses for Mobile Devices
Project Specifications
Coding the Basics
WML
WMLS
WML
WMLS

Adding the Scoring (Hangman)
0-|-/ \
Finishing Up
WML
<?xml version="1.0"?><!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN""http://www.wapforum.org/DTD/wml_1.1.xml"><!-- hangman.wml - WML hangman game --><wml><!-- Game initialization - only calls init script --><card id="init" title="Hangman"><onevent type="onenterforward"><go href="hangman.wmls#init()"/></onevent><p>Initializing...</p></card><!-- Status card. Shows hanged man and revealed word --><!-- User presses Accept key to make a guess --><card id="status" title="Hangman"><do type="accept" label="Guess"><go href="#guess" /></do> <p> |<br/>$man<br/><br/>$blank</p></card><!-- Accepts user's guess (one character, lowercase) --><card id="guess" title="Hangman"><do type="accept"><go href="hangman.wmls#guess()" /></do> <p> $blank<br/> Guess: <input name="guess" maxlength="1" format="a" /> </p> </card> <!-- Game over, player has been hanged. --> <card id="hung" title="Hangman"> <do type="accept" label="Restart"> <go href="#init" /> </do> <p> You've been hanged!<br/><br/> Word was:<br/> $word<br/> Your guess:<br/> $blank </p> </card> <!-- Game over, player wins..--> <card id="win" title="Hangman"> <do type="accept" label="Restart"> <go href="#init" /> </do> <p> You win!<br/><br/> Word was:<br/> $word<br/> </p> </card> </wml>
WMLS
// hangman.wmls // Functions for hangman game // Variables: // word = word to be guessed// blank = blank representation of 'word', letters// begin as asterisks ("*") and are revealed as guessed// hang = current count of incorrect guesses// man = current ASCII representation of hanging man// guess = current character guessed// Initialize gameextern function init() { // Init vars. Change words every so often (or add to them) var words = "animal announce banana doctor elephant giraffe"; var idx,x,hang = 0; var blank,word,man = ""; // Pick a random word from list idx = Lang.random(6); word = String.elementAt(words,idx," "); // Build a blank string (letters all "*") that // is the same length as our word for (x = 1; x <= String.length(word); x++ ) { blank = blank + "*"; } // Pass all values to browser WMLBrowser.setVar("word",word); WMLBrowser.setVar("blank",blank); WMLBrowser.setVar("hang",hang); WMLBrowser.setVar("man",man); // Display status card WMLBrowser.go("hangman.wml#status");}// Evaluate current guessextern function guess() {// Init varsvar x = 0;var temp = "";var correct = false;var man = "";// Pieces for the hanging man,comma delimitedvar manpieces = " , 0\r,-,|,-\r,/, \\\r";// Get current valuesvar word = WMLBrowser.getVar("word");var hang = WMLBrowser.getVar("hang");var blank = WMLBrowser.getVar("blank");var guess = WMLBrowser.getVar("guess");// Walk one character at a time through word// If guess = character, reveal character// If guess != character, keep current value// (revealed character or blank)// Also, set "correct" if at least one char foundfor (x = 0; x <= String.length(word); x++ ) { if ( String.subString(word,x,1) == guess ) { temp = temp + guess; correct = true; } else { temp = temp + String.subString(blank,x,1); }}// If letter wasn't found, add one to hanging counterif (! correct) { hang++; }// Build our hanging manif (hang > 0) { for (x = 1; x <= hang; x++ ) { man = man + String.elementAt(manpieces,x,","); }}// Blank the guess so <input> is blankguess = "";// Pass current values to browserWMLBrowser.setVar("blank",temp);WMLBrowser.setVar("guess",guess);WMLBrowser.setVar("hang",hang);WMLBrowser.setVar("man",man);// Determine whether player has won (no more// "*" in blank), has lost (6 pieces of man// displayed, or keep playing (else).if ( String.find(temp,"*") == -1 ) { WMLBrowser.go("hangman.wml#win");} else { if (hang >= 6) { WMLBrowser.go("hangman.wml#hung"); } else { WMLBrowser.go("hangman.wml#status"); }}}



Things to Add
What Do You Want from WML?
About the Author