TutorialsA* Search

1  Slide the Tiles

Goal

By the end of this chapter, the puzzle lies ready on the worktable. Eight Tiles sit out of order on the velvet, and the Goal waits on a parchment card beside them. Click a Tile beside the Blank, and it slides in. Put them all in order, and the card says Solved.

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 2 from it.

8-Puzzle Solver, Chapter 1 finishedMyth project · 3.6 MB

To open it, start Myth Engine, choose File › Open Project... and pick the downloaded file.

1.1 The Idea

Try the game above. Click Tile 5, in the top-left corner, and nothing moves, because Tile 5 isn’t beside the Blank. Now click Tile 4, above the Blank. It glides straight down in 0.22 seconds and lands square.

That’s this chapter’s whole game: the worktable, the Tiles, the Goal on its parchment card, and your hand. The navy bar under the Board stays empty, and only your hands move the Tiles.

To you, the puzzle is eight Tiles on velvet. The game needs something smaller to hold. In Chapter 2, a search will write down dozens of Boards, one after another, and check each new one against the rest. A Board that fits in one number is quick to write down and quick to check. So the game keeps the whole puzzle as one number.

Read the Board the way you read a page. Go along the top row, then the middle, then the bottom, and write each Tile’s number as you go, with a 0 for the Blank. You get 542703816. That’s the Board State, the whole puzzle in nine digits.

Each place on the Board is a Slot. Slots are numbered the same way, from Slot 0 in the top-left corner to Slot 8 in the bottom-right. So the first digit of the Board State is Slot 0’s, and the last is Slot 8’s. The Blank is in Slot 4, the middle.

Think of the Board State as the puzzle written on a slip of paper. The Tiles are a drawing of what the slip says. Change the slip, and the drawing follows.

A Move is one Tile sliding into the Blank, and on the slip it’s a swap: the Tile’s digit and the 0 trade places. Every Move costs the same, one slide. Keep that in mind. In Chapters 2 and 3 you’ll build A* Search, and it finds a Route with the fewest Moves.

The Goal is a Board State too: 123456780, the Tiles in order with the Blank last. The puzzle is solved when the Board State equals it. That’s one comparison of two numbers.

One Object holds the slip and decides every Move. It’s Puzzle Rules, and it has no picture at all. The Tiles only ask it.

Two small Functions you’ll make today, Slot Distance and Board After Move, look modest. Chapter 2’s search runs on both of them.

One more thing, so it doesn’t worry you. Most parts of this chapter end with something new on the screen. The part named Puzzle Rules doesn’t. When you run the game at its end, your Tiles stand exactly where they stood. The part after it, A Move, makes them move at last.

1.2 The Plan

Here’s how the pieces work together. Read each line from left to right. Almost every name in them is new, so read them once for their shape. They’ll make sense one at a time as you build.

  • The Scene starts -> Start Board writes the start Board into $boardState -> each Tile, as it’s created, finds its Slot there and goes to it (Slide To Slot).
  • Each Goal Cell is created -> Show Goal Tile finds its place on the parchment card and its number in the Goal.
  • You click a Tile -> Click To Choose calls Choose Tile -> Choose Tile sends tileChosen to Puzzle Rules.
  • Puzzle Rules hears tileChosen -> Hand Moves checks the Tile is beside the Blank, makes the Move in $boardState, and sends boardChanged.
  • Every Tile hears boardChanged -> the one whose Slot changed slides there -> it sends slideFinished to Puzzle Rules -> Hand Moves listens again.
  • Check Goal hears boardChanged too -> it shows Solved when $boardState equals the Goal.
  • You press a key from 1 to 8 -> Tile Keys calls Choose Tile, the same as a click.

1.3 Set Up

A new project opens on an empty blue Scene. It can feel like a great deal of nothing, and the feeling lasts only until the first thing you place.

If you made a Blank 2D project on the Welcome page and installed the Starter Kit, you’re ready. If not, choose File > New Project… and pick Blank 2D. Name it 8-Puzzle Solver, choose its folder with Browse…, and press Create Project. Then install the Starter Kit with File > Install Myth Pack… and the file from the button below. Myth Engine asks first. Its window says the kit adds 2 resources, the game’s two pictures. Press Install.

8-Puzzle Solver Starter KitMyth Pack · 2642 KB · every picture

To install it, open Myth Engine, choose File › Install Myth Pack... and pick the downloaded file.

Turn on Advanced Mode now, from the Settings menu, because the Tiles glide with two of its blocks. Before your first card, on the Making page, says more.

The Set up card follows these paragraphs. Read them first, then work down the card from the top. Leave three of its blocks for later. COMMANDS come with the keys, in the last part. GLOBAL VARIABLES are made on a Logic Component’s Globals card, so they wait for Start Board, in the part named Puzzle Rules. And each part places its own Objects from PLACE THESE, once they exist.

ART names the two pictures. The Starter Kit brought both, so there’s nothing to make.

The SCENE block names a Scene called Puzzle Table, marked (new). Your project already has one Scene, named Scene, so give it the card’s name instead of making another. In the Resources panel, open Scenes, right-click Scene, choose Rename, and type Puzzle Table. Start Scene follows the new name by itself.

Now open Game Settings, the button at the top of the Resources panel on the left. Enter the card’s GAME SETTINGS lines from the top down. The Set up card on the Making page says where each one lives.

Pixels per Meter comes first, and that’s on purpose. The moment you type the Reference Height, Myth works out the game’s height in meters, at the Pixels per Meter it has then. In the card’s order, that’s 850 pixels at 40 to the meter: 21.25 meters, the game’s own height.

Typed them the other way round? Nothing is lost. Once Pixels per Meter reads 40, type a different number into Reference Height, then 850 again. Myth works the height out afresh each time it changes.

Reference Width and Reference Height make the game’s screen 1000 by 850 pixels. Every X and Y you’ll type for something on the screen counts in those pixels. The Page Background is the dark slate around the game. Click its swatch and type the code into the HEX box.

Now the camera. Open Puzzle Table, pick Select, the arrow above the preview, and click an empty spot. The Scene’s Properties appear on the left. Under Cameras and Views, press Add View. Myth makes the Main Camera and the Main View together, sized from the Game Settings you’ve typed. They already match the card. Check them against its Camera and View lines. Under the View, one line sums it up and ends with 1 meter = 40 screen px.

If a camera number is different, type the card’s over it. The Main Camera’s boxes are right there, under Visible World Area: Position X and Y, then Visible Width and Visible Height. If the View’s pixels are different, look again at Reference Width and Reference Height.

