C++ 如何在C++;
我试图在这里找到答案,但我发现什么都不起作用。我这里有一个21点游戏。我的下一步是开始在游戏中添加货币余额和赌注,但在我这么做之前,我正在研究我的“再次玩”选项。就目前情况而言,当球员再次比赛时,他们的手牌与上一轮相同。我相信我需要调用析构函数来删除当前的手牌和牌组,然后重新开始。不幸的是,我不知道如何清理手和开始一个新的甲板。我试图在名为play的函数中调用这个析构函数。在这里,如果玩家说他们想再玩一次,我会删除手牌和牌组,然后在主界面中重建它们。但我试过“deck.deck::~deck()”和“deck.~deck()”这两个词,但都不起作用。我会上传我所有的代码。如果有人有任何想法,请帮助我。我知道当析构函数超出范围时,编译器应该调用析构函数,但是当游戏仍在运行且main仍在运行时,我如何从新的手牌和牌组开始呢? 谢谢你的帮助 这是我的头文件:C++ 如何在C++;,c++,destructor,C++,Destructor,我试图在这里找到答案,但我发现什么都不起作用。我这里有一个21点游戏。我的下一步是开始在游戏中添加货币余额和赌注,但在我这么做之前,我正在研究我的“再次玩”选项。就目前情况而言,当球员再次比赛时,他们的手牌与上一轮相同。我相信我需要调用析构函数来删除当前的手牌和牌组,然后重新开始。不幸的是,我不知道如何清理手和开始一个新的甲板。我试图在名为play的函数中调用这个析构函数。在这里,如果玩家说他们想再玩一次,我会删除手牌和牌组,然后在主界面中重建它们。但我试过“deck.deck::~deck()
//blackjack.h A class to represent a deck of cards
#include <iostream>
#include <string>
class Card {
friend class Deck;
private:
int card_index; //card number 0 to 51
Card(int index) { card_index = index; } //made this private so user can't say card at index 100..can use it because of friend class
public:
Card() { card_index = 52; }
char suit() const;
char value() const;
std::string str() const;
int getValue(std::string c);
};
class Deck {
private:
Card cards[52];
int pos;
public:
Deck();
~Deck();
Card deal() { return cards[pos++]; };
void shuffle();
int size() const { return 52 - pos; };
};
class Hand {
friend class Deck;
friend class Card;
private:
int handSize;
int ctotal;
Card myCards[52];
public:
Hand() { handSize = 1; };
~Hand();
Hand(int n) { handSize = n; };
void dealFrom(Deck& d);
void reveal();
int total();
void hit(Deck& d);
};
std::ostream& operator<< (std::ostream& out, const Card& c);
//blackjack.h表示一副牌的类
#包括
#包括
班级卡{
朋友级甲板;
私人:
int card_index;//卡号0到51
Card(int-index){Card\u index=index;}//将此设置为私有,因此用户不能说索引为100的卡。。可以使用它,因为friend类
公众:
Card(){Card_index=52;}
char suit()常量;
char value()常量;
std::string str()常量;
int getValue(std::string c);
};
甲板{
私人:
信用卡[52];
int pos;
公众:
甲板();
~Deck();
卡片交易(){返回卡片[pos++];};
无效洗牌();
int size()常量{return 52-pos;};
};
班主任{
朋友级甲板;
朋友班卡;
私人:
int-handSize;
int ctotal;
卡我的卡[52];
公众:
Hand(){handSize=1;};
~Hand();
Hand(intn){handSize=n;};
无效交易(甲板和d);
虚空显示();
int total();
空袭(甲板与d);
};
std::ostream&operator析构函数通常不是手动调用的东西。对于堆栈上的内存,当对象超出范围时,会自动调用析构函数。对于堆上的内存,使用delete
时会调用析构函数。在这种情况下,您实际上不想删除手,您只想重置它deck=deck()
obj类;
对象~Class();
将调用该对象上的析构函数。但是,您不应该这样做。例如:
#包括
福班{
公众:
Foo(){}
~Foo(){
printf(“a\n”);
如果(foo_m)删除foo_m;
}
私人:
int*foo_m=新int(42);
};
int main(){
富富,;
foo.~foo();
}
从输出中可以看到,析构函数被调用了两次。当我们第一次手动“销毁”对象时,以及当它实际离开堆栈时
几乎从不手动调用析构函数。对象不会消失,您只会破坏其状态并获得未定义的行为。您真正想要的可能是一个类似于clear()
或reset()
函数的函数来重新初始化状态。或者,正如评论中所建议的,您可以将“指定默认对象”移动到现有对象中,以重置状态,而无需编写额外的函数。在游戏仍在运行且main仍在运行的情况下,如何使用新的手牌和牌组开始游戏
基本上,您只需要在一个地方调用play
:在main
的内部循环(“回合未结束”)之外。除了所有重复的代码,你的问题是当玩家想要再次玩游戏时,你将quit
和quitGame
都设置为false
,这样内部循环永远不会终止,你的牌组也永远不会被重新洗牌
其他问题,留给读者作为练习:响应
可以在赋值之前读取。你的洗牌程序不是很好,因为很多牌不会移动。你不直接调用析构函数。您是否正在尝试“重置”这些对象?如果是这样,您可以将新对象复制并分配给变量deck=deck()代码>。这将导致销毁以前的Deck
对象,同时创建一个新对象并将其分配回Deck
变量。通常不手动调用析构函数,除非同时使用placement new(这是您很少需要做的事情)。可能会提供一些有用的建议。需要显式调用析构函数是一种迹象,表明您已经将自己从糟糕的设计中逼到了绝境,或者您有这样做的特定原因。析构函数用于清理类所拥有的资源,而不是重置它们。你的类没有任何需要清理的数据,因此你实际上不需要析构函数。奇怪的是,“播放”实际上没有播放(发生在main()
,这是导致这个兔子洞的真正问题)。货币数据应通过从main()
到play
的引用提供,实际的牌组、手牌管理等均应从play
驱动。也就是说,main
应该只控制整个程序。在play()
及其支持函数中进行任何单次交易,包括牌组洗牌、交易、下注(使用main()
提供的资金)等。不,这不是一个,而是一个“析构函数”。有趣的是,人们通常会反过来做,从后者推断出动词“to destruct”;)是的,被抓住了,换了衣服。漫画太多了。不过,让print语句保持原样。这就是意图
//blackjack.cpp - Implementations of the Deck and Card classes
#include "blackjack.h"
#include <cstdlib>
char Card::suit() const {
static char suits[] = { 'H', 'S', 'D', 'C' };
//return card_index < 52 ? suits[card_index % 4] : 'X';
return suits[card_index % 4];
}
char Card::value() const {
static char values[] =
{ '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K', 'A' };
//return card_index < 52 ? values[card_index / 4] : 'X';
return values[card_index / 4];
}
std::string Card::str() const {
std::string s;
s += value();
s += suit();
return s;
}
Deck::Deck() {
for (int i = 0; i < 52; i ++) {
cards[i] = Card(i);
}
pos = 0;
}
void Deck::shuffle() {
for (int i = 0; i < 52; i++) {
int j = rand() % 52;
Card tmp = cards[i];
cards[i] = cards[j];
cards[j] = tmp;
}
pos = 0;
}
std::ostream& operator<< (std::ostream& out, const Card& c) {
out << c.str();
return out;
}
int Card::getValue(std::string c) {
char v = c[0];
int val = v - '0';
if (val > 9) {
switch(v){
case 'T':
case 'J':
case 'Q':
case 'K':
val = 10;
break;
case 'A':
val = 11;
}
}
return val;
}
void Hand::dealFrom(Deck& d) {
for(int i = 0; i < handSize; i++)
myCards[i] = d.deal();
}
void Hand::reveal(){
for (int i = 0; i < handSize; i++)
std::cout << myCards[i] << " " << std::endl;
}
void Hand::hit(Deck& d) {
int index = handSize;
handSize++;
myCards[index] = d.deal();
}
int Hand::total() {
ctotal = 0; //reset card total
for (int i = 0; i < handSize; i ++) {
ctotal += myCards[i].getValue(myCards[i].str());
}
for (int i = 0; i < handSize; i ++) { //make ace 1 if over 21
if ( (myCards[i].getValue(myCards[i].str()) == 11) && ctotal > 21 )
ctotal = ctotal - 10;
}
return ctotal;
}
#include "blackjack.h"
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
void play(bool& quitGame, bool& quit, Deck& deck, Hand& d,Hand & p) { //function to play again?
char ans;
cout << "\nPlay Again? y or n" << endl;
cin >> ans;
if (ans == 'y' || ans == 'Y') {
quitGame = false;
quit = false;
deck.Deck::~Deck(); //trying to delete the deck and hand objects before next game
d.Hand::~Hand();
p.Hand::~Hand();
//deck.~Deck();
//d.~Hand();
//p.~Hand();
} else if (ans == 'n' || ans == 'N')
quitGame = true;
else {
cout << "Incorrect response." << endl;
play(quitGame, quit, deck, d, p);
}
}
void reveal(Hand& d, Hand& p) { //function to reveal the hand
cout << "Your hand is: " << endl;
p.reveal();
cout << "Your total is: " << endl;
cout << p.total() << endl;
cout << endl;
cout << "Dealer's hand is: " << endl;
d.reveal();
cout << "Dealer's total is: " << endl;
cout << d.total() << endl;
}
void autoComplete(Hand& d, Hand& p, bool& quit, bool& quitGame, Deck& deck) { //function to check for blackjack and over 21
if (p.total() == 21 && d.total() == 21) {
cout << "You and dealer both hit blackjack. You tied." << endl;
quit = true;
play(quitGame, quit, deck, d, p);
} else if(p.total() == 21) {
cout << "Congratulations, you hit blackjack. You win!" << endl;
quit = true;
play(quitGame, quit, deck, d, p);
} else if(d.total() == 21) {
cout << "Sorry. Dealer hit blackjack. You lose." << endl;
quit = true;
play(quitGame, quit, deck, d, p);
} else if (p.total() > 21 && d.total() > 21) {
cout << "You and dealer both passed 21. Game is a tie." << endl;
quit = true;
play(quitGame, quit, deck, d, p);
} else if (p.total() > 21 && d.total() < 21) {
cout << "You passed 21. You lose.";
quit = true;
play(quitGame, quit, deck, d, p);
} else if (d.total() > 21 && p.total() < 21) {
cout << "Dealer passed 21. You win.";
quit = true;
play(quitGame, quit, deck, d, p);
}
}
int main() {
srand(time(0));
char response; // variable to hit or stand
bool quit = false; //variable to end the current round
bool quitGame = false; //variable to play game again
while (quitGame == false) { //while the player wants to continue playing
Deck deck; //create deck
Hand p(2); //player's hand
Hand d(2); //dealer's hand
deck.shuffle(); //shuffle deck
p.dealFrom(deck); //deal from deck
d.dealFrom(deck);
while (quit == false) { //while the round isn't over
reveal(d, p); //reveal the cards
autoComplete(d, p, quit, quitGame, deck); //check for blackjack and over 21
if(p.total() < 21 && quit == false) { //if games not over and player is under 21
cout << "Press 'h' to hit or 's' to stand." << endl;
cin >> response;
}
if (response == 'h') {
cout << " " << endl;
p.hit(deck);
if (d.total() < 17) //if the dealer hasn't hit 17, dealer hits deck
d.hit(deck);
}
if (response == 's') {
cout << " " << endl;
while (d.total() < 17){ //if the dealer hasn't hit 17, keep hitting deck
d.hit(deck);
}
if (d.total() < 21 && p.total() < 21) {
if (d.total() > p.total() && quit == false) { //if dealers total is higher than players total
reveal(d, p);
cout << "\nDealer wins!" << endl;
quit = true;
play(quitGame, quit, deck, d, p);
} else if (p.total() > d.total() && quit == false) { //if players total is higher than dealers total
reveal(d, p);
cout << "\nYou win!" << endl;
quit = true;
play(quitGame, quit, deck, d, p);
} else if (p.total() == d.total() && quit == false) { //if dealers total equals players total
reveal(d, p);
cout << "\nYou tied." << endl;
quit = true;
play(quitGame, quit, deck, d, p);
}
}
}
}
}
return 0;
}