TutorialsA* Search

Appendix A — Logic Reference

Every Logic Component and Function in 8-Puzzle Solver, as it is in the finished game. Each entry stands on its own: read what it does, see what it needs, and build it from its card into your own game. A card’s Shared Variables and Per Instance Variables are the values you can change. A Shared Variable holds one value for the whole Object, under Variables in its Properties. A Per Instance Variable holds one for each placement in the Scene.

A.1 Board After Move (Function)

Built in Chapter 1, Slide the Tiles.

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))

A.2 Check Goal

Built in Chapter 1, Slide the Tiles.

Logic ComponentCheck GoalAttach to: Puzzle Rules

Says "Solved" on the Status Line when a Move, the player's or the Route's, makes the Goal, as its Tile begins to slide.

Attach toAny Object
On Board Changed
WhenboardChangedCustom Event
1If$boardState == data('Puzzle Settings', 'puzzle', 'goalBoard')
Then
2Show Status RowFunction
row
solved

A.3 Choose Tile (Function)

Built in Chapter 1, Slide the Tiles.

FunctionChoose Tile

Tells Puzzle Rules which Tile was chosen: by the player's click, tap, or key, or by the Route's next Move. 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

A.4 Click To Choose

Built in Chapter 1, Slide the Tiles.

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

A.5 Hand Moves

Built in Chapter 1, Slide the Tiles.

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 the player, or by the Route), the Move is stored and every Tile is told (boardChanged); while that Tile slides, other choices are ignored. When New puzzle or Reset puts a whole Board at once (boardJumped), any slide is cut short, so choices count again.

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
On Tile Chosen
WhentileChosenCustom Event
ModeWhile Sliding
(no Actions)
On Slide Finished
WhenslideFinishedCustom Event
1Switch Mode
Event
On Tile Chosen
Mode
Ready
On Board Jumped
WhenboardJumpedCustom Event
1Switch Mode
Event
On Tile Chosen
Mode
Ready

A.6 Show Goal Tile

Built in Chapter 1, Slide the Tiles.

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'

A.7 Slide To Slot

Built in Chapter 1, Slide the Tiles.

Logic ComponentSlide To SlotAttach to: Tile

Keeps this Tile on the Slot the Board State gives it. It jumps there when it is created and when New puzzle or Reset puts a whole Board at once (boardJumped), cutting short any slide. When a Move 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
1Trigger Custom Event on Object
Custom Event
boardJumped
On Board Jumped
WhenboardJumpedCustom Event
1Stop Recurring Timer
Timer Name
slide
2Control Tween
3Slot Of TileFunction
Action Name
jumpSlot
board
$boardState
tile
self.numberedTile.number
4Slot PositionFunction
Action Name
jumpPlace
slot
jumpSlot.value
layout
board
5Set Position
Position Relative To
Screen
X
jumpPlace.x
Y
jumpPlace.y
6Change Component Value
Component Value
self.slideToSlotData.shownSlot
Value
jumpSlot.value
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
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

A.8 Slot Distance (Function)

Built in Chapter 1, Slide the Tiles.

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

A.9 Slot Of Tile (Function)

Built in Chapter 1, Slide the Tiles.

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

A.10 Slot Position (Function)

Built in Chapter 1, Slide the Tiles.

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

A.11 Start Board

Built in Chapter 1, Slide the Tiles.

Logic ComponentStart BoardAttach to: Puzzle Rules

Sets up the Board State when the puzzle opens: the Start Board from Puzzle Settings, when it can reach the Goal (Check Start Board) and is not already the Goal. A Board that cannot, or that leaves nothing to solve, is refused: the Board opens as the Goal, and the Status Line asks for a new puzzle.

Attach toAny Object
When the Scene Starts
WhenScene Start
1Check Start BoardFunction
Action Name
startCheck
board
data('Puzzle Settings', 'puzzle', 'startBoard')
2IfstartCheck.value == true && data('Puzzle Settings', 'puzzle', 'startBoard') != data('Puzzle Settings', 'puzzle', 'goalBoard')
Then
3Change Variable
Variable
$boardState
Value
data('Puzzle Settings', 'puzzle', 'startBoard')
4Otherwise
5Change Variable
Variable
$boardState
Value
data('Puzzle Settings', 'puzzle', 'goalBoard')
6Show Status RowFunction
row
tryNew

A.12 Tile In Slot (Function)

Built in Chapter 1, Slide the Tiles.

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

A.13 Tile Keys

