看懂代码从main函数开始
这是主类

package foxnrabbit;import java.util.ArrayList;
import javax.swing.JFrame;import field.Field;
import field.View;
import field.Location;import animal.Animal;
import animal.Fox;
import animal.Rabbit;import cell.Cell;public class FoxAndRabbit {//成员变量private Field theField;//Field变量,用来管理新的网格private View theView;//继承自Jpanel的类,用来显示图形/*------构造函数------*/public FoxAndRabbit(int size) {//创建网格theField=new Field(size,size);//遍历网格for(int row=0;row<theField.getHeight();row++){for(int col=0;col<theField.getWidth();col++){double probability=Math.random();//随机放入狐狸if(probability<0.05){theField.place(row,col,new Fox());}//随机放入兔子else if(probability<0.15){theField.place(row, col,new Rabbit());}}}/*------把theField加入到显示框------*/theView=new View(theField);JFrame frame = new JFrame();frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setResizable(false);frame.setTitle("Cells");frame.add(theView);frame.pack();frame.setVisible(true);}/*------开始函数,传入的参数是程序要执行的次数------*/public void satrt(int steps){for (int i=0;i<steps;i++) {step();theView.repaint();//Java底层函数try {Thread.sleep(200);} catch (Exception e) {e.printStackTrace();}}}/*------step()函数,每次更新表格- - - - - -*/public void step() {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){//把管理的对象造型为Animal对象Animal animal=(Animal)cell;//年龄增长animal.grow();if(animal.isAlive()) {    //向周围移动Location loc=animal.move(theField.getFreeNeighbour(row, col));if(loc!=null) { theField.move(row,col,loc); }//获取周围的兔子,储存进容器里面Cell[] neighbour=theField.getNeighbour(row, col);ArrayList<Animal> listRabbit=new ArrayList<Animal>();for(Cell an:neighbour) {//instanceof关键字,判断是不是某个类的实例if(an instanceof Rabbit) { listRabbit.add((Rabbit)an); }                          }//吃掉兔子if(!listRabbit.isEmpty()) //isEmpty()是ArrayList的函数,没有元素则返回true{                         //这里涉及到了多态,这个animal实际上是Fox的对象,调用的是Fox的feed()//(animal本身是抽象类,自己不可能有对象的)Animal fed=animal.feed(listRabbit);//fed得到了兔子的对象之后,调用函数删除这个对象(被吃掉if(fed!=null) { theField.remove((Cell)fed); }}//动物繁殖Animal baby=animal.breed();if(baby!=null) { theField.placeRandomAdj(row,col,(Cell)baby); } }else { theField.remove(row ,col); }}}}}/*------看懂函数先从main函数开始------*/public static void main(String[] args) {//创建一个30x30的网格 //走100步FoxAndRabbit fr=new FoxAndRabbit(30);fr.satrt(100);        }}

view类

package field;import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Color;
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;}/*** paint()函数,由于继承了JPanel类,该函数在对象初始化的会被自动调用* drawLine()函数,前两个数是第一个点的坐标值,后两个数是第二个点的坐标值* 该函数会先画一个与区域大小一样* 然后会遍历整个区域,如果存在对象,给网格上色 */@Overridepublic void paint(Graphics g) {super.paint(g);//Invoked by Swing to draw components. 画出传入的图形g.setColor(Color.gray);for(int i=0;i<theField.getHeight();i++){g.drawLine(0, i*GRID_SIZE, theField.getWidth()*GRID_SIZE, i*GRID_SIZE);g.drawLine(i*GRID_SIZE, 0, i*GRID_SIZE, theField.getHeight()*GRID_SIZE);}//遍历传入的区域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);}}}}//这个函数我并没由找到他的作用说明,根据在细胞自动机里面的代码,写上就好了@Overridepublic Dimension getPreferredSize() {return new Dimension(theField.getWidth()*GRID_SIZE+1, theField.getHeight()*GRID_SIZE+1);}
}

Field类

