这段 Java 代码实现了一个三维版本的康威生命游戏(Conway's Game of Life)的图形用户界面(GUI)程序。康威生命游戏是一个零玩家游戏,它包括一个二维或多维的网格,每个网格中的细胞有存活或死亡两种状态,根据其周围细胞的存活情况按照一定规则进行迭代更新。此程序模拟了一个三维的细胞世界,并且通过 JFrame
和 JPanel
提供了可视化的界面,以一定的时间间隔展示细胞状态的演化。
java
public class ThreeDimensionalConwayGameOfLifeGUI extends JFrame {
ThreeDimensionalConwayGameOfLifeGUI
类继承自 JFrame
,这意味着它是一个窗口,用于承载游戏的可视化界面。java
private static final int SIZE_X = 20;
private static final int SIZE_Y = 20;
private static final int SIZE_Z = 20;
private static final int CELL_SIZE = 10;
private static final int DELAY = 500;
SIZE_X
、SIZE_Y
和 SIZE_Z
:分别表示三维网格在 x、y、z 三个方向上的大小,即细胞世界的尺寸。CELL_SIZE
:每个细胞在界面上显示的大小(像素)。DELAY
:定时器的延迟时间(毫秒),控制细胞状态更新的时间间隔。java
private boolean[][][] currentGeneration;
private boolean[][][] nextGeneration;
private GamePanel gamePanel;
private Timer timer;
currentGeneration
:一个三维布尔数组,用于存储当前代细胞的存活状态。nextGeneration
:同样是三维布尔数组,用于存储下一代细胞的存活状态。gamePanel
:GamePanel
类的实例,用于绘制细胞的可视化界面。timer
:Timer
类的实例,用于定时触发细胞状态的更新和界面的重绘。ThreeDimensionalConwayGameOfLifeGUI()
java
public ThreeDimensionalConwayGameOfLifeGUI() {
currentGeneration = new boolean[SIZE_X][SIZE_Y][SIZE_Z];
nextGeneration = new boolean[SIZE_X][SIZE_Y][SIZE_Z];
initializeRandomly();
gamePanel = new GamePanel();
add(gamePanel);
timer = new Timer(DELAY, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
evolve();
gamePanel.repaint();
}
});
timer.start();
setTitle("三维康威生命游戏");
setSize(SIZE_X * CELL_SIZE, SIZE_Y * CELL_SIZE);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setVisible(true);
}
currentGeneration
和 nextGeneration
数组。initializeRandomly()
方法随机初始化当前代细胞的存活状态。GamePanel
实例并添加到窗口中。Timer
对象,设置延迟时间为 DELAY
毫秒,每次触发时调用 evolve()
方法更新细胞状态并调用 gamePanel.repaint()
方法重绘界面。initializeRandomly()
方法java
private void initializeRandomly() {
Random random = new Random();
for (int x = 0; x < SIZE_X; x++) {
for (int y = 0; y < SIZE_Y; y++) {
for (int z = 0; z < SIZE_Z; z++) {
currentGeneration[x][y][z] = random.nextBoolean();
}
}
}
}
Random
类随机为 currentGeneration
数组中的每个元素赋值(true
或 false
),以此随机初始化细胞的存活状态。countNeighbors(int x, int y, int z)
方法java
private int countNeighbors(int x, int y, int z) {
int count = 0;
for (int dx = -1; dx <= 1; dx++) {
for (int dy = -1; dy <= 1; dy++) {
for (int dz = -1; dz <= 1; dz++) {
if (dx == 0 && dy == 0 && dz == 0) {
continue;
}
int newX = x + dx;
int newY = y + dy;
int newZ = z + dz;
if (isValidCoordinate(newX, newY, newZ) && currentGeneration[newX][newY][newZ]) {
count++;
}
}
}
}
return count;
}
(x, y, z)
处细胞的存活邻居数量。isValidCoordinate()
方法检查邻居坐标是否有效,若有效且邻居细胞存活则计数器加 1。isValidCoordinate(int x, int y, int z)
方法java
private boolean isValidCoordinate(int x, int y, int z) {
return x >= 0 && x < SIZE_X && y >= 0 && y < SIZE_Y && z >= 0 && z < SIZE_Z;
}
(x, y, z)
是否在三维网格的有效范围内。true
,否则返回 false
。evolve()
方法java
public void evolve() {
for (int x = 0; x < SIZE_X; x++) {
for (int y = 0; y < SIZE_Y; y++) {
for (int z = 0; z < SIZE_Z; z++) {
int neighbors = countNeighbors(x, y, z);
if (currentGeneration[x][y][z]) {
// 存活细胞规则
nextGeneration[x][y][z] = neighbors == 3 || neighbors == 4 || neighbors == 5;
} else {
// 死亡细胞规则
nextGeneration[x][y][z] = neighbors == 4;
}
}
}
}
// 更新当前代
for (int x = 0; x < SIZE_X; x++) {
for (int y = 0; y < SIZE_Y; y++) {
for (int z = 0; z < SIZE_Z; z++) {
currentGeneration[x][y][z] = nextGeneration[x][y][z];
}
}
}
}
countNeighbors()
方法计算其存活邻居数量。nextGeneration
数组:
nextGeneration
数组的值复制到 currentGeneration
数组中,完成当前代的更新。GamePanel
内部类java
private class GamePanel extends JPanel {
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
for (int x = 0; x < SIZE_X; x++) {
for (int y = 0; y < SIZE_Y; y++) {
for (int z = 0; z < SIZE_Z; z++) {
if (currentGeneration[x][y][z]) {
g.setColor(Color.BLACK);
} else {
g.setColor(Color.WHITE);
}
g.fillRect(x * CELL_SIZE, y * CELL_SIZE, CELL_SIZE, CELL_SIZE);
}
}
}
}
}
GamePanel
类继承自 JPanel
,用于绘制细胞的可视化界面。paintComponent()
方法,遍历 currentGeneration
数组,根据细胞的存活状态设置绘制颜色(存活为黑色,死亡为白色),并在界面上绘制相应的矩形。main()
方法java
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new ThreeDimensionalConwayGameOfLifeGUI();
}
});
}
SwingUtilities.invokeLater()
方法确保在事件调度线程中创建和显示 GUI,避免线程安全问题。ThreeDimensionalConwayGameOfLifeGUI
类的实例,启动游戏。完整代码
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
public class ThreeDimensionalConwayGameOfLifeGUI extends JFrame {
private static final int SIZE_X = 20;
private static final int SIZE_Y = 20;
private static final int SIZE_Z = 20;
private static final int CELL_SIZE = 10;
private static final int DELAY = 500;
private boolean[][][] currentGeneration;
private boolean[][][] nextGeneration;
private GamePanel gamePanel;
private Timer timer;
public ThreeDimensionalConwayGameOfLifeGUI() {
currentGeneration = new boolean[SIZE_X][SIZE_Y][SIZE_Z];
nextGeneration = new boolean[SIZE_X][SIZE_Y][SIZE_Z];
initializeRandomly();
gamePanel = new GamePanel();
add(gamePanel);
timer = new Timer(DELAY, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
evolve();
gamePanel.repaint();
}
});
timer.start();
setTitle("三维康威生命游戏");
setSize(SIZE_X * CELL_SIZE, SIZE_Y * CELL_SIZE);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setVisible(true);
}
private void initializeRandomly() {
Random random = new Random();
for (int x = 0; x < SIZE_X; x++) {
for (int y = 0; y < SIZE_Y; y++) {
for (int z = 0; z < SIZE_Z; z++) {
currentGeneration[x][y][z] = random.nextBoolean();
}
}
}
}
private int countNeighbors(int x, int y, int z) {
int count = 0;
for (int dx = -1; dx <= 1; dx++) {
for (int dy = -1; dy <= 1; dy++) {
for (int dz = -1; dz <= 1; dz++) {
if (dx == 0 && dy == 0 && dz == 0) {
continue;
}
int newX = x + dx;
int newY = y + dy;
int newZ = z + dz;
if (isValidCoordinate(newX, newY, newZ) && currentGeneration[newX][newY][newZ]) {
count++;
}
}
}
}
return count;
}
private boolean isValidCoordinate(int x, int y, int z) {
return x >= 0 && x < SIZE_X && y >= 0 && y < SIZE_Y && z >= 0 && z < SIZE_Z;
}
public void evolve() {
for (int x = 0; x < SIZE_X; x++) {
for (int y = 0; y < SIZE_Y; y++) {
for (int z = 0; z < SIZE_Z; z++) {
int neighbors = countNeighbors(x, y, z);
if (currentGeneration[x][y][z]) {
// 存活细胞规则
nextGeneration[x][y][z] = neighbors == 3 || neighbors == 4 || neighbors == 5;
} else {
// 死亡细胞规则
nextGeneration[x][y][z] = neighbors == 4;
}
}
}
}
// 更新当前代
for (int x = 0; x < SIZE_X; x++) {
for (int y = 0; y < SIZE_Y; y++) {
for (int z = 0; z < SIZE_Z; z++) {
currentGeneration[x][y][z] = nextGeneration[x][y][z];
}
}
}
}
private class GamePanel extends JPanel {
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
for (int x = 0; x < SIZE_X; x++) {
for (int y = 0; y < SIZE_Y; y++) {
for (int z = 0; z < SIZE_Z; z++) {
if (currentGeneration[x][y][z]) {
g.setColor(Color.BLACK);
} else {
g.setColor(Color.WHITE);
}
g.fillRect(x * CELL_SIZE, y * CELL_SIZE, CELL_SIZE, CELL_SIZE);
}
}
}
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new ThreeDimensionalConwayGameOfLifeGUI();
}
});
}
}