0

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

在此处输入图像描述

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

在此处输入图像描述

其中一项任务是编写一个方法,通过使用Math.random();randomBugBug 作为参数并将 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 应该移动五次,除非它到达网格的边缘。有时会出现的问题是,Bug 移动了 5 次以上,它做了 6 或 10 步,尽管我通过使用 condition 来限制它n <= 0

我应该在代码中更改或添加什么以便完成分配?

4

3 回答 3

0

问题是你总是randomBug(x, Math.random(), n-1);在最后打电话。您永远不会从该方法返回。这是一个无限循环。

为了解决这个问题,我会n >= 0从所有分支中删除测试,然后在函数顶部添加这个测试。

if (n < 0) return; // Or n <= 0?

此 if 测试称为递归函数的基本情况。

于 2016-11-16T12:45:52.847 回答
0

首先,你应该让你的代码尽可能的简单,尽量将重复的元素分开(你的代码至少有2个)。

其次,当您的 n 达到 0 时,它会通过所有检查并转到 else 条件。然后它继续朝着那个方向前进,直到它再也不能了。我很惊讶你还没有得到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

如果第二个 if 语句也大于 0.25,则无需检查它,因为您的第一个检查已经确认它是。

于 2016-11-16T12:48:35.543 回答
0

Is this a bit better ? I have tried it, it seems it works...

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

    }
于 2016-11-16T13:17:01.440 回答