Start Scene should already read Puzzle Table · 2D. It followed the name.

Set upWhat this chapter adds
ART (sprites, from the starter kit)
Observatory Worktable
UI Background
COMMANDS (Game Settings > Input Manager)
Slide Tile 1Button
Keybindings1
Slide Tile 2Button
Keybindings2
Slide Tile 3Button
Keybindings3
Slide Tile 4Button
Keybindings4
Slide Tile 5Button
Keybindings5
Slide Tile 6Button
Keybindings6
Slide Tile 7Button
Keybindings7
Slide Tile 8Button
Keybindings8
GLOBAL VARIABLES
$boardStateNumberstarts at 0
$chosenTileNumberstarts at 0
$statusLineTextstarts at
GAME SETTINGS > General > World Scale
Pixels per Meter40
GAME SETTINGS > Display > Window
Title8-Puzzle Solver
GAME SETTINGS > Display > Reference Resolution
Reference Width1000
Reference Height850
GAME SETTINGS > Display > Page Background (Outside the Game)
Color#101E29
SCENEPuzzle Table (new)
Camera Main CameraX 12.5, Y 10.625, view 25 x 21.25 m
View Main View1000 x 850 pixels, camera Main Camera
GAME SETTINGS > General > Startup
Start ScenePuzzle Table · 2D
SCENE Puzzle Table: PLACE THESE
ObjectXY
Observatory Background500-425
Title500-82
Subtitle500-119
Status Line766-604
Puzzle Rules021.25
Tile337-560
with Data Structure > Values > Number = 1
Tile487-260
with Data Structure > Values > Number = 2
Tile487-410
with Data Structure > Values > Number = 3
Tile337-260
with Data Structure > Values > Number = 4
Tile187-260
with Data Structure > Values > Number = 5
Tile487-560
with Data Structure > Values > Number = 6
Tile187-410
with Data Structure > Values > Number = 7
Tile187-560
with Data Structure > Values > Number = 8
Goal Label766-227
Goal Cell694-317
with Data Structure > Values > Slot = 0
Goal Cell766-317
with Data Structure > Values > Slot = 1
Goal Cell838-317
with Data Structure > Values > Slot = 2
Goal Cell694-389
with Data Structure > Values > Slot = 3
Goal Cell766-389
with Data Structure > Values > Slot = 4
Goal Cell838-389
with Data Structure > Values > Slot = 5
Goal Cell694-461
with Data Structure > Values > Slot = 6
Goal Cell766-461
with Data Structure > Values > Slot = 7
Goal Cell838-461
with Data Structure > Values > Slot = 8

Save your project now with Ctrl+S. Do it again at the end of every part.

1.4 The Worktable

First, the table itself.

Everything behind the Tiles on the Welcome page is one picture. The dark wood, the brass frames, the velvet Board, the parchment card, the navy bar, the lantern and the star charts are all the Observatory Worktable. It’s drawn 1000 by 850 pixels, so it fills the whole screen.

It goes on a Screen UI Object, the Observatory Background, with a Sprite whose Scene Depth Draw Order of -30 keeps it behind everything else. An Object card and its components on the Making page shows how. Read it down to the paragraph on UI Interaction. The rest waits for the Tile. A new Screen UI Object comes with UI Interaction, but the worktable’s card doesn’t list it, so remove it.

The card gives the size twice. Under Transform, the Bounding Box is the Object’s own box, and the Sprite’s Transform > Size is how big the picture is drawn. On every card in this game, the two match.

ObjectObservatory Background
Transform
Presentation > SpaceWindow / UI
Presentation > Render LayerUI
Bounding Box > SizeX 1000, Y 850
Sprite
Scene Depth Draw Order-30
Z Index Within Object-30
SpriteObservatory Worktable
Transform > SizeX 1000, Y 850

The plate at the top of the picture is blank, and the words on it are yours to add. The Title says 8-puzzle (A*) in pale gold. Under it, smaller, the Subtitle says Slide tiles into order. Each is a Screen UI Object with a Text / UI and nothing else, so remove UI Interaction from both.

ObjectTitle
Transform
Presentation > SpaceWindow / UI
Presentation > Render LayerUI
Text / UI
Text8-puzzle (A*)
Font Size32
EmphasisSemibold
Color#F4E4BF
AlignmentCenter
RenderingVector
ObjectSubtitle
Transform
Presentation > SpaceWindow / UI
Presentation > Render LayerUI
Text / UI
TextSlide tiles into order.
Font Size16
EmphasisSemibold
Color#E0CDA5
AlignmentCenter
RenderingVector

Now place all three. Open Puzzle Table, find each one under Predefined Objects in the Place Scene Content panel, and drag it onto the Scene. Type its X and Y into its Screen Offset (px). The worktable goes at 500 and -425, the Title at 500 and -82, and the Subtitle at 500 and -119.

Across, 500 is the middle of the screen. Down, a minus sign means below the top edge, because up counts as positive there. So -425 is halfway down.

Run the game: press Play, the triangle at the top of the editor. The worktable fills the window. The plate reads 8-puzzle (A*), with its smaller line under it, and the velvet Board is empty. Close the game’s window to come back.

The table is set for a puzzle.

1.5 Eight Tiles

Now the Tiles.

Each one is a cream square, 142 pixels across, with a big slate-blue number. They stand 150 pixels apart, so a thin line of navy velvet shows between them.

There are eight Tiles but only one Tile Object, placed eight times, and each placement carries its own number. Tile 5 is always the same Tile, wherever it slides.

That number lives in a Data Structure, a small form of named fields that an Object carries. This one, Numbered Tile, has a single field, number. A Data Structure card on the Making page shows how to make it.

Data StructureNumbered Tile

The number a Tile carries, 1 to 8. Each Tile placement sets its own; the Tile shows it and its Logic reads it.

numberNumberdefault 0

The Tile is a number on a picture. The picture is UI Background, the tiny white square from the Starter Kit, drawn at 142 pixels and tinted cream on each placement. Its Z Index Within Object of -1 keeps it under the number. The number is the Text {number}, braces and all: it shows the number field of the Tile’s own Numbered Tile.

The Tile keeps its UI Interaction. That’s what will let a click reach it.

The card says Numbered Tile comes From Logic, because in the finished game Slide To Slot brings it. Your Tiles need their numbers now, though. So attach it yourself: Data Structure is under Data in the Component Toolbox, and Numbered Tile is in its Data Structure list. When Slide To Slot arrives later, it finds this one and uses it. No second copy is made. Your Tile’s Data Structure part won’t say From Logic, and that’s all right.

