我正在研究一个学校项目的程序,该程序旨在输出二十一点游戏中的所有卡值,并告诉你一些关于这些卡的可能组合的事情。
循环设计用于将卡放入手中并检查一些不同的可能性,然后再放入另一张卡并执行相同的操作,当它达到五张卡时它会清除手并移动到一组新的卡值,直到它已经使用了甲板上的所有卡片。
现在每一张第四张和第五张卡片在循环中都会以某种方式破坏。请记住,虽然我正在使用指针,数组和类(以及更多),但我仍然无法完全理解所做的一切,甚至阅读了“C ++ Early Objects Eighth edition”一书到第10章。
这是一个输出的例子,它表明得分管理员得分正确,但是放在手中的牌在循环的第五次迭代中开始陷入困境,这似乎反映在得分了。
AC CL 2C 3C 4C 5C 6C 7C 8C 9C TC JC QC KCAH 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:15C: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:1KS: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
(假设手中的第一个ace为11,其他所有为1)0:0:0:X:0:0:0:0
(表示手是否破裂的bool)0:0:0:0:X:0:0:0
(表示一手牌的布尔值)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 ++的术语或一般的编程。
答案 0 :(得分:1)
好吧,这可能需要几次迭代。让我们看看......当我点起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;
运行它,并告诉我们发生了什么(通过在此答案中添加注释)。
修改强>
(小心报告输出 - 一个小错误会让我们走错路。)
让我们删除主函数中的大部分代码:
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
试一试,告诉我们结果。