2010-10-27 64 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