如何正确结束简单的纸牌游戏?

How to properly end simple card game?

我正在创建一个简单的 high/low 纸牌游戏作为我的第一个游戏模式,您需要猜测下一张纸牌是比当前纸牌高还是低。我已经将 GUI 实现为 JPanel,游戏逻辑主要位于单独的 class 中。

我的问题是我无法让游戏在 Game Over 正确停止。比如,如果猜测正确,GUI 上的分数会更新,卡片会移动到下一张。如果答案错误,显示最终得分并将 high/low 按钮替换为重新启动按钮。目前逻辑上有问题,我无法弄清楚它是什么,因为游戏似乎很随机地结束,即使答案应该是正确的,有时它没有结束,当它应该结束时。

谁能帮我找出问题所在?

通常跟踪游戏是否在 java 结束的最佳方法是什么?

这是游戏的JPanel

/*imports were here*/
public class gamePanel_highLow extends javax.swing.JPanel {

    private highLow game = new highLow();
    private boolean playedGame = false;


    /**
     * Initializes the game view and makes restart button invisible
     */
    public gamePanel_highLow() {
        initComponents();
        restartButton.setVisible(false);
    }

    /* stuff for init components made by gui editor were here */                        

    private void lowerButtonActionPerformed(java.awt.event.ActionEvent evt) {                                            
        Card card = game.getCurrentCard();        
        BufferedImage cardIMG = card.getCardImage();
        Image scaledCard = cardIMG.getScaledInstance( 90, 138,  java.awt.Image.SCALE_SMOOTH ) ;
        cardImage.setIcon(new ImageIcon(scaledCard));               
        currentCard.setText(game.getCurrentCard().toString() + " [" + game.getCurrentCard().getCardIntValue() + "]");                      

        playedGame = game.chooseLow();

            if(playedGame == true) { // maybe not best wording, as check is gameOver = true
                score.setText("---");
                cardIMG = card.getCardBackImage();
                scaledCard = cardIMG.getScaledInstance( 90, 138,  java.awt.Image.SCALE_SMOOTH ) ;
                cardImage.setIcon(new ImageIcon(scaledCard));             
                lowerButton.setVisible(false);
                higherButton.setVisible(false);
                text_or.setVisible(false);
                restartButton.setVisible(true);
                currentCard.setText(game.getCurrentCard().toString() + " [" + game.getCurrentCard().getCardIntValue() + "]" + "final score: " + game.getCurrentScore());
            }
            else {
                score.setText(game.getCurrentScore() + "");
            }
    }                                           

    private void higherButtonActionPerformed(java.awt.event.ActionEvent evt) {                                             
        Card card = game.getCurrentCard();        
        BufferedImage cardIMG = card.getCardImage();
        Image scaledCard = cardIMG.getScaledInstance( 90, 138,  java.awt.Image.SCALE_SMOOTH ) ;
        cardImage.setIcon(new ImageIcon(scaledCard));               
        currentCard.setText(game.getCurrentCard().toString() + " [" + game.getCurrentCard().getCardIntValue() + "]");                      

        playedGame = game.chooseHigh();

            if(playedGame == true) {
                score.setText("---");
                cardIMG = card.getCardBackImage();
                scaledCard = cardIMG.getScaledInstance( 90, 138,  java.awt.Image.SCALE_SMOOTH ) ;
                cardImage.setIcon(new ImageIcon(scaledCard));             
                lowerButton.setVisible(false);
                higherButton.setVisible(false);
                text_or.setVisible(false);
                restartButton.setVisible(true);
                currentCard.setText(game.getCurrentCard().toString() + " [" + game.getCurrentCard().getCardIntValue() + "]" + "final score: " + game.getCurrentScore());
            }
            else {
                score.setText(game.getCurrentScore() + "");
            }
    }                                            

    private void restartButtonActionPerformed(java.awt.event.ActionEvent evt) {                                              
        lowerButton.setVisible(true);
        higherButton.setVisible(true);
        text_or.setVisible(true);
        restartButton.setVisible(false);

        Card card = game.getCurrentCard();
        BufferedImage cardIMG = card.getCardImage();
        Image scaledCard = cardIMG.getScaledInstance( 90, 138,  java.awt.Image.SCALE_SMOOTH ) ;
        cardImage.setIcon(new ImageIcon(scaledCard));

        currentCard.setText(game.getCurrentCard().toString() + " [" + game.getCurrentCard().getCardIntValue() + "]");

        playedGame = false;
        game = new highLow();
    }

这是游戏逻辑class:

public class highLow {

      private int correctGuesses = 0;      
      private CardDeck deck;           
      private Card currentCard;
      private Card nextCard;      
      private Boolean gameOver = false;

