2016-12-28 51 views
0

在我的空閒時間開發一個簡單的自動生成戰爭遊戲時,我遇到了一個「StackOverFlow」錯誤。有關如何解決此堆棧溢出錯誤的任何建議? Java

這是我的Deck類錯誤發生的地方: 它發生在我的compare()方法中。任何關於我能做些什麼來避免這個錯誤的見解都是可以接受的,因爲我很難理解可以做些什麼來解決這個問題,並且對於這個錯誤甚至意味着什麼除了我的課程沒有很好地完成遞歸之外幾乎沒有什麼知識。謝謝!

import java.util.*; 
import java.math.*; 
public class Deck 
{ 
    private int num = 0; 
    private int cardnum2 = 0; 
    private int cardnum = 0; 
    private int decrease = 0; 
    private int rnd = 0; 
    private int winner = 0; 
    private String suit = " "; 
    private int suitNum = 0; 
    private int val = 1; 
    private String name = ""; 
    private ArrayList<Card> Deck = new ArrayList<Card>(); 
    private Card[] cardCheck = new Card[51]; 
    private ArrayList<Card> play1 = new ArrayList<Card>(); 
    private ArrayList<Card> play2 = new ArrayList<Card>(); 
    public Deck() 
    { 
     createDeck(); 
    } 
    public void createDeck() 
    { 
     for(int i = 0; i < 4; i++) 
     { 
      val = 1; 
      suit = " "; 
      name = " "; 
      suitNum++; 
      System.out.println(); 
      System.out.println(); 
      for(int z = 0; z < 13; z++) 
      { 
       if(suitNum == 1) 
       { 
        suit = "Hearts"; 
       } 
       if(suitNum == 2) 
       { 
        suit = "Diamonds"; 
       } 
       if(suitNum == 3) 
       { 
        suit = "Spades"; 
       } 
       if(suitNum == 4) 
       { 
        suit = "Clubs"; 
       } 
       if(val == 1) 
       { 
        name = "Ace"; 
       } 
       else if(val == 11) 
       { 
        name = "Jack"; 
       } 
       else if(val == 12) 
       { 
        name = "Queen"; 
       } 
       else if(val == 13) 
       { 
        name = "King"; 
       } 
       else { 
        name = ""; 
       } 
       Card myCards = new Card(val, suit, name); 
       Deck.add(myCards); 
       System.out.print(myCards + " "); 
       val++; 
      } 
     } 
    } 
     public void Deal() 
     { 
      int size = 52/2; 
      for(int i = 0; i < size; i++) 
      { 
        Random(); 
        for(int z = 0; z < cardCheck.length; z++) 
        { 
         if(cardCheck[i] == null) 
         { 
          cardCheck[i] = Deck.get(rnd); 
          play1.add(cardCheck[i]); 
          System.out.println(play1); 
         } 
         else 
         { 
          Random(); 
         } 
        } 
      } 
      System.out.println(); 
      System.out.println(); 
      for(int i = 0; i < size; i++){ 
       Deck.remove(play1.get(i)); 
      } 
       for(int i = 0; i < size; i++){ 
        play2.add(Deck.get(i)); 
      } 
      for(int i = 0; i < size; i++) 

      { 
       System.out.println(play2.get(i)); 
      } 
    } 
    public void Random() 
    { 
     rnd = (int)(Math.random() * 52) - decrease; 
    } 

    public void flip() 
    { 
     if(play1.indexOf(cardnum) >= play1.size() || play2.indexOf(cardnum2) >= play2.size()) 
     { 
     cardnum = (int)(Math.random() * play1.size()); 
     System.out.println(play1.get(cardnum)); 
     cardnum2 = (int)(Math.random() * play2.size()); 
     System.out.println(play2.get(cardnum2)); 
     } 
    } 
    public void compare() 
    { 
     System.out.println("War!!!\n"); 
     if(play1.get(cardnum).getNum() > play2.get(cardnum2).getNum()) 
     { 
      System.out.println(); 
      winner = 1; 
      System.out.println(play1.get(cardnum) + " vs " + play2.get(cardnum2)); 
      play1.add(play2.get(cardnum2)); 
      play2.remove(cardnum2); 
      System.out.println("Player 1 took the cards!"); 
      System.out.println(); 
      printDecks(); 
     } 
     if(play1.get(cardnum).getNum() < play2.get(cardnum2).getNum()) 
     { 
      System.out.println(); 
      winner = 2; 
      System.out.println(play1.get(cardnum) + " vs " + play2.get(cardnum2)); 
      play2.add(play1.get(cardnum)); 
      play1.remove(cardnum); 
      System.out.println("Player 2 took the cards!"); 
      System.out.println(); 
      printDecks(); 
      } 
     if(play1.get(cardnum).getNum() == play2.get(cardnum2).getNum()) 
     { 
      System.out.println(); 
      System.out.println(play1.get(cardnum) + " vs " + play2.get(cardnum2)); 
      System.out.println("War!!"); 
      winner = 0; 
      flip(); 
      flip(); 
      flip(); 
      compare(); 
      System.out.println(); 
      printDecks(); 
     } 
     } 

