25.2.4小记(FoxandRabbit代码复现)
1.接口(interface)不仅可以用于定义方法的签名,还可以充当类型的一部分。其本身可以作为类来引用
eg.Cell[][] field
数组中的对象是实现了这个接口的类的实例。
是一种特殊的class
return list.toArray(new Cell[list.size()]);
中list.toArray是将原来的数组填充到()中的对象中(这里新创建了一个新的Cell数组则无需重新分配内存)


图形机制
swing
在界面窗口上看到的所有东西都叫部件
(1)容器(其本身就是一种部件) :
1.所以容器也可以被放在另外一个容器中
2.容器可以管理其中的部件(通过布局管理器Layoutmanager)
对于frame来说,默认采用的布局管理器用的时候BorderLayout(其中具体位置参数由程序库自行计算)
BorderLayout : 将容器化成五块区域
其中添加的时候若没有给定具体位置参数则默认为CENTER

(2)部件:可以放在容器里
通过add这个动作将一个部件加入一个容器里面去
具体代码:
1.animal(package):
(1)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/agelimit;
}
public abstract Animal breed();
public void grow(){
age++;
if(age > agelimit){
die();
}
}
private 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> neighbour){
return null;
}
protected void longerlife(int addage){
agelimit += addage;
}
}
(2)Fox
package animal;
import cell.Cell;
import java.awt.Color;
import java.awt.Graphics;
import java.util.ArrayList;
public class Fox extends Animal implements Cell {
public Fox(){
super(20,4);
}
@Override
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> neighbour){
Animal ret = null;
if(Math.random() < 0.2){
ret = neighbour.get((int)(Math.random()*neighbour.size()));
longerlife(2);
}
return ret;
}
}
(3)Rabbit
package animal;
import cell.Cell;
import java.awt.Color;
import java.awt.Graphics;
import java.util.ArrayList;
public class Fox extends Animal implements Cell {
public Fox(){
super(20,4);
}
@Override
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> neighbour){
Animal ret = null;
if(Math.random() < 0.2){
ret = neighbour.get((int)(Math.random()*neighbour.size()));
longerlife(2);
}
return ret;
}
}
2.cell(package):
(1)Cell
package cell;
import java.awt.Graphics;
public interface Cell {
void draw(Graphics g,int x,int y,int size);
}
3.field(package):
(1)Field
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 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<=1;i++){
for(int j=-1;j<=1;j++){
int l=row+i;
int r=col+j;
if(-1 < l && l < height && -1 < r && r < width && !(l==row && r==col)){
list.add(field[l][r]);
}
}
}
return list.toArray(new Cell[list.size()]);
}
public Location[] getFreeNeighbour(int row,int col){
ArrayList<Location> list = new ArrayList<Location>();
for(int i=-1;i<=1;i++){
for(int j=-1;j<=1;j++){
int l = row + i ;
int r = col + j ;
if(-1 < l && l < height && -1 < r && r < width && !(l==row && r==col) && field[l][r] == null){
list.add(new Location(l,r));
}
}
}
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 Cell remove(int row,int col){
Cell ret = field[row][col];
field[row][col] =null;
return ret;
}
public void remove(Cell cell){
for(int i=0;i<height;i++){
for(int j=0;j<width;j++){
if(field[i][j] == cell){
field[i][j] = null;
}
}
}
}
public void clear(){
for(int i=0;i<height;i++){
for(int j=0;j<width;j++){
field[i][j] = null;
}
}
}
public void move(int row,int col,Location loc){
field[loc.getRow()][loc.getCol()] = field[row][col];
remove(row,col);
}
public Cell place(int row,int col,Cell c){
Cell ret = field[row][col];
field[row][col] = c;
return ret;
}
}
(2)Location
package field;
public class Location {
private int row;
private int col;
public Location(int row,int col){
this.col = col;
this.row = row;
}
public int getRow(){
return row;
}
public int getCol(){
return col;
}
}
(3)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.getHeight(); 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);
}
}
4.FoxAndRabbit(package)
(1)FoxAndRabbit
package FoxAndRabbit;
import field.Field;
import field.view;
import field.Location;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import javax.swing.*;
import animal.Fox;
import animal.Rabbit;
import animal.Animal;
import cell.Cell;
public class FoxAndRabbit {
private Field thefield;
private view theview;
private JFrame frame;
private class StepListener implements ActionListener{
@Override
public void actionPerformed(ActionEvent e){
step();
theview.repaint();
}
}
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());
}
}
}
theview = new view(thefield);
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.setTitle("Fox and Rabbit");
frame.add(theview,BorderLayout.CENTER);
JButton btnStep = new JButton("单步");
frame.add(btnStep, BorderLayout.NORTH);
btnStep.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e){
System.out.println("按下啦!");
step();
frame.repaint();
}
});
frame.pack();
frame.setVisible(true);
}
public void step(){
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 ){
Animal animal = (Animal)cell;
animal.grow();
if( animal.isAlive()){
//move
Location loc = animal.move(thefield.getFreeNeighbour(row, col));
if( loc != null ){
thefield.move(row, col, loc);
}
//eat animal.eat(thefield);
if( animal instanceof Fox){
Cell[] neighbour = thefield.getNeighbour(row, col);
ArrayList<Animal> listRabbit = new ArrayList<Animal>();
for( Cell an : neighbour ){
if( an instanceof Rabbit ){
listRabbit.add( (Rabbit)an );
}
}
if( !listRabbit.isEmpty() ){
Animal fed = animal.feed(listRabbit);
if( fed != null ){
thefield.remove((Cell)fed);
}
}
}
//breed
Animal baby = animal.breed();
if( baby != null ){
thefield.placeRandomAdj(row, col, (Cell)baby);
}
}else{
thefield.remove(row, col);
}
}
}
}
}
public void start( int steps ){
for( int i = 0; i < steps; i++){
step();
theview.repaint();
try{
Thread.sleep(200);
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
public static void main(String[] args) {
FoxAndRabbit fnr = new FoxAndRabbit(30);
// fnr.start(100);
}
}

浙公网安备 33010602011771号