Skip to content

Commit c9e2cf3

Browse files
Add delay for a hint
Add delay for a hint. That way, instead of trying to use hints to write the answers, learners will be quietly encouraged to try to solve the problem themselves. This adds a shorter delay (15 seconds) for each hint. If the user has seen a hint and hasn't changed anything, they can re-see the hint. We earlier added a delay for "give up". This modifies the give up timer so that if they've asked for a hint, the give up timer starts from the time of the last hint. That way, people *can* give up, but they have to at least wait a little time. Signed-off-by: David A. Wheeler <[email protected]>
1 parent 651bf91 commit c9e2cf3

File tree

1 file changed

+58
-11
lines changed

1 file changed

+58
-11
lines changed

docs/labs/checker.js

Lines changed: 58 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,14 @@ let page_definitions = {}; // Definitions used when preprocessing regexes
1616
let user_solved = false; // True if user has *ever* solved it on this load
1717
let user_gave_up = false; // True if user ever gave up before user solved it
1818

19-
let startTime = Date.now();
19+
let startTime = Date.now(); // Time this lab started.
20+
let lastHintTime = null; // Last time we showed a hint.
21+
22+
// Has the input changed since we showed a hint?
23+
// We track this so people can re-see a hint they've already seen.
24+
// This initial value of "true" forces users to wait a delay time before
25+
// they are allowed to see their first hint on an unchanged page.
26+
let changedInputSinceHint = true;
2027