package field;import java.util.ArrayList;
import java.util.function.IntFunction;import animal.Fox;
import animal.Rabbit;
import cell.Cell;public class Field {//测试代码private static final Location[] adjacent= {new Location(-1,-1),new Location(-1,0),new Location(-1,1),new Location(0,-1),new Location(0,0),new Location(0,1),new Location(1,-1),new Location(1,0),new Location(1,1)};//成员变量private int height;private int width;private Cell[][] field;//构造函数public Field(int height, int width) {this.height=height;this.width=width;field=new Cell[height][width];}public int getHeight()   {   return height;  }public int getWidth()  {   return width;   }/*** place函数,* 在Field类中,先定义Cell类型的变量ret* Field的成员变量同时也是Cell类型的变量数组field[][],* 让ret和field[row][col]管理同一个对象,此时ret管理的是null* 让field[row][col]管理传入的细胞对象变量* (不能实例化,但是可以管理实现了它的接口的Fox和Rabbit,* 此时ret也会跟着管理这个对象*/    public Cell place(int row, int col, Cell o) {//      Cell ret=field[row][col];field[row][col]=o;
//      return ret;return field[row][col];//改写了这个函数,这样看条例更清晰}//获取当前对象public Cell get(int row,int col) {return field[row][col];}/***Field的getNeighbour()函数用于获取周围有对象的空格*他要遍历周围所有的位置*并且定义一个容器来储存Cell型变量(实际上可能是Fox或Rabbit的对象*返回list长度的Cell变量数组    */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;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()]);}/***Field的getFreeNeighbour()函数用于获取周围没有管理对象的位置 *它会遍历周围所有的位置*如果周围的位置是空的*它就会用ArrayList把这些位置存到容器里面*最后返回该数组长度的数组   */  public Location[] getFreeNeighbour(int row,int col) {ArrayList<Location> list=new ArrayList<Location>();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&&field[r][c]==null) {list.add(new Location(r,c));}}}return list.toArray( new Location[list.size()]);}/*** 由于Animal的移动以后,当前loc的位置已经发生了变化* 由发生变化的位置接管原来位置上面的对象* 把原来位置上的对象清除*/public void move(int row, int col, Location loc) {field[loc.getCol()][loc.getRow()]=field[row][col];remove(row,col);  }//删除对象,这个函数在FoxAndRabbit类里面被调用public void remove(Cell cell) {for(int row=0;row<height;row++) {for(int col=0;col<width;col++){if(field[row][col]==cell) { field[row][col]=null; break; }}}}//删除对象,这个函数在类里面调用public Cell remove(int row, int col) {Cell ret=field[row][col];field[row][col]=null;return ret;}/***这个函数的作用把产生的小baby放入到随机一个格子里面去*首先定义Location数组,接收周围没有对象的空格*如果有空格,获取一个0到该数组长度之间的一个随机整数*用该空格去管理传进来的baby(已经造型为Cell*返回true*这里的返回值我并不清楚它的作用 */public boolean placeRandomAdj(int row, int col, Cell baby) {boolean ret=false;Location[] FreeAdj=getFreeNeighbour(row, col);if(FreeAdj.length>0){int index=(int)(Math.random()*FreeAdj.length);field[FreeAdj[index].getRow()][FreeAdj[index].getCol()]=baby;ret=true;}return ret;       }//清除所有对象public void clear(){for(int i=0;i<height;i++){for(int j=0;j<width;j++){field[i][j]=null;}}}
}

Location类

package field;public class Location {private int x;private int y;public Location(int x, int y) {this.x = x;this.y = y;}public int getRow() {return x;}public int getCol() {return y;}
}

Cell接口;

package cell;import java.awt.Graphics;public interface Cell {void draw(Graphics g,int x,int y, int size);
}

Animal类