The card’s foot lists two Logic Components and a Shared Variable that don’t exist yet. Leave them off for now.

ObjectTile
Transform
Presentation > SpaceWindow / UI
Presentation > Render LayerUI
Bounding Box > SizeX 142, Y 142
Text / UI
Text{number}
Font Size50
EmphasisBold
Color#233947
AlignmentCenter
RenderingVector
Sprite
Z Index Within Object-1
SpriteUI Background
Transform > SizeX 142, Y 142
Tint (on its placement)#F1E8D3
UI Interaction(as it is added)
Data Structure
From LogicSlide To Slot, Click To Choose
Data StructureNumbered Tile
Logic
Slide To Slot
Click To Choose
Shared Variables
puzzleRulesPuzzle Rules

Then place eight Tiles from PLACE THESE, the last block of the Set up card. The link takes you to the top of the card, so scroll down past the Game Settings to its foot. Your browser’s Back button brings you here again. Under each Tile is a line like with Data Structure > Values > Number = 1. That’s the placement’s own number. Give each Tile its Tint, #F1E8D3, too. A placement’s own values on the Making page shows where both of them go.

Look at where the card puts them. Tile 5 goes at 187 and -260, the top-left Slot, with Tile 4 beside it and then Tile 2. They’re placed exactly as the puzzle starts.

Run the game. Eight cream Tiles sit on the velvet: 5 4 2 across the top, then 7, an empty square and 3, then 8 1 6 across the bottom. Click one. Nothing happens yet. For now the Tiles are only a picture of a puzzle.

1.6 The Goal on Its Card

Next, the picture on the parchment card that shows where the Tiles belong.

On the parchment card, under the word Goal, sits a small picture of the solved puzzle: 1 2 3, 4 5 6, 7 8, and a last cell, empty and a shade darker than the rest. Each of the nine cells is a Goal Cell, 64 pixels square.

You could type a number into each cell by hand. The game doesn’t. It reads the Goal from a table and draws whatever the Goal says. Change the Goal, and the picture follows.

Two tables hold the facts. Puzzle Settings has one row, puzzle, with two Board States: startBoard, the puzzle the game opens with, and goalBoard, the Goal. A Data Table card on the Making page shows how to make a table.

Data TablePuzzle SettingsData Structure: Puzzle Settings Entry
Row 0puzzle
startBoard542703816
goalBoard123456780

The table’s columns are the fields of its own Data Structure, Puzzle Settings Entry, which Myth makes with the table. Give it its two fields first. Their defaults are the puzzle’s own numbers, so the new row comes out right, and you only name it puzzle.

Data StructurePuzzle Settings Entry

One row of the "Puzzle Settings" Data Table.

startBoardNumberdefault 542703816
goalBoardNumberdefault 123456780

Board Layout says where each drawing of a Board sits on the screen, one row for each. The board row is the Board you play on. The goalPicture row is the small copy on the parchment card, with its Slots closer together. In each row, boardLeft and boardTop are the center of Slot 0, the top-left Slot, and slotSpacing is how far apart the Slots stand.

Data TableBoard LayoutData Structure: Board Layout Entry
Row 0board
boardLeft187
boardTop-260
slotSpacing150
Row 1goalPicture
boardLeft694
boardTop-317
slotSpacing72

Board Layout Entry works the same way, and its defaults are the board row’s numbers. Only the goalPicture row needs new ones.

Data StructureBoard Layout Entry

One row of the "Board Layout" Data Table.

boardLeftNumberdefault 187
boardTopNumberdefault -260
slotSpacingNumberdefault 150

Each Goal Cell carries a Goal Slot, a Data Structure of two fields. The first, slot, says which Slot of the picture the cell shows. The second, label, is the number it shows. It starts empty, so clear its Value box, and the Blank’s cell keeps it that way.

Data StructureGoal Slot

What one Goal Cell shows. slot is the Slot of the Goal Picture it shows (0 to 8, in reading order), set on each placement; label is the number it shows: the Tile the Goal has in that Slot, empty for the Blank.

slotNumberdefault 0
labelTextdefault (empty)

1.6.1 Tile In Slot

Here is the chapter’s hardest idea, so it gets the most room.

Tile In Slot answers one question: which Tile is in this Slot? You hand it a Board State and a Slot, and it hands back tile, the digit in that place, with 0 for the Blank.

How do you pull one digit out of a number? With two moves from ordinary arithmetic. Dividing by 10 pushes the last digit past the decimal point, and floor() throws away everything after the point. And % 10, the remainder after dividing by 10, keeps only the last digit.

Count it out for Slot 1 of 542703816. Slot 8 holds the last digit, so after any Slot come 8 - slot more digits. After Slot 1, that’s seven. The pow(10, 8 - slot) in the formula is a 1 with that many zeros after it, ten million here. Dividing by it pushes all seven past the decimal point, and floor() throws them away. What’s left is the first two digits, a 5 and a 4. And % 10 keeps the last of those, 4. Tile 4 is in Slot 1, top middle, as the Board shows.

Ask about Slot 4, and the answer is 0. That’s the Blank.

The whole answer fits in one line. That’s the Value of its only Action, a Return, which gives the answer back. Its RETURN TYPE is Number.

It’s your first Function. A Function card on the Making page shows how to make one, with its PARAMETERS, its RETURN TYPE and its Return.

FunctionTile In Slot

Which Tile is in one Slot of a Board State: 0 for the Blank. The Board State's first digit is Slot 0 (the top-left cell) and its last digit is Slot 8.

PARAMETERS
NameTypeStarts at
boardNumber0
slotNumber0
RETURN TYPENumber
ACTIONS
1Return
Value
floor(board / pow(10, 8 - slot)) % 10

1.6.2 Slot Position

No player ever sees Slot Position, yet every Tile and every Goal Cell asks it where to stand. It’s the one place where a Slot becomes a spot on the screen.

It works in two moves. First, the Slot’s column and row: the column is what’s left over when slot is divided by 3, and the row is how many whole rows of 3 come before it. Second, pixels. It starts at the Slot 0 center from Board Layout, adds slotSpacing for each column across, and takes away slotSpacing for each row down.

It takes away because up counts as positive on the screen, so a lower row has a smaller y.

Which drawing? That’s layout, a word naming a row of Board Layout: board for the Board, goalPicture for the Goal picture. One Function serves both.

