c++ - 几次(非常好)迭代后循环崩溃/损坏

标签 c++ arrays pointers for-loop

我正在为一个学校项目开发一个程序,该项目旨在输出二十一点游戏中的所有纸牌值,并告诉您有关这些纸牌的一些可能组合的一些信息。

循环旨在将一张牌放入手中并检查一些不同的可能性,然后再放入另一张牌并执行相同的操作,当它达到五张牌时,它会清除手牌并移动到一组新的牌值,直到它已用完牌组中的所有牌。

现在,每四张和第五张卡片在循环过程中都会以某种方式损坏。请记住,虽然我正在使用指针、数组和类(以及更多),但我仍然不完全理解一切在做什么,即使通读了“C++ Early Objects Eighth edition”一书直到第 10 章.

这是发生的输出示例,它表明记分员正在正确计分,但放入手牌的牌在循环的第五次迭代中开始变得困惑,这似乎反射(reflect)在分数。

AC 2C 3C 4C 5C 6C 7C 8C 9C TC JC QC KC

AH 2H 3H 4H 5H 6H 7H 8H 9H TH JH QH KH

AD 2D 3D 4D 5D 6D 7D 8D 9D TD JD QD KD

AS 2S 3S 4S 5S 6S 7S 8S 9S TS JS QS KS

AC : AC : 1 : 11 : 0 : 0 : 1 : 1

2C:AC2C:3:13:0:0:2:1

3C:AC2C3C:6:16:0:0:3:1

4C:AC2C3C4C:10:20:0:0:4:1

5C:AC2C3C AC:7:20:0:1:5:0

清手

6C:6C:6:6:0:0:1:1

7C:6C7C:13:13:0:0:2:1

8C:6C7C8C:21:21:0:0:3:1

9C:6C7C8C9C:30:30:1:0:4:1

TC:6C7C8C C6C:27:27:1:1:5:0

...这里还有几个,但我把它们去掉了,因为它一遍又一遍地出现同样的问题...

清手

QS : QS : 10 : 10 : 0 : 0 : 1 : 1

KS : QSKS : 20 : 20 : 0 : 0 : 2 : 1

...就在这里它崩溃了而不是完成手...

为了让这篇文章更容易阅读,我会在一行中告诉你每个部分(用冒号分隔)代表什么

((显示第一张/下一张牌)X:0:0:0:0:0:0:0

(显示手中的任何东西)0:X:0:0:0:0:0:0

(假设任何 A 都是 1 的分数)0:0:X:0:0:0:0:0

(假设手中的第一个 A 是 11,其他都是 1)0:0:0:X:0:0:0:0

(一个 bool 值来表示这手牌是否失败)0:0:0:0:X:0:0:0

(一个代表完整手牌的 bool 值)0:0:0:0:0:X:0:0

(手牌数)0:0:0:0:0:0:X:0

(确定是否可以抽取另一张牌的 bool 值))0:0:0:0:0:0:0:X

最上面的部分只是显示了所有可能的卡片值并且看起来工作正常。我想知道的是,为什么第五次迭代似乎无法单独留下第四张卡片并且不会弄乱第五张卡片,当然还有它崩溃的原因。这是我的代码,

我的主文件必须是正确的,因为老师给了我们,我们不应该弄乱它:

 #include <iostream>
 #include "BlackJackHand.h"
 #include "PlayingCard.h"

using namespace std;

