关于翁恺老师Java网课中细胞自动机的一点点想法

一点关于细胞自动机的见解

个人非常喜欢翁恺老师的网课。在学习细胞自动机之后产生了一点自己的想法。在这里写出来,本人现在的水平尚且达不到Java入门,一点愚昧见解还请大佬们海涵。

贴上源码

感谢@一条sin大佬贴出来的代码,原文链接https://blog.csdn.net/weixin_42546792/article/details/101168863

小弟在这里CTRL C+V一下。

package cellmachine;
import javax.swing.JFrame;
import cell.Cell;
import field.*;

public class CellMachine {
	public static void main(String[] args) {
		Field field=new Field(30,30);
		for(int row=0;row<field.getHeight();row++) {
			for(int col=0;col<field.getWidth();col++) {
				field.place(row, col, new Cell());
			}
		}
		for(int row=0;row<field.getHeight();row++) {
			for(int col=0;col<field.getWidth();col++) {
				Cell cell=field.get(row, col);
				if(Math.random()<0.5) {
					cell.reborn();
				}
			}
		}
		View view =new View(field);
		JFrame frame=new JFrame();
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setResizable(false);
		frame.setTitle("Cells");
		frame.add(view);
		frame.pack();
		frame.setVisible(true);
		
		for(int i=0;i<1000;i++) {
			for(int row=0;row<field.getHeight();row++) {
				for(int col=0;col<field.getWidth();col++) {
					Cell cell=field.get(row, col);
					Cell[] neighbor=field.getNeighbor(row, col);
					int numOfLive=0;
					for(Cell c:neighbor) {
						if(c.isAlive()) {
							numOfLive++;
						}
					}
					System.out.print("["+row+"]["+col+"]:");
					System.out.print(cell.isAlive()?"live":"dead");
					System.out.print(":"+numOfLive+"-->");
					if(cell.isAlive()) {
						if(numOfLive<2||numOfLive>3) {
							cell.die();
							System.out.print("die");
						}
					}else if(numOfLive==3) {
						cell.reborn();
						System.out.print("reborn");
					}
					System.out.println();
				}
			}
			System.out.println("UPDATE");
			frame.repaint();
			try {
				Thread.sleep(200);
			} catch(InterruptedException e) {
				e.printStackTrace();
			}
			
		}
	}

}
————————————————
版权声明:本文为CSDN博主「一条sin」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_42546792/article/details/101168863
package field;
import java.util.ArrayList;
import cell.Cell;

public class Field {	
	private int width;
	private int height;
	private Cell[][] field;
	
	public Field (int width,int height) {
		this.width=width;
		this.height=height;
		field=new Cell[height][width];
	}
	
	public int getWidth() {return width;}
	public int getHeight() {return height;}
	
	public Cell place(int row,int col,Cell o){
		Cell ret=field[row][col];
		field[row][col]=o;
		return ret;
	}
	
	public Cell get(int row,int col) {
		return field[row][col];
	}
	
	public Cell[] getNeighbor(int row,int col) {
		ArrayList<Cell> list= new ArrayList<Cell>();
        for(int i=-1;i<2;i++){
            for(int j=-1;j<2;j++){
                int r=row+i;
                int c=col+j;
                if ( r >-1 && r<height && c>-1 && c<width && !(r== row && c == col) ) {
                    list.add(field[r][c]);
                }
            }
        }
       return list.toArray(new Cell[list.size()]);
	}
}
————————————————
版权声明:本文为CSDN博主「一条sin」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_42546792/article/details/101168863
package field;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.*;
import cell.Cell;

public class View extends JPanel {
	private static final long serialVersionUID=-5258995676212660595L;
	private static final int GRID_SIZE=16;
	private Field theField;
	
	public View(Field field) {
		theField=field;
	}

