0

我希望有人可以帮助我解决IndexOutOfBoundsException错误。

我可以设置一个区域内的单位数量,我可以设置该区域的所有者,但是防御功能会导致问题。

痕迹:

Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.RangeCheck(ArrayList.java:547)
at java.util.ArrayList.get(ArrayList.java:322)
at stackOverflow.Territory.calculateLoses(Territory.java:136)
at stackOverflow.Territory.defend(Territory.java:95)
at stackOverflow.Territory.defend(Territory.java:40)
at stackOverflow.Territory.main(Territory.java:155)



import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public enum Territory {

// Europe
GREATBRITAIN("Great Britain"), ICELAND("Iceland");

private final String name;
private int numberOfUnits;
private Player player;
private int ad = 0, dd = 0;

private Territory(String name) {
    this.name = name;
    this.numberOfUnits = 0;
    this.player = null;
}

public void setOwner(Player p) {
    this.player = p;
}

public Player getOwner() {
    return this.player;
}

public int getNumberUnits() {
    return this.numberOfUnits;
}

public void setNumberUnits(int units) {
    this.numberOfUnits = units;
}

public boolean defend(Territory attacker) throws Exception {
    return defend(attacker, attacker.numberOfUnits - 1);
}

public boolean defend(Territory attacker, int attackingUnits)
        throws Exception {
    if (attackingUnits > (attacker.getNumberUnits() - 1)) {
        throw new Exception("Invalid number of units");
    }

    attacker.setNumberUnits(attacker.numberOfUnits - attackingUnits);
    Player defender = this.player;
    this.player = null;
    int defendingUnits = this.numberOfUnits;
    this.numberOfUnits = 0;

    if (this.numberOfUnits >= 3 && defendingUnits >= 2) {
        ad = 3;
        dd = 2;
    }
    if (this.numberOfUnits >= 3 && defendingUnits == 1) {
        ad = 3;
        dd = 1;
    }
    if (this.numberOfUnits == 2 && defendingUnits >= 2) {
        ad = 2;
        dd = 2;
    }
    if (this.numberOfUnits == 2 && defendingUnits == 1) {
        ad = 2;
        dd = 1;
    }
    if (this.numberOfUnits == 1 && defendingUnits >= 2) {
        ad = 1;
        dd = 2;
    }
    if (this.numberOfUnits == 1 && defendingUnits == 1) {
        ad = 1;
        dd = 1;
    }
    if (this.name == "Great Britan" || this.name == "Central America"
            || this.name == "Argentina" || this.name == "Egypt"
            || this.name == "Western Australia" || this.name == "India") {
        dd++;
    }

    List<Die> attackerDice = createDice(ad);
    List<Die> defenderDice = createDice(dd);
    System.out.printf("Attacker: %d \tDefender: %d\n", attackingUnits,
            defendingUnits);
    while (attackingUnits > 0 && defendingUnits > 0) {
        roll(attackerDice);
        System.out.println(attackerDice);
        roll(defenderDice);
        System.out.println(defenderDice);

        attackingUnits -= calculateLoses(attackerDice, defenderDice, false);
        defendingUnits -= calculateLoses(defenderDice, attackerDice, true);

        System.out.printf("Attacker: %d \tDefender: %d\n", attackingUnits,
                defendingUnits);
    }

    if (defendingUnits > 0) {
        this.player = defender;
        this.numberOfUnits = defendingUnits;
        return true;
    } else if (attackingUnits > 0) {
        this.numberOfUnits = attackingUnits;
        this.player = attacker.player;
        return false;
    } else {
        // No one owns the territory as all units died
        return false;
    }
}

private List<Die> createDice(int number) {
    List<Die> dice = new ArrayList<Die>();
    for (int i = 0; i < number; i++) {
        dice.add(new Die());
    }
    roll(dice);
    return dice;
}

private void roll(List<Die> dice) {
    for (Die d : dice) {
        d.roll();
    }
    Collections.sort(dice);
}

private int calculateLoses(List<Die> diceOne, List<Die> diceTwo,
        boolean defender) {
    int number = 0;
    for (int i = 0; i < 2; i++) {
        int comparison = diceOne.get(i).compareTo(diceTwo.get(i));
        if (comparison > 0 || (!defender && comparison == 0)) {
            number++;
        }
    }
    return number;
}

String units()
{
    return "" + numberOfUnits;
}

public static void main(String[] args) throws Exception
{
    Territory.GREATBRITAIN.setNumberUnits(5);
    System.out.println(Territory.GREATBRITAIN.getNumberUnits());
    Territory.ICELAND.setNumberUnits(5);
    System.out.println(Territory.ICELAND.getNumberUnits());
    Territory.GREATBRITAIN.defend(Territory.ICELAND);
}
}
4

2 回答 2

6

看起来其中一个addd两个都是 0。

鉴于此代码,这是有道理的:

this.numberOfUnits = 0;

// Lots of these, all requiring numberOfUnits to be greater than 0
if (this.numberOfUnits >= 3 && ...)
{
    ad = ...;
    dd = ...;
}

if当您刚刚设置numberOfUnits为 0时,您如何期望进入任何这些块?

这只是您的代码中的问题之一。其他人指出了风格或正确性的其他方面。我不打算在这里修复你所有的代码——但你应该分析一下你自己是如何诊断出来的。例如,您是否尝试过在调试器中单步执行代码?

于 2013-04-10T21:01:11.477 回答
2

这段代码是错误的:

if (this.name == "Great Britan" || this.name == "Central America"
        || this.name == "Argentina" || this.name == "Egypt"
        || this.name == "Western Australia" || this.name == "India") {
    dd++;
}

用于this.name.equals("Great Britain")测试字符串是否包含相同的字符,而不是它们是否存储在内存中的相同位置。

此外,您的许多单独的if陈述看起来像是不好的做法;使用else或其他东西来检查您至少击中了一个案例 - 设置后您显然没有击中任何一个this.numberOfUnits >= [stuff]案例this.numberOfUnits = 0;

于 2013-04-10T21:04:33.337 回答