@@ -18,6 +18,7 @@ let user_gave_up = false; // True if user ever gave up before user solved it
1818
1919let  startTime  =  Date . now ( ) ;  // Time this lab started. 
2020let  lastHintTime  =  null ;  // Last time we showed a hint. 
21+ let  lastHintTarget  =  null ;  // Last hint button user used. 
2122
2223// Has the input changed since we showed a hint? 
2324// We track this so people can re-see a hint they've already seen. 
@@ -356,15 +357,20 @@ function calcOneMatch(attempt, index = 0, correct = correctRe) {
356357 * Return true iff all of attempt matches all of correct. 
357358 * @attempt  - Array of strings that might be correct 
358359 * @correct  - Array of compiled regexes describing correct answer 
360+  * @validIndexes  - Array of indexes to check (default: all indexes) 
359361 */ 
360- function  calcMatch ( attempt ,  correct  =  correctRe )  { 
362+ function  calcMatch ( attempt ,  correct  =  correctRe ,   validIndexes   =   null )  { 
361363    if  ( ! correct )  {  // Defensive test, should never happen. 
362364        alert ( 'Error: Internal failure, correct value not defined or empty.' ) ; 
363365        return  false ; 
364366    } 
365367    for  ( let  i  =  0 ;  i  <  correct . length ;  i ++ )  { 
366-         // If we find a failure, return false immediately (short circuit) 
367-         if  ( ! calcOneMatch ( attempt ,  i ,  correctRe ) )  return  false ; 
368+         if  ( validIndexes  ==  null  ||  validIndexes . includes ( i ) )  { 
369+             // If we find a failure, return false immediately (short circuit) 
370+             if  ( ! calcOneMatch ( attempt ,  i ,  correctRe ) )  { 
371+                 return  false ; 
372+ 	    } 
373+ 	} 
368374    } 
369375    // Everything passed. 
370376    return  true ; 
@@ -557,23 +563,10 @@ function findHint(attempt, validIndexes = undefined) {
557563} 
558564
559565/** Show a hint to the user. */ 
560- function  showHint ( e )  { 
561-     // Get data-indexes value using e.target.dataset.indexes 
562-     // alert(`Form id = ${e.target.form.id}`); 
563-     let  attempt  =  retrieveAttempt ( ) ; 
564- 
565-     // Check if the answer's already correct. This shouldn't happen, since 
566-     // it was already checked. This is just a little defensive programming. 
567-     if  ( calcMatch ( attempt ,  correctRe ) )  { 
568-         alert ( t ( 'already_correct' ) ) ; 
569-     }  else  if  ( ! hints )  { 
570-         alert ( t ( 'no_hints' ) ) ; 
571-     }  else  { 
572-         // Use *precalculated* input field indexes to work around 
573-         // problem in Chrome translator. 
574-         let  validIndexes  =  e . target . dataset . inputIndexes ; 
575-         alert ( findHint ( attempt ,  validIndexes ) ) ; 
576-     } 
566+ function  showHint ( e ,  attempt ,  validIndexes )  { 
567+     // Use *precalculated* input field indexes to work around 
568+     // problem in Chrome translator. 
569+     alert ( findHint ( attempt ,  validIndexes ) ) ; 
577570} 
578571
579572/** Show the answer to the user */ 
@@ -628,27 +621,42 @@ function maybeShowAnswer(e) {
628621    } 
629622} 
630623
624+ // Return true iff target is the same hint button as last time, without edits. 
625+ function  sameHint ( target )  { 
626+     return  ( target  ==  lastHintTarget )  &&  ! changedInputSinceHint ; 
627+ } 
628+ 
631629/** Maybe show a hint to the user (depending on timer). */ 
632630function  maybeShowHint ( e )  { 
633-     // If answer is correct, confirm it and don't cause a penalty. 
631+     // If there are no hints, just say so without delay. 
632+     if  ( ! hints  ||  hints . length  ===  0 )  { 
633+         alert ( t ( 'no_hints' ) ) ; 
634+         return ; 
635+     } 
636+ 
637+     // Confirm correct answer if it is, and don't cause a penalty or delay. 
638+     // For "hint" we only consider the answers for THIS form. 
634639    let  attempt  =  retrieveAttempt ( ) ; 
635-     if  ( calcMatch ( attempt ,  correctRe ) )  { 
640+     let  formIndexes  =  JSON . parse ( e . target . dataset . inputIndexes ) ; 
641+     if  ( calcMatch ( attempt ,  correctRe ,  formIndexes ) )  { 
636642        alert ( t ( 'already_correct' ) ) ; 
637643        return ; 
638644    } 
639645
640-     // Answer is not correct. Determine if delay  time has passed. 
646+     // Answer is not correct. Determine how much  time has passed. 
641647    let  elapsedTime  =  elapsedTimeSinceClue ( ) ; 
642648
649+     // Reply if the minimum delay time has passed. 
643650    // Only enforce delay timer if changedInputSinceHint is true. That way, 
644651    // people can re-see a previously-seen hint as long as they 
645652    // have not changed anything since seeing the hint. 
646-     if  ( changedInputSinceHint   &&   ( elapsedTime  <  HINT_DELAY_TIME ) )  { 
653+     if  ( ( elapsedTime  <  HINT_DELAY_TIME )   &&   ! sameHint ( e . target ) )  { 
647654        alert ( myFormat ( t ( 'try_harder_hint' ) ,  [ HINT_DELAY_TIME . toString ( ) ] ) ) ; 
648655    }  else  { 
649656        lastHintTime  =  Date . now ( ) ;  // Set new delay time start 
657+         lastHintTarget  =  e . target ;  // Set last hint button used 
650658        changedInputSinceHint  =  false ;  // Allow redisplay of hint 
651-         showHint ( e ) ; 
659+         showHint ( e ,   attempt ,   formIndexes ) ; 
652660    } 
653661} 
654662
0 commit comments