/* Puzzle : Un tipico juego de puzzle */
/* Juan J. Sierralta P. */
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.lang.*;
import java.io.*;
/*
*/
//
public class Puzzle extends Applet
implements MouseListener
{
int v, h; // Se divide la imagen V x H celdas
int iw, ih; // Ancho y Alto de la imagen
int cw, ch; // Ancho y Alto de una celda
int movidas; // Numero de movidas
int last; // Ultima celda (negra)
int numCeldas; // Numero de celdas
boolean solved; // Resuelto ?
Image[] Celda; // Arreglo de imagenes
int[] Orden; // Orden de las imagenes
int lastPos; // Posicion del cuadro vacio
Image Imagen; // Imagen original
String movStr; // String para las movidas
Color backCol; // Un color
// El constructor
public Puzzle()
{
// Se inicializan variables
movidas = 0;
numCeldas = 0;
last = 0;
lastPos = 0;
solved = false;
movStr = "Movidas: 0";
// Escuchamos eventos de mouse
addMouseListener(this);
}
// init: Y Dios creo el mundo....
public void init()
{
try
{
// Obtenemos la imagen
Imagen = getImage(getDocumentBase(),getParameter("img"));
MediaTracker t = new MediaTracker(this);
t.addImage(Imagen, 0);
t.waitForID(0);
// Obtenemos el cuadriculado deseado
iw = Imagen.getWidth(null);
ih = Imagen.getHeight(null);
v = Integer.parseInt(getParameter("v"),10);
h = Integer.parseInt(getParameter("h"),10);
cw = iw / h;
ch = ih / v;
numCeldas = v*h;
last = numCeldas - 1;
lastPos = last;
// Ahora creamos numCeldas subimagenes
Celda = new Image[numCeldas];
Orden = new int[numCeldas];
CropImageFilter f;
FilteredImageSource fis;
for (int y=0; y < v; y++)
{
for (int x=0; x < h; x++)
{
f = new CropImageFilter(cw*x, ch*y, cw, ch);
fis = new FilteredImageSource(Imagen.getSource(), f);
int i = y*h+x;
Orden[i] = i;
Celda[i] = createImage(fis);
t.addImage(Celda[i], i);
}
}
t.waitForAll();
// Barajamos las subimagenes
shuffle();
} catch (Exception e) {};
}
// suffle: Baraja las subimagenes
private void shuffle()
{
for (int i=0; i < numCeldas*2; i++)
{
int si = (int) (Math.random() * numCeldas);
int di = (int) (Math.random() * numCeldas);
int tmp = Orden[si];
Orden[si] = Orden[di];
Orden[di] = tmp;
}
}
// Puntaje: Calcula el numero de celdas bien posicionadas.
public int Puntaje()
{
int score=0;
for(int i=0; i < numCeldas; i++)
{
if (Orden[i]==i) {score++;}
}
return score;
}
// mouseClicked: Se llama cuando se hace un click de mouse
public void mouseClicked(MouseEvent e)
{
int x = e.getX();
int y = (e.getY() - 50);
x = x / (cw + 1);
y = y / (ch + 1);
int pos = y*h + x;
if ( (pos != lastPos) && (solved==false) && (pos<=last))
{
// Izquierda
if (((pos%h)!=0) && (Orden[pos-1]==last))
{
Orden[pos-1]=Orden[pos];
Orden[pos]=last;
lastPos = pos;
movidas++;
repaint();
}
// Arriba
else if (((pos-h)>=0) && (Orden[pos-h]==last))
{
Orden[pos-h]=Orden[pos];
Orden[pos]=last;
lastPos = pos;
movidas++;
repaint();
}
// Derecha
else if (((pos%h)!=h) && (Orden[pos+1]==last))
{
Orden[pos+1]=Orden[pos];
Orden[pos]=last;
lastPos = pos;
movidas++;
repaint();
}
// Abajo
else if (((pos+h)<=last) && (Orden[pos+h]==last))
{
Orden[pos+h]=Orden[pos];
Orden[pos]=last;
lastPos = pos;
movidas++;
repaint();
}
movStr = "Movidas: " + movidas;
}
}
// Nuestra clase no hace nada con los demas
// eventos de mouse
public void mousePressed(MouseEvent e)
{
}
public void mouseReleased(MouseEvent e)
{
}
public void mouseEntered(MouseEvent e)
{
}
public void mouseExited(MouseEvent e)
{
}
// update: Repinta el componente, llama a paint
public void update(Graphics g)
{
paint(g);
}
// paint: Aqui se dibuja el componente
public void paint(Graphics g)
{
// Borramos el texto anterior
backCol = Color.lightGray;
g.setColor(backCol);
g.fillRect(0,0,150,49);
backCol = Color.black;
g.setColor(backCol);
// Imprimimos el numero de movidas
g.drawString(movStr,5,12);
// Obtenemos el puntaje y lo mostramos
int score = Puntaje();
if (score==last)
{
// Ganamos !
solved=true;
g.drawString("Felicitaciones !",5,24);
}
else
{
// Mostramos el puntaje (numero de piezas bien colocadas)
g.drawString(score + " piezas correctas",5,24);
}
// Hacemos un rectangulo negro detras de las subimagenes
// asi, separando cada celda por 1 pixel de sus vecinas
// se ve una grilla.
g.fillRect(0, 50, iw + h - 2, ih + v);
// Dibujamos cada subimagen
for (int y=0; y < v; y++)
{
for (int x=0; x < h; x++)
{
if ( Orden[y*h + x] != last)
g.drawImage(Celda[Orden[y*h+x]], (x * cw) + x, 50 + (y * ch) + y, this);
}
}
}
}