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


}
posted @ 2025-02-05 00:11  Ryan_jxy  阅读(20)  评论(0)    收藏  举报