int main() {

  // Create a Blackjack hand object
   BlackJackHand myHand;

  // arrays of values and suits for normal cards
   char
     *values = "A23456789TJQK",
     *suits = "CHDS";

  const int DECK_SIZE = 52;
   const int SUIT_SIZE = 13;
   PlayingCard *deck[DECK_SIZE]; // array of pointers to class objects

  // Initialize and display a card deck
   int
     i,
     j;

  for(i = 0; i < 4; i++) {
     for(j = 0; j<SUIT_SIZE; j++) {
       deck[i * SUIT_SIZE + j] = new PlayingCard(values[j], suits[i]);
       cout << deck[i * SUIT_SIZE + j]->getCardCode();
       cout << " ";
     }
     cout << endl;
   }
   cout << endl;

  // Add each from deck to hand, then remove card from hand
   // before adding next card. Check funcs.
   for(i = 0; i < DECK_SIZE; i++) {
     cout << deck[i]->getCardCode();
     myHand.addCard(deck[i]);
     deck[i] = NULL;  // Remove card from deck
     cout << " : ";
     cout << myHand.getAllCardCodes();
     cout << " : " << myHand.getLowScore()
       << " : " << myHand.getHighScore()
       << " : " << myHand.isBust()
       << " : " << myHand.isFull()
       << " : " << myHand.getCardCount()
       << " : " << myHand.canTakeCard()
       << endl;
     if(!myHand.canTakeCard()) {
         cout << "\nClearing hand\n";
         myHand.clearHand();
     }
   } // end for

  cout << "\nClearing hand\n";
   myHand.clearHand();

  PlayingCard
     *card1 = new PlayingCard('J', 'C'),
     *card2 = new PlayingCard('A', 'S'),
     *card3 = new PlayingCard('A', 'D');


  BlackJackHand hand2 = BlackJackHand(card1,card2);
   card1 = card2 = 0;
   cout << hand2.getAllCardCodes();
   cout << " : " << hand2.getLowScore()
     << " : " << hand2.getHighScore()
     << " : " << hand2.isBust()
     << " : " << hand2.isFull()
     << " : " << hand2.getCardCount()
     << " : " << hand2.canTakeCard()
     << endl;

  cout << "\nAdding a second ace:\n";

  hand2.addCard(card3);
   card3 = 0;
   cout <<hand2.getAllCardCodes();
   cout << " : " << hand2.getLowScore()
     << " : " << hand2.getHighScore()
     << " : " << hand2.isBust()
     << " : " << hand2.isFull()
     << " : " << hand2.getCardCount()
     << " : " << hand2.canTakeCard()
     << endl;

    for (int i = 0; i < DECK_SIZE; i++)
         if (deck[i] != NULL)
             delete deck[i];

  return 0;
 } // end main

这是手的class.h

#ifndef BLACKJACKHAND_H
#define BLACKJACKHAND_H
#include <iostream>
#include "PlayingCard.h"

using namespace std;

class BlackJackHand
{
    public:
        BlackJackHand();
//          Default constructor. Initializes private member variables.

        BlackJackHand(class PlayingCard *c1, class PlayingCard *c2);
//          Overloaded constructor.
//          Initializes private member variables and adds c1 and c2 to the hand.
        bool addCard(PlayingCard *card);
//          For adding a card to the hand.
//          It will print a warning, not add the card,
//          and return false if one of these conditions is true:
//          The low score of the hand is 21
//          The hand is bust (low value > 21)
//          The hand is full (the full number of cards has been added to the hand)
//          If the card is successfully added, this function returns true.
        PlayingCard *hand[5];
        int getCardCount();
//          Returns the number of cards that are in the hand.
        int getHighScore();
//          As you probably know, blackjack allows an ace to count as either a 1 or an 11.
//          This function returns the score of the hand counting the first ace in the hand as an 11.
//          Make sure you don't count all the aces as 11.
        int getLowScore();
//          Returns the score counting all the aces as 1.
        void clearHand();
//          This function clears the hand. Any cards in the hand are deleted.
//          Deleted means that the delete operator is used on every card in the hand.
        bool isBust();
//          Returns true if the lowScore is above 21, false if not.
        bool isFull();
//          Returns true if the hand is full, i.e. the hand has 5 cards in it.
        bool canTakeCard();
//          Returns true if the hand can take another card.
//          That means that the low score is less than 21 and the hand has less than 5 cards in it.
        string getAllCardCodes();
//          Displays the cards in the hand. Each card is displayed followed by a space.
    private:
       string *c1,
              *c2;
        int count;
};

#endif // BLACKJACKHAND_H

这是手的class.cpp

#include <iostream>
#include "PlayingCard.h"
#include "BlackJackHand.h"


BlackJackHand::BlackJackHand()
{
    hand[0] = 0;
    hand[1] = 0;
    hand[2] = 0;
    hand[3] = 0;
    hand[4] = 0;

    count = 0;
}

