实训Part4-code

本文介绍了五个角色——ChameleonKid、RockHound、BlusterCritter、QuickCrab和KingCrab,它们分别实现了颜色变化策略、石头处理、邻域生物计数、快速移动和驱赶行为。每个角色都重写了关键方法,如颜色调整、邻居搜索和行动决策,展示了编程中的面向对象和行为设计原则。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

文件结构

 .
 ├── BlusterCritter
 │   ├── BlusterCritter.java
 │   └── BlusterCritterRunner.java
 ├── ChameleonKid
 │   ├── ChameleonKid.java
 │   └── ChameleonKidRunner.java
 ├── KingCrab
 │   ├── KingCrab.java
 │   └── KingCrabRunner.java
 ├── ModifiedChameleonCritter
 │   ├── ModifiedChameleonCritter.java
 │   └── ModifiedChameleonCritterRunner.java
 ├── QuickCrab
 │   ├── QuickCrab.java
 │   └── QuickCrabRunner.java
 └── RockHound
 │   ├── RockHound.java
 │   └── RockHoundRunner.java
 └── Readme.md

Coding Exercises

  1. Modify the processActors method in ChameleonCritter so that if the list of actors to process is empty, the color of the ChameleonCritter will darken (like a flower).
    增加渐变变量:
    private static final double DARKENING_FACTOR = 0.05;	// lose 5% of color value if the list of actors to process is empty
    
    修改void processActors(ArrayList<Actor> actors)函数
    public void processActors(ArrayList<Actor> actors)
    {
        int n = actors.size();
        if (n == 0){
        	/**
             * Causes the color of this ChameleonCritter to darken.
             */ 
        	Color c = getColor();
            int red = (int) (c.getRed() * (1 - DARKENING_FACTOR));
            int green = (int) (c.getGreen() * (1 - DARKENING_FACTOR));
            int blue = (int) (c.getBlue() * (1 - DARKENING_FACTOR));
    
            setColor(new Color(red, green, blue));
        	
        	return;
        }
            
        int r = (int) (Math.random() * n);
    
        Actor other = actors.get(r);
        setColor(other.getColor());
    }
    

