2013-12-07 74 views
0

有些人可能更早見過這個代碼,我繼續這樣做,現在我遇到了空指針和indexOutOfBound異常的問題。指數超出界限的錯誤有時取決於玩家的數量或手的大小。如何使線程按順序打印java

這是代碼,主要CardGame類

public class CardGame 
{ 
    static Player[] players; 
    static int handSize; 
    static Queue<Card>[] playingDeckArray; 
    static int playersNum; 

    public static void main(String[] args){ 
     Scanner reader = new Scanner(System.in); 

     System.out.println("\nHello, how many players would you like"); 
     playersNum = Integer.parseInt(Checks.userInputCheck("\\d")); 
     System.out.println("\nHow many cards should each player begin with"); 
     int handSize = Integer.parseInt(Checks.userInputCheck("\\d")); 
     System.out.println("\nWhich strategy would you like to use 1 or 2"); 
     int strategy = Integer.parseInt(Checks.userInputCheck("[12]$")); 

     Logger.createDeck(playersNum, handSize); 

     makePlayers(playersNum, handSize, strategy); 

     makePlayingDecks(playersNum); 

     dealInitialHand(playersNum, players, handSize); 

     makePlayerOutputs(); 

     //Player.startPauseThread(); 

     for (int i = 0; i < players.length; i++){ 
      logInitialHand(players[i]); 
     } 

     for (int i = 0; i < players.length; i++){ 
      isWinner(players[i]); 
     } 

     for (int i = 0; i < players.length; i++){ 
      new Thread(players[i]).start(); 
     } 
    } 

    private static void makePlayers( int noPlayers, int noCardsInHand, int strategyChosen){ 
     players = new Player[noPlayers]; 
     for(int i = 0; i < noPlayers; i++){ 
      players[i] = new Player(strategyChosen, noCardsInHand, i+1); 
      players[i].fillHand(); 
     } 

    } 

    private static void dealInitialHand(int noPlayers, Player[] players, int noCardsInHand){ 
     System.out.println("\nPlease enter the name of the deck file"); 
     File theDeck = new File (Checks.userInputCheck("deckfile.txt")); 

     int line = 0; 

     try{ 
      Scanner fileScanner = new Scanner(theDeck); 
      for(int h = 0; h < noCardsInHand; h++){ 
       for(int p = 0; p < noPlayers; p++){ 
        line = Integer.parseInt(fileScanner.nextLine()); 
        players[p].setHand(line, h); 
       } 
      } 

      for(int t = 0; t < noCardsInHand; t++){ 
       for(int i = 0; i < playingDeckArray.length; i++){ 
        line = Integer.parseInt(fileScanner.nextLine()); 
        playingDeckArray[i].add(new Card(line)); 
       } 
       } 

      }catch (Exception e) { 
      e.printStackTrace(); 
     } 

     seePlayerHands(); 
    } 

    private static void makePlayingDecks(int noPlayers){ 
     playingDeckArray = new Queue[noPlayers]; 
     for(int i = 0; i < playingDeckArray.length; i++){ 
      playingDeckArray[i] = new ConcurrentLinkedQueue<Card>(); 
      System.out.println(playingDeckArray[i]); 
     } 

    } 

    private static void seePlayerHands(){ 
     for (int i = 0; i < players.length; i++){ 
      System.out.println(players[i].getPlayerName() + "'s hand is currently"); 
      players[i].seeHand(); 
     } 
    } 

    private static void makePlayerOutputs(){ 
     for (int i = 0; i < players.length; i++){ 
      Logger.createPlayerOutputs(players[i].getPlayerName()); 
     } 
    } 

    private static void logInitialHand(Player player){ 
     Logger.addToOutput(player.getPlayerName(), (player.getPlayerName() + "'s initial hand is ")); 
     Logger.addToOutput(player.getPlayerName(), player.getHand()); 
    } 

    private static void isWinner(Player player){ 
     boolean winner = true; 
     int first = player.hand[0].getCardValue(); 

     for (Card element : player.hand) { 
      if (element.getCardValue() != first) { 
       winner = false; 
      } 
     } 

     if (winner == true){ 
      Logger.addToOutput(player.getPlayerName(), (player.getPlayerName() + " has won the game with a hand of ")); 
      Logger.addToOutput(player.getPlayerName(), player.getHand()); 
      System.out.println(player.getPlayerName() + " has won the game with a hand of "); 
      player.seeHand(); 
      System.exit(0); 
     } 
    } 
} 

