Apologies for the recent interruption in service; I accidentally allowed the domain to expire.

Grid Puzzle Source

(Last Update 11:00 on Monday, 22 August 2005)

// Java Grid Puzzle applet
// Neil Rashbrook
// Last modified August 22 2005
import java.applet.Applet;
import java.awt.Color;
import java.awt.Container;
import java.awt.Event;
import java.awt.Frame;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.util.StringTokenizer;
public class griddler extends Applet implements Runnable {
int rows, cols, cells, count;
int[][] row, col;
Color[][] matrix;
Color[] save, temprow, tempcol;
Color last;
Point p;
Frame cursorFrame;
public void init() {
super.setBackground(Color.gray);
rows = Integer.parseInt(super.getParameter("rows"));
cols = Integer.parseInt(super.getParameter("cols"));
row = new int[rows + 1][];
col = new int[cols + 1][];
temprow = new Color[cols + 2];
tempcol = new Color[rows + 2];
System.err.println("rows=" + read(row, "row"));
System.err.println("cols=" + read(col, "col"));
matrix = new Color[rows + 2][cols + 2];
Container c = this;
while ((c = c.getParent()) != null && !(c instanceof Frame));
cursorFrame = (Frame)c;
(new Thread(this)).start();
}
public boolean isFocusTraversable() {
return true;
}
public boolean mouseDown(Event evt, int x, int y) {
if (save != null) return false;
if (evt.shiftDown() && evt.controlDown()) {
int[] data;
Dimension d = size();
System.err.println("<applet code=" + super.getClass().getName() + ".class codebase=\"" + super.getCodeBase() + "\" width=" + d.width + " height=" + d.height + ">");
System.err.println("<param name=\"rows\" value=\"" + rows + "\">");
for (int i = 1; i <= rows; i++) {
int n = 0;
for (int j = 1; j <= cols; j++) if (matrix[i][j] == Color.black && matrix[i][j - 1] != Color.black) n++;
if (n == 0) row[i] = data = new int[1];
else {
row[i] = data = new int[n];
n = 0;
for (int j = 1; j <= cols; j++) {
if (matrix[i][j] == Color.black) row[i][n]++;
else if (row[i][n] > 0 && ++n == row[i].length) break;
}
}
System.err.print("<param name=\"row" + i + "\" value=\"" + row[i][0]);
for (n = 1; n < row[i].length; n++) {
System.err.print(".");
System.err.print(row[i][n]);
}
System.err.println("\">");
}
System.err.println("<param name=\"cols\" value=\"" + cols + "\">");
for (int j = 1; j <= cols; j++) {
int n = 0;
for (int i = 1; i <= rows; i++) if (matrix[i][j] == Color.black && matrix[i - 1][j] != Color.black) n++;
if (n == 0) col[j] = new int[1];
else {
col[j] = new int[n];
n = 0;
for (int i = 1; i <= rows; i++) {
if (matrix[i][j] == Color.black) col[j][n]++;
else if (col[j][n] > 0 && ++n == col[j].length) break;
}
}
System.err.print("<param name=\"col" + j + "\" value=\"" + col[j][0]);
for (n = 1; n < col[j].length; n++) {
System.err.print(".");
System.err.print(col[j][n]);
}
System.err.println("\">");
}
System.err.println("</applet>");
matrix = new Color[rows + 2][cols + 2];
repaint();
(new Thread(this)).start();
} else if (p != null && (x -= p.x - 1) > cells && (y -= p.y - 1) > cells && x % cells != 0 && y % cells != 0 && (x /= cells) <= cols && (y /= cells) <= rows)
paint(y, x, matrix[y][x] = last = evt.shiftDown() ? Color.white : evt.controlDown() ? Color.black : matrix[y][x] == Color.black ? Color.white : Color.black);
return false;
}
public boolean mouseDrag(Event evt, int x, int y) {
if (save == null && last != null && (x -= p.x - 1) > cells && (y -= p.y - 1) > cells && x % cells != 0 && y % cells != 0 && (x /= cells) <= cols && (y /= cells) <= rows && matrix[y][x] != last) paint(y, x, matrix[y][x] = last);
return false;
}
public void paint(Graphics g) {
if (matrix != null) {
Dimension d = super.size();
cells = Math.min((d.width - 1) / cols, (d.height - 1) / rows);
p = new Point(((d.width + 1 - cells * cols) >> 1) - cells, ((d.height + 1 - cells * rows) >> 1) - cells);
int y = p.y;
for (int i = 1; i <= rows; i++) {
y += cells;
int x = p.x;
for (int j = 1; j <= cols; j++) {
x += cells;
if (matrix[i][j] != null) {
g.setColor(matrix[i][j]);
g.fillRect(x, y, cells - 1, cells - 1);
}
}
}
}
}
private void paint(int i, int j, Color c) {
if (p != null) {
Graphics g = super.getGraphics();
g.setColor(c);
g.fillRect(p.x + j * cells, p.y + i * cells, cells - 1, cells - 1);
g.dispose();
}
}
private int read(int[][] data, String prefix) {
int i, total = 0;
for (i = 1; i < data.length; i++) {
StringTokenizer st = new StringTokenizer(super.getParameter(prefix + i), ".");
int n = st.countTokens();
data[i] = new int[n];
for (int j = 0; j < n; j++) total += data[i][j] = Integer.parseInt(st.nextToken());
}
return total;
}
public void run() {
if (cursorFrame != null) cursorFrame.setCursor(Frame.WAIT_CURSOR);
System.err.println(System.currentTimeMillis());
int i, j, left = rows * cols;
boolean diff;
int[] colsdone = new int[rows + 1];
int[] rowsdone = new int[cols + 1];
boolean[] cdiffs = new boolean[cols + 2];
for (i = 1; i <= rows; i++) if (testrowquick(i)) for (j = 1; j <= cols; j++) {
if (save[j] != Color.lightGray) {
cdiffs[j] = true;
colsdone[i]++;
rowsdone[j]++;
left--;
}
paint(i, j, matrix[i][j] = save[j]);
}
super.showStatus("" + left);
boolean[] rdiffs = new boolean[rows + 2];
for (j = 1; j <= cols; j++) if (testcolquick(j)) for (i = 1; i <= rows; i++) if (save[i] != matrix[i][j]) {
if (save[i] != Color.lightGray) {
rdiffs[i] = true;
colsdone[i]++;
rowsdone[j]++;
left--;
matrix[i][j] = null;
}
if (matrix[i][j] == null) paint(i, j, matrix[i][j] = save[i]);
}
super.showStatus("" + left);
do {
diff = false;
for (int done = 1; done <= cols && done <= rows; done++) {
for (i = 1; i <= rows; i++) if (rdiffs[i] && row[i].length == done) {
save = new Color[cols + 2];
count = 0;
for (j = 1; j <= cols; j++) if (matrix[i][j] == null || matrix[i][j] == Color.lightGray) count++;
if (testrow(i, 0, 0)) for (j = 1; j <= cols; j++) if (matrix[i][j] != save[j]) {
if (save[j] != Color.lightGray) {
diff = true;
cdiffs[j] = true;
colsdone[i]++;
rowsdone[j]++;
left--;
}
paint(i, j, matrix[i][j] = save[j]);
}
rdiffs[i] = false;
if (diff) break;
}
for (j = 1; j <= cols; j++) if (cdiffs[j] && col[j].length == done) {
save = new Color[rows + 2];
count = 0;
for (i = 1; i <= rows; i++) if (matrix[i][j] == null || matrix[i][j] == Color.lightGray) count++;
if (testcol(j, 0, 0)) for (i = 1; i <= rows; i++) if (matrix[i][j] != save[i]) {
if (save[i] != Color.lightGray) {
diff = true;
rdiffs[i] = true;
colsdone[i]++;
rowsdone[j]++;
left--;
}
paint(i, j, matrix[i][j] = save[i]);
}
cdiffs[j] = false;
if (diff) break;
}
if (diff) break;
}
super.showStatus("" + left);
} while (left != 0);
System.err.println(System.currentTimeMillis());
save = null;
if (cursorFrame != null) cursorFrame.setCursor(Frame.DEFAULT_CURSOR);
}
private boolean testcol(int j, int elem, int pos) {
if (elem == col[j].length) {
for (int i = pos; i <= rows; i++) {
if (matrix[i][j] == Color.black) return true;
tempcol[i] = Color.white;
}
for (int i = 1; i <= rows; i++) {
if (save[i] == null) paint(i, j, save[i] = tempcol[i]);
else if (save[i] != Color.lightGray && save[i] != tempcol[i]) {
if (matrix[i][j] == null) paint(i, j, matrix[i][j] = Color.lightGray);
else paint(i, j, Color.lightGray);
if (--count == 0) return false;
save[i] = Color.lightGray;
}
}
} else {
int next = pos + col[j][elem++];
loop: while (next++ <= rows) {
if (matrix[pos][j] == Color.black) return true;
tempcol[pos++] = Color.white;
if (matrix[next][j] == Color.black) continue;
for (int i = pos; i < next; i++) {
if (matrix[i][j] == Color.white) continue loop;
tempcol[i] = Color.black;
}
if (!testcol(j, elem, next)) return false;
for (int i = pos - 1; i <= rows; i++) if (save[i] != Color.lightGray) continue loop;
break;
}
}
return true;
}
private boolean testcolquick(int j) {
int count = rows;
int pos = 0;
int elem;
for (elem = 0; elem < col[j].length; elem++) {
tempcol[pos++] = Color.white;
for (int i = 0; i < col[j][elem]; i++) tempcol[pos++] = Color.black;
}
while (pos <= rows) tempcol[pos++] = Color.white;
if (elem == 0) {
save = tempcol;
return true;
}
save = new Color[rows + 2];
do {
for (int i = 1; i <= rows; i++) {
if (save[i] == null) save[i] = tempcol[i];
else if (save[i] != Color.lightGray && save[i] != tempcol[i]) {
if (--count == 0) return false;
save[i] = Color.lightGray;
}
}
System.arraycopy(tempcol, 0, tempcol, 1, pos);
} while (tempcol[pos] != Color.black);
return true;
}
private boolean testrow(int i, int elem, int pos) {
if (elem == row[i].length) {
for (int j = pos; j <= cols; j++) {
if (matrix[i][j] == Color.black) return true;
temprow[j] = Color.white;
}
for (int j = 1; j <= cols; j++) {
if (save[j] == null) paint(i, j, save[j] = temprow[j]);
else if (save[j] != Color.lightGray && save[j] != temprow[j]) {
if (matrix[i][j] == null) paint(i, j, matrix[i][j] = Color.lightGray);
else paint(i, j, Color.lightGray);
if (--count == 0) return false;
save[j] = Color.lightGray;
}
}
} else {
int next = pos + row[i][elem++];
loop: while (next++ <= cols) {
if (matrix[i][pos] == Color.black) return true;
temprow[pos++] = Color.white;
if (matrix[i][next] == Color.black) continue;
for (int j = pos; j < next; j++) {
if (matrix[i][j] == Color.white) continue loop;
temprow[j] = Color.black;
}
if (!testrow(i, elem, next)) return false;
for (int j = pos - 1; j <= cols; j++) if (save[j] != Color.lightGray) continue loop;
break;
}
}
return true;
}
private boolean testrowquick(int i) {
int count = cols;
int pos = 0;
int elem;
for (elem = 0; elem < row[i].length; elem++) {
temprow[pos++] = Color.white;
for (int j = 0; j < row[i][elem]; j++) temprow[pos++] = Color.black;
}
while (pos <= cols) temprow[pos++] = Color.white;
if (elem == 0) {
save = temprow;
return true;
}
save = new Color[cols + 2];
do {
for (int j = 1; j <= cols; j++) {
if (save[j] == null) save[j] = temprow[j];
else if (save[j] != Color.lightGray && save[j] != temprow[j]) {
if (--count == 0) return false;
save[j] = Color.lightGray;
}
}
System.arraycopy(temprow, 0, temprow, 1, pos);
} while (temprow[pos] != Color.black);
return true;
}
public String toString() {
StringBuffer sb = new StringBuffer();
String l = System.getProperty("line.separator");
sb.append("<applet code=").append(super.getClass().getName()).append(".class codebase=\"").append(super.getCodeBase()).append("\" width=").append(size().width).append(" height=").append(size().height).append(">").append(l);
sb.append("<param name=\"rows\" value=\"").append(rows).append("\">").append(l);
for (int i = 1; i <= rows; i++) {
sb.append("<param name=\"row").append(i).append("\" value=\"");
StringBuffer found = null;
int n = 0;
for (int j = 1; j <= cols; j++) {
if (matrix[i][j] == Color.black) n++;
else if (n > 0) {
if (found != null) sb.append('.');
found = sb.append(n);
n = 0;
}
}
if (found == null) sb.append(n);
else if (n > 0) sb.append('.').append(n);
sb.append("\">").append(l);
}
sb.append("<param name=\"cols\" value=\"").append(cols).append("\">").append(l);
for (int j = 1; j <= cols; j++) {
sb.append("<param name=\"col").append(j).append("\" value=\"");
StringBuffer found = null;
int n = 0;
for (int i = 1; i <= rows; i++) {
if (matrix[i][j] == Color.black) n++;
else if (n > 0) {
if (found != null) sb.append('.');
found = sb.append(n);
n = 0;
}
}
if (found == null) sb.append(n);
else if (n > 0) sb.append('.').append(n);
sb.append("\">").append(l);
}
return sb.append("</applet>").append(l).toString();
}
}

Frames Version
Customization Page
Back to Grid Puzzle Page


640661
38.107.179.229