Java:接口(狐狸和兔子)

包:foxandrabbit

主程序(FoxAndRabbit)

package foxandrabbit;


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 start(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); }
				}
			}
		}
		
	}

	public static void main(String[] args) {
		FoxAndRabbit fr=new FoxAndRabbit(30);
		fr.start(50);		
	}

}

包:field

数据处理(Field)

package field;


import java.util.ArrayList;

import cell.Cell;



public class Field {
  private int width;
  private int height;
  private Cell[][] 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),
  };

  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 cell) {
    // !这里的Cell o并非Cell类的对象,而是实现了Cell接口的对象
    field[row][col] = cell;
    Cell ret = field[row][col];
    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;
        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 Location[] getFreeNeighbour(int row, int col) {
    ArrayList<Location> list = new ArrayList<Location>();
    for (Location loc : adjacent) {
      int r = row + loc.getRow();
      int c = col + loc.getCol();
      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()]);
  }

  public boolean placeRandomAdj(int row, int col, Cell cell) {
    boolean ret = false;
    Location[] freeAdj = getFreeNeighbour(row, col);
    if (freeAdj.length > 0) {
      int idx = (int) (Math.random() * freeAdj.length);
      field[freeAdj[idx].getRow()][freeAdj[idx].getCol()] = cell;
      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;
      }
    }
  }

  public void remove(Cell fed) {
    for (int row = 0; row < height; row++) {
      for (int col = 0; col < width; col++) {
        if (field[row][col] == fed) {
          field[row][col] = null;
          break;
        }
      }
    }
  }

  public Cell remove(int row, int col) { // *函数重构
    field[row][col] = null;
    Cell ret = field[row][col];
    return ret;
  }

  public void move(int row, int col, Location loc) {
    field[loc.getRow()][loc.getCol()] = field[row][col];
    remove(row, col);
  }
}

图形绘制(View)

package field;



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

import javax.swing.JPanel;

import cell.Cell;


public class View extends JPanel {
  private static final long serialVersionUID = -2417015700213488315L;
  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);
    g.setColor(Color.GRAY);
    for (int row = 0; row < theField.getHeight(); row++) 
      g.drawLine(0, row * GRID_SIZE, theField.getWidth() * GRID_SIZE, row * GRID_SIZE);
    for ( int col = 0; col<theField.getWidth(); col++ )
      g.drawLine(col * GRID_SIZE, 0, col * GRID_SIZE, theField.getHeight() * GRID_SIZE);
    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);
  }
}

存储移动位置(Location)

package field;


public class Location {
	private int row;
	private int col;

	public Location(int row, int col) {
		this.row = row;
		this.col = col;
	}

	public int getRow() {
		return row;
	}

	public int getCol() {
		return col;
	}
}

包:Cell

接口(Cell)

package cell;

import java.awt.Graphics;
public interface Cell {//注意这里不能写成interface class
  /*
   * Cell是一个接口而非类(接口是一种完全抽象的抽象类)
   * !这个接口就是为了实现Fox和Rabbit类new的对象能够传递给Field类
   * Field类中指明需要的对象的类是Cell而Cell是作为中间承接者
   * Fox和Rabbit类需要有implements Cell语句来实现接口


   * !注意这里函数可以不用写函数前缀,只需要写返回值类型
   * ?抽象类无函数主体,只需声明函数原型,实现抽象类/接口的类都必须Override所有抽象方法,否则此子类仍为抽象类
   * ?abstract与final是冲突对立关系,抽象是用来被继承或重写的,final相反是不让继承/重写的
   */
  void draw(Graphics g, int x, int y, int size);
}

包:animal

动物类[父类](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;
  }

  protected int getAge() {
    return age;
  }

  protected double getAgePercent() {
    return (double) age / (double) ageLimit;
  }

  public abstract Animal breed();

  public void grow() {
    age++;
    if (age >= ageLimit)
      die();
  }

  public void die() {
    isAlive = false;
  }

  public boolean isAlive() {
    return isAlive;
  }

  public boolean isBreedable() {
    return (age >= breedableAge);
  }

  //概率移动,移动位置
  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;
  }

  @Override
  public String toString() {
    return "" + age + ":" + (isAlive ? "live" : "dead");
  }

  public Animal feed(ArrayList<Animal> neighbor) {
    return null;
  }

  protected void longerLife(int inc) {
    ageLimit += inc;
  }

}

狐狸[子类](Fox)

package animal;


import java.awt.Graphics;

import java.awt.Color;
import java.util.ArrayList;

import cell.Cell;


/**
 * *Fox实现接口Cell,使Fox对象能间接传给Field
 */
public class Fox extends Animal implements Cell {
  public Fox() {
    super(20, 4);
  }

  @Override // 实现接口Cell中的draw()
  public 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);
  }

  @Override
  public Animal breed() {
    Animal ret = null;
    if (isBreedable() && Math.random() < 0.05) {
      ret = new Fox();
    }
    return ret;
  }

  @Override
  public String toString() {
    return ("Fox:" + super.toString());
  }

  @Override
  public Animal feed(ArrayList<Animal> neighbor) {	//狐狸进食增加寿命
    Animal ret = null;
    if (Math.random() < 0.2) {
      ret = neighbor.get((int) (Math.random() * neighbor.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); // *寿命&&生育年龄
  }

  @Override
  public 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);
  }

  @Override
  public Animal breed() {
    Animal ret = null;
    if (isBreedable() && Math.random() < 0.12) {
      ret = new Rabbit();
    }
    return ret;
  }

  @Override
  public String toString() {
    return "Rabbit" + super.toString();
  }
}

相关:
Java:Swing

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值