Player類 公共類播放機實現Runnable { 卡[]手; String playerName; int strategyChosen; int playerNumber;

private boolean running = true; 
    private boolean paused = false; 

    public void setPaused(boolean paused){ 
     this.paused = paused; 
    } 

    public void run(){ 
     while(running){ 
      if(!paused){ 
       synchronized(this){ 
        playGame(); 
       } 
     } 
     } 
    } 

    private void playGame(){ 
     synchronized(this){ 
     switch(strategyChosen){ 
      case 1 : playStratOne(); 
      break; 
      case 2 : playStratTwo(); 
      break; 
      } 
     } 
    } 

    public static void startPauseThread(){ 
    Thread add = new Thread(pauseInputThread); 
    add.start(); 
    } 


    static Thread pauseInputThread = new Thread(){ 
    private boolean running = true; 
    private boolean paused = false; 

     public void run(){ 
      while(running){ 
       if(!paused){ 
        for(;;){ 
        System.out.println("FEED ME"); 
        Scanner reader = new Scanner(System.in); 
        String result = Checks.userInputCheck("[pPrR]$"); 
         if(result == "p"){ 
          for (int i = 0; i < CardGame.players.length; i++){ 
          CardGame.players[i].setPaused(true); 
         } 
        } 
       } 
       } 
      } 
     } 
     }; 

    private Player(){ 
    } 

    private int getPlayerNumber(){ 
     return playerNumber; 
    } 

    public Player(int strategy, int cardsInHand, int playerNumber){ 
     hand = new Card[cardsInHand]; 
     strategyChosen = strategy; 
     this.playerNumber = playerNumber; 
     playerName = "Player " + playerNumber; 
    } 

    public String getPlayerName(){ 
     return playerName; 
    } 

    public void fillHand(){ 
     for (int i = 0; i < hand.length; i++){ 
      hand[i] = new Card(0); 
     } 
    } 

    public void setHand(int value, int index){ 
     hand[index].setCardValue(value); 
    } 

    public void seeHand(){ 
     for (int i = 0; i < hand.length; i++){ 
      System.out.println(hand[i].getCardValue()); 
     } 
    } 

    public String getHand(){ 
     String result = ""; 
     for (int i = 0; i < hand.length; i++){ 
      result = result + hand[i].getCardValue() + " \n" ; 
     } 
     return result; 
    } 

    public int getHandValue(Card card){ 
     return card.getCardValue(); 
    } 

    private void playStratOne(){ 
     System.out.println("fuck"); 
    } 

    private void playStratTwo(){ 
     synchronized(this){ 
      int index = 0; 
      System.out.println(getPlayerName() + " discards a " + hand[index].getCardValue() + " to deck " + playerNumber); 
      CardGame.playingDeckArray[playerNumber-1].add(new Card(getHandValue(hand[index]))); 

      for(int i = 1; i < hand.length+1; i++){ 
       if (index == hand.length-1){ 
        hand[index] = null; 
       }else{ 
        hand[index] = hand[index+i]; 
        index = index + i; 
       } 
      } 
      if (playerNumber == 1){ 
       System.out.println(getPlayerName() + " draws a " + ((CardGame.playingDeckArray[playerNumber + CardGame.playersNum - 2].poll()).getCardValue()) + " from deck " + (CardGame.playersNum)); 
       hand[index] = CardGame.playingDeckArray[playerNumber + CardGame.playersNum - 2].poll(); 
      }else{ 
       System.out.println(getPlayerName() + " draws a " + ((CardGame.playingDeckArray[playerNumber - 2].poll()).getCardValue()) + " from deck " + (playerNumber - 1)); 
       hand[index] = CardGame.playingDeckArray[playerNumber - 2].poll(); 
      } 

      System.out.println(getPlayerName()+ "'s hand is "); 
      seeHand(); 
      for(int i = 0; i < CardGame.playingDeckArray.length; i++){ 
      } 

      checkWinner(); 
     } 
    } 

    private void checkWinner(){ 
     boolean winner = true; 
     int first = hand[0].getCardValue(); 

     for (Card element : hand) { 
      if (element.getCardValue() != first) { 
       winner = false; 
      } 
     } 

     if (winner == true){ 
      Logger.addToOutput(getPlayerName(), (getPlayerName() + " has won the game with a hand of ")); 
      Logger.addToOutput(getPlayerName(), getHand()); 
      System.out.println(getPlayerName() + " has won the game with a hand of "); 
      seeHand(); 
      System.exit(0); 
     } 
    } 
} 

的卡類

public class Card 
{ 
    int cardValue; 

    private Card(){ 
    } 

    public Card(int value){ 
     cardValue = value; 
    } 

    public void setCardValue(int value){ 
     cardValue = value; 
    } 

    public int getCardValue(){ 
     return cardValue; 
    } 

    public int getCardValue(Card card){ 
     return cardValue; 
    } 
} 

遊戲的目的是讓所有相同的值卡的手。

我想知道是否有一種方法,使線程才能打印,而且我不明白爲什麼會發生nullPointers和IndexOutOfBounds錯誤

這是一個2玩家遊戲的2手的大小結果

Hello, how many players would you like 
2 
Thank You 


How many cards should each player begin with 
2 
Thank You 


Which strategy would you like to use 1 or 2 
2 
Thank You 

The deck has been created 
It is called deckfile.txt 

Please enter the name of the deck file 
deckfile.txt 
Thank You 

