📄 board.java
字号:
/* * @(#)Board.java 1.22 02/07/25 @(#) * * Copyright (c) 2000-2001 Sun Microsystems, Inc. All rights reserved. * PROPRIETARY/CONFIDENTIAL * Use is subject to license terms. */package example.tilepuzzle;import example.About;import java.util.Random;import javax.microedition.lcdui.*;import javax.microedition.midlet.MIDlet;public class Board extends Canvas implements CommandListener {MIDlet midlet;Display dpy;Options options;// this string must be exactly 15 characters longString letters = "RATEYOURMINDPAL"; Font font;Piece blankp;Piece[] all;Piece[][] grid;Random rand;// grid origin in pixelsint gridx;int gridy;// grid width and height, in cellsint gridw;int gridh;// cell geometry in pixelsint cellw;int cellh;int cellyoff;int cellxoff;// commandsstatic final int CMD_ABOUT = 0;static final int CMD_EXIT = 1;static final int CMD_OPTIONS = 2;static final int CMD_RESET = 3;static final int CMD_START = 4;static final int CMD_UNLOCK = 5;static final int CMD_ZLAST = 6; // must be ze last, of courseCommand cmd[];// state variablesstatic final int INITIALIZED = 0;static final int PLAYING = 1;static final int WON = 2;int gameState;boolean cheated;void D(String s) { System.out.println(s); } class Piece { String label; boolean inv; int serial; // serial number for ordering int ix, iy; // initial location in grid coordinates int x, y; // current location in grid coordinates Piece(String str, int ser, int nx, int ny, boolean v) { label = str; serial = ser; x = ix = nx; y = iy = ny; inv = v; } void setLocation(int nx, int ny) { x = nx; y = ny; } boolean isHome() { return (x == ix) && (y == iy); } void goHome() { setGrid(this, ix, iy); } // assumes background is white void paint(Graphics g) { int px = x * cellw; int py = y * cellh; if (label != null) { if (inv) { // black outlined, white square with black writing g.setColor(0); g.setFont(font); g.drawRect(px, py, cellw-2, cellh-2); g.drawString(label, px+cellxoff, py+cellyoff, Graphics.TOP|Graphics.LEFT); } else { // black square with white writing g.setColor(0); g.fillRect(px, py, cellw-1, cellh-1); g.setColor(0xFFFFFF); g.setFont(font); g.drawString(label, px+cellxoff, py+cellyoff, Graphics.TOP|Graphics.LEFT); } } } } class BoardCommand extends Command { int tag; BoardCommand(String label, int type, int pri, int tag_) { super(label, type, pri); tag = tag_; } }void setGrid(Piece p, int x, int y) { grid[x][y] = p; p.setLocation(x, y);}// swap the piece at sx, sy with the blank piece// assumes that this is a legal movevoid moveBlank(int swapx, int swapy) { setGrid(grid[swapx][swapy], blankp.x, blankp.y); setGrid(blankp, swapx, swapy);}// swaps the pieces at (x1, y1) and (x2, y2)// no parity checking is done! void swap(int x1, int y1, int x2, int y2){ Piece t = grid[x1][y1]; setGrid(grid[x2][y2], x1, y1); setGrid(t, x2, y2);}boolean isSolved() { for (int i = 0; i < gridh; i++) { for (int j = 0; j < gridw; j++) { if (! grid[j][i].isHome()) { return false; } } } return true;}// return a random integer in the range [0..n)int randRange(int n) { int r = rand.nextInt() % n; if (r < 0) r += n; return r;}// randomize by making random movesvoid randomize_by_moving() { int dx, dy, v; for (int i = 0; i < 100; i++) { dx = dy = 0; v = (rand.nextInt() & 2) - 1; // 1 or -1 if ((rand.nextInt() & 1) == 0) dx = v; else dy = v; if (blankp.x + dx < 0) dx = 1; if (blankp.x + dx == gridw) dx = -1; if (blankp.y + dy < 0) dy = 1; if (blankp.y + dy == gridh) dy = -1; moveBlank(blankp.x + dx, blankp.y + dy); } // now move the blank tile to the lower right corner while (blankp.x != gridw-1) moveBlank(blankp.x + 1, blankp.y); while (blankp.y != gridh-1) moveBlank(blankp.x, blankp.y + 1);}// shuffle the tiles randomly and place the blank at the bottom rightvoid shuffle() { int limit = gridw*gridh-1; Piece ta[] = new Piece[limit]; Piece temp; System.arraycopy(all, 0, ta, 0, limit); for (int i = 0; i < limit; i++) { int j = randRange(limit); temp = ta[j]; ta[j] = ta[i]; ta[i] = temp; } for (int i = 0; i < limit; i++) { setGrid(ta[i], i/gridw, i%gridw); } setGrid(blankp, gridw-1, gridh-1);}void randomize(boolean hard) { shuffle(); int ra, rb; int x, y; if (hard) { ra = 7; rb = 0; } else { ra = 0; rb = 7; } x = rand.nextInt() & 1; y = rand.nextInt() & 1; if (x == 1 && y == 1) { x = 2; y = 0; } swap(x, y, all[ra].x, all[ra].y); swap((rand.nextInt()&1)+1, 3, all[rb].x, all[rb].y); if ((displacement() & 1) == 1) swap(1, 3, 2, 3);}// Compute and return the displacement, that is, the number of// pairs of tiles that are out of order. The blank tile *must*// be in the lower right corner.int displacement() { boolean temp[] = new boolean[gridw*gridh-1]; // all false int n = 0; for (int i = 0; i < gridh; i++) { for (int j = 0; j < gridw; j++) { Piece p = grid[j][i]; if (p == blankp) continue; temp[p.serial] = true; for (int k = 0; k < p.serial; k++) { if (!temp[k]) n++; } } } return n;}void resetGrid() { Piece temp[] = new Piece[gridw*gridh]; int k = 0; for (int i = 0; i < gridw; i++) { for (int j = 0; j < gridh; j++) { temp[k++] = grid[i][j]; } } for (k = 0; k < temp.length; k++) { temp[k].goHome(); }}void rearrangeFunnily(boolean hard) { resetGrid(); if (hard) { // RATE YOUR MIDP LAN swap(0, 0, 3, 1); swap(2, 2, 3, 2); swap(3, 2, 0, 3); swap(0, 3, 2, 3); } else { // RATE YOUR MIDP NAL swap(2, 2, 3, 2); swap(3, 2, 0, 3); }}void setState(int ns) { gameState = ns; switch (gameState) { case INITIALIZED: addCommand(cmd[CMD_ABOUT]); removeCommand(cmd[CMD_RESET]); addCommand(cmd[CMD_START]); addCommand(cmd[CMD_UNLOCK]); addCommand(cmd[CMD_EXIT]); addCommand(cmd[CMD_OPTIONS]); break; case PLAYING: addCommand(cmd[CMD_ABOUT]); addCommand(cmd[CMD_RESET]); removeCommand(cmd[CMD_START]); removeCommand(cmd[CMD_UNLOCK]); addCommand(cmd[CMD_EXIT]); addCommand(cmd[CMD_OPTIONS]); break; case WON: addCommand(cmd[CMD_ABOUT]); removeCommand(cmd[CMD_RESET]); addCommand(cmd[CMD_START]); addCommand(cmd[CMD_UNLOCK]); addCommand(cmd[CMD_EXIT]); addCommand(cmd[CMD_OPTIONS]); break; }}public Board(MIDlet midlet_) { int i; // "global" variables midlet = midlet_; dpy = Display.getDisplay(midlet); gridw = 4; gridh = 4; font = Font.getFont(Font.FACE_SYSTEM, Font.STYLE_PLAIN, Font.SIZE_MEDIUM); // REMIND update when font metrics info gets implemented cellw = font.charWidth('M') + 7; cellh = font.getHeight() + 1; cellxoff = 3; cellyoff = 0; gridx = (getWidth() - (gridw*cellw) + 1) / 2; gridy = 10; cheated = false; rand = new Random(); // create the grid arrays grid = new Piece[gridw][]; for (i = 0; i < gridw; i++) { grid[i] = new Piece[gridh]; } all = new Piece[gridw*gridh]; for (i = 0; i < (gridw*gridh)-1; i++) { int x = i % gridw; int y = i / gridw; String s = letters.substring(i, i+1); grid[x][y] = all[i] = new Piece(s, i, x, y, i < (gridw*gridh/2)); } // make the special blank piece blankp = new Piece(null, gridw*gridh-1, gridw-1, gridh-1, false); grid[gridw-1][gridh-1] = blankp; all[gridw*gridh-1] = blankp; // set up commands cmd = new Command[CMD_ZLAST]; cmd[CMD_ABOUT] = new BoardCommand("About", Command.HELP, 5, CMD_ABOUT); cmd[CMD_EXIT] = new BoardCommand("Exit", Command.EXIT, 6, CMD_EXIT); cmd[CMD_OPTIONS] = new BoardCommand("Options", Command.SCREEN, 3, CMD_OPTIONS); cmd[CMD_RESET] = new BoardCommand("Reset", Command.SCREEN, 1, CMD_RESET); cmd[CMD_START] = new BoardCommand("Start", Command.SCREEN, 1, CMD_START); cmd[CMD_UNLOCK] = new BoardCommand("Unlock", Command.SCREEN, 4, CMD_UNLOCK); // set up the listener setCommandListener(this); // set up options screen options = new Options(dpy, this); // set up initial state setState(INITIALIZED);}public void commandAction(Command c, Displayable d) { switch (((BoardCommand) c).tag) { case CMD_ABOUT: About.showAbout(Display.getDisplay(midlet)); break; case CMD_EXIT: midlet.notifyDestroyed(); break; case CMD_OPTIONS: dpy.setCurrent(options); break; case CMD_RESET: cheated = false; resetGrid(); setState(INITIALIZED); repaint(); break; case CMD_START: cheated = false; if (options.funny) { rearrangeFunnily(options.hard); } else { randomize(options.hard); } setState(PLAYING); repaint(); break; case CMD_UNLOCK: cheated = true; setState(PLAYING); repaint(); break; }}public void showNotify() { // System.out.println("Board: showNotify");}public void hideNotify() { // System.out.println("Board: hideNotify");}public void paint(Graphics g) { g.setColor(0xFFFFFF); g.fillRect(0, 0, getWidth(), getHeight()); g.translate(gridx, gridy); g.setColor(0); g.drawRect(-2, -2, gridw*cellw + 2, gridh*cellh + 2); for (int j = 0; j < gridw; j++) { for (int k = 0; k < gridh; k++) { grid[j][k].paint(g); } } if (gameState == WON) { g.translate(-g.getTranslateX(), -g.getTranslateY()); g.setColor(0); g.setFont(Font.getDefaultFont()); g.drawString( (cheated ? "CHEATER!" : "YOU WIN!"), getWidth() / 2, getHeight() - 1, Graphics.BOTTOM|Graphics.HCENTER); }}public void keyPressed(int code) { if (gameState != PLAYING) return; int game = getGameAction(code); int swapx = blankp.x; int swapy = blankp.y; int direction = (options.reversed ? -1 : 1); switch (game) { case Canvas.UP: swapy += direction; break; case Canvas.DOWN: swapy -= direction; break; case Canvas.LEFT: swapx += direction; break; case Canvas.RIGHT: swapx -= direction; break; default: return; } if (swapx < 0 || swapx >= gridw || swapy < 0 || swapy >= gridh) { return; } moveBlank(swapx, swapy); repaint(); if (isSolved()) { setState(WON); }}}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -