// 15-Puzzle
// Written by: Deepak Kumar
// November 2019
// Purpose: Program to play the 15-puzzle
// It displays a 15-puzzle
// Then the user can shuffle the tiles by pressing the 's' key.
// Using the arrow keys, the user can move the "blank" tile up, down, left, or right
// This class models a 15-Puzzle board
class Board {
// Every board has 16 spaces, it is a 4x4 puzzle
// One of which is a blank, represented by a 0
int N = 4; // NxN board
// An initial board for testing purposes, no longer used
int[][] example = {{1, 10, 15, 4},
{13, 6, 3, 8},
{2, 9, 12, 7},
{14, 5, 0, 11}};
int[][] board; // The puzzle board
// key codes of arrow keys, representing moves
int left = 37;
int right = 39;
int up = 38;
int down = 40;
int[] moves = {left, right, up, down};
PFont font; // display font
Board() { // Constructor, creates a fresh (solved) puzzle
board = new int[N][N];
int tile = 0; // blank tile goes first
for (int r = 0; r < N; r++) {
for (int c = 0; c < N; c++) {
board[r][c] = tile;
tile++;
}
}
// Also create the font that will be used
font = loadFont("Arial-BoldMT-48.vlw");
textFont(font);
} // Board()
void shuffle() { // shuffles the puzzle using the moves() method
// pick a random number of moves to shuffle
int nMoves = int(random(20, 50));
for (int i=0; i < nMoves; i++) {
// do a random move (pick direction)
int m = int(random(4));
this.move(moves[m]);
}
this.display();
} // shuffle()
void move(int k) { // Make a move represented by key, k (up, down,left, right
// This involves moving the blank space up, left, down, or right
// Find r, j of blank
int r=0, c=0;
for (int i=0; i < N; i++) {
for (int j=0; j < N; j++) {
if (board[i][j]==0) {
r = i;
c = j;
}
}
}
// Find out which key was pressed and then make the move
// Does nothing if an incorrect key is pressed, or if there is
// No move that can be made.
if (k == up) {
// Move blank up
if (r > 0) {
board[r][c] = board[r-1][c];
board[r-1][c] = 0;
}
} else if (k == down) {
// move blank down
if (r < N-1) {
board[r][c] = board[r+1][c];
board[r+1][c] = 0;
}
} else if (k == left) {
// move blank left
if (c > 0) {
board[r][c] = board[r][c-1];
board[r][c-1] = 0;
}
} else if (k == right) {
// move blank right
if (c < N-1) {
board[r][c] = board[r][c+1];
board[r][c+1] = 0;
}
}
} // move();
void printBoard() {
// prints the board in Console
for (int i=0; i < N; i++) {
for (int j=0; j < N; j++) {
print(board[i][j] + "\t");
}
println();
}
} // print()
void display() {
// Displays the puzzle as it currently stands
textSize(48);
textAlign(CENTER);
int w = height/5;
int x = (width - N*w)/2;
int y = (height - N*w)/2;
pushMatrix();
translate(x, y);
for (int i=0; i < N; i++) {
// Draw row i
for (int j=0; j < N; j++) {
// Draw all columns of row i
noFill();
rect(j*w, i*w, w, w);
fill(0);
text(board[i][j], j*w+w/2, i*w+w/2);
if (board[i][j] == 0) {
fill(0);
rect(j*w, i*w, w, w);
}
}
}
popMatrix();
} // display()
} // class Board