It hands back two numbers, x and y, so its answer is a small Data Structure, Slot Position Result. Make that first. Then it’s on the Return Type list.

Data StructureSlot Position Result

What Slot Position gives back: x and y, the center of the Slot on screen.

xNumberdefault 0
yNumberdefault 0

Slot Position is the first Function with a line of Actions, seven blocks hanging from the Start block at the top of the canvas. Two Declare Variables make slotX and slotY, which live only while it runs. Four Change Variables work them out. Last, the Return gives both back, as x and y. Actions, one at a time shows how to add each one, join it to the line and set its Operator.

Join all seven. A block left standing apart from the line does nothing when the game runs, and the Goal Cells would land in the wrong places.

In the editor, a Change Variable’s box may show self in front, as in self.slotX. It’s the same Variable.

FunctionSlot Position

Where one Slot of a Board drawing is on screen: the center of that Slot, from the Board Layout row named by layout ("board" for the Board, "goalPicture" for the Goal Picture). This is the only place a Slot is turned into a position.

PARAMETERS
NameTypeStarts at
slotNumber0
layoutTextboard
RETURN TYPESlot Position Result (a Data Structure)
ACTIONS
1Declare Variable
Name
slotX
Value
0
2Declare Variable
Name
slotY
Value
0
3Change Variable
Variable
slotX
Value
data('Board Layout', layout, 'boardLeft')
4Change Variable
Variable
slotX
Operator
+=
Value
(slot % 3) * data('Board Layout', layout, 'slotSpacing')
5Change Variable
Variable
slotY
Value
data('Board Layout', layout, 'boardTop')
6Change Variable
Variable
slotY
Operator
-=
Value
floor(slot / 3) * data('Board Layout', layout, 'slotSpacing')
7Return
x
slotX
y
slotY

1.6.3 Show Goal Tile

From one Goal Cell’s point of view, the job is short. It knows its own slot. When it’s created, it asks Slot Position where that Slot sits in the goalPicture layout, and goes there. Next it asks Tile In Slot which Tile the Goal has in that Slot.

If the Goal has a Tile in that Slot, the cell writes the Tile’s number into its own label, as words. That’s text(goalTile.value). If it’s the Blank, the cell writes nothing. It tints its picture a darker cream instead.

Its Set Position counts in screen pixels from the top-left corner, as Screen Offset does, so its Position Relative to list says Screen. World is where the list starts.

Type goalPicture into the layout box bare, the way the card shows it. The card always shows which boxes want quote marks, so step 7’s color keeps its quotes. Values, quote marks and all on the Making page says why the same box can differ from one Logic to the next.

It’s your first Logic Component. A Logic Component card on the Making page shows how to make one. Its Data Structures card gets Goal Slot, from Existing Data Structures, so it reads its slot as self.goalSlot.slot. Events: the When bars shows its Create Event. Its Actions go in the way Slot Position’s did. This time the line runs down from the Event’s Mode block, where Start was. The Else is in If, Else, Repeat and While.

Logic ComponentShow Goal TileAttach to: Goal Cell

Shows one Slot of the Goal in the Goal Picture. Each Goal Cell placement sets the Slot it shows (Goal Slot). When the Goal Cell is created it moves to that Slot of the Goal Picture (Slot Position with the Board Layout row goalPicture) and shows the Tile the Goal (Puzzle Settings / goalBoard) has there; the Blank's cell shows no number and is drawn darker.

Attach toAny Object
DATA STRUCTURES
Goal Slotself.goalSlot
When Created
WhenCreate
1Slot PositionFunction
Action Name
spot
slot
self.goalSlot.slot
layout
goalPicture
2Set Position
Position Relative To
Screen
X
spot.x
Y
spot.y
3Tile In SlotFunction
Action Name
goalTile
board
data('Puzzle Settings', 'puzzle', 'goalBoard')
slot
self.goalSlot.slot
4IfgoalTile.value > 0
Then
5Change Component Value
Component Value
self.goalSlot.label
Value
text(goalTile.value)
6Otherwise
7Change Sprite Tint Property
Value
'#d5c6a7'

The Goal Cell is a small Tile, made the same way, with its label where a Tile shows its number. Attach Show Goal Tile, and its Goal Slot arrives From Logic. It has no UI Interaction, because nobody clicks the Goal. The Goal Label is the word Goal above the cells, made like the Title.

ObjectGoal Cell
Transform
Presentation > SpaceWindow / UI
Presentation > Render LayerUI
Bounding Box > SizeX 64, Y 64
Text / UI
Text{label}
Font Size32
EmphasisSemibold
Color#233947
AlignmentCenter
RenderingVector
Sprite
Z Index Within Object-1
SpriteUI Background
Transform > SizeX 64, Y 64
Tint (on its placement)#E8D9B9
Data Structure
From LogicShow Goal Tile
Data StructureGoal Slot
Logic
Show Goal Tile
ObjectGoal Label
Transform
Presentation > SpaceWindow / UI
Presentation > Render LayerUI
Text / UI
TextGoal
Font Size21
EmphasisSemibold
Color#233947
AlignmentCenter
RenderingVector

Place the Goal Label at 766 and -227. Next, place the nine Goal Cells from PLACE THESE, at the foot of the Set up card, each with its own Slot, 0 to 8, and its Tint, #E8D9B9.

Run the game. On the parchment card, under Goal, you see 1 2 3, 4 5 6, 7 8, and a darker empty cell. Every one of those numbers came out of goalBoard, the Goal in Puzzle Settings.

The parchment card knows where the Tiles belong.

1.7 Puzzle Rules

Now the puzzle gets a keeper.

Puzzle Rules is an Empty Object, with no picture and no words. The whole puzzle lives on it. That means the Board State, the Moves and, from Chapter 2, the search. The Tiles only ask. Puzzle Rules decides.

1.7.1 Start Board

When the Scene starts, Start Board copies startBoard from Puzzle Settings into $boardState. That’s its whole job in this chapter: it writes the puzzle down. It’s also the first piece to run. A Scene Start runs before the Tiles are created, so the Board State is waiting by the time each Tile appears.

Make Start Board, but give it no Event yet. The three Global Variables come first. One holds the Board State, one the Tile you chose last, and one the words under the Goal. On Start Board’s canvas, press + on the Globals card and choose New Global… for each one in your Set up card’s GLOBAL VARIABLES. Leave off the $: $boardState goes in as boardState. The last one, $statusLine, is Text and starts empty. Clear its Default box.

