Video Slide Puzzle

Brandon Dyck
CS 2550-X01

Play game

Game Description

The 14-15 Puzzle in Puzzleland
From Sam Lloyd's Cyclopedia of 5000 Puzzles (1915).
Public domain.

Video Slide Puzzle is a Javascript/HTML5 implementation of the classic slide puzzle, or 15 puzzle, with a video, rather than a static image, as the texture for the puzzle pieces. When the game loads, a list of available videos is loaded into the "Select background" option list via AJAX, the puzzle is rendered using the first video in the list, and the player can able to select a different video at any time during gameplay using the "Select background" list.

The puzzle has fifteen pieces and one empty space arranged in a 4×4 grid. When the game loads, and subsequently whenever the player clicks the "New game" button, the pieces are shuffled to a solvable starting position, and the timer is reset to zero and starts counting upward. When the player clicks a puzzle piece adjacent to the empty space, the piece moves into the space, leaving a space in its previous position. Motion of puzzle pieces is animated. Once the pieces are in the correct positions and until a new game is started, the timer stops, the empty space in the puzzle is filled with the missing piece of the video, and clicking on the puzzle will no longer have any effect until a new game is started.

The "Undo" button is disabled when gameplay starts and is enabled as soon as the player moves a puzzle piece. When the player clicks the "Undo" button, the last piece moved moves to its previous position. This can be repeated until all moves have been reverted, at which point the "Undo" button is disabled again until the player makes another move.

You can see a non-functional mockup of the game board. (The mockup does not show a game in progress, as that would require either a great deal of manual video editing or writing the bulk of the game's view code.) There is also a proof-of-concept of rendering and moving slices of an HTML5 video element.

Model Design

Data representation

The model represents the game board internally with the following objects:
Rows

A public, constant integer indicating the number of rows in the game board.

Columns

A public, constant integer indicating the number of columns in the game board.

Empty

A public, constant integer representing the empty puzzle piece.

position

A private, zero-indexed sequence of Rows × Columns integers from 0 to Rows × Columns − 1 representing the initial game board layout. Each index corresponds to a game board position as follows (for a 4×4 grid):

0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15

The value at each index represents the correct position of the puzzle piece currently in that position. For example, if position4 = 12 in a 4×4 puzzle, then the puzzle piece at the first column and second row must be moved to the first column and fourth row in order to solve the puzzle. The exception is that the value Rows × Columns − 1 represents the empty space in the board.

moves

A private integer sequence representing the order in which pieces have been moved into the empty space. This sequence can be used together with position to reconstruct the initial board position.

Functions

The model provides the following public functions:
getPosition():integer[]

Returns a copy of position.

getPositionOf(piece:integer):integer[]

Returns the current position of piece.

getMoves():integer[]

Returns a copy of moves.

isSolved():boolean

Returns a boolean value indicating whether the puzzle is in a solved position.

move(piece:integer):void

Moves piece into the empty space. Throws an exception if piece is not an integer, piece < 0, piece ≥ Rows × Columns, or piece is not adjacent to the empty space.

undo():void

Changes position to its previous state and removes the last element of moves. Throws an exception if moves is empty.

isSolved:boolean

A public read-only property indicating whether the puzzle is in its solved position.

Initialization

Initialization of the model does the following:

  1. Initialize position to a length of Rows × Columns, with each value equal to its index.
  2. Randomly arrange the puzzle using the Fisher-Yates (Knuth) shuffle.
  3. Check the puzzle for solvability using the formula described in Mark Ryan (2004), returning to Step 2 if the puzzle is not solvable.
  4. Initialize moves to a length of 0.

The Fisher-Yates shuffle delivers an even distribution of permutations in O(n) time. Since exactly one half of all permutations of the board are solvable (Kevin Gong 2004), we can expect to have to shuffle the board 1.5 times per game, on average. Checking for solvability using a naïve algorithm based on Ryan's formula will run in O(n2) time, but this is not enough to matter on a game board small enough for human use. Overall, this seems a reasonably fast method of creating solvable games.