How to resolve the algorithm 15 puzzle game step by step in the Processing programming language

Published on 12 May 2024 09:40 PM

How to resolve the algorithm 15 puzzle game step by step in the Processing programming language

Table of Contents

Problem Statement

Implement the Fifteen Puzzle Game.

The   15-puzzle   is also known as:

Let's start with the solution:

Step by Step solution about How to resolve the algorithm 15 puzzle game step by step in the Processing programming language

Source code in the processing programming language

int number_of_grid_cells = 16;  //   Set the number of cells of the board here 9, 16, 25 etc  
color piece_color = color(255, 175, 0);
color background_color = color(235, 231, 178);
color piece_shadow_dark = color(206, 141, 0);
color piece_shadow_light = color(255, 214, 126);
int z, t, p, piece_number, row_length, piece_side_length;

PuzzlePiece[] piece = new PuzzlePiece[number_of_grid_cells]; //  Number of puzzle pieces objects array

void setup() { 
  size(400, 400);  // Window size width and height must be egual
	background(200, 50, 0);
  row_length = int(sqrt(number_of_grid_cells));
  piece_side_length = width/row_length;
  textSize(piece_side_length/2.7);
  textAlign(CENTER);

  PVector[] xy_values = new PVector[number_of_grid_cells]; //  Setting the x and y values for each cell on grid
  for (int i = 0; i < number_of_grid_cells; i += row_length) { // Values are the top left pixel of the cell
    for (int j = 0; j < row_length; j++) {
      xy_values[z] = new PVector();
      xy_values[z].x = j*piece_side_length;
      xy_values[z].y = t*piece_side_length; 
      z++;
    }
    t++;
  } 

  int[] place = new int[number_of_grid_cells]; // This array is  to help placing the pieces randomly and store values in piece objects array
  for (int i = 0; i < number_of_grid_cells; i++) place[i] = 0;
  piece_number = 0;

  while (piece_number < number_of_grid_cells) {  // Placing pieces randomly in grid
    p = int(random(0, number_of_grid_cells));
    if (place[p] == 0) { // Once placed will be set to 1 to avoid designing again at this location
      piece[piece_number] = new PuzzlePiece(piece_number, xy_values[p].x, xy_values[p].y); // Creating the piece objects array 
      place[p] = 1;
      piece[piece_number].design(); // Design newly create piece object
      piece_number++;
    }
  }
}

void draw() {  
  for (int i = 0; i < number_of_grid_cells; i++) {   // Search all piece object indexes and verify which one is mouse pressed in this loop
    if (mousePressed == true && mouseX >= piece[i].xPosition() && mouseX <= piece[i].xPosition()+piece_side_length && mouseY >= piece[i].yPosition() && mouseY <= piece[i].yPosition()+piece_side_length && piece[i].pieceNumber() != 15) {  
      if (pieceMove(piece[number_of_grid_cells-1].xPosition(), piece[number_of_grid_cells-1].yPosition(), piece[i].xPosition(), piece[i].yPosition())) {
        float temp_x = piece[number_of_grid_cells-1].xPosition(); // Remember x and y value of final piece index (white piece) 
        float temp_y = piece[number_of_grid_cells-1].yPosition();
        piece[number_of_grid_cells-1].storePos(piece[i].xPosition(), piece[i].yPosition()); // Store clicked x and y value in final index of piece array
        piece[i].storePos(temp_x, temp_y); // Store temp x and y value (the last/previous final index values) in current clicked piece index  
        piece[number_of_grid_cells-1].design(); // draw the final index piece index (only final piece index is painted white)
        piece[i].design(); // Draw a numbered piece of current index
      }
    }
  }
}

boolean pieceMove(float final_index_piece_x, float final_index_piece_y, float current_index_x, float current_index_y) {
  // If both x values from clicked and white piece have same value meaning in same horizontal column 
  // AND   current clicked y value is equal to white piece y value - piece side lenght  OR  current clicked y value + piece side lenght is egual to white piece y 
  if (current_index_x == final_index_piece_x && (current_index_y == final_index_piece_y-piece_side_length || (current_index_y == final_index_piece_y+piece_side_length))) return true;
  // If both y values from clicked and white piece have same value meaning in same vertical column 
  // AND   current clicked x value is equal to white piece x value - piece side lenght  OR  current clicked x value + piece side lenght is egual to white piece x 
  else if (current_index_y == final_index_piece_y && (current_index_x == final_index_piece_x-piece_side_length || (current_index_x == final_index_piece_x+piece_side_length))) return true;
  else return false;
}

class PuzzlePiece {   
  int piece_number;
  float x_pos, y_pos;

  PuzzlePiece(int _piece_nr, float _xp, float _yp) {
    piece_number = _piece_nr;
    x_pos = _xp;
    y_pos = _yp;
  }  

  void storePos(float _xp, float _yp) {
    x_pos = _xp;
    y_pos = _yp;
  }

  int pieceNumber() {
    return piece_number;
  }

  float xPosition() {
    return x_pos;
  }

  float yPosition() {
    return y_pos;
  }

  void design() {
    noStroke();
    fill(piece_color);
    if (piece_number == number_of_grid_cells-1) fill(background_color);   
    rect(x_pos+1, y_pos+1, piece_side_length-1, piece_side_length-1);
    if (piece_number != number_of_grid_cells-1) {
      fill(0); // Black text shadow
      text(piece_number+1, x_pos+piece_side_length/2+1, y_pos+piece_side_length/2+textAscent()/2);
      fill(255);
      text(piece_number+1, x_pos+piece_side_length/2, y_pos+piece_side_length/2+textAscent()/2);
      stroke(piece_shadow_dark);
      line(x_pos+piece_side_length-1, y_pos+1, x_pos+piece_side_length-1, y_pos+piece_side_length-1); // Right side shadow
      line(x_pos+2, y_pos+piece_side_length, x_pos+piece_side_length-1, y_pos+piece_side_length); // Bottom side shadow
      stroke(piece_shadow_light);
      line(x_pos+2, y_pos-1, x_pos+2, y_pos+piece_side_length); // Left bright
      line(x_pos+2, y_pos+1, x_pos+piece_side_length-1, y_pos+1); // Upper bright
    }
  }
}