Player 1's hand is currently 
1 
3 
Player 2's hand is currently 
2 
3 
Player 1 discards a 1 to deck 1 
Player 1 draws a 4 from deck 2 
Player 2 discards a 2 to deck 2 
Player 1's hand is 
Player 2 draws a 4 from deck 1 
3 
2 
Player 2's hand is 
3 
1 
Player 1 discards a 3 to deck 1 
Player 2 discards a 3 to deck 2 
Player 1 draws a 2 from deck 2 
Player 2 draws a 1 from deck 1 
Player 1's hand is 
2 
3 
Player 1 discards a 2 to deck 1 
Player 2's hand is 
1 
3 
Player 2 discards a 1 to deck 2 
Player 2 draws a 2 from deck 1 
Player 2's hand is 
3 

這給出了一個空指針異常,當我玩5人遊戲與5

Player 1's hand is currently 
1 
4 
1 
4 
8 
Player 2's hand is currently 
2 
1 
1 
3 
1 
Player 3's hand is currently 
3 
2 
10 
6 
2 
Player 4's hand is currently 
3 
7 
5 
8 
6 
Player 5's hand is currently 
4 
4 
2 
1 
4 
Player 1 discards a 1 to deck 1 
Player 2 discards a 2 to deck 2 
Player 5 discards a 4 to deck 5 
Player 3 discards a 3 to deck 3 
Player 4 discards a 3 to deck 4 

handsize我得到的indexOutOf界限例外

Exception in thread "Thread-8" Exception in thread "Thread-9" java.lang.ArrayIndexOutOfBoundsException: 6 
at Player.playStratTwo(Player.java:132) 
at Player.playGame(Player.java:38) 
at Player.run(Player.java:27) 
at java.lang.Thread.run(Thread.java:722) 

道歉,如果我問太多,但幫助將不勝感激。

回答

1

讓我們看看下面的代碼:

int index = 0; 
System.out.println(getPlayerName() + " discards a " + hand[index].getCardValue() + " to deck " + playerNumber); 
CardGame.playingDeckArray[playerNumber-1].add(new Card(getHandValue(hand[index]))); 

for(int i = 1; i < hand.length+1; i++){ 
    if (index == hand.length-1){ 
     hand[index] = null; 
    }else{ 
     hand[index] = hand[index+i]; 
     index = index + i; 
    } 
} 

所以,在for循環的開始,指數不能比0

不同的值,如果hand.length是5,說,那麼循環將從1到5 - 這是令人困惑的運行,而「我比陣列的長度還要多一個」,但這就是你所擁有的。一個潛在的問題是java數組從0開始,所以如果你的數組長度是5,那麼它的卡片數量是0-4,而不是1-5。如果將數組聲明爲6的長度,這可能是正確的。我還沒有挖掘出所有的代碼來確定你是如何聲明它的。

因此,循環運行從1到5;如果索引是4,那麼將該元素設置爲null。因此,索引1,2,3和5中的值將嘗試執行if語句的另一部分。如果它是5,那麼你最好有一個數組,它將容納索引6(長度爲7),因爲你有一個索引+ i進入數組。顯然你沒有,因爲你的錯誤消息說6是一個數組索引越界。

Java錯誤消息和堆棧跟蹤是它最有用的兩個功能。他們經常告訴你什麼是問題,以及它發現的代碼在哪裏 - 這在編程世界中並不普遍。如果您要用Java編程,請學會信任您的錯誤消息,並學會閱讀並從中獲取信息,以此作爲解決問題的出發點。另外,讓我說使用'索引'是令人困惑的 - 除了我認爲是長度爲+1的長度錯誤和長度錯誤外,它似乎仍然通過循環在「i」後面保持一個計數 - 1.如果你使用i遍歷數組元素,那麼我不能用於比較某些東西,看看你在哪裏,接下來該做什麼等,而不是使用另一個int?

最後,讓我告誡你,將數組的最後一個元素設置爲null不會縮短數組。如果你有一個5個對象的數組,並且你把最後一個設置爲null,那麼你在第5個元素中有一個數組爲null的數組,而不是數組4.我不知道你是否期望數組的長度發生改變,但你似乎有可能在這裏給出了代碼。

+0

謝謝你的回答,我覺得我已經過了複雜的teh索引,但是應該發生的是應該丟棄他們手中的第一張牌到合適的卡片隊列,這將成爲玩家1陣列中的第0個元素,玩家2的第一個元素等等。這代表放棄在他們「前方」的牌組中的玩家。然後玩家從他們後面的甲板上抽出,因此玩家2將從第一個索引中的甲板上抽取第一個索引中的玩家3,但是玩家1將從該陣列中的最後一個元素抽取,玩家5之間的最後一個甲板和1.我只是不 – user3074140

+0

明白爲什麼我得到不同數量的球員索引錯誤,當然,如果迭代是問題,我應該得到一個一致的錯誤。我還想知道設置爲null不會減小數組的大小,我只是希望玩家放棄他們手中的第一張牌,然後將剩下的牌移動填補空白,然後將最終設置爲空,那麼玩家將從甲板上抽取並放入空指數中,這是他們手中的最後一張牌。頁面感謝您的回覆 – user3074140

+0

我有建議:消除數組並使用ListArray代替。您可以從ListArray中移除一個元素,並且ListArray的長度將減1。然後調試它而不是盯着它。使用eclipse或任何合理的開發環境,設置斷點並逐步執行代碼,以瞭解值爲何會到達原來的位置。 – arcy