Classic game of eight movable tiles in a 3 × 3 square with one missing.
The rows are numbered from –1 to +1 from top to bottom;
the columns are numbered – to +1 from left to right.
That means that tile (0, 0) is in the center.
The nine
.png
files, however,
have numbers that are zero-based.
The original photo from the Wikipedia article was chopped into nine smaller pieces (of which eight are displayed) by a Unix shellscript using the Netpbm toolkit. You probably would rather chop it up using a different application.
The white background is one big
View
.
The
init
method of the
View
(called by the
loadView
method of the view controller)
creates eight smaller
TileView
s.
Each
TileView
is derived from class
UIImageView
and holds a 100 × 100
UIImage
.
It also holds a row number and a column number
(each in the range –1 to 1 inclusive)
which change as the
TileView
is moved around.
We saw class
UIImage
here,
and will see class
UIImageView
here.
subclass of
UIView |
is specialized for holding a |
---|---|
UILabel |
single-line
String |
UITextView |
multi-line
String |
UIImageView |
UIIimage |
The
View
contains the row number and column number of the currently empty location.
The
View
calls
hitTest(_:withEvent:)
to find out which subview (if any) was touched.
The subview contains its own row and column number.
If the subview is not landlocked,
it animates into the empty location.
PuzzleAppDelegate
ViewController
.
The
loadView
method creates the big white
View
.
View
TileView
:
the property
userInteractionEnabled
makes the
TileView
touch-sensitive.
Images.xcassets
,
an Xcode
asset catalog
file.
See
America.
Each imageset consists of only one image.
The lower right image
(22.png
)
is not used by this app.
00.png
01.png
02.png
10.png
11.png
12.png
20.png
21.png
22.png
America
tells you how to add the image files to the project’s
Images.xcassetts
file.
When creating class
TileView
,
make it a subclass of class
UIImageView
:
Choose options for your new file:
Class: View
Subclass of: UIImageView
init(frame:)
method of class
View
.
for var i = 0; i < 100; ++i { //Pick a random number in the range 0 to 7 inclusive. //Then convert the random number from UInt32 to plain old Int. let r: Int = Int(arc4random_uniform(8)); //Pick a random TileView, i.e., one of the last 8 items in the //subviews property of this View. let tileView: TileView = subviews[subviews.count - 1 - r] as TileView; tryToMoveTileView(tileView); }Would it be more dramatic if we increase the duration of the animation?
String rank; if nmoves < 10 { rank = "genius"; } else if nmoves < 20 { rank = "brighter than average"; } else //etc.
TileView
that cannot move.