- Learn
- Build a Game
- Chess
- 8 The Hint
8 The Hint
By the end of this chapter, a Hint button sits in the row. Press it on your Turn. The Computer suggests a Move, and its two Squares turn blue-green while a message under the Board names it.
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 9 from it.
To open it, right-click the downloaded file, choose Extract All... and then Extract. Start Myth Engine, choose File › Open Project... and pick the .mythproj file in the new folder. CREDITS.md and the licenses folder beside it come with the game.
8.1 The Idea
Play your game from Chapter 7, and stop a few Moves in, when it’s your Turn. Every Piece seems to have somewhere to go. Which one? The Computer across the table would know, because it’s been choosing Moves all game.
This chapter lets you ask it. A Hint is the Move the Computer would play in your place. Press Hint, and for a moment the words under the Board say Finding a hint…. Two Squares turn blue-green. They’re the Square to move from and the Square to move to. A dark green bar, laid on top of the buttons, says it in words: Try e2 to e4.
You’ve met the hard part already. Asking for a Hint is the letter from Chapter 7, posted again. The question goes to Stockfish, the game goes on, and the answer comes back later as a message of its own, hintChosen. While it’s on its way, the sign says a sixth Game State, Finding A Hint, and the Board takes no clicks.
The new idea is smaller, and quieter. A Hint is only good for the position it was asked about. Move one Piece, and it’s out of date. So the game keeps the Hint in one place, a row named Hint, and two pieces of Logic read it. Every click on the Board empties that row. An empty row is no Hint at all, and the blue-green goes.
8.2 The Plan
Here’s how the pieces work together. Read each line from left to right, once now for the shape, and again after your first Hint.
- Hint is pressed -> Report Hint sends hintPressed -> Give A Hint turns the sign to Finding A Hint and asks Stockfish.
- Stockfish answers -> hintChosen -> Give A Hint checks the Move with Find Legal Moves.
- The Move is legal -> hintFound -> Show Hint Message shows the bar. And positionChanged -> Square Marks colors the two Squares.
- No answer in time, or a Move that isn’t legal -> Mark Hint Not Found -> the words say A hint could not be found.
- A click on the Board, or Undo -> Forget The Hint empties the Hint’s row, and the blue-green goes.
8.3 Set Up
Playing, Promotion, Game Over, Computer's Turn, Computer Unavailable, Finding A HintFinding A Hint joins the Game States, after Computer Unavailable. The two placements wait for the last part of the chapter, once the Hint Message exists.
8.4 What the Computer Reads Now
A Hint needs a little more to read, and a place for its answer.
8.4.1 Hint Strength
One row of the "Hint Strength" Data Table, which follows it. How hard Stockfish searches for a Hint, whatever Strength the Computer plays at (the Stockfish Bridge reads it). One row, Hint. skillLevel: Stockfish's Skill Level, from 0 (weakest) to 20 (strongest). thinkingSeconds: how long Stockfish thinks, in seconds.
200.5Hint Strength has one row, Hint. Its skillLevel is 20, the best Stockfish plays, and it thinks for half a second. Whatever Strength the Computer plays you at, a Hint is the strongest Move it can find. Why a table, and not a Shared Variable? The Stockfish Bridge reads it too.
8.4.2 Chosen Moves
Chosen Moves gets a second row, Hint, as empty as the first. Stockfish writes its Hint here, the way it writes its own Move into row Computer.
8.4.3 Kinds
One row of the "Kinds" Data Table, which follows it. One row per Kind of Piece, one column per Side. White and Black: the frame of the Piece Set art that shows this Kind for that Side (every Piece Set art keeps the same frame order). The columns are named for the Sides, so the Side of a Piece picks its column. promotionWords: what the Hint message adds when its Move promotes a Pawn to this Kind (empty for the King and the Pawn, which a Pawn never becomes).
0617, promote to queen410, promote to rook28, promote to bishop39, promote to knight511Kinds, from Chapter 1, gets a Text column, promotionWords. Add that field to Kinds Entry, with its Value cleared. The table shows it at once. A Hint can promote a Pawn, and the message says so: Try e7 to e8, promote to queen. Each of the four words starts with a comma and a space, because it goes on the end of the message. Type them that way. The King’s and the Pawn’s stay empty, because no Pawn is ever promoted to either one.
8.4.4 Words
Your moveCheckPromotion: choose a PieceYou win · CheckmateYou lose · CheckmateDraw · StalemateDraw · Insufficient materialDraw · Fifty-move ruleDraw · Threefold repetitionThinking…Opponent disconnectedFinding a hint…A hint could not be found.Two rows join Words. Finding a hint… ends with the same three dots as Thinking…. They’re one character, not three periods, so copy it from the card.
8.4.5 Stockfish Bridge
stockfish-bridge.js, from the zip781.9 KB783.7 KBstockfishBridgeStockfishBridgeClassic BuildThe Library’s file grows. It can find a Hint now, as well as the Computer’s own Move. Download Chapter 8’s zip from the card, and unzip it. Then open the Library’s Source section, press Import .js… again, and pick stockfish-bridge.js in the new folder. Look at the Alias afterward. It should still say stockfishBridge.
The new zip carries the same CREDITS.md and licenses folder as Chapter 7’s. Yours are already beside your project.
8.5 Forgetting the Hint
Before the game can show a Hint, it learns to let one go.
8.5.1 Forget The Hint
Forgets the Hint: the Chosen Moves table's row Hint is emptied, so no Square shows it any more (the Squares redraw on the next "positionChanged").
- Table
Chosen Moves- Row
"Hint"- Column
"from"- Value
''
- Table
Chosen Moves- Row
"Hint"- Column
"to"- Value
''
- Table
Chosen Moves- Row
"Hint"- Column
"landingKind"- Value
''
Forget The Hint empties the three cells of the Hint row. That’s all forgetting is. Nothing is hidden or switched off. The next time the Squares redraw, none of them finds its name in the row.
8.5.2 Open Promotion Choice
Opens the Promotion choice for a Pawn that is about to reach its last Rank: the Board waits (Game State Promotion), the status line asks for the Piece, and the Promotion panel is shown; Choose Promotion then makes the Move. gameRules: the Game Rules Object. square: the Square the Pawn will be promoted on.
boardStateData StructureBoard State- Component Value
gameRules.boardState.promotionSquare- Value
square
- Variable
$status- Value
data('Words', 'Promotion', 'text')
- UI Group
"Promotion"
- Game State
Promotion
Select and Move has grown long since Chapter 2. Its four Promotion steps from Chapter 4 now move into a Function of their own, Open Promotion Choice. They’re the same four steps. The Promotion Square comes in as square, and the Game Rules as gameRules. Step 3’s UI Group is still "Promotion", with its quote marks, as in Chapter 4.
8.5.3 Select and Move
Decides what a click on a Square means. A click on a Square the selected Piece may move to makes that Move (Make Move: castling and en passant included) and tells the Game Rules "moveMade" (Start Turn then starts the other Side's Turn); when the Move takes a Pawn to its last Rank, it opens the Promotion choice instead (Game State Promotion), and Choose Promotion makes the Move. A click on a Piece of the Side to move selects it and marks its Legal Moves (Find Legal Moves); any other click clears the selection. Then it tells everyone "positionChanged". Its Other is the clicked Square. Every click forgets the Hint (Forget The Hint).
Any Objectself.boardStateself.selectAndMoveData- Type
Text- Name
selectedSquare
- Type
Text- Name
clickedSquare
- Variable
clickedSquare- Value
other.squareInfo.name
- Variable
selectedSquare- Value
self.boardState.selected
selectedSquare != "" && data('Targets', clickedSquare, 'reachable') == true- Component Value
self.selectAndMoveData.side- Value
self.boardState.sideToMove
data('Position', selectedSquare, 'kind') == "Pawn" && data('Position', clickedSquare, 'rank') == data('Sides', self.selectAndMoveData.side, 'promotionRank')- Component Value
self.boardState.promotionSquare- Value
clickedSquare
- Variable
$status- Value
data('Words', 'Promotion', 'text')
- UI Group
"Promotion"
- Game State
Promotion
- gameRules
self- square
clickedSquare
- gameRules
self- from
selectedSquare- to
clickedSquare
- Custom Event
moveMade
data('Position', clickedSquare, 'side') == self.boardState.sideToMove && clickedSquare != selectedSquare- Component Value
self.boardState.selected- Value
clickedSquare
- from
clickedSquare- enPassantSquare
self.boardState.enPassantSquare
- Component Value
self.boardState.selected- Value
''
- Custom Event
positionChanged
Two changes. Step 3, Forget The Hint, goes before the click is read. Only the two Declares come before it. So every click on the Board forgets the Hint, whatever the click turns out to mean. It goes before an old step. Add Forget The Hint apart from the line, then use the round handles to join it after the second Declare, as in Chapter 4. The old steps follow it.
The other change is inside the Promotion If. Delete the four struck steps, and its True line is empty. Use the inner If’s Add Inside Then to add Open Promotion Choice, with self and clickedSquare, and join it there.
8.5.4 Undo
Takes back the Player's last Turn when the Player presses Undo ("undoPressed"): the Computer's reply and the Player's Move before it, or only the Player's Move when the Computer has not replied (it is still thinking, or the game ended on that Move). Then that Turn starts again, as play went: a finished game is played again, and if the Turn is the Computer's (a Player who plays Black, back at the start), the Computer moves again. A Stockfish answer still on its way counts for nothing, because the Game State is no longer Computer's Turn. Undo answers only when a Move has been made, and not while the Promotion choice or a menu (the New Game panel) is open. Undo forgets the Hint (Forget The Hint).
Any Objectself.boardStateself.undoDatadataCount('Move History') > 0- Component Value
self.undoData.movesKept- Value
dataCount('Move History') - 1
self.boardState.sideToMove == self.boardState.playerSide && self.undoData.movesKept > 0- Component Value
self.undoData.movesKept- Operator
-=- Value
1
- gameRules
self- movesKept
self.undoData.movesKept
- Game State
Playing
- gameRules
self
- Custom Event
positionChanged
Undo forgets the Hint too. A Hint from before the Moves you took back would point at the wrong Board. Its new step 2 goes first inside the If. Right-click the If, choose Add Inside Then, and pick Forget The Hint. Use the round handles to join it first on that panel’s line, ahead of the old step. The rest of the If stays behind it.
Run the game. It plays the way it did. Promote a Pawn if you can, and the Promotion choice still opens.
8.6 Asking for a Hint
Now the question, and its answer.
8.6.1 Mark Hint Not Found
Gives up on the Hint: nothing is marked, the game is played again (Game State Playing), and the status line says that no Hint could be found. gameRules: the Game Rules Object.
boardStateData StructureBoard State- Applies to
gameRules- Timer Name
"hintWait"
- Game State
Playing
- Variable
$status- Value
data('Words', 'Hint Not Found', 'text')
- Custom Event
positionChanged
Mark Hint Not Found is what happens when no good Hint comes. It forgets any Hint, gives the Board back to you, and says A hint could not be found. under the Board.
8.6.2 Give A Hint
This card has three Events. They’re the Computer’s Turn from Chapter 7, told again, with a Hint in place of a Move.
Make Give A Hint Data before its Logic, and add it beside Board State on the canvas’s Data Structures card. Its slot name is giveAHintData. It keeps the suggested Move and the wait time while the answer comes back.
What Give A Hint remembers on the Game Rules. fromSquare and toSquare: the Hint's Move. waitSeconds: how long the Board waits for Stockfish's answer (the Hint Strength's thinking time and spareSeconds).
Gives the Player a Hint. When the Hint button is pressed ("hintPressed") on the Player's Turn (Game State Playing), the selection is cleared, the Board waits (Game State Finding A Hint), the status line says a Hint is being found, and the Stockfish Bridge asks Stockfish for a Move at the Hint Strength (the Hint Strength table). When Stockfish answers ("hintChosen"; the Move is in the Chosen Moves table, row Hint) and the Move is a Legal Move, the game is played again, the status line shows the Turn again (Look For Check), everyone hears "hintFound" (the Hint message shows it), and the Squares redraw ("positionChanged") with the Hint marked. When the Move is not legal, is empty, or has not come within the Hint's thinking time and spareSeconds more (the hintWait timer), no Hint is shown (Mark Hint Not Found). spareSeconds: how much longer than its thinking time Stockfish may take to answer, starting Stockfish included.
Any Objectself.boardStateself.giveAHintData- Action Name
isPlaying- Game State
Playing
isPlaying.value == true- Component Value
self.boardState.selected- Value
''
- Game State
Finding A Hint
- Variable
$status- Value
data('Words', 'Finding Hint', 'text')
- Java Script
lib.ext.stockfishBridge.chooseHint(api, ctx.self);
- Component Value
self.giveAHintData.waitSeconds- Value
data('Hint Strength', 'Hint', 'thinkingSeconds')
- Component Value
self.giveAHintData.waitSeconds- Operator
+=- Value
@self.spareSeconds
- Timer Name
"hintWait"- Repeat Every (s)
self.giveAHintData.waitSeconds- Ring Once
Yes
- Custom Event
positionChanged
- Action Name
isFinding- Game State
Finding A Hint
isFinding.value == true- Timer Name
"hintWait"
- Component Value
self.giveAHintData.fromSquare- Value
data('Chosen Moves', 'Hint', 'from')
- Component Value
self.giveAHintData.toSquare- Value
data('Chosen Moves', 'Hint', 'to')
- from
self.giveAHintData.fromSquare- enPassantSquare
self.boardState.enPassantSquare
data('Targets', self.giveAHintData.toSquare, 'reachable') == true- Game State
Playing
- gameRules
self
- Custom Event
hintFound
- Custom Event
positionChanged
- gameRules
self
- Action Name
isStillFinding- Game State
Finding A Hint
isStillFinding.value == true- gameRules
self
On Hint Pressed first asks the sign. Is it Playing? That means it’s your Turn, in a game that goes on. While the Computer thinks, the sign says Computer’s Turn, and a press does nothing. If it’s Playing, the selection and its dots are cleared, and any older Hint is forgotten. The sign turns to Finding A Hint. $status says so too.
Step 8 is your second line of code, Run Code (JS) again, and it asks the Library for a Hint. Type it exactly as the card has it. A clock starts next, as in Ask The Computer: the Hint’s half second of thinking, and spareSeconds more, 20 seconds of patience. Its timer is hintWait, and like answerWait in Chapter 7, it rings once and stops.
On Hint Chosen hears the answer. Is the sign still Finding A Hint? An answer that comes after Undo or New Game counts for nothing. The outer Else forgets it, so it’s never shown.
If it is, it stops the clock and reads the Move from the Hint row. Find Legal Moves checks it, as it checked the Computer’s. A legal Move clears the dots, which were filled only to check, and turns the sign back to Playing. Look For Check puts Your move or Check back under the Board. Then hintFound and positionChanged go out. A Move that isn’t legal clears the dots and gives up, with Mark Hint Not Found.
On the Hint Wait Timer is the clock ringing. If the game is still finding a Hint, it gives up too.
8.6.3 Report Hint and Can Ask For A Hint
Asks whether the Hint button can be used: on the Player's Turn in a game that goes on (Game State Playing). isOn (returned): true when it can.
- Type
Boolean- Name
isOn- Value
false
- Action Name
isPlaying- Game State
Playing
isPlaying.value == true- Variable
isOn- Value
true
- Value
isOn
What the Hint button does: it tells whoever listens (the Game Rules) with "hintPressed". After every change on the Board ("positionChanged"), which the Game Rules also send when the game begins, it asks Can Ask For A Hint whether the button can be used now, and turns it on or off (Show Button On Or Off).
Any ObjectUI Interaction- Custom Event
hintPressed
- Action Name
canUse
- button
self- isOn
canUse.value
Report Hint sends hintPressed on UI Activated. On positionChanged it asks Can Ask For A Hint, named canUse, and hands canUse.value to Show Button On Or Off. It works like Report Undo. Can it be pressed now? Only while the sign says Playing, on your Turn in a game that goes on.
8.6.4 Game Rules
Board StateSelect and MoveSelect and Move DataChoose PromotionChoose Promotion DataMake Computer MoveMake Computer Move DataUndoUndo DataGive A HintGive A Hint DataAttach Give A Hint to the Game Rules.
8.7 Showing the Hint
The answer has come. Now the Board shows it, and so does a bar of words.
8.7.1 Square Marks
Shows the highlight on this Square after every change (the Game Rules send "positionChanged" and are its Other): a tint when it was part of the last Move, when its Piece is selected, when it is one of the Hint's two Squares (the Chosen Moves table, row Hint), or when its King is in Check (the most important one shows). The colors, and how strongly each shows, are its Parameters. While the Computer's Move slides ("slideStarted"), no highlight is shown.
Any Objectself.squareInfo- Alpha
0
self.squareInfo.name == other.boardState.lastFrom || self.squareInfo.name == other.boardState.lastTo- Value
@self.lastMoveColor
- Alpha
@self.lastMoveAlpha
self.squareInfo.name == other.boardState.selected- Value
@self.selectedColor
- Alpha
@self.selectedAlpha
self.squareInfo.name == data('Chosen Moves', 'Hint', 'from') || self.squareInfo.name == data('Chosen Moves', 'Hint', 'to')- Value
@self.hintColor
- Alpha
@self.hintAlpha
self.squareInfo.name == other.boardState.checkSquare- Value
@self.checkColor
- Alpha
@self.checkAlpha
- Alpha
0
Square Marks gets one more If, steps 8 to 10. Is this Square the Hint’s from Square, or its to Square? If so, it turns blue-green: hintColor, at hintAlpha, two new constant Shared Variables.
The If goes between the selected Square and the Check. Order matters here. Each If paints over the one before it, so the last color to land wins. A King in Check stays red, even under a Hint. Add the new If apart from the line. Use the round handles to join it after the selected Square’s If, on the main line. The Check’s If follows it. Add the new color and alpha inside the Hint’s If with Add Inside Then, and join each one.
8.7.2 Hint Words
The words of the Hint message. from and to: the Squares of the Move it suggests (a1 to h8). promotion: what it adds when the Move promotes a Pawn (", promote to queen"), or nothing.
Hint Words holds the message’s three pieces: from, to, and promotion, the words on the end.
8.7.3 Show Hint Message
Shows the Hint message ("Try e2 to e4.", with ", promote to queen" when the Move promotes a Pawn) for showSeconds when a Hint has been found ("hintFound"), then hides it. The Move is read from the Chosen Moves table (row Hint) into the message's own Hint Words, which its words show. showSeconds: how long the message stays, in seconds.
Any Objectself.hintWordsUI Interaction- Type
Text- Name
landingKind
- Type
Text- Name
fromSquare
- Variable
fromSquare- Value
data('Chosen Moves', 'Hint', 'from')
- Variable
landingKind- Value
data('Chosen Moves', 'Hint', 'landingKind')
- Component Value
self.hintWords.from- Value
fromSquare
- Component Value
self.hintWords.to- Value
data('Chosen Moves', 'Hint', 'to')
- Component Value
self.hintWords.promotion- Value
''
landingKind != data('Position', fromSquare, 'kind')- Component Value
self.hintWords.promotion- Value
data('Kinds', landingKind, 'promotionWords')
- Timer Name
"messageTime"- Repeat Every (s)
@self.showSeconds- Ring Once
Yes
- Visible
No
Show Hint Message hears hintFound. It copies the Hint’s two Squares into its own Hint Words. Next it asks one question. Does the Piece land as a different Kind from the one standing on the from Square? That’s a Pawn being promoted, and promotion takes the Kinds table’s words for it.
Then the bar shows, with Set UI Element Visibility. Its Visible starts on Yes, so leave it. A timer named messageTime starts, and it rings once, after showSeconds: 4 seconds, long enough to read the Move. When it rings, the bar hides. A new Hint before then starts the time again.
Its Data Structures card needs Hint Words in hintWords, and its Components card needs UI Interaction in ui. That’s how it reaches its words and the bar’s visibility.
8.7.4 Hint Message
Window / UIBottom CenterUIX 460, Y 44Text26Square Highlight#244739X 460, Y 44Try {from} to {to}{promotion}.18Semibold#FFF9EBCenterHint WordsThe Hint Message is a dark green bar, 460 pixels wide and 44 high, with cream words. Its picture is the one every Square wears, from Chapter 2, stretched and tinted, so it’s in your project already. Its Text is Try {from} to {to}{promotion}., so it reads its own Hint Words, as an Option Button reads its option. Its Element Type is Text. It takes no clicks, so the buttons under it still answer while it shows.
Make Hint Button from Tool Button, the way you made Undo Button in Chapter 7. It adds Report Hint and keeps the base Object’s tan.
The Set up card places both. Place Hint Button first, with Hint as its Text.
Place the Hint Message next, hidden, at the bottom of the screen, on top of the buttons. Its Object card sets the Tint to dark green, #244739, so that color is already there.
Run the game. Play a Move, wait for the reply, and press Hint.
For a moment, the words under the Board say Finding a hint…. Then two Squares turn blue-green, one with your Piece on it, and a dark green bar on top of the buttons names the Move. Four seconds later, the bar is gone, but the blue-green stays until you click.
The Computer has been playing against you since Chapter 7. Now it plays for you too, once, when you ask.
Watch for each of these.
- On your Turn, press Hint, and Finding a hint… shows under the Board. Then two Squares turn blue-green, and the bar says Try, then the two Squares.
- The bar hides after 4 seconds. The blue-green stays.
- Click any Square, and the blue-green goes at once.
- Play e2 to e4, and look at Hint while the words say Thinking…. It’s faded. Press it anyway, and nothing happens, because the Computer is still thinking.
- Ask for a Hint, then press Undo. The blue-green goes with the Moves you took back.
- Follow a Hint. Click the Piece on the first blue-green Square, then the second. The Move is made, and the Computer replies.
- Open New Game while Hint is lit. The Backdrop lies over the buttons, so Hint can’t be pressed until the panel closes.
Hint asks, and the game goes on. Stockfish answers with a message, and the game checks the Move before it shows it. The answer sits in one row, Hint. Square Marks reads it and colors two Squares, and Show Hint Message reads it and names the Move. A click, or Undo, empties the row, and both stop showing it.
Underneath is one idea. Keep a thing in one place, and let everything that shows it read from there. And forgetting it is one small job, in one place.
8.8 If It Didn’t Work
This chapter reuses a lot from Chapter 7, so a slip may look like an old one. Watch what the game does, and think it through.
A block drawn in red, with a number on the Errors bar? Open the bar. It names the block and what it misses. Compare that one block with its card.
Hint stays faded on your Turn, even with nothing else going on? Look at Report Hint’s On Position Changed. Both calls need joining, with canUse.value in Show Button On Or Off’s isOn.
Hint lights up, but a press does nothing? Is Give A Hint attached to the Game Rules? Or perhaps the placement’s Object still picks Undo Button instead of Hint Button.
It says Finding a hint… and stays there? Look at step 8’s Run Code line, letter by letter. If it’s right, the Library may still be Chapter 7’s file, which has no Hint in it. Import stockfish-bridge.js again, from Chapter 8’s zip. After 20 seconds or so, A hint could not be found. shows instead, and the game goes on.
The bar shows, but no Square turns blue-green? Look at the new If in Square Marks, where either of those two Squares should match. Its two tests read from and to, joined with ||.
The bar says Try to .? Show Hint Message’s self may have no Hint Words, or its slot isn’t named hintWords.
The blue-green never goes away? Select and Move’s step 3 may still have no arrow into it, and every click needs to run Forget The Hint first.
Each of these is one small fix. Make it, run the game again, 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.
A Hint names one Move. What else could your game tell a player who’s stuck? Perhaps a softer Hint, that colors only the Piece to move and leaves the Square for them to find. Or a Hint that thinks at the Computer’s own Strength, so it’s only as good as the opponent. Hint Strength is one row, two numbers, and both are yours to change. What your Hint knows is up to you.
Still stuck? Search the manual, or ask in the Myth Engine Discord (opens a new tab).
Your game can teach now, a little. In Chapter 9, the Board starts to show what could happen next.
