如何使用递归函数使 Bug 对象移动五次?
How to make Bug object move five times using recursive function?
我正在从 Allen B. Downey "Think Java" 写的书中学习 Java。在第 5 章中,介绍了 GridWorld
的概念,您基本上有一个 10x10 的网格,其中 "actors" 例如 Bug、Rocks 和 Grid 本身,它代表对象。安装代码后,GridWorld
GUI 将显示一个包含两个角色的网格,一个 "bug" 和一个 "rock"。
点击演员,会出现一个带有方法的下拉菜单,可以调用该演员。
其中一项作业是通过使用名为 randomBug
的 Math.random();
编写一个方法,该方法将 Bug 作为参数并将 Bug 的方向设置为 0、90、180 或 270 之一,即北、东、南、西,以相等的概率,然后如果可以的话移动虫子。
下一个作业是修改randomBug
取一个整数n
并重复n
次。
这是我的代码:
/*
* 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);
}
}
我正在尝试使用递归函数重复这个过程五次,所以 Bug 应该移动五次,除非它到达 Grid 的边缘。有时会出现的问题是 Bug 移动超过 5 次,它移动 6 或 10 步,即使我使用条件 n <= 0
限制了它。
我应该在代码中更改或添加什么才能完成作业?
问题是你总是在最后调用 randomBug(x, Math.random(), n-1);
。你永远 return 从方法。这是一个无限循环。
要解决这个问题,我会从所有分支中删除 n >= 0
测试,然后将此测试添加到函数的顶部。
if (n < 0) return; // Or n <= 0?
这个 if 测试称为递归函数的基本情况。
首先,你应该让你的代码尽可能简单,尽量把重复的元素分开(你的代码至少有2个)。
其次,当您的 n 达到 0 时,它无法通过所有检查并转到 else 条件。然后它继续朝那个方向前进,直到它不能再前进。我很惊讶你还没有得到 Whosebug。
最后你的代码应该看起来像这样:
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
如果第二个 if 语句也大于 .25,则无需检查第二个 if 语句,因为您的第一个检查已经确认它是。
这样好一点吗?我试过了,好像还行...
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);
}
我正在从 Allen B. Downey "Think Java" 写的书中学习 Java。在第 5 章中,介绍了 GridWorld
的概念,您基本上有一个 10x10 的网格,其中 "actors" 例如 Bug、Rocks 和 Grid 本身,它代表对象。安装代码后,GridWorld
GUI 将显示一个包含两个角色的网格,一个 "bug" 和一个 "rock"。
点击演员,会出现一个带有方法的下拉菜单,可以调用该演员。
其中一项作业是通过使用名为 randomBug
的 Math.random();
编写一个方法,该方法将 Bug 作为参数并将 Bug 的方向设置为 0、90、180 或 270 之一,即北、东、南、西,以相等的概率,然后如果可以的话移动虫子。
下一个作业是修改randomBug
取一个整数n
并重复n
次。
这是我的代码:
/*
* 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);
}
}
我正在尝试使用递归函数重复这个过程五次,所以 Bug 应该移动五次,除非它到达 Grid 的边缘。有时会出现的问题是 Bug 移动超过 5 次,它移动 6 或 10 步,即使我使用条件 n <= 0
限制了它。
我应该在代码中更改或添加什么才能完成作业?
问题是你总是在最后调用 randomBug(x, Math.random(), n-1);
。你永远 return 从方法。这是一个无限循环。
要解决这个问题,我会从所有分支中删除 n >= 0
测试,然后将此测试添加到函数的顶部。
if (n < 0) return; // Or n <= 0?
这个 if 测试称为递归函数的基本情况。
首先,你应该让你的代码尽可能简单,尽量把重复的元素分开(你的代码至少有2个)。
其次,当您的 n 达到 0 时,它无法通过所有检查并转到 else 条件。然后它继续朝那个方向前进,直到它不能再前进。我很惊讶你还没有得到 Whosebug。
最后你的代码应该看起来像这样:
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
如果第二个 if 语句也大于 .25,则无需检查第二个 if 语句,因为您的第一个检查已经确认它是。
这样好一点吗?我试过了,好像还行...
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);
}