import java.applet.Applet; import java.awt.Graphics; import java.awt.Color; import java.awt.Event; import java.awt.Dimension; import java.util.Random; import java.awt.event.MouseEvent; public class SlidePuzzle extends Applet { int columns = 0; int rows = 0; int[] puzzleData; protected final int parseSize(String sizeStr) { int v; v = Integer.parseInt(sizeStr); if (v <= 1) v = 2; else if (v > 10) v = 10; return v; } public void init() { int x = 4; int y = 4; String param; param = getParameter("size"); if (param != null) { x = parseSize(param); y = x; } param = getParameter("columns"); if (param != null) x = parseSize(param); param = getParameter("rows"); if (param != null) y = parseSize(param); initPuzzle(x, y); // "subscribe" to mouseclicks enableEvents(MouseEvent.MOUSE_CLICKED); } // Initialize puzzle to given matrix dimensions public void initPuzzle(int x, int y) { int size = x*y; int i; Random rnd = new Random(); columns = x; rows = y; // Allocatie out data storage (array of int) puzzleData = new int[size]; // put the numbers into the cells for (i=0; i < size-1; i++) puzzleData[i] = i+1; // The '0' cell is the "blank" cell puzzleData[size-1] = 0; // Shuffle the tiles. for (i=0; i < 2*size; i++) exchange(Math.abs(rnd.nextInt()) % size, Math.abs(rnd.nextInt()) % size); } // Paints the applet public void paint(Graphics g) { Dimension b = getSize(); int i; int size = columns * rows; int w = b.width / columns; int h = b.height / rows; for (int y=0; y 0) { g.setColor(Color.blue); g.fillRect(x * w, y * h, w - 2, h - 2); g.setColor(Color.white); g.drawString("" + i, x*w+1, (y+1)*h - 8); } } } } // Swap two cells at given coordinates (offset into puzzleData array) public void exchange(int i, int j) throws ArrayIndexOutOfBoundsException { int m = puzzleData[i]; puzzleData[i] = puzzleData[j]; puzzleData[j] = m; } // Returns cell value at x,y public int dataAt(int x, int y) { return puzzleData[x + (y*rows)]; } // returns index into puzzleData array for given coordinates public int indexOf(int x, int y) { return (x + (y*rows)); } // Handles mouse events protected void processMouseEvent(MouseEvent e) { if (e.getID() == MouseEvent.MOUSE_CLICKED) { hasClickedAt(e.getX(), e.getY()); } } // The real mous click handler. protected void hasClickedAt(int x, int y) { Dimension b = getSize(); int i, t; int size = columns * rows; int atX = columns * x / b.width; int atY = rows * y / b.height; // Where did we click i = atX + (columns * atY); t = -1; // Find the blank neighbor if (puzzleData[i] != 0) { if ((atX > 0) && (dataAt(atX-1, atY) == 0)) t = indexOf(atX-1, atY); else if ((atY > 0) && (dataAt(atX, atY-1) == 0)) t = indexOf(atX, atY-1); else if ((atX < columns-1) && (dataAt(atX+1, atY) == 0)) t = indexOf(atX+1, atY); else if ((atY < rows-1) && (dataAt(atX, atY+1) == 0)) t = indexOf(atX, atY+1); // If we found a blank neigbor, move the clicked tile over there. if (t >= 0) { exchange(i,t); repaint(); } } } public String getAppletInfo() { return "SlidePuzzle - (c)1998 by Mike Looijmans (my first applet)"; } public String[][] getParameterInfo() { String[][] pinfo = { {"size", "int", "sides of the puzzle"}, {"columns", "int", "x-dimension (overrides sides)"}, {"rows", "int", "y-dimension (overrides sides)"} }; return pinfo; } }