After that come its Scene Start and its one Action.

Logic ComponentStart BoardAttach to: Puzzle Rules

Sets up the Board State when the puzzle opens: the Start Board from Puzzle Settings.

Attach toAny Object
When the Scene Starts
WhenScene Start
1Change Variable
Variable
$boardState
Value
data('Puzzle Settings', 'puzzle', 'startBoard')

Make Puzzle Rules, an Empty Object, and attach Start Board to it. Its card names three more Logic Components, and each one comes later in the chapter. Its Shared Variable comes with the last of them.

ObjectPuzzle Rules
Logic
Start Board
Hand Moves
Check Goal
Tile Keys
Shared Variables
puzzleRulesPuzzle Rules

Place Puzzle Rules from PLACE THESE. It stands in the world, not on the screen, so its 0 and 21.25 go into World Position. That’s the top-left corner of the screen, in the world’s meters. With no picture, it never shows. But Logic only runs on an Object the Scene has placed, so it has to be there.

1.7.2 Slot Of Tile

Start Board wrote the puzzle down, and now each Tile has to find itself in it. Slot Of Tile asks Tile In Slot’s question the other way round. Where is this Tile?

It looks at every Slot in reading order and asks Tile In Slot what’s there. When the answer is the Tile it wants, it keeps that Slot. A Repeat does the looking. It runs nine times, once for each Slot. If, Else, Repeat and While on the Making page shows how to fill one.

Inside a Repeat, local.index counts the times round, starting at 0. The first time round it’s 0, so Slot Of Tile reads Slot 0, then Slot 1, and on up to Slot 8. So local.index is the Slot.

A Declare Variable makes slot, starting at -1, no Slot at all, and that’s the answer if no Slot holds the Tile. Ask it for Tile 0, and it finds where the Blank is. Hand Moves will need that.

On its card, slot names two things. The Declared slot keeps the answer, and the Return gives it back. In step 3, slot is Tile In Slot’s own Parameter, and local.index fills it.

FunctionSlot Of Tile

Where one Tile is in a Board State: the Slot (0 to 8) that holds it. Tile 0 is the Blank.

PARAMETERS
NameTypeStarts at
boardNumber0
tileNumber0
RETURN TYPENumber
ACTIONS
1Declare Variable
Name
slot
Value
-1
2Repeat9times
Each time
3Tile In SlotFunction
Action Name
digit
board
board
slot
local.index
4Ifdigit.value == tile
Then
5Change Variable
Variable
slot
Value
local.index
6Return
Value
slot

1.7.3 Slide To Slot

Slide To Slot is the Tile’s own Logic, and it has three moments: the jump, the slide and the landing. You’ll build all three here, though only the jump does anything yet.

The jump comes when the Tile is created. It asks Slot Of Tile where its own number is in $boardState. Slot Position says where that Slot sits on the Board, and Set Position puts the Tile there. Last, it remembers that Slot as shownSlot, the Slot it’s shown in.

Fill its left cards before any Event. On Data Structures, Numbered Tile is the one you made, so the Tile reads its own number as self.numberedTile.number. Slide To Slot Data is new. Choose New Data Structure for it, and Myth makes it, names it after the Logic and opens it. Its one field, shownSlot, is on its card below. That’s where each Tile keeps the Slot it’s shown in: self.slideToSlotData.shownSlot.

Shared Variables come next. One is puzzleRules, the Object a Tile reports to. The other is slideSeconds, how long a slide takes: 0.22 seconds, a quick glide.

Data StructureSlide To Slot Data

What each Tile remembers: shownSlot, the Slot it is drawn in (-1 before the first Board is shown), so it slides only when its Slot changes.

shownSlotNumberdefault -1
Logic ComponentSlide To SlotAttach to: Tile

Keeps this Tile on the Slot the Board State gives it. It jumps there when it is created. When the Board State moves it, it slides there in a straight line at an even speed, taking slideSeconds, lands exactly on the Slot, and tells Puzzle Rules that the slide is over.

Attach toAny Object
DATA STRUCTURES
Numbered Tileself.numberedTile
Slide To Slot Dataself.slideToSlotData
SHARED VARIABLES
NameTypeKindStarting Value
puzzleRulesObjectConstantNone
slideSecondsNumberConstant0.22
When Created
WhenCreate
1Slot Of TileFunction
Action Name
startSlot
board
$boardState
tile
self.numberedTile.number
2Slot PositionFunction
Action Name
startPlace
slot
startSlot.value
layout
board
3Set Position
Position Relative To
Screen
X
startPlace.x
Y
startPlace.y
4Change Component Value
Component Value
self.slideToSlotData.shownSlot
Value
startSlot.value

The slide waits for a message, boardChanged, which every Tile hears after a Move. Each Tile asks where it is now. Only the Tile that moved gets an answer different from its shownSlot, and the If lets only that one through. The other seven stay put.

Two Tween Properties make the slide, one for X and one for Y. Both take slideSeconds at an even speed, so they start together and arrive together, and the Tile travels in a straight line. On a Screen UI Object, the X and Y in the Property list are its place on the screen, in the same pixels as Screen Offset. A timer named slide is started too. It rings once, when the slide should be over.

Nothing sends boardChanged yet, though in the next part Hand Moves will.

Logic ComponentSlide To Slotcontinued
On Board Changed
WhenboardChangedCustom Event
1Slot Of TileFunction
Action Name
mySlot
board
$boardState
tile
self.numberedTile.number
2IfmySlot.value != self.slideToSlotData.shownSlot
Then
3Change Component Value
Component Value
self.slideToSlotData.shownSlot
Value
mySlot.value
4Slot PositionFunction
Action Name
place
slot
mySlot.value
layout
board
5Tween
Value
self.transform.position.x
Target
place.x
Duration
@self.slideSeconds
6Tween
Value
self.transform.position.y
Target
place.y
Duration
@self.slideSeconds
7Start Recurring Timer
Timer Name
slide
Repeat Every (s)
@self.slideSeconds
Ring Once
Yes

The landing comes when the timer rings. Control Tween ends the glide, and Set Position puts the Tile exactly on its Slot, so it never stops a hair off. Last, the Tile tells Puzzle Rules the slide is over: slideFinished.