    public void playW() 
    { 
     while(play1.size() > 0 || play2.size() > 0) 
     { 
      flip(); 
      compare(); 
     } 
    } 
    public void printDecks() 
    { 
     for(int i = 0; i < play1.size(); i++) 
     { 
      System.out.print(play1.get(i) + " "); 
     } 
     System.out.println(); 
     for(int i = 0; i < play2.size(); i++) 
     { 
      System.out.print(play2.get(i) + " "); 
     } 
     System.out.println(); 
     System.out.println("Player 1 has: " + play1.size() + " cards"); 
     System.out.println("Player 2 has: " + play2.size() + " cards"); 
    } 
} 
+3

是的,不叫'比較()'*** ***內的'比較()'方法。另外你爲什麼要給一個類Deck,一個同名的字段Deck ArrayList?這會混淆我們所有人以及未來 - 你。 –

+0

話雖如此,你的整個程序結構爲你胡亂混合的用戶界面與您的主要結構類型的破碎。重新編寫此代碼,並從Deck中獲取用戶界面。 –

+0

@HovercraftFullOfEels很抱歉的名字....我是新來的Java,並建立了我需要打破一些可憐的習慣:/所以,你會建議我寫一個單獨的方法的情況下有戰爭,用我比較( )方法在那裏?謝謝,這是我第一次完全獨立的項目,我沒有計劃就太多了,但至少它一直是學習經驗:) – RyanWantsToLearn

回答

1

並沒有什麼知識,什麼這個錯誤甚至意味着除了我的類沒有遞歸做得很好。

是的,你的代碼有遞歸,而且很容易找到。你知道這個問題來自於比較方法,所以你所要做的就是在compare()的範圍內查找該方法,並找出你正在調用方法的地方。

解決方法是不在本身內部調用方法,爲什麼它應該這樣做呢?

您遇到問題的部分原因是您的班級結構中斷。甲板類是應該代表一副牌的結構和行爲的類,只不過是一種類似的東西,它應該有像public void shuffle()這樣的方法,如public Card Deal()等等。它不應該有任何直接與用戶交互的代碼,並且這些代碼應該放在其他地方,可能在你的驅動程序或Game類中,或者甚至完全是單獨的類。

我猜你還想要一個Hand類,一個持有玩家的手,也許在這個類的內部,有一個比較方法,比較當前Hand和另一個Hand,並傳入一個參數。

你還想要一個遊戲類應該有一個遊戲循環來控制遊戲,當有贏家或平局,持有甲板,持有一個或多個球員對象時結束......

例如,

public enum Suit { 
    CLUBS, DIAMONDS, HEARTS, SPADES 
} 

public enum Value { 
    //.... 
}  

public class Card { 
    private Suit suit; 
    private Value value; 

    // TODO: constructor, methods including equals, hashCode 
} 

public class Deck { 
    private List<Card> cards = new ArrayList<>(); 

    public Card deal() { 
     return cards.remove(0); 
    } 

    public void shuffle() { 
     Collection.shuffle(cards); 
    } 

    //.... 

} 

class Player { 
    // either use a List in each Player or create a class called hand 
    private List<Card> hand; 
    private int cash; 
    private String name; 
    private Game game; 

    // TODO: constructor 
    // TODO: methods including receiveCard(Card c), List<Card> showHand(),... 
} 

public class Game { 
    private Player p1; 
    private Player p2; 
    private Deck deck; 
    private int moneyPot; 
+0

謝謝!我感到有點沮喪,但我認爲我可以重新啓動並快速加速。良好的學習曲線,我認爲這將激發我繼續改進的動力。 – RyanWantsToLearn

+0

讓項目略高於你的能力是最好的進步方式。不要猶豫,向其他開發者展示你的代碼,以幫助你修復你的壞習慣。祝你好運。 – Sharcoux

1

這更是一個評論,但它變得太長。

對此代碼有很多話要說。使用開關盒而不是系列if。或者至少在其他情況下使用。如果你在裏面使用case,for循環的重點是什麼?如果你隨後增加一個suitNum變量,那麼'i'變量是什麼?不要使用大寫字母作爲方法。只有班。爲什麼隨機編輯一個變量並返回void?這將是更合乎邏輯的隨機()返回你想要的結果,這樣你會得到免費的無用變量「RND」

的還有很多更多的話要說,但它是一個良好的開端。簡而言之,關於你的錯誤,堆棧溢出意味着你的程序使用了太多的內存。這在包含無限遞歸循環的代碼中尤爲常見。在這裏,無限遞歸是由於所謂的比較方法中比較方法......