package animal;import java.util.ArrayList;
import field.Location;public abstract class Animal {//成员变量private int ageLimit;private int breedableAge;private int age;private boolean isAlive=true;//构造函数,传入生命上限和可繁殖年龄public Animal(int ageLimit, int breedableAge) {this.ageLimit = ageLimit;this.breedableAge = breedableAge;}public int getAge() {return age;}protected double getAgePercent() {return (double)age/ageLimit;}//  public abstract Animal breed();/*** 在之前的讨论中,我们用新的breed()函数,代替了原来的函数* 这个函数做的事情是是到达了生育年龄* 并且符合一定的几率* 产生一个新的对象(Fox或者Rabbit*/public Animal breed(){Animal ret=null;if(isBreedable()&&Math.random()<getValue()){ret=getAnimal();}return ret;}public abstract Animal getAnimal();public abstract double getValue();//生长函数public void grow() {age++;if(age>=ageLimit){die();}}protected void die() {isAlive=false;    }public boolean isAlive() {return isAlive;}protected boolean isBreedable(){return age>=breedableAge;}   /*** Animal的move()函数*  传入Location的数组作为参数*  如果传入的参数不为空,几率符合*  由ret接管数组里面的一个随机位置对象*  最后返回这个位置*/public Location move(Location[] freeAdj) {Location ret=null;if(freeAdj.length>0&&Math.random()<0.02) { ret=freeAdj[(int)(Math.random()*freeAdj.length)];}       return ret;     }@Overridepublic String toString() {return ""+age+":"+(isAlive?"live":"dead");}//让子类覆盖,实际这个函数并没有被调用public Animal feed(ArrayList<Animal> neighbour) {return null;}//吃掉兔子之后增加生命上限protected void longerLife(int inc) {ageLimit+=inc;}}

Fox类

package animal;import java.awt.Color;
import java.awt.Graphics;
import java.util.ArrayList;import cell.Cell;public class Fox extends Animal implements Cell{public Fox(){super(20,4);//生命上限20岁,生育年龄4岁}@Overridepublic void draw(Graphics g, int x, int y, int size) {int alpha=(int)((1-getAgePercent())*255);g.setColor(new Color(0,0,0,alpha));//用数字代表颜色,最后一个值是颜色深度,逐渐递减g.fillRect(x, y, size, size);}//已经改写过的函数,增加可扩展性@Overridepublic Animal breed() {return super.breed();}@Overridepublic Animal getAnimal() {return new Fox();}@Overridepublic double getValue() {return 0.05;}@Overridepublic String toString() {// TODO Auto-generated method stubreturn "Fox:"+super.toString();}/*** Fox的feed()函数,他的参数是Animal的容器(周围的兔子*  定义Animal类型的变量ret*  在一定的几率下接收任意一个兔子*  提高两个生命上限*  返回这只兔子   */@Overridepublic Animal feed(ArrayList<Animal> neighbour) {Animal ret=null;if(Math.random()<0.2) {ret=neighbour.get((int)(Math.random()*neighbour.size()));longerLife(2);}return ret;}}

Rabbit类:

package animal;import java.awt.Color;
import java.awt.Graphics;import cell.Cell;public class Rabbit extends Animal implements Cell {public Rabbit() {super(10,2);}@Overridepublic void draw(Graphics g, int x, int y, int size) {int alpha=(int)((1-getAgePercent())*255);g.setColor(new Color(255,0,0,alpha));g.fillRect(x, y, size, size);}@Overridepublic Animal breed() {return super.breed();}@Overridepublic Animal getAnimal() {return new Rabbit();}@Overridepublic double getValue() {return 0.12;}@Overridepublic String toString() {return "Rabbit"+super.toString();}}

程序关系图:

狐狸与兔子,代码解析相关推荐

  1. java兔子问题流程图_C语言编程狼追兔子问题代码解析

    原标题:C语言编程狼追兔子问题代码解析 问题描述 一只兔子躲进了10个环形分布的洞中的一个.狼在第一个洞中没有找到兔子,就隔一个洞,到第3个洞去找:也没有找到,就隔2个洞,到第6个洞去找:以后每次多一 ...

  2. 翁恺老师 狐狸和兔子练习

    习题描述 狐狸.兔子都有年龄: 到达一定年龄上限会自然死亡: 狐狸随机吃掉周围一只兔子: 狐狸.兔子可以随机生一只小的放在旁边格子: 如果不吃不生,狐狸.兔子可以随机向旁边格子移一步会随机吃掉 Ani ...

  3. 狐狸逮兔子实验 c++

    实验描述 狐狸逮兔子实验 (一)问题描述 围绕着山顶有10个圆形排列的洞,互利要吃兔子,兔子说:"可以,但必须找到我,我就藏于这10个洞中,你先到1号洞找,第二次隔1个洞(即3号洞)找,第二 ...

  4. 【经典算法】:狐狸抓兔子问题

    前言 问题见百度 狐狸抓兔子问题 代码 全在注释里面了,没啥好说的 // 狐狸找兔子问题 // author:seen // time:2015-09-20#include <iostream& ...

  5. 7-7 狐狸和兔子(下图所示的棋盘中,F 表示狐狸,H 表示兔子)

    狐狸每次可以向左或向右移动1格,兔子每次可以向左或向右跳过2格进到第3格里.狐狸先走,然后它们交替移动. 如果兔子跳进狐狸所在的格子则会被吃掉.如果狐狸走进兔子所在的格子可以把兔子吃掉. 狐狸 F 的 ...

  6. 综合实验一 狐狸逮兔子

    一)问题描述 围绕着山顶有10个圆形排列的洞,狐狸要吃兔子,兔子说:"可以,但必须找到我,我就藏于这10个洞中,你先到1号洞找,第二次隔1个洞(即3号洞)找,第二次隔2个洞(即6号洞)找,以 ...

  7. C++经典问题:狐狸找兔子

    问题描述: 围绕着山顶有10个洞,一只狐狸和一只兔子住在各自的洞里.狐狸想吃掉兔子.一天,兔子对狐狸说:"你想吃我有一个条件,先把洞从1-10编上号,你从10号洞出发,先到1号洞找我:第二次 ...

  8. matrix_multiply代码解析

    matrix_multiply代码解析 关于matrix_multiply 程序执行代码里两个矩阵的乘法,并将相乘结果打印在屏幕上. 示例的主要目的是展现怎么实现一个自定义CPU计算任务. 参考:ht ...

  9. CornerNet代码解析——损失函数

    CornerNet代码解析--损失函数 文章目录 CornerNet代码解析--损失函数 前言 总体损失 1.Heatmap的损失 2.Embedding的损失 3.Offset的损失 前言 今天要解 ...

  10. 视觉SLAM开源算法ORB-SLAM3 原理与代码解析

    来源:深蓝学院,文稿整理者:何常鑫,审核&修改:刘国庆 本文总结于上交感知与导航研究所科研助理--刘国庆关于[视觉SLAM开源算法ORB-SLAM3 原理与代码解析]的公开课. ORB-SLA ...

最新文章

  1. 徒手解密 Spring Boot 中的 Starter自动化配置黑魔法
  2. Java Private、protected、public、以及无修饰符的可见范围
  3. c语言二维图形变换程序,【计算机图形学】3-2 二维几何变换根本代码
  4. jpa 原生sql 查询返回一个实体_spring data系列之jpa
  5. 6个好用的Web开发工具
  6. 怎么获取codeforces的数据_飞瓜数据5大功能盘点,帮你抓住2019抖音新一波涨粉红利期!...
  7. c#执行多句oracle,C#一次执行多条SQL语句,Oracle11g数据库
  8. 【安全资讯】热门Windows激活软件KMSPico被植入恶意程序
  9. 小程序js车牌号手机号正则表达
  10. aliplayer 直播在微信和支付宝浏览器自动播放兼容
  11. windows硬盘读写速度测试
  12. 成功解决Initialization failed for ‘https://start.spring.io‘ Please check URL, network and proxy settings
  13. 三星手机和计算机如何连接打印机,WIFI当道 手把手教你如何实现无线打印
  14. python_文件统计问题:文件” seqs_fasta.txt”保存着具有fasta格式的100多个蛋白质氨基酸序列
  15. 《郭论—捡史》郭德纲/著 读后得
  16. delphi 发送html邮件,delphi – 以HTML格式发送电子邮件
  17. php 微信朋友圈 更新时间,微信朋友圈可见天数怎么设置
  18. NEFU 大一寒假培训【一】二维数组、结构体
  19. cad批量转换pdf格式
  20. @Transactional注解什么情况会失效?

热门文章

  1. “expression cannot be used as a function”报错
  2. GoJS滚动表格的使用
  3. 关于加减运算时能否使用等价无穷小的问题
  4. linux 技能包【5】:时间同步 chrony
  5. mysql 分组查询男生女生人数各多少_COUNT(*)分组查询,男女两组人数各多少 对where进行筛选...
  6. 爬虫中extract的简单用法
  7. matebook13 java开发_紧急要跑程序?华为 MateBook X Pro一键搞定立马进状态
  8. 【Qt】QML快速入门7——输入元素
  9. sap 标准委外和工序委外_SAP委外加工
  10. c语言中表示男性别的字符是什么,C语言结构中根据性别分类按年龄升序输出姓名...