ColdFusion TIPS PLUS
Issue 00113 http://www.cftipsplus.com
I. My CommentsII. ColdFusion In Context: Logical Deduction
By R. Martin Ladner
martin.ladner@charter.net
Check out the NEW product by Macromedia!!
http://www.macromedia.com/software/contribute/I like this for some of my clients.
I. Comments:
Hope you had a Great Thanksgiving. The times may be bad and the times may be getting better. No matter I am glad to be a part of the ColdFusion Community. I am excited at what we provide the world. The web is not going away. I only hope to find better ways to contribute to those of us building websites and building our future. Keep your chins up and realize one way or the other we can make things look better.
If you have some side projects send them my way I am willing to do some small projects if you have a need. I am open to do code review or usability assessment.
Keep Coding,
Nathan Stanford
NathanS<at>nsnd.com
http://www.cftipsplus.com
II. ColdFusion in Context: Logical Deduction
By R. Martin Ladner
martin.ladner@charter.net
Suppose you want practice in working with individual positions within a string. This tip lets you do this while having fun at the same time by letting you build a guessing game that requires logic to play well.
Set Defaults
Put all code in guess.cfm. You'll need to define an application in memory to host this session. Once you ask for session management, defaults (such as automatic cookies) will do just fine for this task.
<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>
Check the User's Guess
The user gets three kinds of feedback: all correct, the number of digits having the right value in the right position, and the number of remaining digits that have the right values but are in the wrong place. If the user has guessed correctly, say so and remove the answer from memory so the next submission will return a new answer. If the user has guessed a number that's out of bounds, replace the guess with "^^^^" to encourage a 4-digit guess.
<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>
Display the Form and Enjoy the Result
The form is an anticlimax after the work done thus far. Leaving the action empty causes the form to be submitted to itself. Keep the user from entering more than four characters. Set the field size to 5 in case the user has somehow specified a large font. Display the previous guess.
<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=
SPONSOR ADS:
This e-mail is sponsored by the following ads.
Advanced, Intensive ColdFusion Training!Visit this site. If you have plans to get training here is a company
that provides Advanced, Intensive ColdFusion Training. Check them out.
http://www.coldfusiontraining.com/index.cfm?ref=cftipsplus
Publisher and Creator:
Nathan Stanford,
NathanS<at>nsnd.com
http://www.cftipsplus.com
Macromedia and ColdFusion are U.S. registered trademarks.
Copyright (c) 2000 - 2002
CFTIPSPLUS.COM and NSND.COM
Permission is granted to circulate this publication via
MANUAL forwarding by email to friends provided that the text is
forwarded in its entirety and no fee is charged.