    /**
     * Initializes the game
     */
    public highLow() {
        deck = new CardDeck();
        deck.fillDeck();
        deck.shuffleDeck();
        correctGuesses = 0;
        gameOver = false;
        currentCard = deck.dealCard();
        nextCard = null;
    }

    public Card getCurrentCard() {
        return currentCard;
    }

    public Card getNextCard() {
        return nextCard;
    }

    public int getCurrentScore() {
        return correctGuesses;
    }

    public boolean getGameOver() {
        return gameOver;
    }

    /**
     * Guesses next card is higher than current card.
     * @return If correct, add 1 to correctGuesses and return 1.
     * @return If wrong, set game over and return 0.
     */
    public boolean chooseHigh() {   

        nextCard = deck.dealCard();

        if(nextCard.getCardIntValue() > currentCard.getCardIntValue()) {
                correctGuesses++;
                gameOver = false;
        }
        else {
            gameOver = true;
        }
    currentCard = nextCard;
    return gameOver;
}    

    /**
     * Guesses next card is lower than current card.
     * @return If correct, add 1 to correctGuesses and return 1.
     * @return If wrong, set game over and return 0.
     */
    public boolean chooseLow() {

       nextCard = deck.dealCard();

        if(nextCard.getCardIntValue() < currentCard.getCardIntValue()) {
                correctGuesses++;
                gameOver = false;
        }
        else {
            gameOver = true;
        }
    currentCard = nextCard;
    return gameOver;
} 
}

当然,这是非常准系统,但我不明白为什么 gameOver 不起作用,也不知道如何修复它。 if 已经有一段时间了,但是新的修复程序破坏了其他东西。

编辑: 这是 Card class:

/*imports*/

public class Card implements Comparable {
private CardSuit  suit;
private CardValue value;
private BufferedImage image;
private static boolean sortByValue = true;

/**
 *
 * @param card_suit     Suit of the card (clubs, spades, diamonds, hearts) 
 * @param card_value    Value of the card (1-14)
 * @param card_image    Image file used in GUI
 */
public Card (CardSuit card_suit, CardValue card_value, BufferedImage card_image) {
    suit  = card_suit;
    value = card_value;
    image = card_image;
}

/**
 *
 * @return The card's suit
 */
public CardSuit getCardSuit() {
    return suit;
}

/**
 *
 * @return The card's value
 */
public CardValue getCardValue() {
    return value;
}

/**
 *
 * @param suit  Card suit for filename
 * @param value Card value for filename
 * @return The specific filename located in cardImages folder 
 */
public static String getImageFilename( CardSuit suit, CardValue value ) {
    return suit.getSuitAcronym() + value.getValueAcronym() + ".png";
}

/**
 *
 * @return Buffered image of a specific card to be used in GUI
 */
public BufferedImage getCardImage() {
    return image;
}

/**
 *
 * @return get image representing back of the card
 */
public BufferedImage getCardBackImage() {

    String imageFile = "src/main/java/cardImages/back.png";   // Stores image filename.
                BufferedImage img = null; // Initializes image as null.
                try {
                    img = ImageIO.read(new File(imageFile));    // Places proper image path to img variable
                }
                catch (IOException e) {
                    e.printStackTrace();  // Traces any errors
                }
    return img;                   
}

/**
 *
 * @return Cards value in integer form for easier comparison
 */
public int getCardIntValue() {
    return value.getCardInt();
}

/**
 *
 * @return prints suit name
 */
public String suitToString() { 
    return suit.toString();
}

/**
 *
 * @return prints card value
 */
public String valueToString() {
    return value.getValue();
}

public String toString() { //print card suit and value
    return value.toString() + " of " + suit.toString();
}

/**
 *
 * @return
 */
public String toStringWithIntegers() { //print card suit and numerical version of value
    return value.getCardInt() + " of " + suit.toString();
}

/**
 *  card sorting aid for deck and shuffle
 */
public static void sortCardsBySuit() { 
        sortByValue = false;
}

/**
 *  card sorting aid for deck and shuffle
 */
public static void sortCardsByValue() { 
        sortByValue = true;
}

/**
 *
 * @param card card object to compare with
 * @return compares suit and value to another card object.
 */
public boolean sameAs( Card card ) {
  if ( ( value != card.value ) || ( suit != card.suit ) )
     return false;
  else
     return true;
}

public int compareTo(Object otherCardObj) { //another comparison used only for sorting cards and creating a deck.
    Card otherCard = (Card) otherCardObj;
    int value_difference =  value.compareTo(otherCard.value);
    int suit_difference =   suit.compareTo(otherCard.suit);

    if ( sortByValue ) {
     if ( value_difference != 0 )
        return value_difference;
     else
        return suit_difference;
  }
  else {
     if ( suit_difference != 0 )
        return suit_difference;
     else
        return value_difference;
  }
}
}

CardValue class 为卡片赋值。 SuitValue 在这个游戏中并没有真正使用,所以很确定这里不需要:

/*imports*/

public class CardValue implements Comparable {
private String name;     // full name of value
private String acronym;  // acronym of value, used in the image files

private CardValue( String value_name, String value_acronym ) {
  name    = value_name;
  acronym = value_acronym;
}

// All card values

public final static CardValue TWO   = new CardValue("Two",   "2" );
public final static CardValue THREE = new CardValue("Three", "3" );
public final static CardValue FOUR  = new CardValue("Four",  "4" );
public final static CardValue FIVE  = new CardValue("Five",  "5" );
public final static CardValue SIX   = new CardValue("Six",   "6" );
public final static CardValue SEVEN = new CardValue("Seven", "7" );
public final static CardValue EIGHT = new CardValue("Eight", "8" );
public final static CardValue NINE  = new CardValue("Nine",  "9" );
public final static CardValue TEN   = new CardValue("Ten",   "10");
public final static CardValue JACK  = new CardValue("Jack",  "11");
public final static CardValue QUEEN = new CardValue("Queen", "12");
public final static CardValue KING  = new CardValue("King",  "13");
public final static CardValue ACE   = new CardValue("Ace",   "14");

String getValue() {
    return name;
}

/**
 *
 * @return get value acronym
 */
public String getValueAcronym() {
    return acronym;
}

/**
 *
 * @return get value as int
 */
public int getCardInt() {
    return Integer.parseInt(acronym);
}

/**
 *
 * @return print name of value eg. Jack
 */
  @Override
public String toString() {
  return name;
}

// All values in a list for comparison.