# Set the number of cells of the board here 9, 16, 25 etc
num_grid_cells = 16
piece_color = color(255, 175, 0)
background_color = color(235, 231, 178)
piece_shadow_dark = color(206, 141, 0)
piece_shadow_light = color(255, 214, 126)

def setup():
    global piece, piece_number, row_length, piece_side_length
    size(400, 400)  # Window size width and height must be egual
    background(200, 50, 0)
    row_length = int(sqrt(num_grid_cells))
    piece_side_length = width / row_length
    textSize(piece_side_length / 2.7)
    textAlign(CENTER)
    # Setting the x and y values for each cell on grid
    xy_val = []
    t = 0
    for i in range(0, num_grid_cells, row_length):
        for j in range(row_length):
            xy_val.append((j * piece_side_length,
                           t * piece_side_length))
        t += 1
    piece = []  # Puzzle piece objects
    placed = [False] * num_grid_cells  # to help placing the pieces randomly
    piece_number = 0
    # Placing pieces randomly in grid
    while (piece_number < num_grid_cells):
        p = int(random(0, num_grid_cells))
        # Once placed will be set to True to avoid adding again at this location
        if not placed[p]:
            # Creating the piece objects list
            piece.append(PuzzlePiece(piece_number, xy_val[p][0], xy_val[p][1]))
            placed[p] = True
            piece[piece_number].design()  # Draw newly create piece object
            piece_number += 1

def draw():
    # Search all piece object indexes and verify which one is mouse pressed
    for i in range(num_grid_cells):
        if (mousePressed and
                piece[i].x <= mouseX <= piece[i].x + piece_side_length and
                piece[i].y <= mouseY <= piece[i].y + piece_side_length and
                piece[i].piece_number != 15):
            if (pieceMove(piece[num_grid_cells - 1].x, piece[num_grid_cells - 1].y, piece[i].x, piece[i].y)):
                # Remember x and y value of final piece index (white piece)
                temp_x = int(piece[num_grid_cells - 1].x)
                temp_y = int(piece[num_grid_cells - 1].y)
                # Store clicked x and y value in final index of piece list
                piece[num_grid_cells - 1].set_pos(piece[i].x, piece[i].y)
                # Store temp x and y value (the last/previous final index
                # values) in current clicked piece
                piece[i].set_pos(temp_x, temp_y)
                # draw the final index piece index (only final piece index is
                # painted white)
                piece[num_grid_cells - 1].design()
                piece[i].design()  # Draw a numbered piece of current index

def pieceMove(final_index_piece_x, final_index_piece_y, current_index_x, current_index_y):
    # If both x's from clicked and white piece have same value meaning in same horizontal column
    # AND current clicked y value is equal to white piece y value - piece side lenght OR
    # current clicked y value + piece side lenght is egual to white piece y
    if (current_index_x == final_index_piece_x and (current_index_y == final_index_piece_y - piece_side_length or
                                                    (current_index_y == final_index_piece_y + piece_side_length))):
        return True
    # If both y's from clicked and white piece have same value meaning in same vertical column AND current clicked x value
    # is equal to white piece x value - piece side lenght OR current clicked x value + piece side lenght is
    # egual to white piece x
    elif (current_index_y == final_index_piece_y and (current_index_x == final_index_piece_x - piece_side_length or
                                                      (current_index_x == final_index_piece_x + piece_side_length))):
        return True
    else:
        return False

class PuzzlePiece:

    def __init__(self, pn, xp, yp):
        self.piece_number = pn
        self.x = xp
        self.y = yp

    def set_pos(self, xp, yp):
        self.x = xp
        self.y = yp

    def design(self):
        noStroke()
        fill(piece_color)
        if (self.piece_number == num_grid_cells - 1):
            fill(background_color)
        rect(self.x + 1, self.y + 1,
             piece_side_length - 1, piece_side_length - 1)
        if (self.piece_number != num_grid_cells - 1):
            fill(0)  # Black text shadow
            text(self.piece_number + 1, self.x + piece_side_length / 2 + 2,
                 self.y + piece_side_length / 2 + textAscent() / 2)
            fill(255)
            text(self.piece_number + 1, self.x + piece_side_length / 2,
                 self.y + piece_side_length / 2 + textAscent() / 2)
            stroke(piece_shadow_dark)
            line(self.x + piece_side_length - 1, self.y + 1, self.x +
                 piece_side_length - 1, self.y + piece_side_length - 1)  # Right side shadow
            line(self.x + 2, self.y + piece_side_length, self.x +
                 piece_side_length - 1, self.y + piece_side_length)  # Bottom side shadow
            stroke(piece_shadow_light)
            # Left bright
            line(self.x + 2, self.y - 1, self.x + 2,
                 self.y + piece_side_length)
            # Upper bright
            line(self.x + 2, self.y + 1, self.x +
                 piece_side_length - 1, self.y + 1)


  

You may also check:How to resolve the algorithm Comma quibbling step by step in the Eiffel programming language
You may also check:How to resolve the algorithm Draw a pixel step by step in the Java programming language
You may also check:How to resolve the algorithm Dot product step by step in the SPARK programming language
You may also check:How to resolve the algorithm Set right-adjacent bits step by step in the 11l programming language
You may also check:How to resolve the algorithm Doomsday rule step by step in the FOCAL programming language