TicTacToe游戏的OutOfBoundsException;问题:数组?

时间:2010-10-27 20:23:31

标签: java arrays exception-handling arraylist

我是写一个井字游戏的开始。我刚刚运行它并获得了以下堆栈跟踪:

 Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
 at java.util.ArrayList.rangeCheck(ArrayList.java:571)
 at java.util.ArrayList.get(ArrayList.java:349)
 at TicTacToe.isMarked(TicTacToe.java:23)
 at TicTacToe.mark(TicTacToe.java:59)
 at TicTacToe.main(TicTacToe.java:7)

我怀疑我的ArrayList设置方式有问题吗?我在某处读到了导致问题的空值,但这是我第一次处理数组,所以我不熟悉这个主题。无论如何,这是我的代码:

    import java.util.*;

    public class TicTacToe {

    public static void main(String[] args) {
    newBoard();
    ******************System.out.println(mark(1));************
    System.out.println(mark(5));
    System.out.println(mark(9));
   }

 // Creates a blank board.
 public static ArrayList<String> newBoard() {
  ArrayList<String> board = new ArrayList<String>(8);
  return board;
 }

 // Returns true if the square has been marked.
 public static boolean isMarked(int numberOfSquare) {
  if (numberOfSquare > 9 || numberOfSquare < 1) {
   throw new IllegalArgumentException("Input a valid square number.");
  }
  ************if (newBoard().get(numberOfSquare - 1) == null) {***********
   return false;
  } else
   return true;
 }

 // Returns the number of moves that have been made.
 public static int moveCount() {
  return countMove();
 }

 // If called, adds 1 to number of moves.
 public static int countMove() {
  int moveNumber = 0;
  moveNumber++;
  return moveNumber;
 }

 // Checks for a win at the specified array location and player (X or O).
 public static boolean checkForWin(int x, int y, int z, int player) {
  if (player == 0) {
   return (newBoard().get(x)).equals("O")
     && (newBoard().get(y)).equals("O")
     && (newBoard().get(y)).equals("O");
  } else {
   return (newBoard().get(x)).equals("O")
     && (newBoard().get(y)).equals("O")
     && (newBoard().get(y)).equals("O");
  }
 }

 // Places an X or O on the specified square.
 public static boolean mark(int markSquareNumber) {
  if (markSquareNumber > 9 || markSquareNumber < 1) {
   throw new IllegalArgumentException("Input a valid square number.");
  }
  ***********if (isMarked(markSquareNumber)) {*******************
   throw new IllegalArgumentException("Square is already marked.");
  }
  if (moveCount() % 2 != 0) {
   newBoard().add(markSquareNumber - 1, "X");
   countMove();
  } else {
   newBoard().add(markSquareNumber - 1, "O");
   countMove();
  }
  if (checkForWin(0, 1, 2, 1) || checkForWin(3, 4, 5, 1)
    || checkForWin(6, 7, 8, 1)) {
   System.out.println("Player-X just won horizontally!");
   return true;
  } else if (checkForWin(0, 3, 6, 1) || checkForWin(1, 4, 7, 1)
    || checkForWin(2, 5, 8, 1)) {
   System.out.println("Player-X just won vertically!");
   return true;
  } else if (checkForWin(0, 4, 5, 1) || checkForWin(2, 4, 6, 1)
    || checkForWin(0, 4, 8, 1)) {
   System.out.println("Player-X just won diagonally!");
   return true;
  }
  if (checkForWin(0, 1, 2, 0) || checkForWin(3, 4, 5, 0)
    || checkForWin(6, 7, 8, 0)) {
   System.out.println("Player-O just won horizontally!");
   return true;
  } else if (checkForWin(0, 3, 6, 0) || checkForWin(1, 4, 7, 0)
    || checkForWin(2, 5, 8, 0)) {
   System.out.println("Player-O just won vertically!");
   return true;
  } else if (checkForWin(0, 4, 5, 0) || checkForWin(2, 4, 6, 0)
    || checkForWin(0, 4, 8, 0)) {
   System.out.println("Player-O just won diagonally!");
   return true;
  } else
   return false;
 }
}

我只是通过堆栈跟踪中出现的行放了一大堆星号。如果有人能够指出我出错的地方那将是出色的,谢谢!

好的,这是我提出的所有精彩输入后我想出的解决方案:(请仅将其用于教育和参考目的,如果您在教学和参考目的,我不想被我的教授大吼大叫我的CS1410课你复制我!!!!)

//Written by JTN for Assignment7.3- CS1410; October 2010. 
import java.util.*;

public class TicTacToe {
private static int moveNumber = 0;
private static ArrayList<String> board = new ArrayList<String>(8);
    public static void main(String[] args) {
        newBoard();
        mark(1);mark(2);
        mark(5);mark(3);
        mark(9);
        boardString();
    }
    // Returns the number of moves that have been made.
    public static int moveCount() {
        return (countMove()-1);
    }

    // If called, adds 1 to number of moves.
    public static int countMove() {
        moveNumber= moveNumber + 1;
        return moveNumber;
    }
    // Creates a blank board.
    public static ArrayList<String> newBoard() {
        for (int i = 0; i <= 8; i++)
            board.add("_");
        return board;
    }

    // Returns true if the square has been marked.
    public static boolean isMarked(int numberOfSquare) {
        if (numberOfSquare > 9 || numberOfSquare < 1) {
            throw new IllegalArgumentException("Input a valid square number.");
        }
        if ((board.get(numberOfSquare - 1)).equals("_")) {
            return false;
        } else
            return true;
    }