In the following exercises, your first step should be to decide which of the five methods—getActors, processActors, getMoveLocations, selectMoveLocation, and makeMove—should be changed to get the desired result.

  1. Create a class called ChameleonKid that extends ChameleonCritter as modified in exercise 1. A ChameleonKid changes its color to the color of one of the actors immediately in front or behind. If there is no actor in either of these locations, then the ChameleonKid darkens like the modified ChameleonCritter.
    需要重载的函数:

    getActors();
    

    重载:

        /**
         * A ChameleonKid gets the actors in the 2 locations immediately in front, behind
         * @return a list of actors occupying these locations
         */
        public ArrayList<Actor> getActors()
        {
            ArrayList<Actor> actors = new ArrayList<Actor>();
            int[] dirs =
                { Location.AHEAD, Location.HALF_CIRCLE };
            for (Location loc : getLocationsInDirections(dirs))
            {
                Actor a = getGrid().get(loc);
                if (a != null)
                    actors.add(a);
            }
    
            return actors;
        }
    	
        /**
         * Finds the valid adjacent locations of this critter in different
         * directions.
         * @param directions - an array of directions (which are relative to the
         * current direction)
         * @return a set of valid locations that are neighbors of the current
         * location in the given directions
         */
        public ArrayList<Location> getLocationsInDirections(int[] directions)
        {
            ArrayList<Location> locs = new ArrayList<Location>();
            Grid gr = getGrid();
            Location loc = getLocation();
        
            for (int d : directions)
            {
                Location neighborLoc = loc.getAdjacentLocation(getDirection() + d);
                if (gr.isValid(neighborLoc))
                    locs.add(neighborLoc);
            }
            return locs;
        } 
    

    运行结果(一步步运行):
    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述
    可以看到,只有前后有物体时才会变色,且若前后都没有物体,颜色会逐渐变深。

  2. Create a class called RockHound that extends Critter. A RockHound gets the actors to be processed in the same way as a Critter. It removes any rocks in that list from the grid. A RockHound moves like a Critter.
    需要重载的函数:

    processActors(ArrayList<Actor> actors)
    

    重载:

    /**
     * Removes any rocks in that list from the grid.
     * If there are no neighbors, no action is taken.
     */
    public void processActors(ArrayList<Actor> actors)
    {
        for (Actor a : actors){
        	if (a instanceof Rock){
        		a.removeSelfFromGrid();
        	}
        }
    }
    
    

    运行结果:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    可以看到,RockHound会将其周围的石头全部删除,运动方式与Critter一致。

  3. Create a class BlusterCritter that extends Critter. A BlusterCritter looks at all of the neighbors within two steps of its current location. (For a BlusterCritter not near an edge, this includes 24 locations). It counts the number of critters in those locations. If there are fewer than c critters, the BlusterCritter’s color gets brighter (color values increase). If there are c or more critters, the BlusterCritter’s color darkens (color values decrease). Here, c is a value that indicates the courage of the critter. It should be set in the constructor.
    需要重载的函数:

    BlusterCritter(int c); //构造函数
    getActors();
    processActors(ArrayList<Actor> actors);
    

    重载:

    private int courage;
    
    public BlusterCritter(int c)
    {
    	super();
    	setColor(Color.RED);
    	courage = c;
    }
    
    /**
     * A crab gets the actors all of the neighbors within two steps of its current location. 
     * (For a BlusterCritter not near an edge, this includes 24 locations).
     * @return a list of actors occupying these locations
     */
    public ArrayList<Actor> getActors()
    {
        ArrayList<Actor> actors = new ArrayList<Actor>();
        
    //        Grid grid = getGrid();
        Location loc = getLocation();
        
        for(int r = loc.getRow()-2; r <= loc.getRow()+2; r++){
        	for(int c = loc.getCol()-2; c <= loc.getCol()+2; c++){
        		if(r != loc.getRow() && c != loc.getCol()){
            		Location loc1 = new Location(r, c);
            		
            		if(getGrid().isValid(loc1)){
            			Actor a = getGrid().get(loc1);
            			if(a != null){
            				actors.add(a);
            			}
            		}
        		}
        		
        	}
        }
    
        return actors;
    }
    
    /**
     * If there are fewer than c critters, the BlusterCritter's color gets brighter (color values increase). 
     * If there are c or more critters, the BlusterCritter's color darkens (color values decrease). 
     * @param actors the actors to be processed
     */
    public void processActors(ArrayList<Actor> actors)
    {
    	int count = 0;
    	
    	for (Actor a : actors)
        {
            if (a instanceof Critter)
                count++;
        }
    	
    //    	double DARKENING_FACTOR = 0.1;
    	
    	if(count < courage){
    		/**
             * Causes the color of this ChameleonCritter to lighten.
             */ 
        	Color c = getColor();
            int red = c.getRed();
            int green = c.getGreen();
            int blue = c.getBlue();
            
            if(red < 255)
            	red++;
            if(green < 255)
            	green++;
            if(blue < 255)
            	blue++;
    
            setColor(new Color(red, green, blue));
    	}
    	else{
    		/**
             * Causes the color of this ChameleonCritter to darken.
             */ 
        	Color c = getColor();
        	int red = c.getRed();
            int green = c.getGreen();
            int blue = c.getBlue();
            
            if(red > 0)
            	red--;
            if(green > 0)
            	green--;
            if(blue > 0)
            	blue--;
    
            setColor(new Color(red, green, blue));
    	}
        
    }
    

    运行结果:红色的为BlusterCritter,蓝色的为Critter。
    首先设置勇气值为2。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    增加Critter。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    可以看出,当两步内的Critter数小于BlusterCritter的勇气值时,BlusterCritter的颜色越来越亮;当两步内的Critter数大于或等于BlusterCritter的勇气值时,BlusterCritter的颜色越来越暗。

  4. Create a class QuickCrab that extends CrabCritter. A QuickCrab processes actors the same way a CrabCritter does. A QuickCrab moves to one of the two locations, randomly selected, that are two spaces to its right or left, if that location and the intervening location are both empty. Otherwise, a QuickCrab moves like a CrabCritter.
    需要重载的函数:

    getMoveLocations();
    

    重载:

        /**
     * @return list of empty locations  A QuickCrab moves to one of the two locations, 
     * randomly selected, that are two spaces to its right or left,
     *  if that location and the intervening location are both empty. 
     *  Otherwise, a QuickCrab moves like a CrabCritter.
     */
    public ArrayList<Location> getMoveLocations()
    {
        ArrayList<Location> locs = new ArrayList<Location>();
        Location loc = getLocation();
        Location loc1 = loc.getAdjacentLocation(getDirection() + Location.LEFT);	// 左一格
        Location loc2 = loc.getAdjacentLocation(getDirection() + Location.RIGHT);	// 右一格
        
        if(getGrid().isValid(loc1) && getGrid().get(loc1) == null){	// 左一格空
        	Location loc3 = loc1.getAdjacentLocation(getDirection() + Location.LEFT);	// 左二格
        	if(getGrid().isValid(loc3) && getGrid().get(loc3) == null){	// 左二格空
        		locs.add(loc3);
        	}
    //        	else{
    //        		locs.add(loc1);
    //        	}
        }
        if(getGrid().isValid(loc2) && getGrid().get(loc2) == null){	// 右一格空
        	Location loc4 = loc2.getAdjacentLocation(getDirection() + Location.RIGHT);	// 右二格
        	if(getGrid().isValid(loc4) && getGrid().get(loc4) == null){	// 右二格空
        		locs.add(loc4);
        	}
    //        	else{
    //        		locs.add(loc2);
    //        	}
        }
        
        if(locs.size() == 0){
        	return super.getMoveLocations();
        }
    
        return locs;
    }
    

    运行结果:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    可以看到,当可以移动两个格时,QuickCrab必定优先移动两个格,不能移动两个格时,就按照CrabCritter的移动方式移动。

  5. Create a class KingCrab that extends CrabCritter. A KingCrab gets the actors to be processed in the same way a CrabCritter does. A KingCrab causes each actor that it processes to move one location further away from the KingCrab. If the actor cannot move away, the KingCrab removes it from the grid. When the KingCrab has completed processing the actors, it moves like a CrabCritter.
    需要重载的函数:

    processActors();
    

    重载:

       /**
     * calculate the distance of two locations
     */
    public int distance(Location loc1, Location loc2)
    {
    	int  d = (int)Math.sqrt(Math.pow(loc1.getRow()-loc2.getRow(), 2) + Math.pow(loc1.getCol()-loc2.getCol(), 2));
    	return d;
    }
    
    /**
     * A KingCrab causes each actor that it processes to 
     * move one location further away from the KingCrab. 
     * If the actor cannot move away, 
     * the KingCrab removes it from the grid. 
     * @param actors the actors to be processed
     */
    public void processActors(ArrayList<Actor> actors)
    {
        for (Actor a : actors)
        {
            ArrayList<Location> locs = getGrid().getEmptyAdjacentLocations(a.getLocation());
            Location tmp = a.getLocation();	// 存储a当前位置
            
            for(Location loc : locs){	//寻找更远的位置
            	if(distance(loc, getLocation()) > 1){
            		a.moveTo(loc);
            		break;
            	}
            }
            
            if(tmp.equals(a.getLocation())){	// 未找到更远的位置,删除
            	a.removeSelfFromGrid();
            }
        }
    }
    

    运行结果:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    可以看到,能移远的都被移远了,不能移远的都被删除了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值