细胞自动机代码解析

import javax.swing.JFrame;

import cell.Cell;
import field.Field;
import field.View;

public class CellMachine {

	//看懂代码从 main 函数开始,这是老师数次在课堂上强调的
	public static void main(String[] args) {
		//定义一个30x30的网格
		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());
			}
		}
		
/*定义一个细胞的变量,这个变量依次管理所有的细胞对象,如果产生的随机数小于1/5,把这个细胞变活*/
		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.2 ) {
					cell.reborn();
				}
			}
		}
		
		/*----------------------创建可视化界面----------------------*/
		View view = new View(field);//把 field作为参数放入 view 里面去
		JFrame frame = new JFrame();//创建frame框架
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//关闭窗口,停止程序
		frame.setResizable(false);//不可被拉伸
		frame.setTitle("Cells");//设置标题 Cells
		frame.add(view);//把 view 加进来显示(有点类似于ArrayList 也是储存的对象		
		/*
		 Causes this Window to be sized to fit the preferred 
		 size and layouts of its subcomponents
		上面是官方文档给的英文注释,他的意思是
		把窗口调整为推荐的大小,并自动排版子组件,学 java 要多查阅文档
		在 eclipse 里面你可以把光标放到这个方法上,他会自动加载出文档
		(如果能看懂英文可以直接读
		*/
		frame.pack();		
		frame.setVisible(true);//设置窗口课可见
		
		/*-----------这里是运行的主代码,代码比较多,一定要细细思考---------*/
		for ( int i=0; i<1000; i++ ) //做了1000次循环(也就是遍历了1000次区域,
		{							 //一个表格算一步的话,走路900,000步
			for ( int row = 0; row<field.getHeight(); row++ ) 
			{
				for ( int col = 0; col<field.getWidth(); col++ ) 
				{
					//上面两个 for 循环遍历了整个区域
					
					Cell cell = field.get(row, col);//定义一个细胞变量,依次管理每个细胞
					
					//定义细胞数组,获取邻居状况(没有定义数组上限是因为不需要,
					//在函数里面直接获取到了所有的邻居
					Cell[] neighbour = field.getNeighbour(row, col);
					
					//统计周围细胞的存活情况
					int numOfLive = 0;
					for ( Cell c : neighbour ) {
						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(); //周围存活数量小于2大于3,细胞死亡
							System.out.print("die");//意思是,周围细胞为2或3的时候不用死
						}
					} 
					else if ( numOfLive == 3 ) //如果细胞是死亡的,周围存活数量为3
					{
						cell.reborn();//细胞可以复活
						System.out.print("reborn");
					}
					System.out.println();
				}//第三层for循环
			}//第二层for循环
			System.out.println("UPDATE");//这个我不知道怎么清除掉的,应该输出1000遍才对
			frame.repaint();//Repaints this component. 更新表格数据
			
			//这里是异常,属于后面讲解的内容 Thread 与线程有关,这里不做讨论
			try {
				Thread.sleep(200);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			
		}//第一层for循环
	}

}

import java.awt.Dimension;
import java.awt.Graphics;

import javax.swing.JFrame;
import javax.swing.JPanel;

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);//Invoked by Swing to draw components. 画出传入的图形
		
		//遍历传入的区域
		for ( int row = 0; row<theField.getHeight(); row++ ) 
		{
			for ( int col = 0; col<theField.getWidth(); col++ ) 
			{	
				//用细胞变量依次管理被遍历的 Cell对象
				Cell cell = theField.get(row, col);
				if ( cell != null ) //该区域有Cell的对象
				{//调用draw函数 对象为传入的 g, x=1x16,y=1x16,y=2x16...
					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);
	}//Constructs a Dimension and initializesit to the specified width and specified height
	//创建一个维度,参数是长和宽,这个函数我也没有找到被调用的地方
	
	/*-----------------------以下是测试代码,不再写注释--------------------------------*/
	public static void main(String[] args) {
		Field field = new Field(10,10);
		for ( int row = 0; row<field.getHeight(); row++ ) {
			for ( int col = 0; col<field.getWidth(); col++ ) {
				field.place(row, col, new Cell());
			}
		}
		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);
	}

}

import java.util.ArrayList;

import cell.Cell;

public class Field {
	private int width;
	private int height;
	private Cell[][] field;//创建一个二维的Cell变量数组,用于储存细胞
	
	//构造函数
	public Field(int width, int height) {
		this.width = width;
		this.height = height;
		field = new Cell[height][width];//同时创造 宽乘高个细胞对象,放进field
	}
	
	/*--------------------这两个函数用于给外界使用-------------------*/
	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某个位置上对细胞对象的管理权限赋给ret
		field[row][col] = o;//该位置去管理一个新的对象
		return ret;
	}
	
	public Cell get(int row, int col) {
		return field[row][col];//获取当前位置
	}
	
	public Cell[] getNeighbour(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;//r,c为方位
				
				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()]);//返回获取到的细胞数组
	}
	
	public void clear() {//清除所有细胞,目前没有看到被调用
		for ( int i=0; i<height; i++ ) {
			for ( int j=0; j<width; j++ ) {
				field[i][j] = null;
			}
		}
	}
}

//import java.awt.Color;//测试代码
import java.awt.Graphics;
 
public class Cell {
	private boolean alive = false;
	
	public void die() { alive = false; }
	public void reborn() { alive = true; }
	public boolean isAlive() { return alive; }
	
	public void draw(Graphics g, int x, int y, int size) {
		g.drawRect(x, y, size, size);//x y是坐标,size是大小,
									 //画一个位于x,y位置上,底色百色的色块
		if ( alive ) //如果存活,填充颜色,默认为黑色
		{
//			g.setColor(Color.yellow);//测试代码
			g.fillRect(x, y, size, size);//给色块填充颜色,参数与drawRect一样
		}
	}
}

view 代码最为复杂,其中的几个函数没有被调用

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值