    // Checks for a win at the specified array location and player (X or O).
    public static boolean checkForWin(int x, int y, int z, int player) {
        if (player == 0) {
            return     (board.get(x)).equals("O")
                    && (board.get(y)).equals("O")
                    && (board.get(z)).equals("O");
        } 
        else {
            return     (board.get(x)).equals("X")
                    && (board.get(y)).equals("X")
                    && (board.get(z)).equals("X");
        }
    }

    // Places an X or O on the specified square.
    public static boolean mark(int markSquareNumber) {
        if (markSquareNumber > 9 || markSquareNumber < 1) {
            throw new IllegalArgumentException("Input a valid square number.");
        }
        if (isMarked(markSquareNumber)) {
            throw new IllegalArgumentException("Square is already marked.");
        }       
        if ((countMove() % 2) == 0){
            board.set(markSquareNumber - 1, "O");
        }
        else {
            board.set(markSquareNumber - 1, "X");
        } 

        if (checkForWin(0, 1, 2, 1) || checkForWin(3, 4, 5, 1)
                || checkForWin(6, 7, 8, 1)) {
            System.out.println("Player-X just won horizontally!");
            return true;
        } else if (checkForWin(0, 3, 6, 1) || checkForWin(1, 4, 7, 1)
                || checkForWin(2, 5, 8, 1)) {
            System.out.println("Player-X just won vertically!");
            return true;
        } else if (checkForWin(0, 4, 5, 1) || checkForWin(2, 4, 6, 1)
                || checkForWin(0, 4, 8, 1)) {
            System.out.println("Player-X just won diagonally!");
            return true;
        }
         else if (checkForWin(0, 1, 2, 0) || checkForWin(3, 4, 5, 0)
                || checkForWin(6, 7, 8, 0)) {
            System.out.println("Player-O just won horizontally!");
            return true;
        } else if (checkForWin(0, 3, 6, 0) || checkForWin(1, 4, 7, 0)
                || checkForWin(2, 5, 8, 0)) {
            System.out.println("Player-O just won vertically!");
            return true;
        } else if (checkForWin(0, 4, 5, 0) || checkForWin(2, 4, 6, 0)
                || checkForWin(0, 4, 8, 0)) {
            System.out.println("Player-O just won diagonally!");
            return true;
        } else
            return false;
    }

    public static String boardString(){
        String row1 = board.get(0)+"|"+board.get(1)+"|"+board.get(2);
        String row2 = board.get(3)+"|"+board.get(4)+"|"+board.get(5);
        String row3 = board.get(6)+"|"+board.get(7)+"|"+board.get(8);
        System.out.println(row1);
        System.out.println(row2);
        System.out.println(row3);
        return row1+row2+row3;
    }
}

8 个答案:

答案 0 :(得分:8)

这一行

ArrayList<String> board = new ArrayList<String>(8);

将不会创建一个包含8个字符串的数组(或者就此而言是9个字符串,如果这是意图)。它将创建一个ArrayList,其初始容量为8个元素,但大小为0。

在为电路板创建ArrayList之后,您必须使用add - 方法填充元素。尝试做类似的事情:

public static ArrayList<String> newBoard() {
    ArrayList<String> board = new ArrayList<String>(8);
    for (int i = 0; i < 9; i++)
        board.add("");
    return board;
}

消息Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0表示您正在尝试访问长度为0的列表中的第0个元素(在没有元素的列表中)。

此外,以下一行:

newBoard().add(markSquareNumber - 1, "X");

应该是

newBoard().set(markSquareNumber - 1, "X");

答案 1 :(得分:2)

看起来没有列表的初始人口。您正在尝试访问不存在的元素。

答案 2 :(得分:2)

从无格式代码的墙上,我想我知道你的问题。

public static ArrayList newBoard() { 
    ArrayList board = new ArrayList(8); 
    return board; 
}

不会在arraylist中初始化任何内容。它当前为空,有0个对象。这就是你想要的。

public static ArrayList newBoard() { 
    ArrayList<String> board = new ArrayList<String>();
    for (int i = 0; i < 9; i++) {
        board.add("");
    }
    return board; 
}

我怀疑为什么你不只是使用String[],在这种情况下new String[9]将创建9个实际的字符串。

顺便说一句,一个tic tac toe board有9个方块,我不知道你用8创建了它。

答案 3 :(得分:1)

ArrayList是一种动态结构。即使你在创建它时设置了“大小”,它也不会填充arraylist。如果您愿意,可以自己填写或使用简单的数组。

另外,你的countMove()函数总是返回1.因为你设置0并且将++ OP也应用到0。如果你想要那个行为,只需返回1

希望这会有所帮助。 欢呼声。

答案 4 :(得分:0)

对于像这里一样的固定数组大小,我不确定为什么你使用的是ArrayList,而不仅仅是一个简单的String[]数组?如果使用以下命令初始化数组:

String[] board = new String[9];

然后你实际上可以获得任何方格的价值,而不必担心超出范围。

答案 5 :(得分:0)

每次尝试从newBoard()获取元素时,您都在调用ArrayList<String>函数。每次都会返回一个空的ArrayList<String>

您需要初始化列表,然后在该变量上调用get函数。其他答案解释了这个。

答案 6 :(得分:0)

newBoard().get(numberOfSquare - 1) == null)

每次调用newBoard()方法时,都会创建一个没有元素的新ArrayList对象。 如果您尝试在空ArrayList上获得某些内容,则会获得IndexOutOfBoundsException

答案 7 :(得分:0)

除了上述问题之外,您似乎每次都调用一个newBoard()方法,创建一个新的ArrayList,实际上并没有像上面人们所说的那样。这样做没有意义。你可能想要一个棋盘对象来检查玩家是否赢了。