Logic ComponentSlide To Slotcontinued
On the Slide Timer
WhenRecurring TimerTimer name: slide
1Control Tween
2Slot PositionFunction
Action Name
restingPlace
slot
self.slideToSlotData.shownSlot
layout
board
3Set Position
Position Relative To
Screen
X
restingPlace.x
Y
restingPlace.y
4Trigger Custom Event on Object
Applies To
@self.puzzleRules
Custom Event
slideFinished

Open the Tile, switch the list to Logic, and attach Slide To Slot. Now its puzzleRules needs an Object. Switch back to Components, and look under Variables in the Tile’s Properties. There’s puzzleRules, marked From Logic. Pick Puzzle Rules in its Value list.

Run the game. The Tiles stand exactly where they stood. That’s right: you placed each one on its Slot, so it jumps to where it already is.

To see the jump, put Tile 5 in the wrong place. Select it in the Scene and type 337 and -410 into its Screen Offset, the middle Slot, where the Blank is. Run the game. Tile 5 is back in the top-left corner, and the middle is empty again. The Board State put it there, not the Scene. Close the game, and type Tile 5’s own X and Y back in: 187 and -260.

Your Tiles answer to the Board State now, and they’re waiting to hear that it changed.

1.8 A Move

Now the Tiles learn to move.

Click Tile 4. In that instant, before anything moves, the game decides whether Tile 4 is beside the Blank. It is, right above it. So the Move is made in the Board State first, and only then does Tile 4 glide down to catch up.

Here is the whole trip, in order. The click reaches the Tile, and the Tile asks Puzzle Rules. Puzzle Rules checks, makes the Move and tells every Tile. Tile 4 slides. When it lands, it tells Puzzle Rules, and Puzzle Rules listens for the next choice.

1.8.1 Slot Distance

Is a Tile beside the Blank? Slot Distance counts how many Moves apart two Slots are: the rows between them plus the columns between them. A Tile never moves on a diagonal, so that sum is the count. Side by side, or one above the other, comes to 1.

A row is floor(slot / 3) and a column is slot % 3, as in Slot Position. The abs() around each difference turns it into a distance, so it never comes out below 0.

In Chapter 2, the search calls Slot Distance for every Tile of a Board, to guess how far that Board is from the Goal.

FunctionSlot Distance

How many Moves apart two Slots are: the rows between them plus the columns between them, since a Tile never moves diagonally. Slots side by side, or one above the other, are 1 apart.

PARAMETERS
NameTypeStarts at
fromSlotNumber0
toSlotNumber0
RETURN TYPENumber
ACTIONS
1Declare Variable
Name
rowsApart
Value
0
2Declare Variable
Name
columnsApart
Value
0
3Change Variable
Variable
rowsApart
Value
abs(floor(fromSlot / 3) - floor(toSlot / 3))
4Change Variable
Variable
columnsApart
Value
abs(fromSlot % 3 - toSlot % 3)
5Return
Value
rowsApart + columnsApart

1.8.2 Board After Move

Board After Move makes a Move on the slip. It hands back the Board State after the Tile in fromSlot slides into the Blank at toSlot.

It looks like a long formula, but it only moves one digit. The Blank is a 0, so the Tile’s digit has to appear at toSlot and vanish from fromSlot. Each Slot has its own place in the number. It’s the pow(10, 8 - slot) that Tile In Slot divides by. Adding the digit at toSlot’s place and taking it away at fromSlot’s does both at once.

Take Tile 4 sliding down from Slot 1 into the Blank at Slot 4. Slot 4’s place is ten thousand, and Slot 1’s is ten million, as Tile In Slot counted. So the Board State gains four ten-thousands and loses four ten-millions. The digits of 542703816 become 5 0 2 7 4 3 8 1 6. The 4 and the 0 have traded places.

First it asks Tile In Slot which Tile is in fromSlot, and names the answer moving. So moving.value is the Tile’s number.

On its card, board is the Board before the Move. Step 1 passes it on to Tile In Slot, whose own Parameter happens to be named board too. The Return starts from it. Its Value is the Board after the Move.

In Chapter 2, the search calls Board After Move for every Board one Move away.

FunctionBoard After Move

The Board State after the Tile in fromSlot slides into the Blank at toSlot.

PARAMETERS
NameTypeStarts at
boardNumber0
fromSlotNumber0
toSlotNumber0
RETURN TYPENumber
ACTIONS
1Tile In SlotFunction
Action Name
moving
board
board
slot
fromSlot
2Return
Value
board + moving.value * (pow(10, 8 - toSlot) - pow(10, 8 - fromSlot))

1.8.3 Choose Tile

Choose Tile is how a Tile asks. A click calls it, and so will a key, so the two can never behave differently.

It has a small problem to solve. A Custom Event is a bell: it rings, but it can’t say who rang it. So Choose Tile writes the chosen number into $chosenTile first, and only then rings tileChosen, for Puzzle Rules alone.

Its puzzleRules is an Object Parameter. A Function card shows how to make one: Nominal, Puzzle Rules. There’s no RETURN TYPE on its card, because Choose Tile only rings a bell and gives nothing back.

FunctionChoose Tile

Tells Puzzle Rules which Tile the player chose, by click, tap, or key. Puzzle Rules decides whether it moves.

PARAMETERS
NameTypeStarts at
puzzleRulesObjectPuzzle Rules
tileNumber0
ACTIONS
1Change Variable
Variable
$chosenTile
Value
tile
2Trigger Custom Event on Object
Applies To
puzzleRules
Custom Event
tileChosen

1.8.4 Hand Moves

Hand Moves is where Puzzle Rules decides. It hears tileChosen and answers in one of two ways. Each way is a Mode, with its own name and its own Actions.

Ready is the way it starts. It asks Slot Of Tile twice: where the chosen Tile is, chosenSlot, and where the Blank is, blankSlot, by asking for Tile 0. Slot Distance says how far apart they are, and if the answer is 1, the Move is real.

What follows happens in this order. Board After Move gives the new Board, and $boardState takes it. Hand Moves switches On Tile Chosen to While Sliding. Last, it rings boardChanged for everyone.

The Board State changes before anything moves on the screen. Everything that hears boardChanged reads the new Board, the sliding Tile included.

Build it in this order. Make the On Tile Chosen Event. Rename its Mode Ready, and add a second one, While Sliding. Make On Slide Finished. Switch Mode picks the Event and the Mode by name, so both Modes have to exist before it does. Modes on the Making page shows each step. When the card is done, attach Hand Moves to Puzzle Rules.

Logic ComponentHand MovesAttach to: Puzzle Rules