Built in Chapter 1, Slide the Tiles.

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

A.14 Add Search State (Function)

Built in Chapter 2, Step Through the Search.

FunctionAdd Search State

Stores a Board the search has just found as a new, open Search State: its route so far (movesSoFar and parentState) and its Estimate of the Moves left. A new row starts open.

PARAMETERS
NameTypeStarts at
boardNumber0
movesSoFarNumber0
parentStateNumber-1
ACTIONS
1Estimate Moves LeftFunction
Action Name
guess
board
board
2Control Data Row
Action Name
addedRow
Table
"Search States"
Row
text(board)
3Set Data Cell
Table
"Search States"
Row
text(board)
Column
"movesSoFar"
Value
movesSoFar
4Set Data Cell
Table
"Search States"
Row
text(board)
Column
"estimatedMovesLeft"
Value
guess.value
5Set Data Cell
Table
"Search States"
Row
text(board)
Column
"parentState"
Value
parentState

A.15 Check Start Board (Function)

Built in Chapter 2, Step Through the Search.

FunctionCheck Start Board

Whether a Board can reach the Goal: it must hold every digit 0 to 8 exactly once, in at most nine digits, and its number of inversions (Count Inversions) and that of the Goal must be both even or both odd. A Move never changes whether the count is even or odd, so a Board that differs from the Goal there can never reach it.

PARAMETERS
NameTypeStarts at
boardNumber0
RETURN TYPEBoolean
ACTIONS
1Declare Variable
Name
missingDigits
Value
0
2Declare Variable
Type
Boolean
Name
canReachGoal
Value
false
3Repeat9times
Each time
4Slot Of TileFunction
Action Name
where
board
board
tile
local.index
5Ifwhere.value == (-1)
Then
6Change Variable
Variable
missingDigits
Operator
+=
Value
1
7Count InversionsFunction
Action Name
boardInversions
board
board
8Count InversionsFunction
Action Name
goalInversions
board
data('Puzzle Settings', 'puzzle', 'goalBoard')
9IfmissingDigits == 0 && (boardInversions.value % 2) == (goalInversions.value % 2) && board == floor(board) && board < 1000000000
Then
10Change Variable
Variable
canReachGoal
Value
true
11Return
Value
canReachGoal

A.16 Count Inversions (Function)

Built in Chapter 2, Step Through the Search.

FunctionCount Inversions

The number of inversions of a Board: pairs of Tiles where the larger number comes first in reading order. The Blank is not counted. A Move never changes whether this number is even or odd: a Tile sliding left or right keeps the reading order, and a Tile sliding up or down passes two other Tiles.

PARAMETERS
NameTypeStarts at
boardNumber0
RETURN TYPENumber
ACTIONS
1Declare Variable
Name
earlierSlot
Value
0
2Declare Variable
Name
inversions
Value
0
3Repeat9times
Each time
4Change Variable
Variable
earlierSlot
Value
local.index
5Tile In SlotFunction
Action Name
earlier
board
board
slot
earlierSlot
6Repeat9times
Each time
7Tile In SlotFunction
Action Name
later
board
board
slot
local.index
8Iflocal.index > earlierSlot && later.value > 0 && earlier.value > later.value
Then
9Change Variable
Variable
inversions
Operator
+=
Value
1
10Return
Value
inversions

A.17 Estimate Moves Left (Function)

Built in Chapter 2, Step Through the Search.

FunctionEstimate Moves Left

The Estimate of the Moves still needed from a Board to the Goal, by the Estimate chosen in $estimate (a row of the Estimates table). Manhattan distance adds, for each Tile, the rows plus the columns between its Slot and its Slot in the Goal; misplaced Tiles adds 1 for each Tile out of place. The Blank is not counted. Neither guesses more Moves than are really needed, which is what lets A* find the shortest Route.

PARAMETERS
NameTypeStarts at
boardNumber0
RETURN TYPENumber
ACTIONS
1Declare Variable
Name
total
Value
0
2Declare Variable
Name
tileMoves
Value
0
3Declare Variable
Type
Boolean
Name
countsSlotsAway
Value
true
4Change Variable
Variable
countsSlotsAway
Value
data('Estimates', $estimate, 'countsSlotsAway')
5Repeat9times
Each time
6Tile In SlotFunction
Action Name
here
board
board
slot
local.index
7Ifhere.value > 0
Then
8Slot Of TileFunction
Action Name
home
board
data('Puzzle Settings', 'puzzle', 'goalBoard')
tile
here.value
9Slot DistanceFunction
Action Name
away
fromSlot
local.index
toSlot
home.value
10Change Variable
Variable
tileMoves
Value
away.value
11IfcountsSlotsAway == false && tileMoves > 0
Then
12Change Variable
Variable
tileMoves
Value
1
13Change Variable
Variable
total
Operator
+=
Value
tileMoves
14Return
Value
total

