Sliding-blocks Puzzle Source
(Last Update 18:11 on Monday, 08 January 2001)
- // Java Sliding-blocks Puzzle applet
- // Neil Rashbrook
- // Last modified January 8 2001
- import java.awt.*;
- public class puzzle extends java.applet.Applet {
-
- Image i, o;
- Graphics g;
- Dimension d;
- shape s[], m;
- int x, y;
- public void init() {
-
- i = super.getImage(super.getCodeBase(), super.getParameter("image"));
- d = super.size();
- int dx = d.width / 4, dx2 = dx + dx;
- int dy = d.height / 10, dy2 = dy + dy, dy4 = dy2 + dy2;
- d.width = dx2 + dx2;
- d.height = dy * 10;
- o = super.createImage(d.width + 1, d.height + 1);
- g = o.getGraphics();
- s = new shape[] {
- new twin(i, -dx2, -d.height, 0, dy4, dx, -dy4, dx2, -dy2),
- new shape(i, dx * -3, dy * -6, dx, 0, dx, dy2),
- new twin(i, -dx2, dy * -3, dx2, 0, dx, dy2, dx2, dy),
- new shape(i, -dx, -dy4, dx * 3, dy, dx, dy2),
- new twin(i, -dx2, dy * -3, dx2, dy4, dx, -dy2, dx2, -dy),
- new twin(i, dx * -4, 0, dx2, dy * 6, -dx, dy2, -dx2, dy),
- new twin(i, -dx2, 0, d.width, dy * 6, -dx, dy4, -dx2, dy2),
- new shape(i, 0, -dy4, 0, dy * 7, dx, dy2),
- new twin(i, dx * -4, dy * -6, dx2, d.height, -dx, -dy2, -dx2, -dy),
- new shape(i, 0, -dy2, dx2, dy * 8, dx, dy2)};
- }
- public String[][] getParameterInfo() {
- return new String[][] {{"image", "url", "image"}};
- }
- public boolean isFocusTraversable() {
- return true;
- }
- public boolean keyDown(Event evt, int key) {
-
- if (key == 9) {
-
- repaint(1);
- if (evt.shiftDown()) {
-
- for (int i = 9; i > 0; ) {
-
- if (s[i--] == m) {
- m = s[i];
- return true;
- }
- }
- m = s[9];
- return true;
- } else {
-
- for (int i = 0; i < 9; ) {
-
- if (s[i++] == m) {
- m = s[i];
- return true;
- }
- }
- m = s[0];
- return true;
- }
- }
- if (m == null) return false;
- switch (key) {
- case Event.LEFT: return mouseDrag(evt, x - 1, y);
- case Event.RIGHT: return mouseDrag(evt, x + 1, y);
- case Event.UP: return mouseDrag(evt, x, y - 1);
- case Event.DOWN: return mouseDrag(evt, x, y + 1);
- case Event.HOME: return mouseDrag(evt, x - d.width, y);
- case Event.END: return mouseDrag(evt, x + d.width, y);
- case Event.PGUP: return mouseDrag(evt, x, y - d.height);
- case Event.PGDN: return mouseDrag(evt, x, y + d.height);
- }
- return false;
- }
- public boolean mouseDown(Event evt, int x, int y) {
- repaint(1);
- this.x = x;
- this.y = y;
- for (int i = 0; i <= 9; i++) if ((m = s[i]).contains(x, y)) return true;
- m = null;
- return true;
- }
- public boolean mouseDrag(Event evt, int x, int y) {
-
- if (m != null) while (x != this.x || y != this.y) {
-
- int dx = x < this.x ? -1 : x > this.x ? 1 : 0;
- int dy = y < this.y ? -1 : y > this.y ? 1 : 0;
- if ((x - this.x) * dx < (y - this.y) * dy) {
- if ((dy == 0 || !shift(0, dy)) && (dx == 0 || !shift(dx, 0))) return true;
- } else {
- if ((dx == 0 || !shift(dx, 0)) && (dy == 0 || !shift(0, dy))) return true;
- }
- repaint(1);
- }
- return true;
- }
- public void paint(Graphics g) {
-
- //g.clearRect(0, 0, d.width, d.height);
- this.g.setColor(Color.lightGray);
- this.g.fillRect(0, 0, d.width, d.height);
- if (this.g.drawImage(i, 0, 0, this)) {
-
- for (int i = 0; i <= 9; i++) if (s[i].x + s[i].ix != 0 || s[i].y + s[i].iy != 0) {
- for (i = 0; i <= 9; i++) s[i].paint(this.g);
- if (m != null) m.focus(this.g);
- break;
- }
- }
- this.g.setColor(Color.black);
- this.g.drawRect(0, 0, d.width, d.height);
- g.drawImage(o, 0, 0, null);
- }
- private boolean shift(int dx, int dy) {
-
- m.shift(dx, dy);
- if (valid()) {
- this.x += dx;
- this.y += dy;
- return true;
- } else {
- m.unshift(dx, dy);
- return false;
- }
- }
- public void update(Graphics g) {
- paint(g);
- }
- private boolean valid() {
- if (!m.inside(d)) return false;
- for (int i = 0; i <= 9; i++) if (s[i] != m && m.overlaps(s[i])) return false;
- return true;
- }
- }
- class shape {
-
- final Image i;
- final int ix, iy;
- int x, y;
- final int width, height;
- shape(Image i, int ix, int iy, int x, int y, int width, int height) {
-
- if (width < 0) {
- x += width;
- ix -= width;
- width = -width;
- }
- if (height < 0) {
- y += height;
- iy -= height;
- height = -height;
- }
- this.i = i;
- this.ix = ix;
- this.iy = iy;
- this.x = x;
- this.y = y;
- this.width = width;
- this.height = height;
- }
- boolean contains(int x, int y) {
- return x > this.x && y > this.y && x < this.x + width && y < this.y + height;
- }
- void focus(Graphics g) {
- g.setColor(Color.darkGray);
- int x = this.x + 3, y = this.y + 3;
- int w = x + width - 6, h = y + height - 6;
- g.drawLine(x, y, x, h);
- g.drawLine(x, y, w, y);
- g.drawLine(x, h, w, h);
- g.drawLine(w, y, w, h);
- }
- boolean inside(Dimension d) {
- return x >= 0 && y >= 0 && x + width <= d.width && y + height <= d.height;
- }
- boolean overlaps(int x, int y, int width, int height) {
- return this.x < x + width && this.y < y + height && x < this.x + this.width && y < this.y + this.height;
- }
- boolean overlaps(shape s) {
- return s.overlaps(x, y, width, height);
- }
- void paint(Graphics g) {
- int w = width, h = height;
- g = g.create(x, y, w + 1, h + 1);
- g.setColor(Color.black);
- g.drawRect(0, 0, w, h);
- w--;
- h--;
- g.setColor(Color.gray);
- g.drawLine(1, 1, 1, h);
- g.drawLine(1, 1, w, 1);
- g.setColor(Color.white);
- g.drawLine(1, h, w, h);
- g.drawLine(w, 1, w, h);
- g.clipRect(2, 2, w - 2, h - 2);
- g.drawImage(i, ix, iy, null);
- g.dispose();
- }
- void shift(int dx, int dy) {
- x += dx;
- y += dy;
- }
- void unshift(int dx, int dy) {
- x -= dx;
- y -= dy;
- }
- }
- class twin extends shape {
-
- shape other;
- twin(Image i, int ix, int iy, int x, int y, int w1, int h1, int w2, int h2) {
- super(i, ix, iy, x, y, w1, h1);
- other = new shape(i, ix, iy, x, y, w2, h2);
- }
- boolean contains(int x, int y) {
- if (super.contains(x, y)) return true;
- return other.contains(x, y);
- }
- void focus(Graphics g) {
- super.focus(g);
- other.focus(g);
- Graphics g1 = g.create(x, y, width + 1, height + 1);
- Graphics g2 = g.create(other.x, other.y, other.width + 1, other.height + 1);
- g1.clipRect(4, 4, width - 7, height - 7);
- g2.clipRect(4, 4, other.width - 7, other.height - 7);
- g1.drawImage(i, ix, iy, null);
- g2.drawImage(i, other.ix, other.iy, null);
- g1.dispose();
- g2.dispose();
- }
- boolean inside(Dimension d) {
- if (!super.inside(d)) return false;
- return other.inside(d);
- }
- boolean overlaps(int x, int y, int width, int height) {
- if (super.overlaps(x, y, width, height)) return true;
- return other.overlaps(x, y, width, height);
- }
- boolean overlaps(shape s) {
- if (s.overlaps(x, y, width, height)) return true;
- return s.overlaps(other.x, other.y, other.width, other.height);
- }
- void paint(Graphics g) {
-
- int w1 = width, h1 = height, w2 = other.width, h2 = other.height;
- Graphics g1 = g.create(x, y, w1 + 1, h1 + 1);
- Graphics g2 = g.create(other.x, other.y, w2 + 1, h2 + 1);
- g1.setColor(Color.black);
- g1.drawRect(0, 0, w1, h1);
- g2.setColor(Color.black);
- g2.drawRect(0, 0, w2, h2);
- w1--;
- w2--;
- h1--;
- h2--;
- g1.setColor(Color.gray);
- g2.setColor(Color.gray);
- g1.drawLine(1, 1, 1, h1);
- g2.drawLine(1, 1, 1, h2);
- g1.drawLine(1, 1, w1, 1);
- g2.drawLine(1, 1, w2, 1);
- g1.setColor(Color.white);
- g2.setColor(Color.white);
- g1.drawLine(1, h1, w1, h1);
- g2.drawLine(1, h2, w2, h2);
- g1.drawLine(w1, 1, w1, h1);
- g2.drawLine(w2, 1, w2, h2);
- if (x == other.x && y == other.y) {
- g1.setColor(Color.gray);
- //g2.setColor(Color.gray);
- g1.drawLine(1, 1, w1, 1);
- g1.drawLine(1, 1, 1, h2);
- }
- g1.clipRect(2, 2, w1 - 2, h1 - 2);
- g2.clipRect(2, 2, w2 - 2, h2 - 2);
- g1.drawImage(i, ix, iy, null);
- g2.drawImage(i, other.ix, other.iy, null);
- g1.dispose();
- g2.dispose();
- }
- void shift(int dx, int dy) {
- super.shift(dx, dy);
- other.shift(dx, dy);
- }
- void unshift(int dx, int dy) {
- super.unshift(dx, dy);
- other.unshift(dx, dy);
- }
- }

38.107.191.103