BlackJackHand::BlackJackHand(PlayingCard *c1, PlayingCard *c2)
{
    hand[0] = c1;
    hand[1] = c2;
    hand[2] = 0;
    hand[3] = 0;
    hand[4] = 0;

    count += 2;

}
bool BlackJackHand::addCard(PlayingCard *card)
{
    if (getLowScore() < 21 || getLowScore() < 21 || isFull() == false)
    {
        hand[getCardCount()] = card;
        count ++;
        return true;
    }
    else
    {
        return false;
    }
}
int BlackJackHand::getCardCount()
{
    return count;
}
int BlackJackHand::getHighScore()
{
    int scoreHigh = 0;
    bool aceCount = false;
    for (int i = 0; i < getCardCount(); i++)
    {
        if (hand[i]->getCardCode() == "AC" || hand[i]->getCardCode() == "AS" || hand[i]->getCardCode() == "AD" || hand[i]->getCardCode() == "AH")
        {
            if (aceCount == false)
            {
                scoreHigh += 11;
                aceCount = true;
            }
            else
            {
                scoreHigh += 1;
            }
        }
        if (hand[i]->getCardCode() == "2C" || hand[i]->getCardCode() == "2S" || hand[i]->getCardCode() == "2D" || hand[i]->getCardCode() == "2H")
        {
            scoreHigh += 2;
        }
        if (hand[i]->getCardCode() == "3C" || hand[i]->getCardCode() == "3S" || hand[i]->getCardCode() == "3D" || hand[i]->getCardCode() == "3H")
        {
            scoreHigh += 3;
        }
        if (hand[i]->getCardCode() == "4C" || hand[i]->getCardCode() == "4S" || hand[i]->getCardCode() == "4D" || hand[i]->getCardCode() == "4H")
        {
            scoreHigh += 4;
        }
        if (hand[i]->getCardCode() == "5C" || hand[i]->getCardCode() == "5S" || hand[i]->getCardCode() == "5D" || hand[i]->getCardCode() == "5H")
        {
            scoreHigh += 5;
        }
        if (hand[i]->getCardCode() == "6C" || hand[i]->getCardCode() == "6S" || hand[i]->getCardCode() == "6D" || hand[i]->getCardCode() == "6H")
        {
            scoreHigh += 6;
        }
        if (hand[i]->getCardCode() == "7C" || hand[i]->getCardCode() == "7S" || hand[i]->getCardCode() == "7D" || hand[i]->getCardCode() == "7H")
        {
            scoreHigh += 7;
        }
        if (hand[i]->getCardCode() == "8C" || hand[i]->getCardCode() == "8S" || hand[i]->getCardCode() == "8D" || hand[i]->getCardCode() == "8H")
        {
            scoreHigh += 8;
        }
        if (hand[i]->getCardCode() == "9C" || hand[i]->getCardCode() == "9S" || hand[i]->getCardCode() == "9D" || hand[i]->getCardCode() == "9H")
        {
            scoreHigh += 9;
        }
        if (hand[i]->getCardCode() == "TC" || hand[i]->getCardCode() == "TS" || hand[i]->getCardCode() == "TD" || hand[i]->getCardCode() == "TH" || hand[i]->getCardCode() == "JC" || hand[i]->getCardCode() == "JS" || hand[i]->getCardCode() == "JD" || hand[i]->getCardCode() == "JH" || hand[i]->getCardCode() == "QC" || hand[i]->getCardCode() == "QS" || hand[i]->getCardCode() == "QD" || hand[i]->getCardCode() == "QH" || hand[i]->getCardCode() == "KC" || hand[i]->getCardCode() == "KS" || hand[i]->getCardCode() == "KD" || hand[i]->getCardCode() == "KH")
        {
            scoreHigh += 10;
        }
        else
        {
            scoreHigh += 0;
        }
    }
    return scoreHigh;
}
int BlackJackHand::getLowScore()
{
        int scoreLow = 0;
        for (int i = 0; i < getCardCount(); i++)
        {
            if (hand[i]->getCardCode() == "AC" || hand[i]->getCardCode() == "AS" || hand[i]->getCardCode() == "AD" || hand[i]->getCardCode() == "AH")
            {
                scoreLow += 1;
            }
            if (hand[i]->getCardCode() == "2C" || hand[i]->getCardCode() == "2S" || hand[i]->getCardCode() == "2D" || hand[i]->getCardCode() == "2H")
            {
                scoreLow += 2;
            }
            if (hand[i]->getCardCode() == "3C" || hand[i]->getCardCode() == "3S" || hand[i]->getCardCode() == "3D" || hand[i]->getCardCode() == "3H")
            {
                scoreLow += 3;
            }
            if (hand[i]->getCardCode() == "4C" || hand[i]->getCardCode() == "4S" || hand[i]->getCardCode() == "4D" || hand[i]->getCardCode() == "4H")
            {
                scoreLow += 4;
            }
            if (hand[i]->getCardCode() == "5C" || hand[i]->getCardCode() == "5S" || hand[i]->getCardCode() == "5D" || hand[i]->getCardCode() == "5H")
            {
                scoreLow += 5;
            }
            if (hand[i]->getCardCode() == "6C" || hand[i]->getCardCode() == "6S" || hand[i]->getCardCode() == "6D" || hand[i]->getCardCode() == "6H")
            {
                scoreLow += 6;
            }
            if (hand[i]->getCardCode() == "7C" || hand[i]->getCardCode() == "7S" || hand[i]->getCardCode() == "7D" || hand[i]->getCardCode() == "7H")
            {
                scoreLow += 7;
            }
            if (hand[i]->getCardCode() == "8C" || hand[i]->getCardCode() == "8S" || hand[i]->getCardCode() == "8D" || hand[i]->getCardCode() == "8H")
            {
                scoreLow += 8;
            }
            if (hand[i]->getCardCode() == "9C" || hand[i]->getCardCode() == "9S" || hand[i]->getCardCode() == "9D" || hand[i]->getCardCode() == "9H")
            {
                scoreLow += 9;
            }
            if (hand[i]->getCardCode() == "TC" || hand[i]->getCardCode() == "TS" || hand[i]->getCardCode() == "TD" || hand[i]->getCardCode() == "TH" || hand[i]->getCardCode() == "JC" || hand[i]->getCardCode() == "JS" || hand[i]->getCardCode() == "JD" || hand[i]->getCardCode() == "JH" || hand[i]->getCardCode() == "QC" || hand[i]->getCardCode() == "QS" || hand[i]->getCardCode() == "QD" || hand[i]->getCardCode() == "QH" || hand[i]->getCardCode() == "KC" || hand[i]->getCardCode() == "KS" || hand[i]->getCardCode() == "KD" || hand[i]->getCardCode() == "KH")
            {
                scoreLow += 10;
            }
            else
            {
                scoreLow += 0;
            }
        }
    return scoreLow;
}
void BlackJackHand::clearHand()
{
    for (int i = 0; i < 5; i++)
    {
        hand[i] = NULL;
    }
    count = 0;
}
bool BlackJackHand::isBust()
{
    if (getHighScore() > 21)
    {
        return true;
    }
    else
    {
        return false;
    }
}
bool BlackJackHand::isFull()
{
    if (getCardCount() == 5)
        return true;
    else
        return false;
}
bool BlackJackHand::canTakeCard()
{
    if (BlackJackHand::isFull() == false)
    {
        return true;
    }
    else
    {
        return false;
    }
}
string BlackJackHand::getAllCardCodes()
{
    string allCodes = "";
    for (int i = 0; i < getCardCount(); i++)
    {
        allCodes += hand[i]->getCardCode();
    }
    return allCodes;
}

