The Location Class
Set 3
Assume the following statements when answering the following questions.
Location loc1 = new Location(4, 3);
Location loc2 = new Location(3, 4);
-
1.How would you access the row value for loc1?
回答:loc1.getRow()
-
2.What is the value of b after the following statement is executed?
boolean b = loc1.equals(loc2);
回答: b == false;
源码来自Location.java
-
3.What is the value of loc3 after the following statement is executed?
Location loc3 = loc2.getAdjacentLocation(Location.SOUTH);
回答: loc3 == (4, 4)
源码来自Location.java(此处没有完全展示)
-
4.What is the value of dir after the following statement is executed?
int dir = loc1.getDirectionToward(new Location(6, 5));
回答:dir == 135(此时方向为southeast)
源码来自Location.java
-
5.How does the getAdjacentLocation method know which adjacent location to return?
回答: getAdjacentLocation 方法中参数 direction 表示想要查找邻居所在的方向,首先该方法会计算出标准的邻居方向(adjustedDirection,我们使用的仅只有8个方向,计算的逻辑会在下面展示),然后再通过这个标准的方向来计算得到邻居的位置。/** * The turn angle for turning 45 degrees to the right. */ public static final int HALF_RIGHT = 45; /** * The turn angle for turning a full circle. */ public static final int FULL_CIRCLE = 360; // reduce mod 360 and round to closest multiple of 45 int adjustedDirection = (direction + HALF_RIGHT / 2) % FULL_CIRCLE; if (adjustedDirection < 0) adjustedDirection += FULL_CIRCLE; adjustedDirection = (adjustedDirection / HALF_RIGHT) * HALF_RIGHT;
The Grid Interface
Set 4
-
1.How can you obtain a count of the objects in a grid? How can you obtain a count of the empty locations in a bounded grid?
回答:- 通过grid.getOccupiedLocations().size()(假设grid是一个Grid object),可以得到当前被占据的格子的个数,也即是当前的所有对象数;
- 通过grid.getNumRows() * grid.getNumCols() - grid.getOccupiedLocations().size(),以所有的格子数减去被占据的格子数,得到空的格子数
-
2.How can you check if location (10,10) is in a grid?
回答:使用grid.isValid(new Location(10,10))
源代码来自Grid.java
-
3.Grid contains method declarations, but no code is supplied in the methods. Why? Where can you find the implementations of these methods?
回答: Grid仅是一个接口,在JAVA中,接口需要指定其他的类来实现对应方法。再这个例子中,可以在AbstractGrid以及BoundedGrid和UnboundedGrid类中找到方法的实现。
还需要注意到的是,在这个例子中,由于AbstractGrid只实现了Grid接口的一些必须方法,所以把它声明为抽象类,并让BoundedGrid和UnboundedGrid类来扩展它并实现其余方法。 -
4.All methods that return multiple objects return them in an ArrayList. Do you think it would be a better design to return the objects in an array? Explain your answer.
回答: 不一定。
对于用户来说,使用数组可以更加方便访问具体的对象(直接使用"[]");
但是在实现方面,在我们想要扩充grid的时候,array要重新计算大小,并且重新分配位置,这大大影响效率。而ArrayList就可以直接扩充,显然效率更高。
The Actor Class
Set 5
-
1.Name three properties of every actor.
回答: color, direction, location. -
2.When an actor is constructed, what is its direction and color?
回答: 颜色为BLUE,方向为NORTH
查看源码(Actor.java)
-
3.Why do you think that the Actor class was created as a class instead of an interface?
回答: 在 Actor中既有状态也有方法,但是接口中是不允许声明实例变量或者实现方法。 -
4.Can an actor put itself into a grid twice without first removing itself? Can an actor remove itself from a grid twice? Can an actor be placed into a grid, remove itself, and then put itself back? Try it out. What happens?
回答:-
1)不能。编程实践如下:
编译运行,得到
显然,我们不能重复将同一个对象放到网格的同一位置。 -
2)不能。编程实践如下:
编译运行结果如下:
显然,在第二次执行removeSelfFromGrid()时,网格中的对象已经被删除了,此时不能再删除一次。 -
3)能。编程实践如下:
运行结果如下:
-
-
5.How can an actor turn 90 degrees to the right?
回答: 可以使用setDirection方法。编程实践如下:
编译运行结果如下:此时虫子已经向右偏离初始方向90°。
Extending the Actor Class
Set 6
-
1.Which statement(s) in the canMove method ensures that a bug does not try to move out of its grid?
回答: 根据isValid函数判断能否移动
-
2.Which statement(s) in the canMove method determines that a bug will not walk into a rock?
回答: 当neighbor == Rock时,返回false
-
3.Which methods of the Grid interface are invoked by the canMove method and why?
回答: isValid 和 get 方法。调用isValid 方法已确认下一个位置是网格中的有效位置;调用get 方法得到笑一个位置中的对象,来判断能否被Bug替代。 -
4.Which method of the Location class is invoked by the canMove method and why?
回答: getAdjacentLocation方法,被用于找到虫子当前方向下一个可能的位置。
-
5.Which methods inherited from the Actor class are invoked in the canMove method?
回答: getGrid,getLocation, getDirection 三个方法。 -
6.What happens in the move method when the location immediately in front of the bug is out of the grid?
回答: 这时虫子会将自己从grid中移除。
-
7.Is the variable loc needed in the move method, or could it be avoided by calling getLocation() multiple times?
回答: move方法中需要loc变量,loc变量存储了虫子再移动之前的位置,用于在虫子移动之后给这个位置加上一个花对象。
此时显然是不能使用getLocation() 方法的,因为在虫子移动之后,getLocation() 得到的是当前位置,无法在访问到旧位置。
-
8.Why do you think the flowers that are dropped by a bug have the same color as the bug?
回答: 更容易判断虫子的运动方向。例如当虫子的运动轨迹是一个环时,如果花的颜色都是一样的话,不能很好体现虫子在这个环上的移动方向,但是如果初始化花的颜色与虫子一样,然后随时间不断变深,就很直观看到虫子的运动轨迹和方向。 -
9.When a bug removes itself from the grid, will it place a flower into its previous location?
回答: 分两种情况。- 1)如果是直接通过调用removeSelfFromGrid() 方法来将虫子从grid中移除的话,不会留下花。查看源码(Actor.java)如下:
可以看到,并没有放入花的操作 - 2)如果是通过move() 方法来将虫子从grid中移除的话,会在之前的位置上留下一朵花。查看源码(Bug.java):
调用演示(此过程单步执行move方法):
- 1)如果是直接通过调用removeSelfFromGrid() 方法来将虫子从grid中移除的话,不会留下花。查看源码(Actor.java)如下:
-
10.Which statement(s) in the move method places the flower into the grid at the bug’s previous location?
回答: 如下所示(源码在Bug.java): -
11.If a bug needs to turn 180 degrees, how many times should it call the turn method?
回答: 4次。查看turn() 方法的源码,发现它在每次调用时只会向右旋转45°,所以想要旋转180°,就需要调用4次turn() 方法。