/* * * * "Game 15" * Created by V.Borisenko */ import java.applet.Applet; import java.awt.*; import java.lang.Math; public class Fifteen extends Applet implements Runnable { Thread mixThread = null; byte field[][] = new byte[4][4]; Button buttons[] = new Button[15]; Button mixButton; Label numMoves; int nMoves = 0; int holeX = 3; int holeY = 3; final int DX = 40; final int DY = 40; final int topSkip = 40; final int topMargin = 5; final int leftMargin = 5; final int MIX_DEPTH = 100; final int MIX_DELAY = 333; boolean mixing = false; public void init() { int x, y; setLayout(null); setFont(new Font("Helvetica", Font.PLAIN, 18)); setBackground(Color.lightGray); mixButton = new Button("Mix"); Label l = new Label("Moves: "); numMoves = new Label("0"); nMoves = 0; add(mixButton); add(l); add(numMoves); mixButton.reshape(leftMargin, topMargin, 50, 30); l.reshape(leftMargin + 65, topMargin, 70, 30); numMoves.reshape(leftMargin + 140, topMargin, 50, 30); for (y = 0; y < 4; y++) { for (x = 0; x < 4; x++) { int k = y*4 + x; if (k >= 15) break; field[x][y] = (byte)k; buttons[k] = new Button("" + (k+1)); add(buttons[k]); buttons[k].reshape( x*DX + leftMargin, y*DY + topSkip, DX, DY ); } } holeX = 3; holeY = 3; field[holeX][holeY] = (byte)(-1); } public boolean action(Event e, Object arg) { Object target = e.target; if (target == mixButton) { mix(); } else { Loop: for (int y = 0; y < 4; y++) { for (int x = 0; x < 4; x++) { int b = field[x][y]; if (b >= 0 && buttons[b] == target) { makeMove(x, y); break Loop; } } } } return false; } public synchronized void makeMove(int x, int y) { System.out.println("makeMove: " + x + ", " + y); int k = field[x][y]; if (k < 0) return; Button b = buttons[k]; int xnew = (-1), ynew = y; if (x-1 >= 0 && field[x-1][y] == (-1)) { xnew = x-1; ynew = y; } if (x+1 < 4 && field[x+1][y] == (-1)) { xnew = x+1; ynew = y; } if (y-1 >= 0 && field[x][y-1] == (-1)) { xnew = x; ynew = y-1; } if (y+1 < 4 && field[x][y+1] == (-1)) { xnew = x; ynew = y+1; } if (xnew >= 0) { b.move( xnew*DX + leftMargin, ynew*DY + topSkip ); field[x][y] = (byte)(-1); field[xnew][ynew] = (byte)k; holeX = x; holeY = y; } nMoves++; numMoves.setText("" + nMoves); // mixButton.requestFocus(); } public void mix() { System.out.println("mix"); if (mixing) { mixing = false; } else if (mixThread == null) { System.out.println("Creating mixing thread."); mixing = true; mixButton.setLabel("Stop"); mixThread = new Thread(this, "Mixing"); mixThread.start(); } } public void run() { // Mixing thread System.out.println("Starting mixing thread."); int prevDir = (-1); for (int i = 0; mixing && i < MIX_DEPTH; i++) { int newx = holeX; int newy = holeY; // Direction of move: 0 - right, 1 - up, 2 - left, 3 - down int dir = (int)(Math.random() * 4. - 0.001); if (dir == (prevDir + 2) % 4) dir = (dir + 1) % 4; if (dir == 0) { // right if (holeX < 3) { newx = holeX + 1; } else { dir++; } } if (dir == 1) { // Up if (holeY > 0) { newy = holeY - 1; } else { dir++; } } if (dir == 2) { // Left if (holeX > 0) { newx = holeX - 1; } else { dir++; } } if (dir == 3) { // Down if (holeY < 3) { newy = holeY + 1; } else if (holeX < 3) { // Right newx = holeX + 1; dir = 0; } } if (newx != holeX || newy != holeY) { makeMove(newx, newy); prevDir = dir; } // Delay try { mixThread.sleep(MIX_DELAY); } catch(InterruptedException e) { System.out.println(e.toString()); } } nMoves = 0; numMoves.setText("" + nMoves); mixing = false; mixButton.setLabel("Mix"); mixThread = null; } public void stop() { mixThread = null; mixing = false; mixButton.setLabel("Mix"); } }