调试游戏逻辑

时间:2015-04-04 13:34:37

标签: java

Spec-

  

在游戏中,孩子们坐在一个圆圈中,一个人在戒指外面(领导者)唱着一首带有固定数量单词的歌曲。围绕圆圈顺时针移动,领导者指向铃声中的每个单词中的新孩子。在歌曲的最后一个单词上指出的孩子已经出局并且必须离开圆圈。然后领导者用较小的圆圈重复该过程。游戏一直持续到最后一个孩子被淘汰。这个孩子就是开始下一场比赛的领导者。

我几乎已经弄清楚了这个逻辑,但是在我的数组的索引中我找不到一个错误,我将当前元素添加到另一个数组(到显示已消除的孩子)然后从当前阵列中删除它们。

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Practice {

    public static void main(String[] args) {

        Scanner sc = new Scanner(System.in);
        System.out.println("Enter number of kids: ");
        int kidCount = sc.nextInt();
        List<Integer> kids = new ArrayList<Integer>();
        List<Integer> rejects = new ArrayList<Integer>();

        System.out.println("Enter number of words in the song: ");
        int words = sc.nextInt();

        int wordCount = 0;

        for (int i = 1; i <= kidCount; i++) {
            kids.add(i);
        }

        for (int i = 0; i < kids.size(); i++) {
            wordCount++;

            if (wordCount % words == 0) {
                rejects.add(kids.get(i));
                kids.remove(kids.get(i));

            }

            if (i == kids.size() - 1) {
                if (wordCount % words != 0) {
                    i = 0;
                } else {
                    rejects.add(kids.get(i));
                    kids.remove(kids.get(i));
                }
            }
        }
        System.out.println(rejects.toString());
    }
}

预期输出如果有6个孩子和3个字: 3 6 4 2 5 1

当前输出 [3,2,4,6]

1 个答案:

答案 0 :(得分:4)

你绕过孩子的方式是有缺陷的。你循环的方式&#34;将始终跳过小孩1,因为您在执行i=0之前立即设置了i++。另外,如果您在上次之前移除了孩子,例如孩子5,你会立即删除最后一个孩子,例如小孩6,因为kids数组的大小已经改变,你有第二个删除子句。此外,删除最后一个孩子后,即使剩下更多孩子,循环也会立即退出,只是因为它没有在i=0中为列表末尾设置else

一般情况下,你应该避免使用for这么多你弄乱柜台。 for应该代表一次通过。你想要完成的是循环,具有就地删除。事实上,你的主要错误是for的条件,因为它并不是你想要的孩子的迭代,而是循环直到只剩下一个孩子。

因此更清洁的实施:

int i = 0;
while (kids.size() > 1) { // Loop until we have a winner
    wordCount++; // Give the kid a word
    if (wordCount >= words) { // It's the last word, he's out
        rejects.add(kids.remove(i)); // Remove the kid at index i and place it into rejects
        // P.S. Small issue with ArrayList API: If your object type is Integer, then there's ambiguity between remove(T) and remove(int), which will prevent auto boxing from being used
        wordCount = 0; // And from the top
    }
    else {
        i++; // This kid is okay, move to the next
        // P.S. If we removed the kid, we're already pointing at the next one, hence the "else"
    }
    if (i >= kids.size()) { // Reached the end of the kids list
        i = 0; // Loop around
    }
}