A.18 Expand Best State (Function)

Built in Chapter 2, Step Through the Search.

FunctionExpand Best State

One Step of the A* search: picks the best open Search State (Pick Best Open State). If it is the Goal, the Goal is accepted ("goalAccepted"); otherwise it is Expanded (Expand State). When no Search State is open, the search stops ("searchStopped"). Both messages go to Puzzle Rules.

PARAMETERS
NameTypeStarts at
puzzleRulesObjectPuzzle Rules
ACTIONS
1Pick Best Open StateFunction
Action Name
best
2Ifbest.found == true
Then
3Ifbest.state == data('Puzzle Settings', 'puzzle', 'goalBoard')
Then
4Trigger Custom Event on Object
Applies To
puzzleRules
Custom Event
goalAccepted
5Otherwise
6Expand StateFunction
puzzleRules
puzzleRules
state
best.state
7Otherwise
8Trigger Custom Event on Object
Applies To
puzzleRules
Custom Event
searchStopped

A.19 Expand State (Function)

Built in Chapter 2, Step Through the Search.

FunctionExpand State

Expands one Search State: closes it, adds it to States checked, and stores every Board one Move away (Store Neighbor). Tells Puzzle Rules "searchStopped" when a new Search State would not fit.

PARAMETERS
NameTypeStarts at
puzzleRulesObjectPuzzle Rules
stateNumber0
ACTIONS
1Declare Variable
Type
Boolean
Name
isFull
Value
false
2Set Data Cell
Table
"Search States"
Row
text(state)
Column
"isOpen"
Value
No
3Change Variable
Variable
$statesChecked
Operator
+=
Value
1
4Slot Of TileFunction
Action Name
blank
board
state
tile
0
5Repeat9times
Each time
6Slot DistanceFunction
Action Name
apart
fromSlot
local.index
toSlot
blank.value
7Ifapart.value == 1
Then
8Store NeighborFunction
Action Name
stored
parentState
state
parentMoves
data('Search States', text(state), 'movesSoFar')
fromSlot
local.index
blankSlot
blank.value
9Ifstored.value == true
Then
10Change Variable
Variable
isFull
Value
true
11IfisFull == true
Then
12Trigger Custom Event on Object
Applies To
puzzleRules
Custom Event
searchStopped

A.20 Pick Best Open State (Function)

Built in Chapter 2, Step Through the Search.

FunctionPick Best Open State

Finds the open Search State with the lowest score, movesSoFar + estimatedMovesLeft (f = g + h). On a tie, the lower estimatedMovesLeft wins; on a further tie, the one stored first. found is No when no Search State is open.

RETURN TYPEPick Best Open State Result (a Data Structure)
ACTIONS
1Declare Variable
Type
Boolean
Name
isFound
Value
false
2Declare Variable
Name
bestState
Value
0
3Declare Variable
Name
bestScore
Value
0
4Declare Variable
Name
bestEstimate
Value
0
5Declare Variable
Name
score
Value
0
6Declare Variable
Name
estimate
Value
0
7Declare Variable
Type
Boolean
Name
isBetter
Value
false
8RepeatdataCount('Search States')times
Each time
9Ifdata('Search States', local.index, 'isOpen') == true
Then
10Change Variable
Variable
estimate
Value
data('Search States', local.index, 'estimatedMovesLeft')
11Change Variable
Variable
score
Value
data('Search States', local.index, 'movesSoFar')
12Change Variable
Variable
score
Operator
+=
Value
estimate
13Change Variable
Variable
isBetter
Value
false
14IfisFound == false
Then
15Change Variable
Variable
isBetter
Value
true
16Ifscore < bestScore
Then
17Change Variable
Variable
isBetter
Value
true
18Ifscore == bestScore && estimate < bestEstimate
Then
19Change Variable
Variable
isBetter
Value
true
20IfisBetter == true
Then
21Change Variable
Variable
isFound
Value
true
22Change Variable
Variable
bestState
Value
dataRow('Search States', local.index)
23Change Variable
Variable
bestScore
Value
score
24Change Variable
Variable
bestEstimate
Value
estimate
25Return
found
isFound
state
bestState

