156 lines
4.2 KiB
Java
156 lines
4.2 KiB
Java
import java.awt.*;
|
|
import java.awt.event.*;
|
|
import java.util.*;
|
|
import javax.swing.*;
|
|
|
|
public class FlippingBitsGame extends JPanel {
|
|
final int maxLevel = 7;
|
|
final int minLevel = 3;
|
|
|
|
private Random rand = new Random();
|
|
private int[][] grid, target;
|
|
private Rectangle box;
|
|
private int n = maxLevel;
|
|
private boolean solved = true;
|
|
|
|
FlippingBitsGame() {
|
|
setPreferredSize(new Dimension(640, 640));
|
|
setBackground(Color.white);
|
|
setFont(new Font("SansSerif", Font.PLAIN, 18));
|
|
|
|
box = new Rectangle(120, 90, 400, 400);
|
|
|
|
startNewGame();
|
|
|
|
addMouseListener(new MouseAdapter() {
|
|
@Override
|
|
public void mousePressed(MouseEvent e) {
|
|
if (solved) {
|
|
startNewGame();
|
|
} else {
|
|
int x = e.getX();
|
|
int y = e.getY();
|
|
|
|
if (box.contains(x, y))
|
|
return;
|
|
|
|
if (x > box.x && x < box.x + box.width) {
|
|
flipCol((x - box.x) / (box.width / n));
|
|
|
|
} else if (y > box.y && y < box.y + box.height)
|
|
flipRow((y - box.y) / (box.height / n));
|
|
|
|
if (solved(grid, target))
|
|
solved = true;
|
|
|
|
printGrid(solved ? "Solved!" : "The board", grid);
|
|
}
|
|
repaint();
|
|
}
|
|
});
|
|
}
|
|
|
|
void startNewGame() {
|
|
if (solved) {
|
|
|
|
n = (n == maxLevel) ? minLevel : n + 1;
|
|
|
|
grid = new int[n][n];
|
|
target = new int[n][n];
|
|
|
|
do {
|
|
shuffle();
|
|
|
|
for (int i = 0; i < n; i++)
|
|
target[i] = Arrays.copyOf(grid[i], n);
|
|
|
|
shuffle();
|
|
|
|
} while (solved(grid, target));
|
|
|
|
solved = false;
|
|
printGrid("The target", target);
|
|
printGrid("The board", grid);
|
|
}
|
|
}
|
|
|
|
void printGrid(String msg, int[][] g) {
|
|
System.out.println(msg);
|
|
for (int[] row : g)
|
|
System.out.println(Arrays.toString(row));
|
|
System.out.println();
|
|
}
|
|
|
|
boolean solved(int[][] a, int[][] b) {
|
|
for (int i = 0; i < n; i++)
|
|
if (!Arrays.equals(a[i], b[i]))
|
|
return false;
|
|
return true;
|
|
}
|
|
|
|
void shuffle() {
|
|
for (int i = 0; i < n * n; i++) {
|
|
if (rand.nextBoolean())
|
|
flipRow(rand.nextInt(n));
|
|
else
|
|
flipCol(rand.nextInt(n));
|
|
}
|
|
}
|
|
|
|
void flipRow(int r) {
|
|
for (int c = 0; c < n; c++) {
|
|
grid[r][c] ^= 1;
|
|
}
|
|
}
|
|
|
|
void flipCol(int c) {
|
|
for (int[] row : grid) {
|
|
row[c] ^= 1;
|
|
}
|
|
}
|
|
|
|
void drawGrid(Graphics2D g) {
|
|
g.setColor(getForeground());
|
|
|
|
if (solved)
|
|
g.drawString("Solved! Click here to play again.", 180, 600);
|
|
else
|
|
g.drawString("Click next to a row or a column to flip.", 170, 600);
|
|
|
|
int size = box.width / n;
|
|
|
|
for (int r = 0; r < n; r++)
|
|
for (int c = 0; c < n; c++) {
|
|
g.setColor(grid[r][c] == 1 ? Color.blue : Color.orange);
|
|
g.fillRect(box.x + c * size, box.y + r * size, size, size);
|
|
g.setColor(getBackground());
|
|
g.drawRect(box.x + c * size, box.y + r * size, size, size);
|
|
g.setColor(target[r][c] == 1 ? Color.blue : Color.orange);
|
|
g.fillRect(7 + box.x + c * size, 7 + box.y + r * size, 10, 10);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void paintComponent(Graphics gg) {
|
|
super.paintComponent(gg);
|
|
Graphics2D g = (Graphics2D) gg;
|
|
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
|
|
RenderingHints.VALUE_ANTIALIAS_ON);
|
|
|
|
drawGrid(g);
|
|
}
|
|
|
|
public static void main(String[] args) {
|
|
SwingUtilities.invokeLater(() -> {
|
|
JFrame f = new JFrame();
|
|
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
|
f.setTitle("Flipping Bits Game");
|
|
f.setResizable(false);
|
|
f.add(new FlippingBitsGame(), BorderLayout.CENTER);
|
|
f.pack();
|
|
f.setLocationRelativeTo(null);
|
|
f.setVisible(true);
|
|
});
|
|
}
|
|
}
|