我正在从Allen B. Downey撰写的书中学习Java,“Think Java”。在第5章中,正在介绍GridWorld
的概念,其中你基本上有一个带有“演员”的网格10x10,例如Bug,一个Rocks和Grid本身,它们代表对象。安装代码后,GridWorld
GUI将显示一个包含两个actor的网格,一个“bug”和一个“rock”。
通过单击actor,有一个带有方法的下拉菜单,可以在该actor上调用。
其中一项任务是编写一个方法,使用名为Math.random();
的{{1}}将Bug作为参数,并将Bug的方向设置为0,90,180或270之一,是北,东,南,西,概率相等,然后如果可能的话移动bug。
接下来的任务是修改randomBug
以取整数randomBug
并重复n
次。
这是我的代码:
n
我正在尝试使用递归函数重复该过程五次,因此Bug应该移动五次,除非它到达Grid的边缘。有时会出现的问题是Bug移动了5次以上,它会产生6或10步,即使我使用条件/*
* AP(r) Computer Science GridWorld Case Study:
* Copyright(c) 2005-2006 Cay S. Horstmann (http://horstmann.com)
*
* This code is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* @author Cay Horstmann
*/
import info.gridworld.actor.ActorWorld;
import info.gridworld.actor.Bug;
import info.gridworld.actor.Rock;
/**
* This class runs a world that contains a bug and a rock, added at random
* locations. Click on empty locations to add additional actors. Click on
* populated locations to invoke methods on their occupants. <br />
* To build your own worlds, define your own actors and a runner class. See the
* BoxBugRunner (in the boxBug folder) for an example. <br />
* This class is not tested on the AP CS A and AB exams.
*/
public class BugRunner
{
public static void main(String[] args)
{
ActorWorld world = new ActorWorld();
Bug redbug = new Bug();
world.add(redbug);
System.out.println(redbug.getLocation());
world.show();
randomBug(redbug, Math.random(), 5);
}
public static void randomBug(Bug x, double y, int n){
if (y <= 0.2 && n >= 0){
x.setDirection(0);
if (x.canMove()) x.move();
} else if (y >= 0.3 && y <= 0.5 && n >= 0){
x.setDirection(90);
if (x.canMove()) x.move();
} else if (y >= 0.6 && y <= 0.8 && n >= 0){
x.setDirection(180);
if (x.canMove()) x.move();
} else {
x.setDirection(270);
if (x.canMove()) x.move();
}
randomBug(x, Math.random(), n-1);
}
}
来限制它。
我应该在代码中更改或添加什么才能完成作业?
答案 0 :(得分:0)
问题是你最后总是打电话给randomBug(x, Math.random(), n-1);
。你永远不会从方法中返回。这是一个无限循环。
要解决此问题,我会从所有分支中删除n >= 0
测试,只需在函数顶部添加此测试。
if (n < 0) return; // Or n <= 0?
这个if-test被称为递归函数的基本情况。
答案 1 :(得分:0)
首先,您应该尽可能简化代码,尝试尽可能地分离重复元素(您的代码至少有2个)。
其次,当你的n达到0时,它将失败所有检查并转到其他条件。然后它继续向那个方向前进,直到它不再存在。我很惊讶你还没有得到一个stackoverflow。
最后你的代码应该看起来像这样:
void randomBug(Bug x, double y, int n)
{
if( n <= 0 ) //separated repeated use of requirement
return;
if( [...] )
x.setDirection( ... );
else if ( [...] )
x.setDirection( ... );
[ more else ifs as needed ]
if( x.canMove() ) //separated repeated use of action
x.move();
randomBug(x, Math.random(), n-1);
}
最后,你一直在检查你的随机是否在两个值之间,在这种特殊情况下不需要:
if( y <= .25 )
// do if smaller than .25
else if( y <= .5 ) //no need to check inbetween
// do if smaller than .5
由于您的第一次检查已经确认它已经大于.25,因此无需检查第二个if语句是否也大于.25。
答案 2 :(得分:0)
这有点好吗?我试过了,看起来有效......
public static void randomBug(Bug x, double y, int n){
if (n <= 0) return;
if (y <= 0.2){
x.setDirection(0);
} else if (y <= 0.5){
x.setDirection(90);
} else if (y <= 0.8){
x.setDirection(180);
} else {
x.setDirection(270);
}
if (x.canMove()) x.move();
randomBug(x, Math.random(), n-1);
}