2013-04-11 110 views
0

基本上,我正在做的是通過一副紙牌進行耐心測試,以確定耐心用完的概率,主要方法僅打印出此數字,沒有用戶系統輸入。當第一張牌被抽出時,你說「1」,第二張牌你說「2」,第三張牌「3」,然後你從第四張牌重新開始。所以它是1-2-3-1-2-3-1 -...如果你在說1時畫一個王牌,當你說2時畫一個2,當你說3時畫一個3,那麼耐心就用完了。這是通過一個總共100次(可能我將它設置爲1000)52張牌。下面是兩個類卡(創建卡)和Carddeck(創建卡片組)以及主要方法d84的實現。局部變量在聲明內部循環時無法解析,但在外部聲明時不能解析NPE

public class Card { 
public static final int SPADES = 1; 
public static final int HEARTS = SPADES + 1; 
public static final int DIAMONDS = SPADES + 2; 
public static final int CLUBS = SPADES + 3; 
private int rank; // value 
private int suit; // color 

/** Creates a card with color, suit (SPADES, HEARTS, DIAMONDS, CLUBS) 
    and value, rank (1-13) */ 
public Card(int suit, int rank) { 
    this.suit = suit; 
    this.rank = rank; 
} 

/** Gets suit */ 
public int getSuit() { 
    return suit; 
} 

/** Gets rank */ 
public int getRank() { 
    return rank; 
} 

/** Returns a readable representation of the card, e.g. "diamonds jack" */ 
public String toString(){ 
    String suitString = "";  
    switch(suit) { 
     case SPADES: suitString = "spades"; break; 
     case HEARTS: suitString = "hearts"; break; 
     case DIAMONDS: suitString = "diamonds"; break; 
     case CLUBS: suitString = "clubs"; break; 
    } 
    String rankString = ""; 
    switch(rank) { 
     case 1: rankString = "ace"; break; 
     case 11: rankString = "jack"; break; 
     case 12: rankString = "queen"; break; 
     case 13: rankString = "king"; break; 
     default: rankString = String.valueOf(rank); 
    } 
    return suitString + " " + rankString; 
} 
} 

-

import java.util.Random; 
public class CardDeck { 
private Card[] theCards; 
private int cardNbr = -1; 
public CardDeck() { 
    theCards = new Card[52]; 
    for (int suit = Card.SPADES; suit <= Card.CLUBS; suit++) { 
     for (int r = 0; r < 13; r++) { 
      theCards[r*suit] = new Card(suit, r+1); 
     } 
    } 
} 
public void shuffle() { 
    Random rand = new Random(); 
    for (int i = 0; i < 52; i++) { 
     int n = rand.nextInt(52); 
     theCards[i] = theCards[n]; 
    } 
} 
public boolean moreCards() { 
    return cardNbr < 51; 
} 
public Card getCard() { 
    cardNbr++; 
    return theCards[cardNbr]; 
}} 

-

public class d84 { 
public static void main(String[] args) { 
    int patBroke = 0; 
    for (int j = 0; j < 100; j++){ 
     CardDeck deck = new CardDeck(); 
     deck.shuffle(); 
     while (deck.moreCards() == true) { 
      int say = 1; 
      while (say <= 3) { 
       Card drawn = deck.getCard(); 
       if (say == drawn.getRank()) { 
        patBroke++; 
        break; 
       } 
      say++; 
      } 
      if (say == drawn.getRank()) { 
       break; 
      } 
     } 
    } 
    System.out.print("The probability of patience running out is " + (1-patBroke/100)); 
} 
} 

執行時,在線程 「主要」 java.lang.Error的異常:未解決的問題編譯:取用不能在d84.main解決(d84.java:17)。它被宣佈?當該子句被刪除時,編譯器在d84.java:11處指出相同的錯誤。如果Card被繪製在循環外部,那麼執行會在17或11處拋出NullPointerException。

Class Card在演講中給出,所以我不會在那裏更改任何代碼。另一方面,Carddeck是我自己的實現,主要方法d84也是我自己的代碼。

那麼,在這種情況下,我該如何避免'繪製無法解決'和NPE?

預先感謝您。

+0

這並不是一個例外,這是一個編譯器錯誤信息。 – 2013-04-11 17:41:45

回答

0

您的問題與循環本身無關,而是與{}子句中的變量範圍有關。變量不能在其聲明範圍之外被引用。

你的邏輯更改爲:

 int say = 1; 
     Card drawn = null; // Added 
     while (say <= 3) { 
      drawn = deck.getCard(); // Changed 
      if (say == drawn.getRank()) { 
       patBroke++; 
       break; 
      } 
      say++; 
     } 
     if (say == drawn.getRank()) { 
      break; 
     } 

(但也有極有可能其他問題)

+0

Card drawn = null;與卡片繪製基本相同;或者我錯了?無論如何,我得到NPE扔在drawn.getRank()行。我並沒有要求任何人仔細檢查我所謂的班級方法,但我沒有得到NPE。謝謝btw。 – Christian 2013-04-13 00:21:19

+0

@Christian - 你必須說'Card drawn = null;'因爲'drawn'否則只能在循環體內部設置,並且循環體不能保證被執行(只要編譯器可以告訴)。在聲明和最終的if中使用''之間必須有一個保證的設置。 – 2013-04-13 01:52:54