This example shows how to create a wordsearch game board using JavaScript, HTML, and CSS.
This particular method doesn't attempt to populate a predetermined word list after creating the board, which leaves an interesting
possibility--to discover whether an algorithm populating squares with random letters can unintentionally encode words into the game board.
And if so, how complicated the words can be.
Let's quickly examine what needs to happen for us to achieve our objective here.
A word search board is a matrix of squares "x" columns wide by "y" rows tall.
Inside of each square appears a letter of the alphabet.
When examined carefully, words can be found by examining letters in adjacent squares to see if they can be used to string something together.
This example will differ in that no specific words will be intentionally included--instead leaving the possibility that the algorithm used to
select letters at random may unintentionally create words. A more interesting wrinkle still is--how complicated of a word can be created through this random technique?
We want the board to be visually appealing enough that someone can examine it at length for patterns, as result we'll want there to be something visually appealing.
Because visually appealing is so subjective, we'll hope that our use of fonts, colors, and spacing will appeal. In order to accommodate changing the visual aspects
without requiring modifications to the underlying logic building the board, we'll use CSS classes in order to apply the rules for the presentation aspects.
Breaking this further into a specific series of steps here's what we'll need to do:
Determine x and y. How wide and tall do we want the table?
Create a matrix x wide by y tall.
Inside of each square we'll want to place a random letter.
Once the board is rendered, we'll want a user interacting with it to be able to see where their interaction will affect the board.
Let's address each section and decide how we'll accomplish that step.
"Determine x and y". Let's start with a default x and y, we'll say "10" by "10".
We'll also explore allowing a user to request a specific number for x and y and use them
to regenerate a board using them. To allow users to provide a value, we'll want to include form inputs
which are one means HTML provides for soliciting feedback.
"Create a matrix x wide by y tall." The HTML table structure provides an excellent way to create the two-dimensional structure we want for our board.
Rather than statically hand-coding a table structure, let's use JavaScript to govern the logic the will allow us not only to dynamically create the structure
but also provide a means of getting random letters to populate the table with.
"Inside of each square we'll want to place a random letter." As described above, we can use JavaScript to create a function we can call over and over again as many
times as we need in order to get a random letter for each square. To make this easier, we'll handle building the board and populating a letter in a single pass.
"Once the board is rendered, we'll want a user interacting with it to be able to see where their interaction will affect the board."
We'll accomplish this by attaching "event listeners" which can detect when the a user's mouse drives over a square, and when the mouse is clicked on a square.
We'll differentiate the mouseover and click events using color changes and perhaps a font change.
Functional Example
Code Sample
Code Process Review
Here's what's happening... line by line.
We're defining the CSS classes we'll use for the various relevant elements of the board. While technically the <STYLE> section is supposed to go in the <HEAD> section of an HTML document, thankfully (for our teaching example here) it still works where it's at in the <BODY>.
Then we're adding a <DIV> container that we'll use to build the game board inside of. Note: this is more commonly done using a "document.write()" method call, but by creating a place holder as we've done here it can give the design oriented a better sense of the layout of the page w/o having to see the variability of the game board itself--the design of which can be a tedious iterative process all by itself.
Did you notice that the DIV is not empty? Well, if you view the source code it actually is empty. What you are seeing in the example is the actual code that we're adding dynamically here. (Just an interesting aside.)
We've added a form button here as well to allow the user to reset the game board on command. And note, here's another reason why using a placeholder can be useful; we're able to rebuild the board inside of the container without requiring the page to be reloaded. If you're getting paid for banner impressions, that's not so great...but if you are a user, that's much better because it's faster than reloading a page even over a fast connection!
Then we're defining the JavaScript functions that will do the operations we'll need to perform in order to create the board and process user interactions.
We're defining a function to get a random letter, and return it. It uses a very simple technique:
Defined the character set (the letters we're going to allow to be a part of our board). Hey, want to freakout your friends? ...remove the letter "E", it's for fun!
Choose a random number between 0 and the number of characters in our character set. (A nice dynamic trick...it doesn't need to be changed if you add or remove characters from the set.)
Finally, using the random number as a position in the string, return the character at that position to the code that called the random letter function.
Then we're defining the functions that will handle the mouse events. Over, Out, and Click.
The handle mouse over function first examines the CSS class of the caller (determined by passing the magic word "this" in the function call we'll examine later) by using a simple regular expression. While regular expressions can be maddeningly complicated, this simple example shows the basic use of the match() method. If you look at the CSS class names we defined earlier, you'll notice one of them contains the text "clicked". When match(/clicked/) finds the letter pattern "clicked" in the class name of the calling object, it returns true; which results in us running the "return" statement immediately following the if() check containing the match() call. This means we don't bother running anything else in the function--we just bail out and return control to whoever called this function. Clear as mud? It'll become more so as you practice. If the class did not contain the text pattern "clicked", then the JavaScript engine continues on to the next statement in the function...
If the calling object hasn't had a property by the name of "orgClassName" then we create one and assign the current value of className to it. Note: orgClassName (in my mind) is hungarian-notation-like for "original class name". So literally the line reads "if there's -not- (!) a property of the passed object named orgClassName, create it and assign it the value of the passed object's className property.
Now that we've recorded the original state of the calling property (which we can use on return trips to this function, or in other functions passed the same object) we'll assign the className property with the CSS class we defined for displaying the moused over state of the letter container.
Notice that the mouseout and clicked functions utilize very similar logic. Basically, once a letter container has been clicked, the mouseover and mouseout functions will ignore requests, and just leave the clicked state showing the clicked CSS class we defined. By setting the orgClassName, we're able to toggle back and forth when a user mouses over and off of a letter container that hasn't yet been clicked.
Next the meat: The game board itself.
First we create a string aptly named "html" which will contain...surprise, HTML that we're building up.
Then we create a looping structure using the for() JavaScript loop command. This "i" loop will handle the rows of the table. It will produce "y" rows in our table. If you examine the first line of the createBoard function you'll notice that the value of "y" comes from the second parameter that's passed to createBoard when it's called (further down in the example in another function).
Notice that each time the "i" loop iterates, we add in <TR> table row HTML.
Then we create another loop using another arbitrary variable named "j" (the proverbial counterpart to "i" since it comes next in the english alphabet...there's really no other significance to it...it could be any letter you want). The "j" loop is used to create "x" columns to augment the rows we're creating and complete the... er, "rix" in our "matrix". Like "y", you'll notice the value of "x" comes in the first argument passed to the createBoard function.
Each time the "j" loop iterates, we add another <TD> table cell, and some event handlers for ommouseover, onmouseout, and onclick. Notice that inside of the event handlers, we're passing the magic word "this" which is a reference to the calling object (in this case the "TD"). As you learn more and more about object oriented programming, the "this" keyword will likely become one of your favorite tricks.
We also make a call to the getRandomLetter() function described earlier, and we add the value that call returns to the HTML string we're building up.
Finally, as the "j", and "i" loops complete, we append an appropriate HTML closing tag for their row or column, and then when both are finished iterating, we close up the TABLE.
The function then returns the string of HTML we've created, back to whoever called the createBoard function. (Note: at this point, the board has not been drawn on the screen...that comes later.)
Finally, I enclosed the createBoard caller into a function I named main() (harkening back to my C programming language days...though to JavaScript the function name "main" bears no importance...it's just another name that needs to be unique to distinguish itself from other functions. My main() function creates a reference to the <DIV> container with the ID of "game" which we created earlier in this sequence. It then takes the returned HTML from the createBoard() function call and replaces the DIV's "innerHTML" (a special name for the HTML inside of an HTML object...in this case the specific object "obj" points at) with the returned HTML containing the wordsearch board.