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);
}
}

No Frames Version
Customization Page
Back to Sliding-blocks Puzzle Page


624553
38.107.191.103