Some days (months??? years???)  ago I began programming in Java language. I produced some simple games.

The 15-puzzle is a sliding puzzle that consists of a frame of numbered square tiles in random order with one tile missing. The puzzle also exists in other sizes, particularly the smaller 8-puzzle. If the size is 3×3 tiles, the puzzle is called the 8-puzzle or 9-puzzle, and if 4×4 tiles, the puzzle is called the 15-puzzle or 16-puzzle named, respectively, for the number of tiles and the number of spaces. The object of the puzzle is to place the tiles in order by making sliding moves that use the empty space.

As usual, at first there are some blablabla….

/**
 * @(#)Fifteen.java
 *
 * One of the most known game
 *
 *  Luigi D'Andrea
 *  @version 1.00 05/04/24
 *  @copyright 2005 xAppSoftware
 */

Now the import section, here I've included all the library needed to implement an applet:

import java.awt.*;
import java.applet.*;
import java.applet.Applet;
import java.awt.event.*;
import java.util.Random;

And now the applet launcher

public class FifteenApplet extends Applet
{
    private Button StartButton;
    void init()
    {
        setBackground(new Color(127,151,175));
        setSize(200,200);
       //  Builds a new button.
        StartButton = new Button("Start Game");
        StartButton.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                Board frame = new Board();
            }
        });
        // adds the button
        add(StartButton);
    }
}

Until now there isn't anything interesting.

But from now on we are going to see the core of the game.

The class Board instantiates the Game, and handles the painting of the board and the mousepressed event. A mousepressed event can happen in the shuffle box or in the board, in the first case the Board class calls the shuffle method of the Fifteen class while in the second case the Board class calls the moveNumber of the Fifteen class.

class Board extends implements MouseListener
{
    Fifteen theGame =   new Fifteen(30);
    private final int offset=   30;
    public Board()
    {
        theGame.shuffle();
        setVisible(true);
        setSize(250, 250);
        setBackground(new Color(127,151,175);
        addWindowListener(new WindowAdapter()
        {
            public void windowClosing(WindowEvent e)
            {
                dispose();
            }
        });
        addMouseListener(this); // "mouse listener" 
    }

    public void paint(Graphics g)
    {
        theGame.paint(g);
        g.setColor(Color.green);
        g.fill3DRect(180, 30, 60, 30, true);
        g.setColor(Color.black);
        g.drawString("Shuffle", 186, 48);
    }
    
    public void mousePressed(MouseEvent e)
    {
        Point mouse =   new Point();
        mouse       =   e.getPoint();

        if(mouse.x>180mouse.x<240mouse.y>30mouse.y<60)
        {
            theGame.shuffle();
            repaint();
        }
         if(mouse.x>offsetmouse.xoffsetmouse.y

The fifteen class is the engine of the game, this class:

  • re-paint the board (pain method)
  • understands if a move is valid (moveNumber method)
  • moves the pieces (moveNumber method)
  • checks for the win (checkWin method)
  • scramble the pieces on the board
class Fifteen
{
    private int board[][]   =    new int[4][4];
     private int offset;
     private boolean win=false;
     public Fifteen(int offset)
     {
         int i, j;
         this.offset     =   offset;
         int counter =   1;
         for(i=0; i<4; i++)
         {
             for(j=0; j<4; j++)
             {
                 board[i][j] =   counter;
                 counter++;
             }
         }
         board[3][3] =   0;
     }
 
     public void paint(Graphics g)
     {
         int i, j;
         for(j=0; j<4; j++)
             for(i=0; i<4; i++)
             {
                 if(board[i][j]<=4  board[i][j]>0 ||
                     board[i][j]<=12  board[i][j]>8)
                 {
                     if(board[i][j]%2==0)
                         g.setColor(Color.red);
                     else
                         g.setColor(Color.blue);
                 }
                 else
                 {
                     if(board[i][j]%2==1)
                         g.setColor(Color.red);
                     else
                         g.setColor(Color.blue);
                 }
                 if(board[i][j]==0)
                     g.setColor(Color.white);
                 g.fill3DRect(offset+30*j, offset+30*i, 30, 30, true);
                 g.setColor(Color.black);
                 if(board[i][j]!=0)
                     g.drawString(""+board[i][j], offset+30*j+12, offset+30*i+18);
             }
         if(win==true)
         {
             g.drawString("You have won", 200, 30);
         }
     }
 

     public void moveNumber(Point mouse)
     {
         int posX, posY, i;
         int aux =   0;
 
         posX    =   ((mouse.x-offset)/30);
         posY    =   ((mouse.y-offset)/30);
         if(posY-1>=0)
         {
             if(board[posY-1][posX]==0)
             {
                 board[posY-1][posX] =   board[posY][posX];
                 board[posY][posX]       =   0;
                 checkWin();
             }
         }
         if(posY+1<4)
         {
             if(board[posY+1][posX]==0)
             {
                 board[posY+1][posX] =   board[posY][posX];
                 board[posY][posX]       =   0;
                 checkWin();
             }
         }
         if(posX-1>=0)
         {
             if(board[posY][posX-1]==0)
             {
                 board[posY][posX-1] =   board[posY][posX];
                 board[posY][posX]       =   0;
                 checkWin();
             }
         }
         if(posX+1<4)
         {
             if(board[posY][posX+1]==0)
             {
                 board[posY][posX+1] =   board[posY][posX];
                 board[posY][posX]       =   0;
                 checkWin();
             }
         }
     }
 
     public void checkWin()
     {
         int i, j, counter;
         boolean flag    =   true;
         counter =   1;
         for(i=0; i<4; i++)
         {
             for(j=0; j<4; j++)
             {
                 if(board[i][j]!=counter)
                     flag    =   false;
                 counter++;
                 if(counter==16)
                     counter=0;
             }
         }
         if(flag==true)
             win=true;
     }
 
     public void shuffle()
     {
         int aux[]   =   new int[16];
         int i, j, counter = 0;
         for(i=0; i<16; i++)
         {
             aux[i]  =   (int)(Math.random()*15);
         }
         for(i=0; i<16; i++)
         {
             for(j=0; j

That's all,

Gg1