	@Override
	public void paint(Graphics g) {
		super.paint(g);
		for(int row=0;row<theField.getHeight();row++) {
			for(int col=0;col<theField.getWidth();col++) {
				Cell cell=theField.get(row, col);
				if(cell!=null) {
					cell.draw(g, col*GRID_SIZE, row*GRID_SIZE, GRID_SIZE);
				}
			}
		}
	}
	
	@Override
    public Dimension getPreferredSize() {
        return new Dimension(theField.getWidth()*GRID_SIZE+1,theField.getHeight()*GRID_SIZE+1);
    }
}
————————————————
版权声明:本文为CSDN博主「一条sin」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_42546792/article/details/101168863
package cell;

import java.awt.*;

public class Cell {
	private boolean alive=false;
	
	public void reborn() {alive=true;}
	
	public boolean isAlive() {
		return alive;
	}
    public void die() {alive=false;}
    
	public void draw(Graphics g,int x,int y,int size) {
		g.drawRect(x, y, size, size);
		if(alive) {
			g.fillRect(x, y, size, size);
		}
	}
}
————————————————
版权声明:本文为CSDN博主「一条sin」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_42546792/article/details/101168863

我的思考

在源码中,首先生成网格以及初代细胞。在后续的更迭中,每次判断都是从 row=0 到 height-1;从col=0到 width-1。那我的理解就是如此行列递增的产生先后顺序对后面的细胞不公平。举个简单的例子:如下图所示:
在这里插入图片描述
假如循环是自左向右,自上向下扫描每一个细胞。我选取了一个孤立细胞团,就是除了这三个黑的,周围全都是白的。
对于上1(上面那排第一个,下同),周围俩活得,所以状态不变。
那么对于上2由于周围邻居达到三个,所以会重生,即在下一轮绘图时,格子会变成黑色。
但是!但是!但是!重点来了,在判断完上2之后,上3在扫描邻居状态的时候会判断定出邻居中有三个活着的细胞,那么复活,但是实际上目前他们呢周围只有中2和中3是活着的,不满足复活条件,按理说在一下轮应该状态不变。可是由于先判断了上2,上2 的状态变成了alive,所以他们靠着目前版图上还不存在上2获得了重生。
那么同理,中1判断周围俩(上2和中2)活得,那我也不死了。
中二,我周边四个活得(上2,上3,中1和中3),那我死了。
。。。。。。。。。
但是实际上呢,不应该仅仅是中2和下2重生,中1和中3死亡吗???

由于先判断了上面一排,改变了他们细胞的状态,就造成了下面两排的细胞不按剧本走。实际上这个状态是该细胞未来(下一轮)才会出现的结果。但是在代码里,判断的依据仅仅是isAlive。我个人觉得对后面的细胞不公平。判断不合理。

小小的修改

在实现业务逻辑的代码里,

for(Cell c:neighbor) {
						if(c.isFill()) {
							numOfLive++;//周围共计多少活细胞
						}
					}

邻居的数量不依赖isAlive,我用图片中是否被填充颜色判断,周围有几个填充色,就是几个活着的细胞。

在cell的代码中,

	private boolean fullfill=false;
	
	public boolean isFill() {
		return fullfill;
	}
  
    
	public void draw(Graphics g,int x,int y,int size) {
		g.drawRect(x, y, size, size);
		if(alive) {
			g.fillRect(x, y, size, size);
			this.fullfill = true;
		}
		else
			this.fullfill = false;
	}

引入 isFill,来判断目前的窗口里的格子状态。
每一轮frame.repaint之后,更新每个cell的填充状态,以此来判断下一轮的生或死。
同样,主函数中的判断条件也要改变。

if(cell.isFill()) {
						if(numOfLive<2||numOfLive>3) {
							cell.die();
							System.out.print("die");
						}
					}
else if(numOfLive==3) {
						cell.reborn();
						System.out.print("reborn");
					}

就写这些吧,其实挺无聊的,就是脑子一抽,突然这么想了。改了几行代码而已。见笑了。

日敲代码三千行,不辞长作死肥宅。

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值