生命游戏
细胞自动机(又称元胞自动机),名字虽然很深奥,但是它的行为却是非常美妙的。所有这些怎样实现的呢?我们可以把计算机中的宇宙想象成是一堆方格子构成的封闭空间,尺寸为N的空间就有NN个格子。而每一个格子都可以看成是一个生命体,每个生命都有生和死两种状态,如果该格子生就显示蓝色,死则显示白色。每一个格子旁边都有邻居格子存在,如果我们把33的9个格子构成的正方形看成一个基本单位的话,那么这个正方形中心的格子的邻居就是它旁边的8个格子。
每个格子的生死遵循下面的原则:
1. 如果一个细胞周围有3个细胞为生(一个细胞周围共有8个细胞),则该细胞为生(即该细胞若原先为死,则转为生,若原先为生,则保持不变) 。
2. 如果一个细胞周围有2个细胞为生,则该细胞的生死状态保持不变;
3. 在其它情况下,该细胞为死(即该细胞若原先为生,则转为死,若原先为死,则保持不变)
设定图像中每个像素的初始状态后依据上述的游戏规则演绎生命的变化,由于初始状态和迭代次数不同,将会得到令人叹服的优美图案。
在工程目录下面创建一个名为lifeGame的package
main.java
package lifeGame;
public class main {
public static void main(String args[]) {
Controll controll=new Controll();
}
}
Cell.java
细胞类,存放和细胞有关的数据和方法
package lifeGame;
public class Cell {
private int Status; //0-死亡 1-存活
private int Living; //周围活细胞数目
// private int X;
// private int Y;
Cell(){
Status=0;
Living=0;
}
Cell(int m_Status,int m_Living){
Status=m_Status;
Living=m_Living;
}
public int getStatus() {
return Status;//获取状态
}
public void setStatus(int m_Status) {
Status=m_Status;//设置状态
}
public int getLiving() {
return Living;//获取当前周围活细胞数目
}
public void setLiving(int m_Living) {
Living=m_Living;//设置当前周围活细胞数目
}
public void UpdateStatus() {
if(this.getLiving()>3||this.getLiving()<2) this.setStatus(0);
else if(this.getLiving()==3) this.setStatus(1);
else this.setStatus(this.Status);
}
// public int getX() {
// //获取x坐标
// }
// public void setX(int m_X) {
// //设置x坐标
// }
// public int getY() {
// //获取y坐标
// }
// public void setY(int m_Y) {
// //设置y坐标
// }
}
Map.java
地图类,存放和地图有关的数据和方法
package lifeGame;
import java.util.Random;
public class Map {
final static public int x=16;
final static public int y=16;
public static Cell [][]initial() {
Cell [][]cell=new Cell[x][y];
for(int i=0;i<x;i++) {
for(int j=0;j<y;j++) {
cell[i][j]=new Cell();
Random random=new Random();
cell[i][j].setStatus(random.nextInt(2));
//cell[i][j].setStatus(1);
}
}
return cell;
}
public static void getLiving(Cell [][]cell){
for(int i=0;i<x;i++) {
for(int j=0;j<y;j++) {
int living=0;
if(i>0&&j>0) living+=cell[i-1][j-1].getStatus();
if(i>0) living+=cell[i-1][j].getStatus();
if(j>0) living+=cell[i][j-1].getStatus();
if(i<x-1&&j<x-1) living+=cell[i+1][j+1].getStatus();
if(i<x-1) living+=cell[i+1][j].getStatus();
if(j<x-1) living+=cell[i][j+1].getStatus();
if(i<x-1&&j>0) living+=cell[i+1][j-1].getStatus();
if(i>0&&j<x-1) living+=cell[i-1][j+1].getStatus();
cell[i][j].setLiving(living);
}
}
}
public static int update(Cell [][]cell){
int count=0;
for(int i=0;i<x;i++) {
for(int j=0;j<y;j++) {
int status=cell[i][j].getStatus();
cell[i][j].UpdateStatus();
if(status==cell[i][j].getStatus()) count++;
}
}
return count;
}
public static void printMap(Cell [][]cell) {
for(int i=0;i<x;i++) {
for(int j=0;j<y;j++) {
System.out.print(cell[i][j].getStatus()+" ");
}
System.out.println();
}
}
}
Controll.Java
核心控制类,实现GUI图形界面
package lifeGame;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
public class Controll {
Controll() {
JFrame jframe=new JFrame();
jframe.setSize(425,460);
JPanel jpanel=new JPanel();
jpanel.setBounds(0,0,400,400);
int count=0;
Cell [][]cell=new Cell[16][16];
cell=Map.initial();
Map.getLiving(cell);
jframe.setTitle("这是第"+count+"次演化");
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jframe.setLocationRelativeTo(null);
jframe.add(jpanel);
jframe.setVisible(true);
Graphics g=jpanel.getGraphics();
for(int i=0;i<16;i++) {
for(int j=0;j<16;j++) {
g.drawRect(i*25, j*25, 25, 25);
}
}
for(int i=0;i<16;i++) {
for(int j=0;j<16;j++) {
if(cell[i][j].getStatus()==1) {
g.fillRect(i*25, j*25, 25, 25);
}
else {
g.drawRect(i*25, j*25, 25, 25);
}
}
}
long d1= System.currentTimeMillis();
while(true) {
long d2= System.currentTimeMillis();
if(d2-d1>200) {
int change;
d1=d2;
jframe.repaint();
change=Map.update(cell);
Map.getLiving(cell);
for(int i=0;i<16;i++) {
for(int j=0;j<16;j++) {
g.drawRect(i*25, j*25, 25, 25);
}
}
for(int i=0;i<16;i++) {
for(int j=0;j<16;j++) {
if(cell[i][j].getStatus()==1) {
g.fillRect(i*25, j*25, 25, 25);
}
else {
g.drawRect(i*25, j*25, 25, 25);
}
}
}
count++;
jframe.setTitle("这是第"+count+"次演化");
if(change==16*16) break;
if(count>1000) break;
}
}
JOptionPane.showMessageDialog(jframe, "在第"+count+"次演化达到平衡", "提示", JOptionPane.PLAIN_MESSAGE);
}
}
运行结果如图所示: