Today we are going to look at the second contest entry. What is interesting about this one is that it takes the opposite approach from the first entry. In the first entry, the user had to guess the right number. In this entry, the computer has to guess it. This is what I had originally wanted, but to be honest, either way is fine, so I have no problem with the first entry's approach.

The second entry can be viewed here. Please go take a look at it before reading on. Now that you have looked at it, here is the code.

<!--Set Default Values --> <cfparam name="numhigh" default="100"> <cfparam name="numlow" default="1"> <cfparam name="numcurrent" default="0"> <cfparam name="guess" default="">

<!--- Set Try Counter ---> <cfparam name="counter" default="-1"> <cfset counter=counter + 1>

<!-- If guess is HIGH --> <cfif guess is 'High'> <cfset numhigh=numcurrent> </cfif>

<!-- If guess is LOW --> <cfif guess is 'Low'> <cfset numlow=numcurrent> </cfif>

<!--- Generate random number between low and high set points ---> <cfset oldcurrent = numcurrent> <cfset numcurrent= RandRange(numlow, numhigh)> <cfloop condition="oldcurrent is numcurrent"> <cfset numcurrent= RandRange(numlow, numhigh)> </cfloop>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" ""> <html xmlns=""> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> <title>Number Guessing Game</title> <style type="text/css"> <!-- .style1 { color: #999999; font-family: Arial, Helvetica, sans-serif; font-size: 14px; font-weight: bold; text-decoration: none; } .style2 { color: #FF0000; font-weight: bold; text-decoration: none; } .textformat { font-family: Arial, Helvetica, sans-serif; font-size: 14px; text-decoration: none; } .start { font-family: Arial, Helvetica, sans-serif; font-size: 14px; font-weight: bold; color: #FF0000; } .guess { font-family: Arial, Helvetica, sans-serif; font-size: 14px; font-weight: bold; color: #0000FF; text-decoration: none; } .title { font-family: Arial, Helvetica, sans-serif; font-size: 18px; font-weight: normal; color: #000099; text-decoration: none; } .newgame { font-family: Arial, Helvetica, sans-serif; font-size: 10px; color: #000099; } --> </style> </head> <body> <table width="100%" border="0" class="textformat"> <tr> <td align="center"><!--Title area --> <span class="title">Number guessing game</span> </td> </tr> <tr> <td align="center"><!--Title area --> <p> </td> </tr> <tr> <td><!--Data Area -->

<cfif guess is ''> <table width="100%" border="0" class="textformat"> <tr> <td align="center">Welcome to the number guessing game. Please select a number between 1 and 100. Once you have your number selected, please click Start.</td> </tr> <tr> <td align="center"><a href="index.cfm?guess=new" class="start">Start</a></td> </tr> </table>


<cfif guess is 'correct'> <table width="100%" border="0" class="textformat"> <tr> <td align="center">I guessed your number within <cfoutput>#counter#</cfoutput> tries.</td> </tr> <tr> <td align="center"><a href="index.cfm?guess=new" class="start">Play Again</a></td> </tr> </table>


<cfif numcurrent gte 0>

<table width="100%" border="0" cellpadding="0" cellspacing="0" class="textformat"> <tr> <td colspan="100" align="center"> <cfoutput> My current guess is the number is <span class="style2">#numcurrent#</span> <p> Is this number <cfif numcurrent is numhigh> <span class="style1"> Low</span> <cfelse> <a href="index.cfm?numcurrent=#numcurrent#&numhigh=#numhigh#&numlow=#numlow#&guess=low&counter=#counter#" class="guess">Low</a> </cfif> : <a href="index.cfm?numcurrent=#numcurrent#&numhigh=#numhigh#&numlow=#numlow#&guess=correct&counter=#counter#" class="guess">Correct</a> : <cfif numcurrent is numlow> <span class="style1"> High</span> <cfelse> <a href="index.cfm?numcurrent=#numcurrent#&numhigh=#numhigh#&numlow=#numlow#&guess=high&counter=#counter#" class="guess">High</a> </cfif> </cfoutput> </td> </tr> <tr> <td colspan="100" align="center"><hr /></td> </tr> <tr> <td colspan="100" align="center">Current guess range</td> </tr> <tr> <td colspan="100" align="center"> </td> </tr> <tr> <cfloop from="1" to="100" index="numtest" step="1"> <cfif numtest gte numlow and numtest lte numhigh> <td width="1%" bgcolor="#00FF00"> </td> <cfelse> <td width="1%" bgcolor="#FF0000"> </td> </cfif>

</cfloop> </tr> <cfoutput> <cfset colspannum=100 - numlow>
<tr> <td colspan="#numlow#" align="right">#numlow#</td>

<td colspan="#colspannum#"></td> </tr> <cfset colspannum=100 - numhigh> <tr> <td colspan="#numhigh#" align="right">#numhigh#</td> <td colspan="#colspannum#"></td> </tr> <tr> <td align="center" class="newgame" colspan="100"></td> </tr> <tr> <td align="center" class="newgame" colspan="100"><a href="index.cfm?guess=new" class="newgame">Start new game</a></td> </tr> <!--- <tr> <td colspan="100" align="center">Low:#numlow# <br /> High: #numhigh# <br /> Current: #numcurrent# <br /> Counter: #counter#</td> </tr>---> </cfoutput> </table>

</cfif> </cfif> </cfif>

</td> </tr>

</table> </body> </html> </span>

So - let's talk about it. The first thing that struct me was the graphical representation of the guesses. I love this. I wasn't concerned about the design of these entries (I'm an 'advanced' programmer but can't design my way out of a paper bag), but this is a simple little thing that I thought was just plain cool. You can actually see the computer narrowing down it's choices. Nice.

Now it's time to get nasty. Like the first entry, this entry does not make use of RAM based variables in order to store information. All information is passed via URL parameters. One problem I have with the code is that he does not use the URL scope. This isn't a bug per se, but it is generally accepted as best practice to specify the scope. (Note my comments from the first entry.) The fact that he uses URL variables also makes them easy to change. One of the first things I did was change a URL variable, numhigh, to an invalid value ("apple"), and the application broke. This is a typical mistake for beginner programmers, and is something I covered in my Macrochat. You must perform validation before working with any variables from an outside source. In this case, he could have used isNumeric, and then check for integer (don't forget that 3.14159 is a number), and lastly check to ensure it was between one and a hundred. Similar validation must be added to all the URL variables he used. I was actually able to get the application to go into an infinite loop by playing with the URL values. (I modified the code on the live version so this wouldn't happen - hopefully.) This is one more reason why using the full scope would help. It gives you a visual cue that the variable is a URL value and cannot be trusted.

One thing I liked about his entry was how he guessed a new number. This is not the best way. The best way, as far as I know, is to make guesses exactly in the middle. I.e., first guess 50, and if too low, then 75, etc. However, his randomized guess is more fun. One of the issues game designers run into is "dumbing down" the computer. If they didn't do this, the computer would either win every time, or perform the exact same actions every time. I don't know if this was the author's intention, but I'm going to assume it was.

In general, I don't have much else to say. I'm not happy with his formatting, but I've yet to find two developers who would actually agree on the same code formatting style (unless they have no choice). Does anyone else have a comment? (And remember, be nice!)