    public final static java.util.List VALUES =
  Collections.unmodifiableList( Arrays.asList( new CardValue[] { TWO, THREE, FOUR, FIVE, SIX, SEVEN,
                                                                 EIGHT, NINE, TEN, JACK, QUEEN, KING, ACE }));
@Override
public int compareTo(Object otherValueObj) {
  CardValue otherValue = (CardValue) otherValueObj;
  return VALUES.indexOf( this ) - VALUES.indexOf( otherValue );
}
}

编辑 2: 从选择 low/high 按钮中删除了新游戏,现在它只在重新启动按钮上。我还将 Rihards 的想法添加到逻辑中,但仍然无法正常运行。

布局如下:http://gyazo.com/b8b5fe50185a134cc1cf0c320d8597d1

点击 1-3 次后死亡,甚至可能只是 luck/random。

我在这里看到 2 个问题,这些问题可能会导致一些问题:

1)您正在开始发新牌

currentCard = deck.dealCard(); 
nextCard = deck.dealCard(); 

然后在选择更高或更低的时候再抽一张牌,所以浪费了一张牌。

2) 你总是检查 nextCard 作为当前卡,所以你实际上并没有在输出中看到 nextCard,你看到 CurrentCardpreviousCard

试试这个:

public boolean chooseHigh() {
        nextCard = deck.dealCard();

            if(nextCard.getCardIntValue() > currentCard.getCardIntValue()) {
                    correctGuesses++;
                    gameOver = false;
            }
            else {
                gameOver = true;
            }
        currentCard = nextCard;
        return gameOver;
    }   

并在初始化时更改:

public highLow() {
    ...
    nextCard = null;
}

编辑 1: 好的,我刚刚注意到你检查了下一张牌,但你显示了前一张牌,新牌只会在下一轮或你输了之后更新 试试这个:

    private void lowerButtonActionPerformed(java.awt.event.ActionEvent evt) {                                            

            playedGame = game.chooseLow();

                if(playedGame == true) { // maybe not best wording, as check is gameOver = true
                    score.setText("---");
                    cardIMG = card.getCardBackImage();
                    scaledCard = cardIMG.getScaledInstance( 90, 138,  java.awt.Image.SCALE_SMOOTH ) ;
                    cardImage.setIcon(new ImageIcon(scaledCard));             
                    lowerButton.setVisible(false);
                    higherButton.setVisible(false);
                    text_or.setVisible(false);
                    restartButton.setVisible(true);
                    currentCard.setText(game.getCurrentCard().toString() + " [" + game.getCurrentCard().getCardIntValue() + "]" + "final score: " + game.getCurrentScore());
                }
                else {
                    score.setText(game.getCurrentScore() + "");
                }

            Card card = game.getCurrentCard();        
            BufferedImage cardIMG = card.getCardImage();
            Image scaledCard = cardIMG.getScaledInstance( 90, 138,  java.awt.Image.SCALE_SMOOTH ) ;
            cardImage.setIcon(new ImageIcon(scaledCard));               
            currentCard.setText(game.getCurrentCard().toString() + " [" + game.getCurrentCard().getCardIntValue() + "]");    
        }