如何使用递归函数使Bug对象移动五次?

时间:2016-11-16 12:40:34

标签: java recursion gridworld

我正在从Allen B. Downey撰写的书中学习Java,“Think Java”。在第5章中,正在介绍GridWorld的概念,其中你基本上有一个带有“演员”的网格10x10,例如Bug,一个Rocks和Grid本身,它们代表对象。安装代码后,GridWorld GUI将显示一个包含两个actor的网格,一个“bug”和一个“rock”。

enter image description here

通过单击actor,有一个带有方法的下拉菜单,可以在该actor上调用。

enter image description here

其中一项任务是编写一个方法,使用名为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); } } 来限制它。

我应该在代码中更改或添加什么才能完成作业?

3 个答案:

答案 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);

    }