其实这个问题并不难,最重要的是要有良好的设计和清晰的思路。我花了2个小时,实现了4个类:poker类,表示扑克牌;flower_dice,代表花色的骰子;point_dice,代表牌点的骰子;以及实现整个程序功能的app类,解决了这个问题。类的结构设计如图所示。
poker类很简单:只有一个表示是否是正面向上的Bool成员。poker的默认构造函数将这个成员初始化为true。将app设为友元使其可以设置这个牌的状态。poker对象将存储在app的map容器pokers中。pokers容器存储着全部的52张牌,即52个pokers对象。这些对象在app的默认构造函数中逐个初始化。
为什么要使用map容器呢?因为map容器是存储“键-值对”的标准库容器。这样的话,可以将存储牌的花色和点数的pair类型作为map的键类型,(这里使用1,2,3,4分别表示花色,1-13表示点数)poker类作为元素类型。从而将每一张牌和牌的花色点数信息一一对应起来。这样,将会使后续的翻牌的实现大大简化。只需使用map容器提供的操作即可。
flower_dice和point_dice分别是表示花色和点数的骰子,这两个骰子的实现很类似:拥有一个表示掷得的点数的私有数据成员,并在默认构造函数中使用C++标准库rand()函数取随机数,用这个随机数初始化掷得的点数。他们将被app类使用,实现掷骰子的操作。因此将他们设为app类的友元以便app可以访问他们所掷得的点数。
app类实现了主程序的所有功能:掷骰子、输出掷得结果、输出纸牌状态、保存为一个文件。
这里还为app添加了一个vector容器成员以存储每次掷骰子所得结果。
main主程序使用app类完成“模拟随机掷骰子,把骰子对应的牌翻过去,然后再掷骰子,再翻牌,.....如此100次。最后,输出还是正面向上的那些纸牌。”的任务
就解释这么多了,具体看注释。别忘了给分啊
//poker.h
//poker类的定义
#ifndef POKER_H //#ifndef..#define...#endif避免头文件重复包含,这个不多说了
#define POKER_H
class poker
{
public:
friend class app;//将app类设为友元使其可以访问isOn成员并设置状态
bool isOn;//表示牌是否向上的bool成员
poker():isOn(true) {}//默认构造函数将bool成员初始化为true
};
#endif
//flower_dice.h
//flower_dice类的定义
#ifndef FLOWER_DICE_H
#define FLOWER_DICE_H
class flower_dice
{
friend class app;//将app设为友元使其可以访问掷得的花色
int flower;//表示花色的int成员
flower_dice():flower(1+rand()%4) {} //默认构造函数使用rand()将
//flower初始为1,2,3,4中的一个随机数
};
#endif
//point_dice.h
//point_dice类定义、
#ifndef POINT_DICE_H
#define POINT_DICE_H
class point_dice
{
friend class app;//将app设为友元使其可以访问掷得的点数
int point;//表示点数的Int成员
point_dice():point(1+rand()%13) {}//默认构造函数使用rand()将
//point初始为1-13中的一个随机数
};
#endif
//app.h
//app类定义
#ifndef APP_H
#define APP_H
#include
#include
#include
#include
#include "poker.h"
#include "flower_dice.h"
#include "point_dice.h"
class app
{
public:
app()//app的默认构造函数
{
for(int i=1;i<=4;++i)//4种花色
for(int j=1;j<=13;++j)//13个点数
pokers[std::pair
//map容器引用一个不存在的键时将会插入元素。这里的作用是
//默认初始化指定花色和点数的poker对象
//花色和点数使用一个pair类型对象表示
}
void throw_dice(int);//掷骰子,int形参为掷骰子的次数
void print_dice_results(std::ostream&) const;
//输出每次掷骰子的结果到ostream形参中,
//这里设置ostream形参是为了保存文件的时候可以直接将文件流传递给函数
//函数将向文件流写入数据,下同
void print_pokers(std::ostream&) const;//输出纸牌状态
void print_pokers_on(std::ostream&) const;//输出正面向上的纸牌
void save_results(std::ofstream&) const;//保存文件,存储数据到ofstream文件流
//形参中
private:
std::map
std::vector
};
#endif
//app.cpp
//app类成员函数的定义
#include "app.h"
void app::throw_dice(int times)
{
for(int i=1;i<=times;++i)
{
flower_dice fd;//创建一个新的表示花色的骰子
point_dice pd;//创建一个新的表示点数的骰子
pokers[std::pair
=!pokers[std::pair
//很关键:将存储纸牌的map容器中指定花色和点数(键)的纸牌 (值)
// 翻过来 这里的花色和点数是两个骰子的数据成员
dice_results.push_back(std::pair
//将这次掷骰子的结果保存到vector容器中
}
}
void app::print_dice_results(std::ostream& os=std::cout) const
//默认实参将形参ostream对象默认设置为标准输出流cout
{
for(std::vector
dice_results.begin();it!=dice_results.end();++it)
os<
< //输出掷骰子的结果,很简单 } void app::print_pokers(std::ostream& os=std::cout) const { for(std::map pokers.begin();it!=pokers.end();++it) os< < <<(it->second.isOn?"On":"Off")< //输出map容器,这个学过map应该都会,不多说了 } void app::print_pokers_on(std::ostream& os=std::cout) const { for(std::map pokers.begin();it!=pokers.end();++it) if(it->second.isOn) os< < //输出正面向上的纸牌,这个也很简单 } void app::save_results(std::ofstream& ofile) const { if(!ofile)//检查ofstream文件流是否可用 std::cerr<<"Unable to open the output file."< else { print_dice_results(ofile);//输出掷骰子结果 ofile< print_pokers(ofile);//输出纸牌状态 } } //主程序main.cpp #include #include "app.h" #include "app.cpp" using namespace std; int main() { app obj; obj.throw_dice(100); obj.print_pokers_on(); return 0; } 记得给分啊