有关如何解决此Stack Overflow错误的任何建议? Java的

时间:2016-12-28 02:17:48

标签: java arrays memory-management stack-overflow

在我的空闲时间开发一个简单的自动生成战争游戏时,我遇到了#34; StackOverFlow"错误。

这是发生错误的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");
    }
}

2 个答案:

答案 0 :(得分:1)

  

并且几乎不知道这个错误甚至意味着什么,除了我的班级没有很好地进行递归。

是的,您的代码有递归,而且很容易找到。您知道问题来自于compare方法,所以您需要做的就是在compare()的方法中查找并找出您自己调用方法的位置。

解决方案不是在自己内部调用方法,为什么要这样做呢?

你的问题部分是因为你的班级结构被打破了。 Deck类是应该代表一副牌的结构和行为的类,仅此而已,它应该有像public void shuffle()这样的方法,如public Card Deal()等。它不应该有任何直接与用户交互的代码,并且此代码应该在其他地方,可能在您的驱动程序或Game类中,或者甚至完全作为单独的类。

我猜你也想拥有一个Hand类,一个拥有玩家的手,也许在这个类的内部,有一个比较当前手的比较方法用另一只手,作为参数传入。

你还想要一个游戏类应该有一个控制游戏的游戏循环,当有胜利者或抽奖时结束,持有甲板,持有1个或多个玩家对象... < / p>

例如,

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;

答案 1 :(得分:1)

这是一个评论,但它变得太长了。

关于这段代码有很多话要说。使用switch case而不是if系列。或者至少使用if else。如果你在里面使用案例,那么for循环有什么意义呢?如果你自己增加一个suitNum变量,那么'i'变量是什么?不要使用大写字母表示方法。只有课程。为什么Random编辑变量并返回void? random()返回你想要的结果更合乎逻辑,这样你就可以摆脱无用的变量'rnd'

还有很多话要说,但这是一个好的开始。关于您的错误,简而言之,堆栈溢出意味着您的程序使用了太多内存。这在包含无限递归循环的代码中尤为常见。这里,无限递归是由比较方法中调用的compare方法...

引起的