A.22 Send When Pressed

Built in Chapter 2, Step Through the Search.

Logic ComponentSend When PressedAttach to: Puzzle Button

Clicking or tapping this button sends its message, a Custom Event, to Puzzle Rules. Each button placement sets its own message and its own words; a button that sets none asks for a Step (stepPressed).

Attach toAny Object
SHARED VARIABLES
NameTypeKindStarting Value
puzzleRulesObjectConstantNone
PER INSTANCE VARIABLES
NameTypeStarting Value
messageTextstepPressed
On Hud Activated
WhenUI Activated
1Trigger Custom Event on Object
Applies To
@self.puzzleRules
Custom Event
self.message

A.23 Store Neighbor (Function)

Built in Chapter 2, Step Through the Search.

FunctionStore Neighbor

Stores the Board made by sliding the Tile in fromSlot into the Blank, reached from parentState (whose route takes parentMoves). A new Board becomes an open Search State (Add Search State); a Board stored before takes the new route only when it is shorter, and is then open again. isFull is Yes when a new Board would not fit in Search Settings / maxStates.

PARAMETERS
NameTypeStarts at
parentStateNumber0
parentMovesNumber0
fromSlotNumber0
blankSlotNumber0
RETURN TYPEBoolean
ACTIONS
1Declare Variable
Name
neighborState
Value
0
2Declare Variable
Name
newMoves
Value
0
3Declare Variable
Type
Boolean
Name
isFull
Value
false
4Board After MoveFunction
Action Name
neighbor
board
parentState
fromSlot
fromSlot
toSlot
blankSlot
5Change Variable
Variable
neighborState
Value
neighbor.value
6Change Variable
Variable
newMoves
Value
parentMoves
7Change Variable
Variable
newMoves
Operator
+=
Value
1
8Check Data Row Exists
Action Name
storedBefore
Table
"Search States"
Row
text(neighborState)
9IfstoredBefore.value == true
Then
10IfnewMoves < data('Search States', text(neighborState), 'movesSoFar')
Then
11Set Data Cell
Table
"Search States"
Row
text(neighborState)
Column
"movesSoFar"
Value
newMoves
12Set Data Cell
Table
"Search States"
Row
text(neighborState)
Column
"parentState"
Value
parentState
13Set Data Cell
Table
"Search States"
Row
text(neighborState)
Column
"isOpen"
Value
Yes
14Otherwise
15IfdataCount('Search States') < data('Search Settings', 'search', 'maxStates')
Then
16Add Search StateFunction
board
neighborState
movesSoFar
newMoves
parentState
parentState
17Otherwise
18Change Variable
Variable
isFull
Value
true
19Return
Value
isFull

A.24 Copy Route Record (Function)

Built in Chapter 3, Trace and Replay the Route.

FunctionCopy Route Record

Copies one record of the Route: a Board on the stored route to the Goal goes into the Solution Route under its Move number, which is its movesSoFar (g) in Search States. parentState is the Board its route came from: the record to copy next, or -1 after the Board the search started from.

PARAMETERS
NameTypeStarts at
boardNumber0
RETURN TYPENumber
ACTIONS
1Declare Variable
Name
moveNumber
Value
0
2Change Variable
Variable
moveNumber
Value
data('Search States', text(board), 'movesSoFar')
3Control Data Row
Action Name
addedRow
Table
"Solution Route"
Row
text(moveNumber)
4Set Data Cell
Table
"Solution Route"
Row
text(moveNumber)
Column
"state"
Value
board
5Return
Value
data('Search States', text(board), 'parentState')

A.25 Tile For Move (Function)

Built in Chapter 3, Trace and Replay the Route.

FunctionTile For Move

Which Tile slides to turn a Board into the next Board of the Route: the Tile that sits in board where nextBoard has its Blank. In nextBoard it has slid into board's Blank.

PARAMETERS
NameTypeStarts at
boardNumber0
nextBoardNumber0
RETURN TYPENumber
ACTIONS
1Slot Of TileFunction
Action Name
nextBlank
board
nextBoard
tile
0
2Tile In SlotFunction
Action Name
moving
board
board
slot
nextBlank.value
3Return
Value
moving.value

A.26 Show Status Row (Function)

Built in Chapter 4, Solve and Pause.

FunctionShow Status Row