Makes each Move on the Board State, one at a time. When a Tile beside the Blank is chosen (by click, tap, or key), the Move is stored and every Tile is told (boardChanged); while that Tile slides, other choices are ignored.

Attach toAny Object
On Tile Chosen
WhentileChosenCustom Event
ModeReady (Starting Mode)
1Slot Of TileFunction
Action Name
chosenSlot
board
$boardState
tile
$chosenTile
2Slot Of TileFunction
Action Name
blankSlot
board
$boardState
tile
0
3Slot DistanceFunction
Action Name
apart
fromSlot
chosenSlot.value
toSlot
blankSlot.value
4Ifapart.value == 1
Then
5Board After MoveFunction
Action Name
afterMove
board
$boardState
fromSlot
chosenSlot.value
toSlot
blankSlot.value
6Change Variable
Variable
$boardState
Value
afterMove.value
7Switch Mode
Event
On Tile Chosen
Mode
While Sliding
8Trigger Custom Event
Custom Event
boardChanged

Remember boardChanged, waiting in Slide To Slot? Hand Moves sends it in step 8, the last step of Ready.

While Sliding has no Actions at all. While it’s the one that answers, a choice does nothing, so two Tiles never move at once. When the sliding Tile lands, it sends slideFinished to Puzzle Rules. On Slide Finished switches On Tile Chosen back to Ready, so Ready answers the next choice.

Logic ComponentHand Movescontinued
On Tile Chosen
WhentileChosenCustom Event
ModeWhile Sliding
(no Actions)
On Slide Finished
WhenslideFinishedCustom Event
1Switch Mode
Event
On Tile Chosen
Mode
Ready

1.8.5 Click To Choose

The last piece of the chain is the click itself. When you click or tap a Tile, its UI Activated Event runs, and Click To Choose calls Choose Tile with this Tile’s own number. The card’s heading, On Hud Activated, is the name Myth gives that Event by itself.

Its left cards hold two things you’ve met in Slide To Slot: Numbered Tile on Data Structures, from Existing Data Structures, and puzzleRules on Shared Variables.

Logic ComponentClick To ChooseAttach to: Tile

Clicking or tapping this Tile chooses it. Puzzle Rules decides whether it moves.

Attach toAny Object
DATA STRUCTURES
Numbered Tileself.numberedTile
SHARED VARIABLES
NameTypeKindStarting Value
puzzleRulesObjectConstantNone
On Hud Activated
WhenUI Activated
1Choose TileFunction
puzzleRules
@self.puzzleRules
tile
self.numberedTile.number

Attach Click To Choose to the Tile, beside Slide To Slot. There’s nothing new to pick. Its puzzleRules has the same name as Slide To Slot’s, so the Tile holds only one, already set to Puzzle Rules.

Run the game and click Tile 5, and nothing happens. Click Tile 4. It glides down in 0.22 seconds and lands square. Now click Tile 5 again. With the Blank beside it, it slides across. Your Tiles move.

Every Move goes through Puzzle Rules, and the Tiles follow.

1.9 Solved

Now the parchment card gets its word.

Under the Goal picture is room for one line of words. In this chapter it says one word, Solved, and only when the Tiles match the Goal.

The words live in a table, Messages, with one row for each thing the game can say. Today it has one row, solved, and Chapter 2 adds more.

Data TableMessagesData Structure: Messages Entry
Row 0solved
wordsSolved

Its Messages Entry has one Text field, words. Clear its Value box, as you did for Goal Slot’s label, because it starts empty.

Data StructureMessages Entry

One row of the "Messages" Data Table.

wordsTextdefault (empty)

1.9.1 Check Goal

Check Goal hears boardChanged too. After every Move, it compares two numbers, $boardState and goalBoard. Equal, and $statusLine takes the solved row’s words. Not equal, and it’s emptied with "", the card’s word with no letters in it.

The Board State changes first, so Solved appears as the last Tile starts to slide, not when it lands.

Check Goal is the only piece of the game that ever says Solved, in this chapter and every one after.

Logic ComponentCheck GoalAttach to: Puzzle Rules

Says "Solved" on the Status Line when a Move makes the Goal, as its Tile begins to slide. After any other Move the Status Line is empty.

Attach toAny Object
On Board Changed
WhenboardChangedCustom Event
1If$boardState == data('Puzzle Settings', 'puzzle', 'goalBoard')
Then
2Change Variable
Variable
$statusLine
Value
data('Messages', 'solved', 'words')
3Otherwise
4Change Variable
Variable
$statusLine
Value
""

Attach Check Goal to Puzzle Rules.

The Status Line shows $statusLine in small slate letters. Make it like the Goal Label, with {$statusLine} as its Text, braces and all.

ObjectStatus Line
Transform
Presentation > SpaceWindow / UI
Presentation > Render LayerUI
Text / UI
Text{$statusLine}
Font Size18
EmphasisSemibold
Color#233947
AlignmentCenter
RenderingVector

Place it at 766 and -604, low on the parchment card. Run the game and solve the puzzle. Play it! below has a way through, if you’d like one.

1.10 Keys 1 To 8

Last come the keys.

Each key is a Command, a name your Logic uses, joined to a key on the keyboard. Make the eight from COMMANDS on your Set up card. They’re Slide Tile 1 to Slide Tile 8, each a Button, each joined to its own number key. The Set up card passage on the Making page shows the Input Manager.

1.10.1 Tile Keys

Tile Keys has eight Events, one for each Command. Each one calls Choose Tile with its own Tile’s number, so a key does what a click does. A Command Pressed Event names its Command in the Event itself, so every key gets an Event of its own.

It’s Click To Choose eight times over. This card is long only because it says the same thing eight ways.

The card’s headings read When Tile1 Is Pressed and so on. Myth gives those names by itself, from each Event’s Command, so you never type one. Its Shared Variables card gets puzzleRules, the same as Click To Choose’s.

Logic ComponentTile KeysAttach to: Puzzle Rules

Keys 1 to 8 choose that Tile, the same as clicking it. A Command Event picks its Command in the Event itself, so each key has its own Event.