2128
let BACKQUOTE = "`"; // Make it easy to use `${BACKQUOTE}`
2229
let DOLLAR = "$"; // Make it easy to use `${DOLLAR}`
@@ -39,7 +46,8 @@ const resources = {
3946
no_matching_hint: 'Sorry, I cannot find a hint that matches your attempt.',
4047
reset_title: 'Reset initial state (throwing away current attempt).',
4148
to_be_completed: 'to be completed',
42-
try_harder: "Try harder! Don't give up so soon. Current time spent (in seconds): {0}",
49+
try_harder_give_up: "Try harder! Don't give up so soon. Current time spent since start or last hint (in seconds): {0}",
50+
try_harder_hint: "Try harder! Don't ask for a hint so soon, wait at least 15 seconds.",
4351
},
4452
},
4553
ja: {
@@ -56,7 +64,8 @@ const resources = {
5664
no_matching_hint: '申し訳ありませんが、あなたの試みに一致するヒントが見つかりません。',
5765
reset_title: '初期状態をリセットします (現在の試行を破棄します)。',
5866
to_be_completed: '完成する',
59-
try_harder: '「もっと頑張ってください! すぐに諦めないでください。現在の所要時間 (秒): {0}」',
67+
try_harder_give_up: 'もっと頑張れ!そんなにすぐに諦めないでください。開始または最後のヒントから経過した現在の時間 (秒単位): {0}',
68+
try_harder_hint: "もっと頑張れ!すぐにヒントを求めず、少なくとも 15 秒待ちます。",
6069
},
6170
},
6271
fr: {
@@ -73,7 +82,9 @@ const resources = {
7382
no_matching_hint: "Désolé, je ne trouve pas d'indice correspondant à votre tentative.",
7483
reset_title: "Réinitialiser l'état initial (abandonner la tentative actuelle).",
7584
to_be_completed: 'à compléter',
76-
try_harder: "Essayez plus fort ! N'abandonnez pas si tôt. Temps actuel passé (en secondes) : {0}",
85+
try_harder_give_up: "Essayez plus fort ! N'abandonnez pas si tôt. Temps actuel passé (en secondes) : {0}",
86+
try_harder_give_up: "Essayez plus fort ! N'abandonnez pas si tôt. Temps actuel passé depuis le début ou le dernier indice (en secondes) : {0}",
87+
try_harder_hint: "Essayez plus fort ! Ne demandez pas d'indice si tôt, attendez au moins 15 secondes.",
7788
},
7889
},
7990
};
@@ -454,6 +465,10 @@ function makeStamp() {
454465
* Then set "grade" in document depending on that answer.
455466
*/
456467
function runCheck() {
468+
// This is only called when *something* has changed in the input.
469+
// From now on, enforce hint delays.
470+
changedInputSinceHint = true;
471+
457472
let attempt = retrieveAttempt();
458473

459474
// Calculate grade and set in document.
@@ -533,6 +548,7 @@ function showHint(e) {
533548
}
534549
}
535550

551+
/** Show the answer to the user */
536552
function showAnswer(e) {
537553
// Get indexes in *this* form.
538554
let formIndexes = JSON.parse(e.target.dataset.inputIndexes);
@@ -543,19 +559,50 @@ function showAnswer(e) {
543559
alert(t('expecting').format(goodAnswer));
544560
}
545561

546-
// "Give up" only shows the answer after this many seconds have elapsed.
547-
const MIN_DELAY_TIME = 60;
562+
// "Give up" only shows the answer after this many seconds have elapsed
563+
// since a clue (lab start or a hint given).
564+
const GIVE_UP_DELAY_TIME = 60;
548565

549-
function maybeShowAnswer(e) {
566+
// "Hint" only shows hint after this many seconds have elapsed
567+
// since a clue (lab start or a hint given).
568+
// Adjust text try_harder_hint if you change this. The text includes the
569+
// number because pluralization rules vary depending on the natural language,
570+
// and we want to tell the user the delay for hints.
571+
const HINT_DELAY_TIME = 15;
572+
573+
/** return time (in seconds) since start and/or last hint */
574+
function elapsedTimeSinceClue() {
550575
let currentTime = Date.now();
551-
let elapsedTime = (currentTime - startTime) / 1000; // in seconds
552-
if (elapsedTime < MIN_DELAY_TIME) {
553-
alert(t('try_harder').format(elapsedTime.toString()));
576+
let lastTime = (lastHintTime == null) ? startTime : lastHintTime;
577+
return ((currentTime - lastTime) / 1000); // in seconds
578+
}
579+
580+
/** Maybe show the answer to the user (depending on timer). */
581+
function maybeShowAnswer(e) {
582+
let elapsedTime = elapsedTimeSinceClue();
583+
if (elapsedTime < GIVE_UP_DELAY_TIME) {
584+
alert(t('try_harder_give_up').format(elapsedTime.toString()));
554585
} else {
555586
showAnswer(e);
556587
}
557588
}
558589

590+
/** Maybe show a hint to the user (depending on timer). */
591+
function maybeShowHint(e) {
592+
let elapsedTime = elapsedTimeSinceClue();
593+
// Only enforce delay timer if changedInputSinceHint is true. That way,
594+
// people can re-see a previously-seen hint as long as they
595+
// have not changed anything since seeing the hint.
596+
if (changedInputSinceHint && (elapsedTime < HINT_DELAY_TIME)) {
597+
// Provide elapsed time (in seconds) in case we want to use it.
598+
alert(t('try_harder_hint').format(elapsedTime.toString()));
599+
} else {
600+
lastHintTime = Date.now(); // Set new delay time start
601+
changedInputSinceHint = false; // Allow redisplay of hint
602+
showHint(e);
603+
}
604+
}
605+
559606
/**
560607
* Reset form.
561608
* We have to implement this in JavaScript to ensure that the final
@@ -822,7 +869,7 @@ function initPage() {
822869
current++;
823870
}
824871
for (let hintButton of document.querySelectorAll("button.hintButton")){
825-
hintButton.addEventListener('click', (e) => { showHint(e); });
872+
hintButton.addEventListener('click', (e) => { maybeShowHint(e); });
826873
// Precompute inputIndexes to work around problems that occur
827874
// if a user uses a browser's built-in natural language translation.
828875
// Presumes button's parent is the form

0 commit comments

Comments
 (0)