我不是在寻求有关我的编码风格(或缺乏编码风格)的帮助,只是想找出这段代码中的错误。我有另一个类的另外两个文件,这里并不真正需要它们(但如果你问,我会发布它们)因为它们必须为以前的项目工作才能让我继续这个项目我认为它们有效美好的。任何帮助将不胜感激,因为我处于死胡同,我只是不知道如何找到这个问题的答案,因为我不太精通 C++ 的术语或一般编程。

最佳答案

好的,这可能需要几次迭代。让我们看看...当我启动 PlayingCard 并运行代码时,它没有崩溃。你说它在之后立即崩溃:

KS : QSKS : 20 : 20 : 0 : 0 : 2 : 1

这应该是甲板的尽头。在我的版本中,它会继续清牌并制作一些新牌。让我们确定它在这里崩溃了。 (我怀疑不是。)在您的代码中添加几行:

} // end for

cout << "deck is empty" << endl;

cout << "\nClearing hand\n";
myHand.clearHand();

cout << "done" << endl;

运行它,并告诉我们发生了什么(通过向这个答案添加评论)。

编辑:

(小心报告输出——一个小错误可能会让我们走上错误的道路。)

让我们删掉 main 函数中的大部分代码:

int main() {

  // CUT!

  PlayingCard
  *card1 = new PlayingCard('J', 'C'),
  *card2 = new PlayingCard('A', 'S'),
  *card3 = new PlayingCard('A', 'D');

  ...
    << endl;

  // comment these lines out, since the deck no longer exists:
  //  for (int i = 0; i < DECK_SIZE; i++)
  //    if (deck[i] != NULL)      
  //      delete deck[i];
  return 0;
} // end main

试一试,然后告诉我们结果。

关于c++ - 几次(非常好)迭代后循环崩溃/损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30158062/

相关文章:

python - 索引一个 numpy 数组

python - 折叠 numpy 数组尾随维度的简单方法?

c - 合并两个数组而不使用数组排序

c - 将 char 数组中的信息放入动态创建的数组中

c++ - 如何使用 boost::asio 查找 UDP 数据包的目标地址?

c# - 从 C# 到 C++ 的回调函数

ios - 我的变量已声明,但我无法快速使用它们

c - 输入一行后程序崩溃了。怎么修?

c++运行时模板参数识别

c++ - 程序终止于大数组的初始化