Shows a situation on the Status Line: $statusRow becomes row, the Messages row of that situation, and the Status Line shows that row's words. While Solve is paused, Solve Timer shows the same row's pausedWords instead.

PARAMETERS
rowText
ACTIONS
1Change Variable
Variable
$statusRow
Value
row
2Change Variable
Variable
$statusLine
Value
data('Messages', $statusRow, 'words')

A.27 Solve Timer

Built in Chapter 4, Solve and Pause.

Logic ComponentSolve TimerAttach to: Puzzle Rules

Decides when the solver takes a Step (takeStep): once each time the player presses Step, and, while Solve runs, up to stepsPerTick Steps every solveSeconds. No Step is taken while a Tile slides, so the Route plays one slide at a time and a Step pressed during a slide does nothing. The Solve button and the A key start Solve or pause it; Escape and Step pause it, and so does the search when it has nothing more to do. Pausing keeps all progress. The Status Line shows the words of $statusRow while Solve runs, and its pausedWords while it is paused.

Attach toAny Object
SHARED VARIABLES
NameTypeKindStarting Value
solveSecondsNumberConstant0.05
stepsPerTickNumberConstant8
When the Scene Starts
WhenScene Start
1Change Variable
Variable
$solveButtonWords
Value
data('Messages', 'solveButton', 'words')
When Solve Is Pressed
WhenCommand PressedCommand: Solve
1Trigger Custom Event on Object
Custom Event
solvePressed
When Pause Is Pressed
WhenCommand PressedCommand: Pause
1Trigger Custom Event on Object
Custom Event
pauseSolve
On Solve Pressed
WhensolvePressedCustom Event
ModePaused (Starting Mode)
1Start Recurring Timer
Timer Name
solveTick
Repeat Every (s)
@self.solveSeconds
2Switch Mode
Event
On Solve Pressed
Mode
Running
3Change Variable
Variable
$solveButtonWords
Value
data('Messages', 'pauseButton', 'words')
4Change Variable
Variable
$statusLine
Value
data('Messages', $statusRow, 'words')
On Solve Pressed
WhensolvePressedCustom Event
ModeRunning
1Trigger Custom Event on Object
Custom Event
pauseSolve
On Step Pressed
WhenstepPressedCustom Event
1Trigger Custom Event on Object
Custom Event
stepDue
2Trigger Custom Event on Object
Custom Event
pauseSolve
On the Solve Tick Timer
WhenRecurring TimerTimer name: solveTick
1Repeat@self.stepsPerTicktimes
Each time
2Trigger Custom Event on Object
Custom Event
stepDue
On Step Due
WhenstepDueCustom Event
ModeNo Tile Sliding (Starting Mode)
1Trigger Custom Event on Object
Custom Event
takeStep
On Step Due
WhenstepDueCustom Event
ModeTile Sliding
(no Actions)
On Board Changed
WhenboardChangedCustom Event
1Switch Mode
Event
On Step Due
Mode
Tile Sliding
On Slide Finished
WhenslideFinishedCustom Event
1Switch Mode
Event
On Step Due
Mode
No Tile Sliding
On Board Jumped
WhenboardJumpedCustom Event
1Switch Mode
Event
On Step Due
Mode
No Tile Sliding
On Pause Solve
WhenpauseSolveCustom Event
1Stop Recurring Timer
Timer Name
solveTick
2Switch Mode
Event
On Solve Pressed
Mode
Paused
3Change Variable
Variable
$solveButtonWords
Value
data('Messages', 'solveButton', 'words')
4Change Variable
Variable
$statusLine
Value
data('Messages', $statusRow, 'pausedWords')

A.28 Choose Estimate

Built in Chapter 5, New Puzzles and Two Estimates.

Logic ComponentChoose EstimateAttach to: Puzzle Rules

The Estimate button and the E key change the Estimate the search uses ($estimate) to the next row of the Estimates table. The search made with the old Estimate is cancelled, so both Estimates can be tried on the same Board.

Attach toAny Object
When Estimate Is Pressed
WhenCommand PressedCommand: Change Estimate
1Trigger Custom Event on Object
Custom Event
estimatePressed
On Estimate Pressed
WhenestimatePressedCustom Event
1Change Variable
Variable
$estimate
Value
data('Estimates', $estimate, 'next')
2Trigger Custom Event on Object
Custom Event
estimateChanged

A.29 New Puzzle

Built in Chapter 5, New Puzzles and Two Estimates.

Logic ComponentNew PuzzleAttach to: Puzzle Rules

