- Learn
- Tutorials
- Algorithms
- Binary Search
- 2 Human Scan
2 Human Scan
By the end of this chapter, you can ask the safe a question. Type a guess and press SCAN, and it answers in gold: HIGHER THAN, or LOWER THAN. You have seven scans. Find the code, and the door swings open on gold.
The game as it is at the end of this chapter. Click the game to play.
If your game and this chapter part ways, here is the chapter’s finished project. Open it and compare, or start Chapter 3 from it.
To open it, start Myth Engine, choose File › Open Project... and pick the downloaded file.
2.1 The Idea
The safe has kept its secret for a whole chapter, shut and silent in its navy room. Now it starts to talk, a little.
Try it in the game above. Type 50 and press Enter, and a gold line appears under the safe: HIGHER THAN 50. Beside the keypad, a counter reads 1 / 7. Lower down, in teal, POSSIBLE CODE: 51 - 100, and across from it, 50 possibilities remain.
The safe never tells you the code. It tells you something true about it, and every true thing rules codes out. That’s the whole game. But you get seven tries, and there are a hundred codes. Trying them one by one won’t get far. So which guess teaches you the most?
A guess the safe accepts, and counts against your seven, is a scan. Each scan brings back a clue. It’s one of three: Higher, Lower or Unlocked.
The codes still possible make up the range, from $low up to $high.
Think of the range as a strip of paper with a hundred squares, one for each code. Every clue snips a piece off one end. The code is always on the piece you keep.
A trial runs from a fresh safe until it opens or you run out of scans. It’s always in one of three phases: Locked, Unlocked or Exhausted. Myth Engine keeps that phase for you as the Game State, one value the whole game can ask about.
Chapter 1 made a promise, and this chapter keeps it. One small Function, Check Guess, holds the code up against your guess. It’s the only piece that ever compares them. And Safe Button’s bell rings for more than Back. SCAN and New safe each need only a word of their own, and Button Clicks learns two more Events to hear them.
Binary search hasn’t started yet. But its rule is already here: a clue rules out every code on one side of the guess. Guess in the middle, and that side is about half.
2.2 The Plan
- The game starts, or you press R -> New Safe calls Start New Safe -> a new code, the whole range, no scans, and the safe Locked.
- You press Enter -> Keypad Keys calls Scan Guess -> Check Guess compares the guess with the code -> Follow the Clue moves one end of the range, or opens the safe.
- The Game State changes -> Show Safe Door draws the safe open or shut.
- The range changes -> Show Possibilities picks “possibility” or “possibilities”.
- You click SCAN or New safe -> Safe Button sends scanClicked or newSafeClicked -> Button Clicks calls Scan Guess or Start New Safe.
2.3 Set Up
This chapter’s Set up card is short. Most of it you’ve done before.
ART names three more pictures from the Starter Kit: the open safe, the gold of the SCAN button, and the plain button under New safe. They’re in your project already.
COMMANDS adds two keys, Scan on Enter and New Safe on R. Add them in the Input Manager, as you did the twelve in Chapter 1.
GLOBAL VARIABLES adds five. Make them now, all in one place. Open Show Entry, press + on its Globals card, and choose New Global… for each one. Four are Numbers that start at 0. The fifth, message, is Text, and it starts empty, with nothing to say yet.
The Game State block is new. It lists the three phases a trial can be in, and Locked is the one the game starts in. The Making page’s In later chapters passage shows where they go. Leave PLACE THESE for later, as before. Each part places its own.
EnterRLocked, Unlocked, ExhaustedLockedSave your project now, and again at the end of each part.
2.4 A Fresh Safe
First, the safe learns to start over.
In Chapter 1, the safe dealt its code once, when the game began. Now a trial can end, so the safe needs to deal again: a new code, the whole range open, no scans counted. The keys for it are R and, later, the New safe button.
Two old pieces grow a little first. Safe State gets a third field, clue, where the last scan’s answer will wait. Safe Settings Entry gets a fourth field, scanBudget, so the table gets a fourth column. Its row says 7. That’s your seven scans, and the counter reads them from this one cell, so changing it changes the game. The Making page explains Changes cards, with their colors.
What the Safe Rules Object carries for its Logic to share. code: the secret code that opens the safe. startsNewEntry: true when the next digit typed starts a new entry instead of adding to the one shown. clue: what the last scan told: 1 the code is higher than the guess, -1 lower, 0 the guess is the code.
One row of the Safe Settings Data Table, made by the engine for the table's rows: lowestCode, highestCode, startEntry, scanBudget (the table's description says what each column means).
1100507Every word the safe says to you lives in one table, Safe Copy. Its Data Structure, Safe Copy Entry, comes with it. Give that one field, text, a Text that starts empty. Then add the ten rows. Each row’s name is how the Logic finds it, and its text is what you’ll read on the screen.
One row of the Safe Copy Data Table, made by the engine for the table's rows: text (the table's description says what each column means).
Scan a guess to get a clue.HIGHER THANLOWER THANUNLOCKED!OUT OF SCANSUse the remaining range.Start a new safe.Code sealed.possibilities remainpossibility remainsThe Message is the gold line under the safe. Its Text is {$message}, so it always shows whatever $message holds. A message can be long, so its Text Bounds list says Wrap to Width. How wide? A Text / UI has a Transform of its own, apart from the Object’s. Its Size X, 440, is the width the words wrap at. Both are in the Text / UI’s Properties, in the card’s order: Text Bounds a little after Color, and its own Transform last, after Rendering.
Window / UIUI{$message}22Bold#F5CD73Wrap to WidthVector4402.4.1 Start New Safe
Start New Safe deals a whole new trial. In Chapter 1, the Logic Component New Safe did part of this itself, when the game began. Now that R does it too, the work moves into a Function that both can call.
It starts the way New Safe did, with a fresh code. Then everything else goes back to where a trial begins. The whole range is open, nothing is counted, and the display waits on its 50 for your first digit to replace.
Last, Set Game State makes the trial Locked, and the message says “Scan a guess to get a clue.”
One line on the card has no box in the editor. Set Game State’s card says Applies to safeRules, but the block has only its Game State list. Why? A Game State belongs to the whole game, not to one Object, so there’s nothing to point at. Leave that line out, here and on every Set Game State and Check Game State to come.
Starts a fresh trial on a new safe: draws a new secret code with the engine's random block, opens the whole range again, sets the scans to 0, and shows the starting entry.
safeStateData StructureSafe State- Action Name
codeRoll- Minimum
data('Safe Settings','Standard Safe','lowestCode')- Maximum
data('Safe Settings','Standard Safe','highestCode')
- Component Value
safeRules.safeState.code- Value
codeRoll.value
- Variable
$low- Value
data('Safe Settings','Standard Safe','lowestCode')
- Variable
$high- Value
data('Safe Settings','Standard Safe','highestCode')
- Variable
$scans- Value
0
- Variable
$lastGuess- Value
0
- Component Value
safeRules.safeState.clue- Value
0
- Variable
$entry- Value
data('Safe Settings','Standard Safe','startEntry')
- Component Value
safeRules.safeState.startsNewEntry- Value
true
- Applies to
safeRules- Game State
Locked
- Variable
$message- Value
data('Safe Copy','Scan a Guess','text')
2.4.2 New Safe
The Logic Component New Safe gets shorter. Its three old blocks come out, and one call to Start New Safe goes in, with self as its safeRules. A second Event does the same when the R key’s Command is pressed. That Command is named New Safe too.
Starts a new safe when the game begins and when the player presses R (the New safe key).
Any Objectself.safeState- Action Name
codeRoll- Minimum
data('Safe Settings','Standard Safe','lowestCode')- Maximum
data('Safe Settings','Standard Safe','highestCode')
- Component Value
self.safeState.code- Value
codeRoll.value
- Variable
$entry- Value
data('Safe Settings','Standard Safe','startEntry')
- safeRules
self
- safeRules
self
Place the Message from PLACE THESE.
Run the game. Under the safe, in gold, it says “Scan a guess to get a clue.” Type 4, then 2, and press R. The display goes back to 50. Somewhere inside, the safe has a new code.
2.5 The Scan
Now the question.
2.5.1 Check Guess
Check Guess is the smallest Function in the game, and the only one that ever compares a guess with the code.
It gets two numbers, a guess and a code. It hands back one number, the clue, and that’s the only thing it ever says. When they’re the same, the clue is 0. When the guess is below the code, it’s 1, because the code is higher. And when the guess is above, it’s -1.
That’s all it does. It doesn’t know about scans, or ranges, or safes. Give it any two numbers, and it answers the same way every time.
The clue is made by a Declare Variable, a value that lives only while Check Guess runs. The If sets it, and the Return at the end hands it back. The answer is a Number. The Making page’s A Function card passage shows where each goes. The Otherwise holds a second If and nothing else, so the canvas draws the pair as one block, Else If. Right-click step 2’s If and choose Add Else If. That one move makes steps 4 and 5 together. Then right-click the Else If and choose Add Else, and that gives you step 7, the last Otherwise.
To fill the Else If’s True line, use its Add Inside Then menu item. That is where the Lower clue goes.
Compares a guess with the code and answers with the clue: 1 when the code is higher than the guess, -1 when it is lower, 0 when the guess is the code.
- Name
clue- Value
0
guess == code- Variable
clue- Value
0
guess < code- Variable
clue- Value
1
- Variable
clue- Value
-1
- Value
clue
2.5.2 Follow the Clue
This is the chapter’s one hard idea, so take it slowly. Follow the Clue is where the range closes in.
It reads the clue that Check Guess left in Safe State, and the guess in $lastGuess. There are three cases.
Count the beats on a first scan, when nothing is ruled out yet. The range is 1 to 100, and you scan 50. The clue comes back as 1, and the message says HIGHER THAN 50. So the code is above 50. That rules out 50 itself, and every code below it. $low moves up to the guess plus 1, which is 51. $high stays at 100.
LOWER works the same way from the other end. The code is below the guess, so $high moves down to the guess minus 1, and $low stays put.
And when the clue is 0, the guess is the code. Both ends close on it, $low and $high both become the guess, and the range is that one code. Set Game State makes the trial Unlocked, and the message says UNLOCKED!
Notice what never happens. A clue never cuts off the code’s square. Higher only removes codes below the guess, and the code is above it. Whatever you scan, the code is still somewhere from $low to $high.
The message names the guess. text() joins its pieces into one line: the words from Safe Copy, a space, then $lastGuess.
After a miss, one more question: was that the last scan? When $scans has reached scanBudget, the trial is Exhausted, and the message says OUT OF SCANS. That If sits on the miss side only. A seventh scan that opens the safe is a win.
Placing that If takes care, and the care starts back at step 6. Look at the card’s bars. Step 6’s Otherwise holds two things: the HIGHER-or-LOWER If at step 7, and the If at step 13 below it. An Else If can’t do that. It holds one If and nothing after it, which is why Check Guess could use one.
So build step 6 with Add Else, not Add Else If. Right-click step 1’s If and choose Add Else. On the canvas, a block that says Else appears out to the right, on the False line. Right-click it, choose Add Inside Else, and pick If. That’s step 7. Its own Otherwise, step 10, comes from step 7’s menu, through Add Else.
When you reach step 13, go back to that same Else, the one from step 6. Choose Add Inside Else again, and pick If. Connect to Sequence joins it to the end of the Else’s line, under step 7’s If. If, Else and Repeat shows the same move.
Did your canvas already show Else If at step 7? Then nothing can hold step 13. Delete the blocks from step 6 on, and build them again as this part describes, with a plain Else. It’s quicker the second time.
Uses the clue of the scan just made: Unlocked when the guess is the code; otherwise the range shrinks past the guess, and the trial is Exhausted when the scan budget is spent.
safeStateData StructureSafe StatesafeRules.safeState.clue == 0- Variable
$low- Value
$lastGuess
- Variable
$high- Value
$lastGuess
- Applies to
safeRules- Game State
Unlocked
- Variable
$message- Value
data('Safe Copy','Unlocked','text')
safeRules.safeState.clue == 1- Variable
$low- Value
$lastGuess + 1
- Variable
$message- Value
text(data('Safe Copy','Higher Than','text'), ' ', $lastGuess)
- Variable
$high- Value
$lastGuess - 1
- Variable
$message- Value
text(data('Safe Copy','Lower Than','text'), ' ', $lastGuess)
$scans >= data('Safe Settings','Standard Safe','scanBudget')- Applies to
safeRules- Game State
Exhausted
- Variable
$message- Value
data('Safe Copy','Out of Scans','text')
2.5.3 Scan Guess
Scan Guess is the scanner. In Chapter 4, the computer will call this same Function, so both players play by one set of rules.
First it asks whether the safe is still Locked, with Check Game State. Its Action Name is safeIsLocked, and the If reads safeIsLocked.value. Leave out its Applies to line again. When the trial is over, nothing counts, and the message says “Start a new safe.”
Then it asks whether the entry is inside the range, from $low to $high. That If’s condition joins two tests with &&, and both must be true. Outside the range, the message says “Use the remaining range.” No scan is counted, and the range doesn’t move. A code you’ve already ruled out costs you nothing.
Inside the range, the scan counts. Then the code goes to Check Guess, along with the guess. Scan Guess hands it over and never compares it. The clue comes back as checkedGuess.value, and Follow the Clue takes it from there.
The two Otherwises belong to different gates. Step 10 belongs to step 3’s range test, so add Else from that If. Step 12 is farther out. It belongs to step 2’s If, which asks whether the safe is Locked.
Tries the entry as a guess. A guess counts only while the safe is Locked and only inside the range of codes still possible; it then counts one scan, asks Check Guess for the clue, and follows it.
safeStateData StructureSafe State- Action Name
safeIsLocked- Applies to
safeRules- Game State
Locked
safeIsLocked.value == true$entry >= $low && $entry <= $high- Variable
$lastGuess- Value
$entry
- Variable
$scans- Operator
+=- Value
1
- Component Value
safeRules.safeState.startsNewEntry- Value
true
- Action Name
checkedGuess- guess
$lastGuess- code
safeRules.safeState.code
- Component Value
safeRules.safeState.clue- Value
checkedGuess.value
- safeRules
safeRules
- Variable
$message- Value
data('Safe Copy','Outside the Range','text')
- Variable
$message- Value
data('Safe Copy','Start a New Safe','text')
2.5.4 Keypad Keys
Keypad Keys gets one more Event: when Scan is pressed, call Scan Guess. Your hands know this one.
Lets the keyboard work the keypad: the digit keys type a digit, Backspace erases the last digit, Delete clears the entry, and Enter scans it. The keypad's buttons call the same Functions.
Any Objectself.safeState- safeRules
self- digit
0
- safeRules
self- digit
1
- safeRules
self- digit
2
- safeRules
self- digit
3
- safeRules
self- digit
4
- safeRules
self- digit
5
- safeRules
self- digit
6
- safeRules
self- digit
7
- safeRules
self- digit
8
- safeRules
self- digit
9
- safeRules
self
- safeRules
self
- safeRules
self
The Scan Count is the gold “1 / 7” beside the keypad, with SCANS in small letters under it. Its Text reads two values at once, $scans and the scanBudget cell, so the 7 follows the table too.
Window / UIUI{$scans} / {data('Safe Settings','Standard Safe','scanBudget')}28Bold#F5CD73VectorWindow / UIUISCANS12Bold#91A9B5VectorPlace them both.
Run the game, click it once, and press Enter. The 50 on the display is your first scan. The counter reads 1 / 7, and the gold line says HIGHER THAN 50 or LOWER THAN 50. Now type a code that clue ruled out, and press Enter. “Use the remaining range.” The counter doesn’t move.
2.6 What’s Left
Next, the safe shows you the range.
The Range Line is teal words under the safe: POSSIBLE CODE: and the two ends. Its Text does the work, {$low} - {$high}, so it follows every clue with no Logic at all.
Window / UIUIPOSSIBLE CODE: {$low} - {$high}14Bold#61C6BEVectorThe Possibilities line says how many codes are left. The count is worked out in its Text too, {$high - $low + 1}. Why the + 1? Because the range holds both its ends. From 51 to 100 is 50 codes, and 100 minus 51 alone would miss one.
The words that come after the count are a harder problem than the count itself. With one code left, it should say “1 possibility remains”, and with more, “possibilities remain”. A Text can’t choose between two words by itself, so the Object carries a small Data Structure, Possibilities Line, with one field, words. Its Text shows that field as {words}, the field’s name alone, as the card spells it. Logic fills it.
What the possibilities line shows after the count of codes still possible, written by Write Possibilities Line. words: possibility remains for one code, possibilities remain for more.
2.6.1 Write Possibilities Line
One thin teal mark remains, and the sentence should agree with it. Write Possibilities Line supplies the words after the count. It reads them from Safe Copy, so the wording stays with the safe’s other messages. Its line Parameter points to the Object that carries Possibilities Line.
Writes the words after the count of codes still possible: possibility remains when only one code is left, possibilities remain otherwise.
possibilitiesLineData StructurePossibilities Line$low == $high- Component Value
line.possibilitiesLine.words- Value
data('Safe Copy','One Possibility Remains','text')
- Component Value
line.possibilitiesLine.words- Value
data('Safe Copy','Possibilities Remain','text')
2.6.2 Show Possibilities
Show Possibilities sits on the Possibilities line and calls Write Possibilities Line, with self as its line. It does it twice, the way Show Entry did in Chapter 1: once on Create, for the start, and once on Variable Changed, for every change after.
This time the Variable Changed Event has no Global in its When bar. The words depend on two Globals, $low and $high, and a clue moves either one. So when its window asks for the Global Variable, pick Any Global Variable, first on the list. On the canvas, under When, it reads When any global variable changes. The card’s heading is shorter. On Variable Changed is the name Myth itself gives an Event like this one, so yours will match it.
Keeps the words after the count of codes still possible right, from the start and whenever the range changes.
Any Objectself.possibilitiesLine- line
self
- line
self
The Possibilities line is a Screen UI Object. As with Safe Rules, attach its Data Structure first, with Possibilities Line picked, and then its Logic.
Window / UIUI{$high - $low + 1} {words}14Medium#AABCC6VectorPossibilities LinePlace the Range Line and the Possibilities.
Run the game. Low on the screen, it reads POSSIBLE CODE: 1 - 100, and across from it, 100 possibilities remain. Press Enter. One end of the range jumps to the far side of the 50, and the count drops to about half.
2.7 Open, or Out of Scans
Now a trial can end.
Find the code in the game you have now, and the message says UNLOCKED! But the safe stays shut, and the keypad still types. This part fixes both.
2.7.1 Show Safe Door
Show Safe Door sits on the Safe and listens for Game State Changed. That Event runs each time Set Game State changes the phase.
When it runs, it asks Check Game State whether the trial is Unlocked, and calls the answer safeIsOpen. If it is, Set Sprite shows the Unlocked Safe picture. If not, the Locked Safe. Set Sprite’s Sprite is a list of your pictures, so pick each one there. The card gives the name to pick.
From the safe’s point of view, there’s nothing to remember. It doesn’t hold whether it’s open. It looks at the Game State each time it changes, and wears the picture that fits.
Its card asks for no Data Structure, because any Object with a picture will do.
Shows the safe open while the trial is Unlocked, and closed in every other phase.
Any Object- Action Name
safeIsOpen- Game State
Unlocked
safeIsOpen.value == true- Sprite
Unlocked Safe
- Sprite
Locked Safe
Window / UIUIX 408, Y 408-1Locked SafeX 408, Y 4082.7.2 Type Digit, Erase Digit and Clear Entry
Once the trial is over, the keypad should stop. So all three Functions now ask Check Game State first, with the Action Name safeIsLocked, as Scan Guess does. Locked, and they do their work as before. Otherwise, nothing changes but the message: “Code sealed.” The trial is over, and R starts the next one.
Erase Digit and Clear Entry change alike. On each Changes card, every old line is marked Delete. The same two Actions come back inside the new If, marked Add. So delete the old blocks. Then build each one again, down its card, from the top.
Removes the last digit of the entry (Back) while the safe is Locked. The next digit typed is added to what is left.
safeStateData StructureSafe State- Variable
$entry- Value
floor($entry / 10)
- Component Value
safeRules.safeState.startsNewEntry- Value
false
- Action Name
safeIsLocked- Applies to
safeRules- Game State
Locked
safeIsLocked.value == true- Variable
$entry- Value
floor($entry / 10)
- Component Value
safeRules.safeState.startsNewEntry- Value
false
- Variable
$message- Value
data('Safe Copy','Code Sealed','text')
Empties the entry (Clear) while the safe is Locked, so the next digit typed is its first digit.
safeStateData StructureSafe State- Variable
$entry- Value
0
- Component Value
safeRules.safeState.startsNewEntry- Value
false
- Action Name
safeIsLocked- Applies to
safeRules- Game State
Locked
safeIsLocked.value == true- Variable
$entry- Value
0
- Component Value
safeRules.safeState.startsNewEntry- Value
false
- Variable
$message- Value
data('Safe Copy','Code Sealed','text')
Type Digit changes more, so its card here is the whole Function, not a Changes card. Delete its blocks and build it again from the top.
One thing inside is new. It no longer sets the entry to the digit. It sets the entry to 0, turns startsNewEntry false, and lets the adding do the rest. That’s Clear Entry’s trick from Chapter 1. So the two Ifs inside sit one after the other, with no Otherwise between them.
The second of those Ifs, step 6, needs care. It goes on step 2’s True line, below step 3’s If, and not inside it. So right-click step 2’s If, choose Add Inside Then, and pick If. Connect to Sequence joins it to the end of that True line, which is right where it belongs.
Step 9’s Otherwise belongs to the outer If, step 2. Add Else there, rather than on the range guard you finished inside it.
Adds one typed digit to the entry while the safe is Locked. The first digit after a finished entry starts a new entry; later digits are added on the right while the entry is below the highest code.
safeStateData StructureSafe State- Action Name
safeIsLocked- Applies to
safeRules- Game State
Locked
safeIsLocked.value == truesafeRules.safeState.startsNewEntry == true- Variable
$entry- Value
0
- Component Value
safeRules.safeState.startsNewEntry- Value
false
$entry < data('Safe Settings','Standard Safe','highestCode')- Variable
$entry- Operator
*=- Value
10
- Variable
$entry- Operator
+=- Value
digit
- Variable
$message- Value
data('Safe Copy','Code Sealed','text')
Run the game, and scan until the safe opens. The door swings open on gold bars, stacked coins and a blue gem. The message says UNLOCKED! The range is the one code, and 1 possibility remains. Now press a digit: “Code sealed.” Press R, and the door shuts on a new code.
2.9 If It Didn’t Work
Something will be a little off the first time, and that’s part of building. Run the game, scan, and watch what the message says. It’s the best clue you have.
Nothing happens when you press Enter? Perhaps the new Event in Keypad Keys has no Command, or a block in Scan Guess stands apart, with no arrow into it. Look at the Scan Command’s key, too. Enter works, but SCAN doesn’t? Then look for scanClicked, spelled the same, on the Scan Button and in Button Clicks.
The message always says “Start a new safe.”? Then the trial isn’t Locked, and Scan Guess turns every guess away. Look at Initial Game State in Game Settings, and at Start New Safe’s Set Game State.
Every guess says “Use the remaining range.”? Perhaps $low and $high are both still 0. New Safe should call Start New Safe when the game starts, and Start New Safe sets them both. Look too at Scan Guess’s condition: $entry >= $low && $entry <= $high.
HIGHER when the code must be lower? Look at Check Guess. When the guess is below the code, the clue is 1, not -1.
The clue is right, but the range never moves? Look at Follow the Clue’s two Change Variables, $lastGuess + 1 for $low and $lastGuess - 1 for $high. One may have gone into the other’s box.
The count goes past 7, and OUT OF SCANS never comes? Look at the scanBudget cell, and at the If in Follow the Clue that compares $scans with it. Is it inside the HIGHER-or-LOWER If, on one side only? It belongs after it, at the end of step 6’s Else.
Does a digit change the entry after UNLOCKED? Look at Type Digit’s outer If, step 2, and the Else that should hang from it at step 9. Move the Else there, run again, and the message can say “Code sealed.”
A digit still changes the entry after the safe opens? Look at Type Digit’s step 9. Its Else belongs to step 2, the Locked test. Move it there, run again, and the message can say “Code sealed.”
The safe never opens? Perhaps Show Safe Door isn’t on the Safe. Look at its two Set Sprites too, each with its own picture picked.
The words stay “possibilities remain” with one code left? Look at Show Possibilities’ second Event. On the canvas, under When, it should read When any global variable changes.
Each of these is one small fix. Make it, run the game, and you’re back with the chapter. The catch-up download in the Goal is this chapter’s game, finished, if you’d like to compare.
Make a harder safe, or a bigger one. In Safe Settings, change scanBudget to 5, and see how often you still get in. Or give highestCode a bigger number, such as 1000, and pick the scanBudget you think is fair. Nothing else needs to change. The counter, the range and the keypad all read the table. Before you start Chapter 3, set them back to 100 and 7, so your game matches the cards that come next.
The safe answers now, one true clue at a time. In Chapter 3, you watch the range shrink, a mark at a time.
