addtextpasscodehint.html
1    <!DOCTYPE html> 
2    <html lang="en"> 
3    <head> 
4      <meta charset="UTF-8"> 
5      <meta name="viewport" content="width=device-width"> 
6      <title>The Room Adventure: Additional Features</title> 
7     
8      <link href="/index.css" rel="stylesheet" type="text/css"/> 
9      <link href="/roomadventure/rooms.css" rel="stylesheet" type="text/css"/> 
10     <link rel="shortcut icon" href="http://stephenjwolf.com/coding/favicon.ico" type="image/x-icon"/> 
11   </head> 
12   <body> 
13   <div id="body"><!-- Required div for navigation bar --> 
14     <div class="imgfloater max150px"><img src="/images/SergeiStudious.png"></div> 
15     <h1>The Room Adventure: Additional Features</h1> 
16    
17     <h2>Offering passcode hints</h2> 
18     <h4>Difficulty: &#9733;&#9733;&#9734;&#9734;&#9734;</h4> 
19     <h4><em>Requirement: Passcode Ending</em></h4> 
20    
21     <div class="flex-container"> 
22       <div> 
23         <!--Explanation--> 
24         <p>In the passcode ending, the player is shown their inventory on a popup and then it disappears before they enter 
25           the passcode. Remembering nine numbers in the right order can be a challenge. Scientifically speaking, we 
26           naturally can only remember seven digits in a short-term situation like that. That's why base phone numbers are 
27           seven digits long.</p> 
28    
29         <p>Let's give the player some help and show the password clues on the screen that asks for the password. Let's 
30           also let the player ask for a hint that clues them in as to how they're supposed to arrange the numbers. 
31    
32         <h2>What we need to do</h2> 
33         <ul> 
34           <li>Update the passcode alert to include the pieces of the passcode.</li> 
35           <li>Add a 'help' option to the passcode entry.</li> 
36           <li>Pick a hint from a list (or only have one).</li> 
37           <li>Charge some points for the hint (optional).</li> 
38         </ul> 
39       </div> 
40       <div class="imgwrapper"> 
41         <br> 
42         <!--Screenshot--> 
43         <img src="/roomadventure/screenimages/textpasscodehint02.png"></div> 
44     </div> 
45    
46    
47     <h2>Step 1</h2> 
48     <p>Right now inside of <span class="function">moveToRoom</span>, we do a quick job of asking for the passcode.</p> 
49    
50     <div class="code"> 
51       <ul> 
52    
53         <li><span class="keyword">else if</span> (direction === <span class="string">"exit"</span>)</li> 
54         <li>{ 
55           <ul> 
56             <li><span class="keyword">var</span> guessPasscode = <span class="function">prompt</span>(<span 
57                 class="string">"What's the passcode?"</span>); 
58             </li> 
59             <li><span class="keyword">if</span> (guessPasscode === <span class="object">passcode</span>.<span 
60                 class="property">exitCode</span>) 
61             </li> 
62           </ul> 
63         </li> 
64         <li><span class="comment">//rest of function</span></li> 
65       </ul> 
66     </div> 
67    
68     <p>When we created this, we kept it simple. But now that we're going to get more complex, let's create a new function 
69       to deal with our new update.</p> 
70    
71     <p>Let's create a function call here since we're already looking at this code. Inside <span 
72         class="function">moveToRoom</span>, change the <span class="keyword">var</span> line to this.</p> 
73    
74     <div class="code"> 
75       <ul> 
76         <li> 
77           <ul> 
78             <li><span class="keyword">var</span> guessPasscode = <span class="function">getPasscodeGuess</span>();</li> 
79           </ul> 
80         </li> 
81       </ul> 
82     </div> 
83    
84     <h2>Step 2</h2> 
85     <p>Let's get oriented before we create our function. It's important to remember what we already have in place and what 
86       we need to change.</p> 
87    
88     <p>There are a couple things the new function needs to do. We want it to show the passcode pieces the player has and 
89       we want to allow the player to guess a hint or the passcode. If we put this in <span 
90           class="function">moveToRoom</span>, it would really clutter up that function. We always want functions to be as 
91       small and as focused as possible.</p> 
92    
93     <p><strong>Remember: to create a new function, you want to be outside of any other functions. Find a place between two 
94       functions so you're not inside another function's set of braces.</strong></p> 
95    
96     <p>We're going to loop through the <span class="object">player</span>'s <span class="property">inventory</span> to 
97       find the passcode pieces the player picked up. When we originally created the <span class="object">passcode</span> 
98       object, we made a <span class="property">codes</span> property. We can use that to identify our passcode pieces, 
99       like we look for inventory items to fix things.</p> 
100   
101    <p>We have this line in <span class="function">getPasscode</span>. </p> 
102   
103   
104    <h2>Step 3</h2> 
105    <p>Let's start creating the function. We're going to build a text string to hold the passcode pieces. We will then 
106      loop through the player's inventory to see if they have any pieces. Ready? This kind of code should look 
107      familiar.</p> 
108   
109    <div class="code"> 
110      <ul> 
111        <li><span class="keyword">function</span> <span class="function">getPasscodeGuess</span>()</li> 
112        <li>{ 
113          <ul> 
114            <li><span class="keyword">var</span> passcodePieces = <span class="string">""</span>;</li> 
115            <li><span class="keyword">for</span> (<span class="keyword">var</span> i = 0; i < <span 
116                class="object">player</span>.<span 
117                class="property">inventory</span>.<span class="property">length</span>; i++) 
118            </li> 
119            <li>{ 
120              <ul> 
121                <li><span class="comment">//let's create a helper variable</span></li> 
122                <li><span class="keyword">var</span> item = <span class="object">player</span>.<span 
123                    class="property">inventory</span>[i]; 
124                </li> 
125                <li>&nbsp;</li> 
126                <li><span class="keyword">if</span> (<span class="object">passcode</span>.<span 
127                    class="property">codes</span>.<span class="function">indexOf</span>(item) !== -1) 
128                </li> 
129                <li>{ 
130                  <ul> 
131                    <li>passcodePieces += item + <span class="string">" "</span>;</li> 
132                  </ul> 
133                </li> 
134                <li>}</li> 
135              </ul> 
136            </li> 
137            <li>}</li> 
138          </ul> 
139        </li> 
140        <li>&nbsp;</li> 
141        <li><span class="comment">//there's more of this function to come shortly...</span></li> 
142      </ul> 
143    </div> 
144   
145   
146    <h2>Step 4</h2> 
147   
148    <div class="flex2"> 
149   
150   
151      <div> 
152        <p>If the player hasn't found any passcode pieces, let's say so. Otherwise, we'll show the passcode pieces. Let's 
153          add this.</p> 
154   
155        <div class="code"> 
156          <ul> 
157            <li> 
158              <ul> 
159                <li><span class="keyword">var</span> text = <span class="string">""</span>;</li> 
160                <li><span class="keyword">if</span> (passcodePieces === <span class="string">""</span>)</li> 
161                <li>{ 
162                  <ul> 
163                    <li>text += <span class="string">"You haven't found any passcode pieces yet. "</span>;</li> 
164                  </ul> 
165                </li> 
166                <li>}</li> 
167                <li><span class="keyword">else</span></li> 
168                <li>{ 
169                  <ul> 
170                    <li>text += <span class="string">"Passcode pieces you have found: "</span>;</li> 
171                    <li>text += passcodePieces;</li> 
172                  </ul> 
173                </li> 
174                <li>}</li> 
175              </ul> 
176            </li> 
177            <li>&nbsp;</li> 
178            <li><span class="comment">//there's more of this function to come shortly...</span></li> 
179          </ul> 
180        </div> 
181   
182      </div> 
183      <div class="max150px"> 
184        <figure><img src="/roomadventure/screenimages/textpasscodehint01.png" alt="No passcode pieces"> 
185          <figcaption>No passcode pieces</figcaption> 
186        </figure> 
187      </div> 
188   
189    </div> 
190   
191    <h2>Step 5</h2> 
192    <p>Let's finish building the text string we're going to display. I'm adding a small cost for the hint, but you don't 
193      have to. We'll add the value when we update the <span class="function">getPasscode</span> function, but we'll set up 
194      some of the code to handle it as we go.</p> 
195   
196    <div class="code"> 
197      <ul> 
198        <li> 
199          <ul> 
200            <li>text += <span class="string">"You can type 'hint' if you need one. "</span>;</li> 
201            <li><span class="keyword">if</span> (<span class="object">passcode</span>.<span 
202                class="property">hintCost</span>) 
203            </li> 
204            <li>{ 
205              <ul> 
206                <li> 
207                <li>text += <span class="string">"Taking a hint costs " + <span class="object">passcode</span>.<span 
208                    class="property">hintCost</span> + " points. "</span>; 
209                </li> 
210              </ul> 
211            </li> 
212            <li>}</li> 
213            <li>text += <span class="string">"Type in the passcode below. "</span>;</li> 
214          </ul> 
215        </li> 
216        <li>&nbsp;</li> 
217        <li><span class="comment">//there's more of this function to come shortly...</span></li> 
218      </ul> 
219    </div> 
220   
221    <h2>Step 6</h2> 
222    <p>Now we need to ask the player to either enter a passcode or ask for a hint. But if the player does ask for a hint, 
223      then we need to show one and then let them try to enter the passcode again. Does this sound familiar? We needed to 
224      do something similar when we created the <span class="function">getDirection</span> function.</p> 
225   
226    <p>We're going to need a <span class="keyword">while</span> loop. It's going to keep looping until the player types in 
227      something other than <span class="string">hint</span>. As with most programming, we have a couple of different 
228      options for handling this. We could use a <span class="keyword">do...while</span> loop, or we could use a <span 
229          class="keyword">while</span>(<span class="keyword">true</span>) loop. </p> 
230   
231    <p>Even though I usually avoid them, the <span class="keyword">while</span>(<span class="keyword">true</span>) saves 
232      us a little code here.</p> 
233   
234    <p>We're going to use a <em>not</em> check here because the function will immediately end if the player did not type 
235      <span class="string">hint</span>. We could use an <span class="keyword">else</span> statement after that, but we 
236      won't actually need one, because the only reason the loop and function would continue is because the player did type 
237      in <span class="string">hint</span>. If you want the <span class="keyword">else</span> in there, you'll just wrap 
238      the hint-related code in one. </p> 
239   
240   
241    <div class="code"> 
242      <ul> 
243        <li> 
244          <ul> 
245            <li><span class="keyword">while</span>(<span class="keyword">true</span>)</li> 
246            <li>{ 
247              <ul> 
248                <li><span class="keyword">var</span> guess = <span class="function">prompt</span>(text);</li> 
249                <li><span class="keyword">if</span> (guess !== <span class="string">"hint"</span>)</li> 
250                <li>{ 
251                  <ul> 
252                    <li><span class="keyword">return</span> guess;</li> 
253                  </ul> 
254                </li> 
255                <li>}</li> 
256              </ul> 
257            </li> 
258          </ul> 
259        </li> 
260        <li>&nbsp;</li> 
261        <li><span class="comment">//there's more of this function to come shortly...</span></li> 
262      </ul> 
263    </div> 
264   
265    <p>That's the quick check for the word <span class="string">hint</span>.</p> 
266   
267    <p>But what if they player uses a capital letter somewhere? We controlled for this before in <span class="function">getDirection</span>. 
268      We used the <span class="function">toLowerCase</span> method on the direction the player typed in so we could simply 
269      how we checked things. We should probably do that here too.</p> 
270   
271    <p>But also, do you remember what we did when the player typed in <span class="string">exit</span>? We were super 
272      cautious and allowed them to put the word anywhere in the string. We used <span class="function">indexOf</span> to 
273      see if <span class="string">exit</span> had been used anywhere in the text.</p> 
274   
275    <p>In the interest of expanding your coding skills, let's put these two together and really try to work with the 
276      player's intentions. You could replace the <span class="keyword">if</span> statement above with this to allow more 
277      flexibility for the player.</p> 
278   
279    <div class="code"> 
280      <ul> 
281        <li> 
282          <ul> 
283            <li> 
284              <ul> 
285                <li><span class="keyword">if</span> (guess.<span class="function">toLowerCase</span>().<span 
286                    class="function">indexOf</span>(<span class="string">"hint"</span>) === -1) 
287                </li> 
288              </ul> 
289            </li> 
290          </ul> 
291        </li> 
292      </ul> 
293    </div> 
294   
295    <p>Remember that if <span class="function">indexOf</span> sends back a <code>-1</code>, then the string wasn't found. 
296      So as long as your passcode doesn't actually have the word <span class="string">hint</span> in it, then this will 
297      work well.</p> 
298   
299   
300    <h2>Step 7</h2> 
301    <p>If the function is still running, then we want to give a hint. If you're charging the player some points for the 
302      hint, then we have to take care of that first.</p> 
303    <p>Only include this part if you want the player to give up some points for each hint.</p> 
304   
305    <div class="code"> 
306      <ul> 
307        <li> 
308          <ul> 
309            <li> 
310              <ul> 
311                <li><span class="keyword">if</span> (<span class="object">player</span>.<span 
312                    class="property">score</span> < <span class="object">passcode</span>.<span 
313                    class="property">hintCost</span>) 
314                </li> 
315                <li>{ 
316                  <ul> 
317                    <li><span class="function">alert</span>(<span class="string">"Sorry, you need at least "</span> + 
318                      <span class="object">passcode</span>.<span class="property">hintCost</span> + <span class="string">" 
319                        points to buy a hint."</span>); 
320                    </li> 
321                    <li><span class="keyword">continue</span>;</li> 
322                  </ul> 
323                </li> 
324                <li>}</li> 
325                <li>&nbsp;</li> 
326                <li><span class="object">player</span>.<span class="property">score</span> -= <span class="object">passcode</span>.<span 
327                    class="property">hintCost</span>; 
328                </li> 
329              </ul> 
330            </li> 
331          </ul> 
332        </li> 
333        <li>&nbsp;</li> 
334        <li><span class="comment">//there's more of this function to come shortly...</span></li> 
335      </ul> 
336    </div> 
337   
338    <p>This is a quick check to see if the player has enough points to spend. If not, the loop <span class="keyword">continue</span>s. 
339      Remember, this means the computer jumps back to the top of the loop and runs it again without running any code below 
340      this point. So, if there <em>are</em> enough points, we deduct them from the player. I don't want to give an extra 
341      popup for this, so I'm going to include this information with the hint. But if you want to add a separate <span 
342          class="function">alert</span> here, you certainly can.</p> 
343   
344    <h2>Step 8</h2> 
345    <p>If we've gotten to this point in the function, then it's actually time to give a hint. You have a choice between 
346      giving a single hint or having a few.</p> 
347   
348    <h3>Offering a single hint</h3> 
349    <p>If you only want to have one hint to offer, then you could do something like this. I still made it sort of a puzzle 
350      for the player, but you can be more direct if you want.</p> 
351   
352    <div class="code"> 
353      <ul> 
354        <li> 
355          <ul> 
356            <li> 
357              <ul> 
358                <li><span class="keyword">var</span> hint = <span class="string">"In Kindergarten, you learned a song that 
359                  sounds like <em>Twinkle, Twinkle, Little Star"</em>"</span>; 
360                </li> 
361                <li>hint += <span class="string">" but it's about something being in a specific order."</span>; 
362                </li> 
363                <li>hint += <span class="string">" Your clues have code words that should be put in that same 
364                  order."</span>); 
365                </li> 
366   
367                <li><span class="keyword">if</span> (<span class="object">passcode</span>.<span 
368                    class="property">hintCost</span>) 
369                </li> 
370                <li>{ 
371                  <ul> 
372                    <li> 
373                    <li>hint += <span class="string">" (This clue cost you " + <span class="object">passcode</span>.<span 
374                        class="property">hintCost</span> + " points.)"</span>; 
375                    </li> 
376                  </ul> 
377                </li> 
378                <li>}</li> 
379   
380                <li><span class="function">alert</span>(hint);</li> 
381              </ul> 
382            </li> 
383            <li>} <span class="comment">//this closes the <em>while</em> loop</span></li> 
384          </ul> 
385        </li> 
386        <li>} <span class="comment">//this closes the function</span></li> 
387      </ul> 
388    </div> 
389   
390    <p>That does it for the single hint. You're all done with this feature.</p> 
391   
392   
393    <h3>Offering several hints</h3> 
394   
395   
396    <p>In the interest of expanding your coding knowledge and practice, let's create multiple hints. I'm going to create a 
397      set of hints in an array and then randomly pick a hint each time the player asks for one. This means the player 
398      could be unlucky and get the same hint more than once (unless we control for that) but I think that makes it more 
399      interesting.</p> 
400   
401    <h4>Leaving an unfinished function</h4> 
402    <p>We're going to jump out of the <span class="function">getPasscodeGuess</span> function for a few minutes. You might 
403      get some errors showing up, but we'll fix them.</p> 
404   
405   
406    <h4>Updating the <span class="function">getPasscode</span> function</h4> 
407    <p>At the top of the function, we recreate the <span class="object">passcode</span> object. Now, ever though we can 
408      create new properties on the fly by just assigning them, it's better practice to show that we intend to do so if we 
409      can.</p> 
410   
411    <p>For good code readability, let's add a <span class="property">hints</span> property to the <span class="object">passcode</span> 
412      object. Well also add the cost of the hint here, which you can set to <code>0</code> if you don't want a cost.</p> 
413   
414    <div class="code"> 
415      <ul> 
416        <li>passcode =</li> 
417        <li>{ 
418          <ul> 
419            <li><span class="property">reward</span>: 100,</li> 
420            <li><span class="property">penalty</span>: 25,</li> 
421            <li><span class="property">exitCode</span>: <span class="string">""</span>,</li> 
422            <li><span class="property">codes</span>: [],</li> 
423            <li><span class="property">rooms</span>: []<strong>, <span class="comment">//remember the comma 
424              here</span></strong></li> 
425            <li><strong><span class="property">hints</span>: [], <span class="comment">&nbsp;//add this</span> </strong> 
426            </li> 
427            <li><strong><span class="property">hintCost</span>: 5</strong></li> 
428          </ul> 
429        </li> 
430        <li>};</li> 
431      </ul> 
432    </div> 
433   
434    <p>When we make the clues for the player and the passcode, let's also call for the hints to be created.</p> 
435    <p>To make it easy to find where to put this, go to the very bottom of the <span class="function">getPasscode</span> 
436      function.</p> 
437   
438    <div class="code"> 
439      <ul> 
440        <li> 
441          <ul> 
442            <li>passcode.hints = <span class="function">makePasscodeHints</span>(passcode); <span 
443                class="comment">//new</span> 
444            </li> 
445            <li><span class="keyword">return</span>; <span class="comment">//already there</span></li> 
446          </ul> 
447        </li> 
448        <li>} &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="comment">//already there</span></li> 
449      </ul> 
450    </div> 
451   
452    <h4>Creating the <span class="function">makePasscodeHints</span> function</h4> 
453    <p>We made a global set of hints. Now we'll copy that set so we can use it without making changes to the original 
454      set.</p> 
455   
456    <div class="code"> 
457      <ul> 
458        <li><span class="keyword">function</span> <span class="function">getPasscodeHints</span>(passcode)</li> 
459        <li>{ 
460          <ul> 
461            <li><span class="keyword">var</span> hints = [];</li> 
462            <li>hints.<span class="function">push</span>(<span class="string">"Twinkle, Twinkle, Little Star sounds like 
463              another song you learned in Kindergarten that reminds us of a certain order."</span>); 
464            </li> 
465            <li>hints.<span class="function">push</span>(<span class="string">"A group of animals had a race. The aardvark 
466              finished first. The bunny was second. The cat was a purrfect third. The dog defended fourth. The elephant 
467              was fifth."</span>); 
468            </li> 
469            <li>hints.<span class="function">push</span>(<span class="string">"Two friends were at the zoo. Rodger went 
470              and FED the horses, but he did it wrong. Instead, his buddy STU did it right."</span>); 
471            </li> 
472            <li>&nbsp;</li> 
473            <li><span class="comment">//How about some really helpful hints?</span></li> 
474   
475            <li><span class="keyword">var</span> exitCode = <span class="object">passcode</span>.<span 
476                class="property">exitCode</span>; 
477            </li> 
478   
479            <li><span class="keyword">for</span> (<span class="keyword">var</span> i = 0; i < exitCode.<span 
480                class="property">length</span>; i += 3) 
481            </li> 
482            <li>{ 
483              <ul> 
484                <li><span class="keyword">var</span> index = <span class="object">Math</span>.<span 
485                    class="function">floor</span>(<span 
486                    class="object">Math</span>.<span class="function">random</span>() * exitCode.<span 
487                    class="property">length</span>); 
488                </li> 
489                <li>hints.<span class="function">push</span>(<span class="string">"Passcode digit #"</span> + (index + 1) 
490                  + <span class="string">" is "</span> + exitCode.<span 
491                      class="function">substring</span>(index, 1)); 
492                </li> 
493              </ul> 
494            </li> 
495            <li>}</li> 
496            <li><span class="keyword">return</span> hints;</li> 
497          </ul> 
498        </li> 
499        <li>}</li> 
500      </ul> 
501    </div> 
502   
503    <h4>Finishing the <span class="function">getPasscodeGuess</span> function</h4> 
504    <div class="flex2"> 
505      <div> 
506        <p>We left this function unfinished which is probably showing you some errors. Let's wrap it up finally.</p> 
507        <p>We have everything we need now, so we just need to pick a hint to show.</p> 
508        <p>This goes at the bottom of the <span class="function">getPasscodeGuess</span> function we were creating.</p> 
509   
510        <div class="code"> 
511          <ul> 
512            <li> 
513              <ul> 
514                <li> 
515                  <ul> 
516                    <li><span class="comment">//make a copy of the global hints so we don't alter them accidentally</span> 
517                    </li> 
518                    <li><span class="keyword">var</span> hints = <span class="object">passcode</span>.<span 
519                        class="property">hints</span>.<span 
520                        class="function">slice</span>(); 
521                    </li> 
522                    <li>&nbsp;</li> 
523                    <li><span class="comment">//now let's pick a hint</span></li> 
524                    <li><span class="keyword">var</span> hintNumber = <span class="object">Math</span>.<span 
525                        class="function">floor</span>(<span 
526                        class="object">Math</span>.<span class="function">random</span>() * hints.<span class="property">length</span>); 
527                    </li> 
528                    <li><span class="keyword">var</span> hint = <span class="string">"Hint #"</span> + (hintNumber + 1) + 
529                      <span 
530                          class="string">" of "</span> + hints.<span class="property">length</span> + <span 
531                          class="string">": "</span>; 
532                    </li> 
533                    <li>hint += hints[hintNumber];</li> 
534   
535   
536                    <li><span class="keyword">if</span> (<span class="object">passcode</span>.<span 
537                        class="property">hintCost</span>) 
538                    </li> 
539                    <li>{ 
540                      <ul> 
541                        <li> 
542                        <li>hint += <span class="string">" (This clue cost you " + <span 
543                            class="object">passcode</span>.<span 
544                            class="property">hintCost</span> + " points.)"</span>; 
545                        </li> 
546                      </ul> 
547                    </li> 
548                    <li>}</li> 
549   
550                    <li><span class="function">alert</span>(hint);</li> 
551                    <li>&nbsp;</li> 
552                    <li><span class="comment">//if you want to remove the hint from the list, add this</span></li> 
553                    <li><span class="comment">//note: the list of hints will be reset if the player guesses wrong and 
554                      tries again</span> 
555                    </li> 
556                    <li>hints.<span class="function">splice</span>(hintNumber, 1);</li> 
557                  </ul> 
558                </li> 
559                <li>&nbsp;</li> 
560                <li>} <span class="comment">//this closes the <em>while</em> loop</span></li> 
561              </ul> 
562            </li> 
563            <li>} <span class="comment">//this closes the function</span></li> 
564          </ul> 
565        </div> 
566   
567        <p>That was a lot of pieces to add multiple hints, but it will enrich the game even more, especially if you get 
568          creative with your hints or change the format of the game.</p> 
569      </div> 
570      <div class="max150px"> 
571        <figure><img src="/roomadventure/screenimages/textpasscodehint03.png" alt="Multiple hints option"> 
572          <figcaption>Multiple hints option</figcaption> 
573        </figure> 
574      </div> 
575    </div> 
576   
577    <h2>Here's a hint... Keep coding!</h2> 
578    <h2>&mdash;Dr. Wolf</h2> 
579   
580    <div id="prevnext"></div> 
581    <!-- required section for navigation sidebar --></div> 
582  <script src="/navigator.js"></script> 
583  <script>begin("roomadventure");</script> 
584  <!-- end of required section for navigation sidebar --> 
585  </body> 
586  </html> 
587