卡西诺纸牌游戏简化版本,求解?
/*这个游戏是这样的:玩家处理带有分值的牌,各个玩家都设法达到总分21而不超过这个数字。
上面有数字的牌的分数就是它们的面值。A充当1或者11分(选择适当的玩家的一个),I,Q或者K都是10分。
计算机是庄家(卡西诺),它对付1到7个玩家。在这一局开始时,包括玩家在内的所有参与者都有两张牌。
玩家可以看到他们的所有牌以及总分。不过,庄家有一张牌暂时是隐藏的。
就下来,只要愿意,各个玩家都有机会一次再拿一张牌。如果某个玩家的总分超过了21(称为“爆引“)
,那么这个玩家就输了。在所有玩家都拿了额外的牌之后,庄家将显示它隐藏的牌。
只要庄家的总分等于或小于16,那么它就必须在拿牌。如果在拿牌。如果庄家爆引了,那么还没有爆引的玩家获胜。
否则,将余下的各个玩家的总分与庄家的总分做比较。如果玩家的总分大于庄家的总分,则玩家获胜。
如果二者的总分相同,则玩家与庄家打成平局。*/
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<ctime>
using namespace std;
class Card//Card类
{
public:
enum rank{ACE=1,TWO,THREE,FOUR,FIVE,SIX,SEVEN,EIGHT,NINE,TEN,JACK,QUEEN,KING};
enum suit{CLUBS,DIAMONDS,HEARTS,SPADES};
friend ostream& operator<<(ostream& os ,const Card& aCard);//重载<<操作符,这样才能将Card对象发送到标准输出
Card(rank r=ACE,suit s=SPADES,bool ifu=true);
int GetValue()const;//返回纸牌的值,1~11
void Flip();//翻一张牌,如果纸牌牌面向上,则变成牌面向上,反之亦然
private:
rank m_Rank;
suit m_Suit;
bool m_IsFaceUp;
};
Card::Card(rank r,suit s,bool ifu):m_Rank(r),m_Suit(s),m_IsFaceUp(ifu)
{}
int Card::GetValue()const
{
int value=0;//如果纸牌面向下,那么它的值是0
if(m_IsFaceUp)
{
value=m_Rank;//对于人头牌,值是10
if(value>10)
value=10;
}
return value;
}
void Card::Flip()
{
m_IsFaceUp=!(m_IsFaceUp);
}
/*定义了两个枚举rank和suit,分别用作这个类的等级和花色数据成员(m_Rank和m_ suit)的类型。这有两个优点。首先,它使代码更易于阅读。
花色数据成员有一个像CLUBS或HEARS这样的值,而不是0或2.其次,他限制了这两个数据成员可能具有的值。m_ Suit只能存储 suit中的值,
而m_Rank只能存储rank中的值。接下来,将重载的operator<<()函数做为这个类的一个友元,这样就可以在屏幕上显示Card对象。
GetValue()返回一个用于Card对象的值,这个值可以在1~11之间。A的值是11(根据手中的其他牌,也可能在Hand类中将它们算作1)。牌面向下
的牌的值是0.*/
class Hand//hand类
{
public:
Hand();
virtual ~Hand();
void Add(Card* pCard);//将一张牌添加到手中
void Clear();//清除手的所有牌
int GetTotal()const;//获取手中的值,只能地将A视为1或11
protected:
vector<Card*> m_Cards;
};
Hand::Hand()
{
m_Cards.reserve(7);
}
Hand::~Hand()//不要在类的外部使用关键字virtual
{
Clear();
}
void Hand::Add(Card* pCard)
{
m_Cards.push_back(pCard);
}
void Hand::Clear()
{
vector<Card*>::iterator iter;
for(iter=m_Cards.begin();iter!=m_Cards.end();++iter)//遍历矢量,释放堆上的所有内存
{
delete *iter;
*iter=NULL;
}
m_Cards.clear();//清空指针矢量,clear()成员函数删除了一个矢量的所以项目并将它的大小设置为0.
}
int Hand::GetTotal()const
{
if(m_Cards.empty())//如果手中没有牌,则返回0
return 0;
if(m_Cards[0]->GetValue()==0)//如果第一张牌是0,那么它的牌面向下,返回0
return 0;
int total=0;//把纸牌的值加起来,将各个A视为1
vector<Card*>::const_iterator iter;
for(iter=m_Cards.begin();iter!=m_Cards.end();++iter)
total+=(*iter)->GetValue();
bool containsAce=false;//确定手中是否包含一张A
for(iter=m_Cards.begin();iter!=m_Cards.end();++iter)
if((*iter)->GetValue()==Card::ACE)
containsAce=true;
if(containsAce&&total<=11)//如果手中包含A,并且总分足够低,则将A视为11
total+=10;//因为已经对A增加了1,所以只要再加上10即可
return total;
}
class GenericPlayer:public Hand
{
friend ostream& operator<<(ostream &os,const GenericPlayer& aGenericPlayer);
public:
GenericPlayer(const string& name="");
virtual ~GenericPlayer();
virtual bool IsHitting()const=0;//支持通用玩家是否继续发牌
bool IsBusted()const;//返回通用玩家是否希望爆引——总分是否大于21
void Bust() const;//宣布通用玩家爆引
protected:
string m_Name;
};
GenericPlayer::GenericPlayer(const string& name):m_Name(name)
{}
GenericPlayer::~GenericPlayer()
{}
bool GenericPlayer::IsBusted()const
{
return(GetTotal()>21);
}
void GenericPlayer::Bust() const
{
cout<<m_Name<<" busts.\n";
}
class Player:public GenericPlayer
{
public:
player(const string& name="");
virtual~ Player();
virtual bool IsHitting()const;//返回玩家是否再发一张牌
void Win()const;//宣布玩家获胜
void Lose()const;//宣布玩家失败
void push()const;//宣布玩家获得平局
};
Player::Player(const string& name):GenericPlayer(name)
{}
Player::~Player()
{}
bool Player::IsHitting()const
{
cout<<m_Name<<",do you want a hit?(Y/N): ";
char response;
cin>>response;
return (response=='y'||response=='Y');
}
void Player::Win()const
{
cout<<m_Name<< "wins.\n";
}
void Player::Lose()const
{
cout<<m_Name<<" loses.\n";
}
void Player::push()const
{
cout<<m_Name<<" pushes.\n";
}
class House:public GenericPlayer
{
public:
House(const string& name="House");
virtual~House();
virtual bool IsHitting() const;//支持庄家是否发牌——总是在16分或者更多低分时发牌
void FlipFirstCard();//降低一张牌翻过来
};
House::House(const string& name):GenericPlayer(name)
{}
House::~house()
{}
bool House::IsHitting() const
{
return (GetTotal()<=16);
}
void House::FlipFirstCard()
{
if(!(m_Card.empty()))
m_Cards[0]->Flip();
else
cout<<" No card to flip!\n";
}
class Deck:public Hand
{
public:
Deck();
virtual~Deck();
void Populate();//创建一幅52张的标准纸牌
void shuffle();//给一个通用玩家发额外的牌
void Deal(Hand& aHand);
void AdditionalCards(GenericPlayer& aGenericPlauer);
};
Deck::Deck()
{
m_Cards.reserve(52);
Populate();
}
Deck::~Deck()
{}
void Deck::Populate()
{
Clear();//创建一幅标准的牌
for(int s=Card::CLUBS;s<=Card::SPADES;++s)
for(int r=Card::ACE;r<=Card::kING;++r)
Add(new Card(static_cast<Card::rank>(r),static_cast<Card::suit>(s)));
}
void Deck::shuffle()
{
random_shuffle(m_Cards.begin(),m_Cards.end());
}
void Deck::Deal(Hand& aHand)
{
if(!m_Cards.empty())
{
aHand.Add(m_Cards.back());
m_Cards.pop_back();
}
else
{
cout<<" out of cards.unble to deal.";
}
}
void Deck::AdditionalCards(GenericPlayer& aGenericPlayer)
{
cout<<endl;
while(!(aGenericPlayer.IsBusted()&&aGenericPlayer.IsHitting())
{
Deal(aGenericPlayer);
cout<<aGenericPlayer<<endl;
if(aGenericPlayer.IsBusted())
aGenericPlayer.Bust();
}
}
class Game
{
public:
Game(const vector<string>& names);
~Game();
void Play();//玩纸牌游戏
private:
Deck m_Players;
House m_House;
vector<Player>m_Players;
};
Game::Game(const vector<string>& names)
{
vector<string>::const_iterator pName;//从一格名字矢量创建一个万家矢量
for(pName=names.begin();pName!=names.end();++pName)
m_Players.push_back(Player(*pName));
srand(time(0));//生成一个随机生成期的种子
m_Deck.populate();
m_Deck.shuffle();
}
Game::~game()
{}
void Game::Play()
{
vector<Player>::iterator pPlayer;
for(int i=0;i<2;++i)
{
for(pPlayer=m_Players.begin();pPlayer!=m_Players.end();++pPlayer)
m_Deck.Deal(*pPlayer);
m_Deck.Deal(m_House);
}
m_House.FilpFirstCard();//隐藏庄家的第一张牌
for(pPlayer=m_Players.begin();pPlayer!=m_Players.end();++pPlayer)//显示每个人的一手牌
cout<<*pPlayer<<endl;
cout<<m_House<<endl;
for(pPlayer=m_Players.begin();pPlayer!=m_Players.end();++pPlayer)//向玩家发额外的牌
m_Deck.AdditionalCards(*pPlayer);
m_House.FlipFirstCard();
cout<<endl<<m_House;
m_Deck.AdditionalCards(m_House);
if(m_house.IsButed())
{
for(pPlayer=m_Players.begin();pPlayer!=m_Players.end();++pPlayer)//仍然在玩的所有人获胜
if(!(pPlayer->IsBusted()))
pPlayer->Win();
}
else
{
for(pPlayer=m_Players.begin();pPlayer!=m_Players.end();++pPlayer)
if(!(pPlayer->IsBusted()))
{
if(pPllayer->GetTotol()>m_House.GetTotol())
pPlayer->Win();
else if(pPlayer->GetTotol()<m_House.GetTotol())
pPlayer->lose();
else
pPlayer->Push();
}
}
for(pPlayer=m_Players.begin();pPlayer!=m_Players.end();++pPlayer)
pPlayer->Clear();
m_House.Clear();
}
ostream &operator<<(ostream &os,const Card& aCard);//函数原型
ostream &operator<<(ostream &os,const GenericPlayer& aGenericPlayer);//函数原型
int main()
{
cout<<" \t\tWelcome to Blackjack!\n\n";
int numPlayers=0;
while(numPlayers<1||numPlayers>7)
{
cout<<"how many players?(1-7): ";
cin>>numPlayers;
}
vector<string>names;
string name;
for(int i=0;i<numPlayers;++i)
{
cout<<"Enter player name: ";
cin>>name;
name.push_back(name);
}
cout>>endl;
Game aGame(names);
char again='y';
while(again!='n'&&again!='N')
{
aGame.play();
cout<<"\nDo you want to play again?(Y/N): ";
cin>>again;
}
return 0;
}
ostream &operator<<(ostream &os,const Card& aCard)//重载<<操作符,这样就可以将Card对象发送到cout
{
const string RANKS[]={"0","A",2","3","4","5","6","7",8","9","10","J","Q","K"};
const string SUITS[]={"c","d","h","s"};
if(aCard.m_IsFaceUp)
os<<RANKS[aCard.m_Rank]<<SUITS[aCard.m_Suit];
else
os<<"XX";
return os;
}
ostream &operator<<(ostream &os,const GenericPlayer& aGenericPlayer)//重载<<操作符,这样就可以将GenericPlayer对象发送到cout
{
os<<aGenericPlayer.m_Name<<":\t";
vector<Card*>::const_interator pCard;
if(!aGenericPlayer.m_Cards.empty())
{
for(pCard=aGenericPlayer.m_Cards.begin();pCard!=aGenericPlayer.m_Cards.end();++pCard)
os<<*(*pCard)<<"\t";
if(aGenericPlayer.GetTotal()!=0)
cout<<"("<<aGenericPlayer.GetTotal()<<")";
}
else
{
os<<"<empty>";
}
return os;
}
/*Compiling...
卡西诺纸牌游戏.cpp
F:\重要课件\C++程序\卡西诺纸牌游戏.cpp(137) : error C2511: 'Player::Player' : overloaded member function 'void (const class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > &)' not found in 'Player'
F:\重要课件\C++程序\卡西诺纸牌游戏.cpp(127) : see declaration of 'Player'
F:\重要课件\C++程序\卡西诺纸牌游戏.cpp(357) : fatal error C1004: unexpected end of file found
Error executing cl.exe.请问这是怎么了?*/