Set 7
-
What methods are implemented in Critter?
答:act()
,getActors()
,processActors(ArrayList<Actor> actors)
,getMoveLocations()
,selectMoveLocation(ArrayList<Location>locs)
,makeMove(Location loc)
Source Code:// @file: GridWorldCode/framework/info/gridworld/actor/Critter.java // @line: 38, 56, 71, 88, 104, 125 public void act() public ArrayList<Actor> getActors() public void processActors(ArrayList<Actor> actors) public ArrayList<Location> getMoveLocations() public Location selectMoveLocation(ArrayList<Location> locs) public void makeMove(Location loc)
-
What are the five basic actions common to all critters when they act?
答:
(1)getActors()
(2)processActors()
(3)getMoveLocation()
(4)selectMoveLocation()
(5)makeMove()
Source Code:// @file:GridWorldCode\framework\info\gridworld\actor\Critter.java // @line: 42~46 ArrayList<Actor> actors = getActors(); processActors(actors); ArrayList<Location> moveLocs = getMoveLocations(); Location loc = selectMoveLocation(moveLocs); makeMove(loc);
-
Should subclasses of Critter override the getActors method? Explain.
答:critter的子类应该重写Critter中的getActors方法。重写critter的getActors方法可以寻找别处的要处理的actor。
Source Code:// @file:GridWorldCode\framework\info\gridworld\actor\Critter.java // @line: 44~57 public ArrayList<Actor> getActors() { ArrayList<Actor> actors = new ArrayList<Actor>(); int[] dirs = { Location.AHEAD, Location.HALF_LEFT, Location.HALF_RIGHT }; for (Location loc : getLocationsInDirections(dirs)) { Actor a = getGrid().get(loc); if (a != null) actors.add(a); } return actors; }
-
Describe the way that a critter could process actors.
答:如果该actor不是Rock或者critter的话,critter会将其移除。
Source Code:// @file:GridWorldCode\framework\info\gridworld\actor\Critter.java // @line: 71~78 public void processActors(ArrayList<Actor> actors) { for (Actor a : actors) { if (!(a instanceof Rock) && !(a instanceof Critter)) a.removeSelfFromGrid(); } }
-
What three methods must be invoked to make a critter move? Explain each of these methods.
答:getMoveLocations()
,selectMoveLocation(ArrayList<Location> locs)
,makeMove(Location loc)
(1) 首先使用getMoveLocations()
来获取critter能移动到有效的地方。
(2) 调用完getMoveLocations()
之后,我们会得到一个可移动到的位置的列表,使用selectMoveLocation(ArrayList<Location> locs)
随机选择critter的下一个location。
(3) 最后,调用makeMove(Location loc)
将critter移动到新的位置。
Source Code:// @file: GridWorldCode\framework\info\gridworld\actor\Critter.java // @line: 38~47 public void act() { if (getGrid() == null) return; ArrayList<Actor> actors = getActors(); processActors(actors); ArrayList<Location> moveLocs = getMoveLocations(); Location loc = selectMoveLocation(moveLocs); makeMove(loc); }
-
Why is there no Critter constructor?
答:这与JAVA的特性有关,如果class A extends class B,且class A中没有创建构造函数,class B创建了构造函数的话就会默认使用class B的构造函数。Critter类继承了Actor类,Actor类中有一个构造函数,所以可以直接使用Actor中的构造函数来初始化critter。
Source Code:// @file: GridWorldCode/framework/info/gridworld/actor/Actor.java // @line: 39~45 public Actor() { color = Color.BLUE; direction = Location.NORTH; grid = null; location = null; }
Set 8
-
Why does act cause a ChameleonCritter to act differently from a Critter even though
ChameleonCritter does not override act?
答:因为在Critter类中,act()
方法调用了processActors()
和makeMove()
来定义critter的行为,而ChameleonCritter中重写了processActors()
和makeMove()
方法,所以即使ChameleonCritter没有重写act方法,但是ChameleonCritter所产生的actor行为会跟Critter不同。
Source Code:// @file: GridWorldCode/framework/info/gridworld/actor/Critter.java // @line: 43,46 processActors(actors); makeMove(loc); // @file: GridWorldCode/projects/critters/ChameleonCritter.java // @line: 36~45,50~54 public void processActors(ArrayList<Actor> actors) { int n = actors.size(); if (n == 0) return; int r = (int) (Math.random() * n); Actor other = actors.get(r); setColor(other.getColor()); } public void makeMove(Location loc) { setDirection(getLocation().getDirectionToward(loc)); super.makeMove(loc); }
-
Why does the makeMove method of ChameleonCritter call super.makeMove?
答:因为ChameleonCritter重写makeMove()
只是为了能在Critter的makeMove()
的基础上,实现在移动之前转变方向,所以在ChameleonCritter中只需要先转换方向然后调用Critter的makeMove()
即可。
Source Code:// @file: GridWorldCode/projects/critters/ChameleonCritter.java // @line: 50~54 public void makeMove(Location loc) { setDirection(getLocation().getDirectionToward(loc)); super.makeMove(loc); }
-
How would you make the ChameleonCritter drop flowers in its old location when it moves?
答:只需要在makeMove()
方法中做相应的修改即可。在调用super.makeMove()
前记录下ChameleonCritter当前的location,然后在调用完super.makeMove()
之后将花朵放置在上面记录好的位置即可。
Source code:// @file: GridWorldCode/projects/critters/ChameleonCritter.java // @line: 50~54 public void makeMove(Location loc) { setDirection(getLocation().getDirectionToward(loc)); super.makeMove(loc); } //将上面的代码修改为以下内容: public void makeMove(Location loc) { Location oldLoc = getLocation(); setDirection(getLocation().getDirectionToward(loc)); super.makeMove(loc); Flower flower = new Flower(getColor()); flower.putSelfInGrid(getGrid(), oldLoc); } }
-
Why doesn’t ChameleonCritter override the getActors method?
答:因为ChameleonCritter并不需要在getActors()
方法上增加功能,所以可以直接使用Critter类中定义的getActors()
而不是重写该方法。
Source Code:// @file: GridWorldCode/famework/info/gridworld/actor/Citter.java // @line: 71~78 public void processActors(ArrayList<Actor> actors) { for (Actor a : actors) { if (!(a instanceof Rock) && !(a instanceof Critter)) a.removeSelfFromGrid(); } }
-
Which class contains the getLocation method?
答:Actor类中包含了getLocation()
方法。// @file: GridWorldCode/famework/info/gridworld/actor/Actor.java // @line: 102~105 public Location getLocation() { return location; }
-
How can a Critter access its own grid?
答:Critter可以通过getGrid()
方法来访问他自己的grid。该方法定义在Actor类中。// @file: GridWorldCode/famework/info/gridworld/actor/Actor.java // @line: 92~95 public Grid<Actor> getGrid() { return grid; }
Set 9
-
Why doesn’t CrabCritter override the processActors method?
答:因为Crab要吃掉其正前方,右前方或左前方的任何位置上的除了Rock和Critter实例的任何其他actor,这与Critter中的processActors(ArrayList<Actor> actors)
方法逻辑一样,CrabCritter又是Critter的子类,所以不需要重写processActors(ArrayList<Actor> actors)
方法。
Source Code:// @file: GridWorldCode/framework/info/gridworld/actor/Critter.java // @line: 71~78 public void processActors(ArrayList<Actor> actors) { for (Actor a : actors) { if (!(a instanceof Rock) && !(a instanceof Critter)) a.removeSelfFromGrid(); } }
-
Describe the process a CrabCritter uses to find and eat other actors. Does it always eat all neighboring actors? Explain.
答:CrabCritter先调用getActors()
方法来获得其正前方,右前方,左前方的所有actors。再将得到的所有actors传递给processActor(ArrayList<Actor> actors)
来吃掉其他的actors。Crab并不是吃掉所有相邻的actors,而是吃掉在正前方,左前方,右前方出现的非Rock,非Critter的actors。
Source Code// @file: GridWorldCode/projects/critters/CrabCritter.java //@line: 44~57 public ArrayList<Actor> getActors() { ArrayList<Actor> actors = new ArrayList<Actor>(); int[] dirs = { Location.AHEAD, Location.HALF_LEFT, Location.HALF_RIGHT }; for (Location loc : getLocationsInDirections(dirs)) { Actor a = getGrid().get(loc); if (a != null) actors.add(a); } return actors; } // @file: GridWorldCode/framework/info/gridworld/actor/Critter.java // @line: 71~78 public void processActors(ArrayList<Actor> actors) { for (Actor a : actors) { if (!(a instanceof Rock) && !(a instanceof Critter)) a.removeSelfFromGrid(); } }
-
Why is the getLocationsInDirections method used in CrabCritter?
答:因为我们要得到Crab前面三个方向的actors列表,所以我们需要先得到这三个位置的location信息,所以我们只需要通过Crab本身的方向位置信息,然后通过调用该getLocationInDirections()
方法就可以得到那三个网格的位置信息。
Source Code:// @file: GridWorldCode/projects/critters/CrabCritter.java // @line: 101~114 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; }
-
If a CrabCritter has location (3, 4) and faces south, what are the possible locations for actors that are returned by a call to the getActors method?
答:(4,4),(4,3),(4,5)
Source Code:// @file: GridWorldCode/projects/critters/CrabCritter.java // @line: 47~48 int[] dirs = { Location.AHEAD, Location.HALF_LEFT, Location.HALF_RIGHT };
-
What are the similarities and differences between the movements of a CrabCritter and a Critter?
答:
(1)similarities:二者都不会再移动之前改变自己的运动方向,而且都是从可移动的位置列表中任意选择一个位置进行移动。
(2)differences:CrabCritter只能左右移动而Critter可以往任意方向移动。Crab在不能移动时会保持不动而Crab在不能移动时会转动方向。
Source Code:// @file: GridWorldCode/projects/critters/CrabCritter.java // @line: 65~71 int[] dirs = { Location.LEFT, Location.RIGHT }; for (Location loc : getLocationsInDirections(dirs)) if (getGrid().get(loc) == null) locs.add(loc); return locs;
-
How does a CrabCritter determine when it turns instead of moving?
答:通过检查可供移动的位置是否跟当前位置相同,如果相同就意味着CrabCritter不能移动只能转动。
Source Code:// @file: GridWorldCode/projects/critters/CrabCritter.java //@line: 79~88 if (loc.equals(getLocation())) { double r = Math.random(); int angle; if (r < 0.5) angle = Location.LEFT; else angle = Location.RIGHT; setDirection(getDirection() + angle); }
-
Why don’t the CrabCritter objects eat each other?
答:因为CrabCritter继承了Critter,所以CrabCritter是Critter的一个实例,又因为CrabCritter并没有重写Critter类中的processActor()
方法,Critter类中的processActor()
方法定义了不能吃Critter,所以CrabCritter不能吃CrabCritter。
Source Code:// @file: GridWorldCode/framework/info/gridworld/actor/Critter.java // @line: 75~76 if (!(a instanceof Rock) && !(a instanceof Critter)) a.removeSelfFromGrid();