Attach toAny Object
SHARED VARIABLES
NameTypeKindStarting Value
puzzleRulesObjectConstantNone
When Tile1 Is Pressed
WhenCommand PressedCommand: Slide Tile 1
1Choose TileFunction
puzzleRules
@self.puzzleRules
tile
1
When Tile2 Is Pressed
WhenCommand PressedCommand: Slide Tile 2
1Choose TileFunction
puzzleRules
@self.puzzleRules
tile
2
When Tile3 Is Pressed
WhenCommand PressedCommand: Slide Tile 3
1Choose TileFunction
puzzleRules
@self.puzzleRules
tile
3
When Tile4 Is Pressed
WhenCommand PressedCommand: Slide Tile 4
1Choose TileFunction
puzzleRules
@self.puzzleRules
tile
4
When Tile5 Is Pressed
WhenCommand PressedCommand: Slide Tile 5
1Choose TileFunction
puzzleRules
@self.puzzleRules
tile
5
When Tile6 Is Pressed
WhenCommand PressedCommand: Slide Tile 6
1Choose TileFunction
puzzleRules
@self.puzzleRules
tile
6
When Tile7 Is Pressed
WhenCommand PressedCommand: Slide Tile 7
1Choose TileFunction
puzzleRules
@self.puzzleRules
tile
7
When Tile8 Is Pressed
WhenCommand PressedCommand: Slide Tile 8
1Choose TileFunction
puzzleRules
@self.puzzleRules
tile
8

Attach Tile Keys to Puzzle Rules. Its puzzleRules now shows under Puzzle Rules’ own Variables, and it points at Puzzle Rules itself, so pick Puzzle Rules in its Value list. Run the game and press 4. Tile 4 slides down, the same as a click.

Play it!

Here is what to watch for, one thing at a time.

  • The worktable fills the window. The plate at the top reads 8-puzzle (A*), and under it, Slide tiles into order.
  • Eight cream Tiles sit on the velvet: 5 4 2 across the top, then 7, the Blank and 3, then 8 1 6.
  • The parchment card shows the Goal: 1 2 3, 4 5 6, 7 8, and a darker empty cell. The line under it is empty.
  • Click Tile 5. Nothing moves, because it isn’t beside the Blank.
  • Click Tile 4. It glides straight down at an even speed, takes 0.22 seconds, and lands square in its Slot.
  • Press 4. Tile 4 slides back up, the same as a click.
  • Press 4 and then 5, quickly. Only Tile 4 moves. While a Tile slides, other choices do nothing.
  • Start the game again for a fresh puzzle. Press 1, 8, 7, 5, 4, 1, 5, 4, 1, 2, 3 and 6, one at a time, each after the last slide ends.
  • As Tile 6 starts its slide, Solved appears under the Goal. Twelve Moves.
How it works

Start Board writes the puzzle down as one number. Each Tile finds its Slot in it, and each Goal Cell finds its number in the Goal. A click only asks. Hand Moves decides, changes the number and rings boardChanged. The Tile that moved slides to catch up, and Check Goal compares two numbers.

Underneath all of it is one idea. The puzzle is stored once, as the Board State, and everything you see only shows it. The Tiles never decide where they are.

That’s what makes a search possible, because a whole Board fits in nine digits. So the search in Chapter 2 can write Boards down, compare them and make Moves on them, all without touching a Tile.

1.11 If It Didn’t Work

Something may be a little off the first time. That’s part of building, and each fix shows you where something lives. Run the game, watch what it does, and think it through one piece at a time.

The window is plain blue, with no worktable? Look in Puzzle Table for the Observatory Background’s placement, at 500 and -425, and at its Sprite’s picture, Observatory Worktable.

A Tile shows 0? Its placement’s Number is still 0. Select it, and type its number under Values, in its Data Structure part.

A 0 in the Goal’s dark empty cell, or under the Goal? Some Text still holds the editor’s 0. Look at Goal Slot’s label, whose Value box should be clear, and at $statusLine, whose Default box should be clear.

All nine Goal Cells are the same color, with no numbers? That means Show Goal Tile never ran. Is it attached to the Goal Cell? If it is, open it and look for a block standing apart from the line, with no arrow into it. Right-click it and choose Connect to sequence to join it.

The Goal Cells pile up in one spot, or show their numbers in the wrong places? Open Slot Position and look for a block standing apart. Join it with Connect to sequence. After that, look at each placement’s Slot, 0 to 8. Last, step 2 of Show Goal Tile should have its Position Relative to on Screen.

Clicking a Tile does nothing at all? Follow the chain from the click, one link at a time, starting at the Tile. Does it still have its UI Interaction? Without it, a click never reaches the Tile at all, so that’s the first link. Is Click To Choose on it? Is Puzzle Rules in the Scene, with Hand Moves on it? Logic only runs on an Object the Scene has placed, so Puzzle Rules has to be there. Is Ready the Starting Mode of On Tile Chosen? And is tileChosen spelled the same, letter for letter, in Choose Tile and in Hand Moves?

A Tile moves once, and then nothing moves again? Perhaps slideFinished never arrived, so Hand Moves is still in While Sliding. Look at On the Slide Timer, the last Event of Slide To Slot, whose timer name is slide, the same as the Timer Name in Start Recurring Timer. Its last step sends slideFinished to @self.puzzleRules. Does the Tile’s puzzleRules, under Variables, say Puzzle Rules? After that, look at On Slide Finished in Hand Moves, which switches back to Ready.

No Tween in the Action List? Advanced Mode is off. Turn it on from the Settings menu, and the Timeline’s Actions appear, Tween and Control Tween among them.

A Tile slides to the wrong Slot? Look at Slot Position, where the fourth step adds, with +=, and the sixth takes away, with -=.

A Tile that isn’t beside the Blank moves anyway? Look at step 4 of Hand Moves, whose If reads apart.value == 1.

Solved never appears? Look for Check Goal on Puzzle Rules, and at the Status Line’s Text, {$statusLine}. After that, look at the solved row of Messages. Its words are Solved.

Clicks work, but the keys don’t? Look at each Command’s key under Keybindings, and for Tile Keys on Puzzle Rules.

Each of these is one small fix. Make it, run the game again, and you’re back with the chapter. And if you’d like to compare, the catch-up download at the top of this chapter is its finished project.

Challenge

Make a puzzle of your own. Open Puzzle Settings and change startBoard in its one row, puzzle. That’s the cell Start Board reads.

Any Board you reach by sliding Tiles away from the Goal can be solved, because every Move can be undone. So start from 123456780, slide a few Tiles in your head or on paper, and write down where you end up, row by row, with 0 for the Blank. One Move away is 123456708, with Tile 8 one Slot to the right. Run the game, and your Tiles start where you said.

Before Chapter 2, put 542703816 back. The search there starts from that puzzle, and its numbers are about it.

Eight Tiles slide where your hand sends them, and the card knows when they’re home. In Chapter 2, something else starts working the puzzle.