Welcome to the eleventh entry in the Intermediate ColdFusion Contest. (Only one more to go after this!) The earlier entries may be found at the end of this post. Today's entry is from Tony Weeg. Before reading on, please check his application here. You can download his code from the download link at the bottom. Please respect the copyright of the creator.

So far - this is my favorite design - although it gets points off for the buttons being a bit confusing. I had to ask Tony what the ^ button did. (It increases your bet by whatever button you had hit last.) Outside of that - I love the look of this entry. Now - in previous entries I spoke about how you can't trust JavaScript. I quickly found two ways to break this application. First - the bet is a read only form field. However, the Web Developer extension for Firefox let's me turn that setting off. Remember when I said to not trust JavaScript? You can't trust read only form fields either. When I changed the value to a string, the application immediately threw an error. Oh - and guess what happens if you enter a negative number? I entered -99999999. I then made myself lose by hitting too much. Then my bank was nice and rich.

The second way to break the application was in the initial screen. When it asks for the amount of money to start with, you can enter a string, and the application correctly ignores it. (Although it should probably tell you instead.) However - you are allowed to enter both 0 and a negative number. The game doesn't crash though - it just asks for more money. (Hey, just like a real casino!)

Ok, so let's dig into the code. Like an earlier entry, he resets his application variables on every hit. Not every variable, but still, none should be reset once set. He also creates card data from XML, which he does using cfsavecontent. He could have used cfxml as well. I normally would have placed the XML outside Application.cfm. But that's just a personal preference. His XML does seem a bit unnecessary though. Let me stop talking about it and show it for those who can't download the code:

<cfsavecontent variable="application.cardsXML"><?xml version='1.0' encoding='ISO-8859-1' ?><cards> <Clubs> <Ace>1</Ace> <King>5</King> <Queen>9</Queen> <Jack>13</Jack> <Ten>17</Ten> <Nine>21</Nine> <Eight>25</Eight> <Seven>29</Seven> <Six>33</Six> <Five>37</Five> <Four>41</Four> <Three>45</Three> <Two>49</Two> </Clubs> <Spades> <Ace>2</Ace> <King>6</King> <Queen>10</Queen> <Jack>14</Jack> <Ten>18</Ten> <Nine>22</Nine> <Eight>26</Eight> <Seven>30</Seven> <Six>34</Six> <Five>38</Five> <Four>42</Four> <Three>46</Three> <Two>50</Two> </Spades> <Hearts> <Ace>3</Ace> <King>7</King> <Queen>11</Queen> <Jack>15</Jack> <Ten>19</Ten> <Nine>23</Nine> <Eight>27</Eight> <Seven>31</Seven> <Six>35</Six> <Five>39</Five> <Four>43</Four> <Three>47</Three> <Two>51</Two> </Hearts> <Diamonds> <Ace>4</Ace> <King>8</King> <Queen>12</Queen> <Jack>16</Jack> <Ten>20</Ten> <Nine>24</Nine> <Eight>28</Eight> <Seven>32</Seven> <Six>36</Six> <Five>40</Five> <Four>44</Four> <Three>48</Three> <Two>52</Two> </Diamonds> </cards></cfsavecontent>

Looking at this I can't help but wonder if a simple loop could have worked as well. One loop over the suits and one over the string names of the cards. I'm not saying this is bad - I'm just saying there are many ways to skin the cat.

Something else I noticed - in fullTilt.cfm he has this code block:

<cfif isDefined("url.clearStartOver") and len(url.clearStartOver)> <cfset structDelete(session,"player")> <cfset structDelete(session,"dealer")> <cfset structDelete(session,"yourName")> <cfset structDelete(session,"lastBetValue")> <cfset structDelete(session,"gameInProgress")> <cfset structDelete(session,"winnerDisplay")> <cfset structDelete(session,"youAlreadyWon")> <cfset structDelete(session,"bankValue")> <cfset structDelete(session,"bankValueForDisplay")> <cfset structDelete(session,"gameOver")> <cflocation url="fullTilt.cfm?step=welcomeToTheTable"> </cfif>

<cfif isDefined("url.makeDeposit") and len(url.makeDeposit)> <cfset structDelete(session,"player")> <cfset structDelete(session,"dealer")> <cfset structDelete(session,"lastBetValue")> <cfset structDelete(session,"gameInProgress")> <cfset structDelete(session,"winnerDisplay")> <cfset structDelete(session,"youAlreadyWon")> <cfset structDelete(session,"bankValue")> <cfset structDelete(session,"bankValueForDisplay")> <cfset structDelete(session,"gameOver")> <cflocation url="fullTilt.cfm?step=makeDeposit"> </cfif>

I would have considered putting the game data in a sub-struct of the Session scope. That way you could nuke the entire game with one structDelete. Or I'd consider making a UDF that does the same as the lines above. That way if you add a new key, you can just update the UDF. (Yes, you can make UDFs that work with the session scope. Normally it is a no-no, but for a utility function like this, I think it would be fine.) Ah - I just reread the code and each block is doing something different. I would still recommend though a more modular approach - again - in case your game data keys change.

Let's turn to his CFC. As you know, I'm going to complain about the lack of var scoping. Sorry Tony. :) Something else I don't agree with - he loads a file of UDFs into his CFC. Not the end of the world, of course, but if I need to use UDFs like that in a CFC, I typically turn them into a CFC.

What does everyone else think?

Earlier Entries:

Download attached file.