继续整理存货^_^,这个应该是很久前从某一个大牛的书中摘录出来的,规则、程序都很简单,记得当时调试正常,启动运行后,看着跃动的混沌的屏幕,逐渐的演化稳定,似乎顿悟了很多。
如果你也对各种AI算法有兴趣,读各种资料的时候总感觉说的很空洞抽象,不妨找一个类似这样的小程序,用心挖掘一下它背后的深刻含义,比如初始状态、最终状态、初始状态对最终状态的影响、收敛性等等等等。
不多说了,码农自然是多帖代码为宜,演化规则如下:
* 经典并且简单的人工生命游戏定义:
* 1.出生 : 如果一个死亡的细胞有三个或者的邻居,它就变成活的;
* 2.生存 : 如果一个活着的细胞有两个或者三个活的邻居,他就仍然活着;
* 3.死亡 : 其它情况下,该细胞(仍然)死亡.
代码如下(摘录自一本书,忘记是哪本了,如有不妥请请及时联系我删除):
/**
* description:
* @date 2008-12-22 上午09:11:49
* 经典并且简单的人工生命游戏定义:
* 1.出生 : 如果一个死亡的细胞有三个或者的邻居,它就变成活的;
* 2.生存 : 如果一个活着的细胞有两个或者三个活的邻居,他就仍然活着;
* 3.死亡 : 其它情况下,该细胞(仍然)死亡.
*/
public class Life extends JApplet{
public static void main(String[] args) {
// 创建主窗口
JFrame frame = new JFrame();
// 设置标题栏
frame.setTitle("Game of life");
// 设置关闭
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// 创建Life对象
JApplet applet = new Life();
// 初始化
applet.init();
// 添加life到frame内容窗格
frame.getContentPane().add(applet);
frame.pack();
frame.setVisible(true);
}
// 重写初始化方法
public void init(){
JPanel panel = new LifePanel();
getContentPane().add(panel);
}
}
// 定义LifePanel类
class LifePanel extends JPanel implements ActionListener{
int n = 30; // 30 * 30
boolean[][] cells1;
boolean[][] cells2;
public LifePanel(){
setPreferredSize(new Dimension(400,400));
setBackground(Color.white);
cells1 = new boolean[n][n];
cells2 = new boolean[n][n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cells1[i][j] = Math.random() < 0.2;
cells2[i][j] = false;
}
}
// 创建并启动Timer对象
Timer timer = new Timer(1000, this);
timer.start();
}
// 重写组件绘制方法
@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.setColor(Color.lightGray); //网格线的颜色
int p = 0;
int c = 16; // 两条线之间的间隔
int len = c * n;
// 绘制网格
for (int i = 0; i <= n; i++) {
g2.drawLine(0, p, len, p);
g2.drawLine(p, 0, p, len);
p += c;
}
g2.setColor(Color.black);
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
// 如果当前细胞存活
if(cells1[i][j]){
int x = i * c;
int y = j * c;
// 画实心黑点
g2.fillOval(x, y, c, c);
}
}
}
}
// 事件响应函数
@Override
public void actionPerformed(ActionEvent e) {
// 当前细胞存活情况
boolean[][] cells = cells1;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
// 当前细胞存活情况记录到s2
cells2[i][j] = cells[i][j];
// 获取当前细胞近邻存活的个数
int nb = neighbors(cells, i, j);
// 近邻存活3个,自己存活
if(3 == nb){
cells2[i][j] = true;
}
// 近邻不是2个或3个,细胞死亡
if(nb < 2 || nb > 3){
cells2[i][j] = false;
}
// 近邻存活2个,维持自身情况
}
}
// 更新当前状态
cells1 = cells2;
cells2 = cells;
repaint();
}
// 获得当前细胞近邻的存活个数
private int neighbors(boolean[][] cells, int x, int y){
int x1 = (x > 0) ? x - 1 : x;
int x2 = (x < n - 1) ? x + 1 : x;
int y1 = (y > 0) ? y - 1 : y;
int y2 = (y < n - 1) ? y + 1 : y;
int count = 0;
for (int i = x1; i <= x2; i++) {
for (int j = y1; j <= y2; j++) {
count +=((cells[i][j]) ? 1 : 0);
}
}
// 自己存活的话,存活个数减去自己
if(cells[x][y]){
count--;
}
return count;
}
}