Puts a whole Board on the table at once, without slides. New puzzle makes a Board by random legal Moves from the Goal (Scramble Board); Reset puts back the Board of the last New puzzle, or the Board the game opened with. Either way it broadcasts boardJumped, so the Tiles jump and the search starts over. When Reset puts back a Start Board that was refused (the Goal), the Status Line asks for a new puzzle again, as when the puzzle opened.

Attach toAny Object
DATA STRUCTURES
New Puzzle Dataself.newPuzzleData
When Created
WhenCreate
1Change Component Value
Component Value
self.newPuzzleData.resetBoard
Value
$boardState
When New Is Pressed
WhenCommand PressedCommand: New puzzle
1Trigger Custom Event on Object
Custom Event
newPressed
When Reset Is Pressed
WhenCommand PressedCommand: Reset
1Trigger Custom Event on Object
Custom Event
resetPressed
On New Pressed
WhennewPressedCustom Event
1Scramble BoardFunction
Action Name
scrambled
2Change Variable
Variable
$boardState
Value
scrambled.value
3Change Component Value
Component Value
self.newPuzzleData.resetBoard
Value
$boardState
4Trigger Custom Event
Custom Event
boardJumped
On Reset Pressed
WhenresetPressedCustom Event
1Change Variable
Variable
$boardState
Value
self.newPuzzleData.resetBoard
2If$boardState == data('Puzzle Settings', 'puzzle', 'goalBoard')
Then
3Show Status RowFunction
row
tryNew
4Trigger Custom Event
Custom Event
boardJumped

A.30 Random Move (Function)

Built in Chapter 5, New Puzzles and Two Estimates.

FunctionRandom Move

Makes one random legal Move on a Board: one of the Tiles beside the Blank, each with the same chance, slides into it. The Tile in notFromSlot is never chosen, so the Move just made is not undone (-1 lets every Tile beside the Blank be chosen). movedTo is the Slot the Tile slid into, where the Blank was.

PARAMETERS
NameTypeStarts at
boardNumber0
notFromSlotNumber-1
RETURN TYPERandom Move Result (a Data Structure)
ACTIONS
1Declare Variable
Name
choices
Value
0
2Declare Variable
Name
counted
Value
0
3Declare Variable
Name
fromSlot
Value
-1
4Slot Of TileFunction
Action Name
blank
board
board
tile
0
5Repeat9times
Each time
6Slot DistanceFunction
Action Name
apart
fromSlot
local.index
toSlot
blank.value
7Ifapart.value == 1 && local.index != notFromSlot
Then
8Change Variable
Variable
choices
Operator
+=
Value
1
9Generate Random Integer
Action Name
pick
Minimum
1
Maximum
choices
10Whilecounted < pick.value
Each time
11Change Variable
Variable
fromSlot
Operator
+=
Value
1
12Slot DistanceFunction
Action Name
apartAgain
fromSlot
fromSlot
toSlot
blank.value
13IfapartAgain.value == 1 && fromSlot != notFromSlot
Then
14Change Variable
Variable
counted
Operator
+=
Value
1
15Board After MoveFunction
Action Name
afterMove
board
board
fromSlot
fromSlot
toSlot
blank.value
16Return
board
afterMove.value
movedTo
blank.value

A.31 Scramble Board (Function)

Built in Chapter 5, New Puzzles and Two Estimates.

FunctionScramble Board

Makes a New puzzle: starts from the Goal and makes Puzzle Settings / scrambleMoves random legal Moves (Random Move), never undoing the Move just made. If that lands on the Goal, one more Move is made. A Board made by legal Moves from the Goal can always be solved.

RETURN TYPENumber
ACTIONS
1Declare Variable
Name
board
Value
0
2Declare Variable
Name
notFromSlot
Value
-1
3Change Variable
Variable
board
Value
data('Puzzle Settings', 'puzzle', 'goalBoard')
4Repeatdata('Puzzle Settings', 'puzzle', 'scrambleMoves')times
Each time
5Random MoveFunction
Action Name
scramble
board
board
notFromSlot
notFromSlot
6Change Variable
Variable
board
Value
scramble.board
7Change Variable
Variable
notFromSlot
Value
scramble.movedTo
8Ifboard == data('Puzzle Settings', 'puzzle', 'goalBoard')
Then
9Random MoveFunction
Action Name
oneMore
board
board
notFromSlot
notFromSlot
10Change Variable
Variable
board
Value
oneMore.board
11Return
Value
board