2010-10-27 49 views
0

我是编写井字游戏的开始。我只是跑了它,并得到了以下堆栈跟踪:TicTacToe游戏的OutOfBoundsException;问题:数组?

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; 
    } 
} 
+2

你可以请你格式化你的代码?选择代码,然后按编辑器顶部的100100按钮。 – shoebox639 2010-10-27 20:24:31

+0

请编辑您的帖子并修复代码格式。这将为您产生更多的反馈/答案。 [编辑]看起来像shoebox639打败了我。 – 2010-10-27 20:25:46

+0

对不起,我把它格式化了,但后来发生了什么事?现在已经修复了。 – 2010-10-27 20:26:59

回答

8

此行

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

不创建8个字符串数组(或9字符串对于这个问题,如果是这样的意图)。这将创建与最初8 容量元素的ArrayList,但是大小为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"); 
+0

谢谢!这似乎解决了这个问题! :)对于记录和这种特殊情况,它需要i <= 8或者你仍然会得到同样的错误,因为0-8排除只有8个,并且在井字游戏中有九个盒子,但只是一个小调整。再次感谢您解决我的愚蠢! – 2010-10-27 20:38:32

+0

这是一个很好的观点。我会更新我的答案:-) – aioobe 2010-10-27 20:39:28

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个实际字符串。

顺便说一下,一个井字板有9个平方,我不知道你只有8

0

创建它对于一个固定的数组的大小就像你在这里,我不知道为什么你使用ArrayList,而不仅仅是一个简单的String[]阵列?如果初始化您的数组:

String[] board = new String[9]; 

然后,您将真正能够得到任何方的价值,而不必担心被出界。

0

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

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

+0

谢谢,这有助于很多! – 2010-10-27 20:56:15

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

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

0

除了上面提到的问题,您似乎每次都会调用newBoard()方法,创建一个新的ArrayList,实际上并没有任何人如上所述。这样做没有意义。您可能希望有一个棋盘对象来检查玩家是否赢了。

1

ArrayList是一个动态结构。即使您在创建时添加了“大小”,它也不会填充数组列表。如果你想要,你可以自己填写或使用简单的数组。

其他的事情,你的countMove()函数总是返回1.因为你设置为0并且把++ OP设置为0。如果你想要这种行为只是返回1

希望这会有所帮助。 干杯。

+0

是的,我也意识到这一点......任何想法如何让每次移动都增加它?我认为如果x总是先走的话,那么他们总是会有奇怪的走势1,3,5等等......所以每当人们标记出某些东西时,它就会增加。 – 2010-10-27 20:57:50

+0

你可以有一个全局变量和countMove()仅用于增量。但是,如果您想为每个用户计数一次,则可以有一个数组,并且该数组的每个条目都是该用户的计数。 – Ron 2010-10-27 21:03:37

+0

一个更好的和优雅的解决方案是有一个类“玩家”和一个变量“移动”。每个实例将修改其局部变量,并且更“干净”。 – Ron 2010-10-27 21:05:23