<cfapplication name="Guess" sessionManagement="yes">
Invite the user to play and hint at the rules. If the Answer to be guessed is not present in session memory - perhaps the session has timed out, or perhaps the user has just arrived - set a new random answer, set the number of tries to zero, and set the guess to "^^^^" so that the last correct guess (if any) won't confuse the situation. If the Answer is in memory, then increment the number of tries and copy the Answer to the request scope for later use. Of course, all access to session variables should be locked, and the code uses an exclusive lock here since we're writing to memory. By the way, documentation says to use the randomize statement first, but if your machine is like mine, this causes the same number to appear again and again. I leave the randomize statement out.
Iteratively guess a number from 1000 to 9999.<br> I'll tell you how many digits you have right. <p> <cfparam name="form.Guess" default=""> <cflock scope="session" timeout="30" type="exclusive"> <cfparam name="session.Answer" default=""> <cfif not len(trim(session.Answer))> I'm thinking of a new number for you to guess.<br> <cfset Answer=randRange(1000,9999)> <cfset session.Answer=Answer> <cfset request.Answer=Answer> <cfset session.Tries=0> <cfset request.Tries=0> <cfset form.Guess="^^^^"> <cfelse> <cfset session.Tries=session.Tries+1> <cfset request.Tries=session.Tries> <cfset request.Answer=session.Answer> </cfif> </cflock>
<cfif form.Guess is request.Answer>
You are right!
<cflock scope="session" timeout="30" type="exclusive">
<cfset session.Answer="">
</cflock>
<cfelse>
<cfif (form.Guess lt 1000) or (form.Guess gt 9999)>
<cfset form.Guess="^^^^">
</cfif>
Consider what it will take to make the remaining tests. It's easy to determine how to match the guess with the answer digit by digit, but how do you keep the correct digits from being considered when determining whether REMAINING digits have right values but are in the wrong position? The solution used here is to modify a temporary copy of the guess and answer so that the value of positions containing exact matches is replaced with something that can never be right. Wherever an exact match is found, the character at that position is replaced with an underscore in the temporary copy of both the guess and the answer. The number of Correct matches is recorded for later display.
Notice the syntax for replacing a character at a given position in a string. Insert the new character first. It will be inserted AFTER the specified position. Then use RemoveChars to remove the character at the specified position. This will shift the new character into the position you want.
<cfset GuessTemp=form.Guess>
<cfset AnswerTemp=request.Answer>
<cfset Correct=0>
<cfloop from="1" to="4" index="Position">
<cfif mid(form.Guess,Position,1) is mid(request.Answer,Position,1)>
<cfset Correct=Correct+1>
<cfset AnswerTemp=insert("_",AnswerTemp,Position)>
<cfset AnswerTemp=removeChars(AnswerTemp,Position,1)>
<cfset GuessTemp=insert("_",GuessTemp,Position)>
<cfset GuessTemp=removeChars(GuessTemp,Position,1)>
</cfif>
</cfloop>
Testing for the remaining digits uses the find command. For each position in the guess that is not an exact match to the answer - its value has not been replaced with an underscore - use find to look for the value in the copy of the answer whose correct positions have also been replaced with underscores so they won't be considered. Keep a count of the remaining positions that are Almost right: a value that's still needed but is not in the right position.
<cfset Almost=0>
<cfloop from="1" to="4" index="Position">
<cfif mid(GuessTemp,Position,1) is not "_">
<cfif find(mid(GuessTemp,Position,1),AnswerTemp)>
<cfset Almost=Almost+1>
</cfif>
</cfif>
</cfloop>
Now provide a scorecard. Tell the user the number of guesses thus far, the number of exact matches, and the number of right values in the wrong position. Close the cfif statement pertaining to evaluation.
Number of guesses used: <cfoutput>#request.Tries#</cfoutput><br> Number of right values in the right position: <cfoutput>#Correct#</cfoutput><br> Number of other right values in the wrong position: <cfoutput>#Almost#</cfoutput> </cfif>
<form method="post"> <input type="text" name="Guess" maxlength="4" size="5" value=<cfoutput>"#form.Guess#"</cfoutput>> <input type="submit" name="Task" value="Guess"> </form>
Browse guess.cfm; here are some hints. Work on getting all four values first, then worry about their positions. For maximum coverage for your first few guesses, don't set two different positions to the same number. Use your back button to see previous entries. (Your guess count is in session memory; it won't be fooled even if the display temporarily shows a previous guess count.) Once you get things narrowed down - you want the total of right values and the total of right values in the wrong position to equal four - then you can work on switching the values to different positions to find the answer. The only way to cheat is to change the code; because, the answer never reaches the browser. (If the code had used form or URL variables to carry the answer, cheating would have been trivial.) =Marty=