C++课程设计实验报告 猜单词游戏.docx
- 文档编号:23535125
- 上传时间:2023-05-18
- 格式:DOCX
- 页数:19
- 大小:878.07KB
C++课程设计实验报告 猜单词游戏.docx
《C++课程设计实验报告 猜单词游戏.docx》由会员分享,可在线阅读,更多相关《C++课程设计实验报告 猜单词游戏.docx(19页珍藏版)》请在冰豆网上搜索。
C++课程设计实验报告猜单词游戏
C++课程设计实验报告
姓名何超翔学号9161010E0509班级9161010E05
选定题目2.4猜单词游戏评定难易级别中等
1.实验内容
1.1程序功能介绍
一个猜单词游戏。
两人游戏时,由一个玩家给出一个单词,在人与计算机游戏时,由计算机给出一个单词,另一个玩家根据组成单词的字母个数猜出单词,猜的次数可以指定,若猜不中,显示一个上吊的人形。
1.2程序设计要求
(1)将猜单词的函数与对应的数据封装到类中,并改写主程序,使程序简化。
(2)根据所猜单词中的字母个数,给出指定几率的提示字母,显示于单词中的正确位置。
(3)在进入猜单词的过程后,首先显示菜单询问是开始猜单词还是修改设置,默认的修改次数为4,默认显示字符的几率为20%,若要修改这个设置,在显示菜单中选择设置选项进行修改。
(4)在人人对抗时,一个玩家给出单词时,单词不显示在屏幕上,字符用“*”号显示。
(5)在猜单词时,输入一个单词,判断函数改为判断输入单词的字符是否与所猜单词一一对应,将猜中的字符显示出来。
(6)在人机对抗时,可以选择随机读取单词,也可以选择向单词库输入单词,同时,将单词库中单词的个数显示出来,并根据单词库中单词个数的多少决定随机选取的范围。
2.程序运行结果界面
图1猜单词游戏主菜单
图2人人对抗游戏选项
图3人人对抗玩家出题
图4人人对抗玩家猜单词
图5人机对抗游戏选项
图6修改设置可以猜错的次数
图7修改设置显示字符的几率
图8人机对抗添加新单词
图9人机对抗玩家猜单词
图10玩家猜单词成功
图11玩家猜单词失败
图12失败后显示正确单词
图13切换皮肤选项
图141号皮肤界面
图152号皮肤界面
图163号皮肤界面
图174号皮肤界面
图18退出游戏界面
3.源程序结构流程框图与说明
图19源程序结构流程图
4.基本数据结构
本程序中用到的主要类有:
基类CGuess;派生类UserGame;派生类CompGame。
(1)基类CGuess
classCGuess
{
protected:
//只能被本类或本类的派生类中的成员函数访问
inti;//循环变量
intchoice;//接受用户主菜单选择
intsub_choice;//接受用户次级菜单选择
doubleproba;//显示字符的概率(0-1)
intguess_num;//总共可猜的次数
intwrong_num;//猜错的次数
intcheck;//Lchosen函数中检测输入的单词与已输入的字符是否重复的标识符
intcheck_2;//Test函数中判断字母是否为正确字母的标识符
intend;//猜单词过程中的循环结束标识符
intchosen_counter;//选对的字符个数
stringword;//欲猜的单词
charletter;//玩家输入的字符
stringtemp;//玩家看见的不断更新的输出
stringletter_chosen;//选择过的字符集
public:
CGuess();
voidMainMenu();//输出程序主菜单,接收用户选择
voidMainPro();//运行程序主菜单,处理用户选择
voidSubMenu();//输出程序次级菜单,处理用户选择
voidSubPro(string&word);//人人和人机对抗模式的公共代码部分
voidChangeSkin();//切换游戏皮肤
voidInitialSet();//修改设置值
voidLchosen(charletter,string&letter_chosen,int&check,int&chosen_counter,inti);
//判断输入的字符是否是单词的一部分,若不是,将其放入已输入过的错误字符集中
voidTest(stringword,charletter,int&wrong_num,string&temp,inti);
//判断输入的字符是否是单词中的字符,如果是,替换到正确位置
voidDrawman(intguess_num,intwrong_num,inti);//画上吊的人形
};
(2)派生类UserGame
classUserGame:
publicCGuess
{
private:
intword_check;//检查第一个玩家输入的是否是单词
stringdisplay_word;//欲显示的单词
stringguess_word;//第二个玩家输入猜想的单词
public:
UserGame();
voidPro_1();//连接人人对抗与基类成员函数SubPro(string&word)
voidPassword();//一个玩家给出单词时以密码形式显示
};
(3)派生类CompGame
classCompGame:
publicCGuess
{
private:
intn;//words.txt中的单词个数
public:
CompGame();
voidPro_2();//连接人机对抗与基类成员函数SubPro(string&word)
voidWordCounter();//显示单词库中的单词数量
voidOpenWordFile();//打开单词库,随机取出一个单词赋给word
voidSaveWordFile();//向单词库输入新单词
};
5.课程设计遇到的技术问题与解决思路
问题1:
光盘文件中的代码过于冗长,尤其是usergame(inti)和compgame(inti)这两个函数,里面有大段的重复代码,应怎样简化该程序?
光盘内的程序还是以面向过程为主,除了类draw以外,都使用一个个函数来实现功能。
课程设计要求将猜单词的函数与对应的数据封装到类中,并改写主程序,使程序简化,并且书上给出了定义为一个类的两个对象的范例。
而我根据实际要求和个人习惯,将程序改写为由一个基类(CGuess)和两个派生类(UserGame和CompGame)组成的程序,具体的结构在报告前文已经说明。
经过这样的改写之后,程序的数据结构变得更加清晰合理,更加优化。
当然,我的程序也还存在一些缺点,仍需改进。
问题2:
游戏界面的色彩过于单调,怎样改变游戏界面背景及文字的颜色?
CMD中有一种color命令,它可以改变命令行程序的背景与文字的颜色,例如命令"colorec",它是让背景颜色变为黄色,文字颜色变为红色。
"color"后面的是两个十六进制数字,第一个对应于背景,第二个对应于文字,各个数字与颜色的对应关系可以在命令行程序中输入"color/"来查询。
当然,在本游戏的程序中,我设计了基类CGuess的成员函数ChangeSkin(),调用system函数执行CMD命令。
函数ChangeSkin()中运用do…while语句和switch语句来处理用户的选择,其具体代码如下:
voidCGuess:
:
ChangeSkin()
{intskin;
interror;
cout< cout<<"猜单词游戏"< cout<<"完成者: 何超翔指导老师: 张爱军"< cout<<"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"< cout<<"皮肤列表(输入0切换回默认皮肤)"< cout<<"1.绿色背景浅绿文字2.绿色背景浅蓝文字"< cout<<"3.红色背景黄色文字4.黄色背景红色文字"< cout<<"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"< cout<<"请选择皮肤: "; cin>>skin; do {switch(skin) {case0: system("color07");error=0;break; case1: system("color3a");error=0;break; case2: system("color3b");error=0;break; case3: system("colorce");error=0;break; case4: system("colorec");error=0;break; default: error=1;cerr<<"输入错误,请重新输入! "; Flush(cin);cin>>skin;break; } }while(error); } 问题3: 在人人对抗模式中,怎样把第一玩家打出的单词以密码的形式显示出来? 课程设计要求在人人对抗时,一个玩家给出单词时,单词不显示在屏幕上,字符用“*”号显示,其类似于密码的输入。 本程序在基础上还要有些限制条件,就是接收的字符必须是字母,当字母为大写时还要转化为小写;如果输入的不是字母,要提示重新输入。 在输入密码时,如果用一般的cin流接收,则密码会显示在屏幕上,起不到保密作用;但如果用getch()函数来接收字符,则输入字符会直接进入内存,然后将其替换成*显示即可。 我参考了21点游戏的程序设计思想,设计了派生类UserGame的成员函数Password(),其具体代码如下: voidUserGame: : Password() {charstr[20]; charch; stringblank; stringt; i=0; intj=0; cout<<"请第一位玩家先输入一个单词: "< cout.flush(); ch=getch(); while(ch! =13) {str[i]=ch; if(str[i]>=97&&str[i]<=122) {cout<<'*';j++; cout.flush(); ch=getch(); } elseif(str[i]>=65&&str[i]<=90) {str[i]=str[i]+32;j++; cout<<'*'; cout.flush(); ch=getch(); } elseif(str[i]<=65||(str[i]>=90&&str[i]<=97)||str[i]>=112) {cout<<"*"; cout.flush(); ch=getch(); } i++; } for(i=0;i word.replace(i,1,1,str[i]); t=word; word=blank; do {word_check=0; for(i=0;i if(! isalpha(t.at(i))) word_check=1; if(word_check==1) {cout<<"\n你输入的不是单词,请重新输入! "< Password(); } else word=t; }while(word_check==1); } 问题4: 在人机对抗模式中,怎样准确地自动统计单词库中的单词个数? 我认为,这个问题与上学期的C++上机实践第56页的S16_4类似,由于单词库words.txt是逐行存储单词的,一行一个字符串,因此我们只需要定义一个足够大的多行字符串空间(string[100][20]),然后从文本文件中逐行接收字符串;但与S16_4不同的是,我们需要用eof函数来判断是否读到文本文件的底端。 我为此设计了派生类CompGame的成员函数WordCounter(),其具体代码如下: voidCompGame: : WordCounter()//参考C++上机实践P56S16_4的方法,有所改动 {charstring[100][20]; n=0; ifstreamcount; count.open("words.txt"); do {count.getline(string[n],20); n++; }while(! count.eof()); cout< count.close(); } 6.设计中的感悟 在完成此次C++课程设计的过程中,我收获颇丰,体会颇深。 实践是认识的目的,上学期我们学习的C++程序设计的基础知识,在这学期的课程设计中得到了充分的运用、巩固,程序设计思维得到了提升。 本次课程设计主要涉及了数组、类与对象、继承与派生、文件流等知识与各种函数的灵活运用,实际上我在课程设计的过程中就已经无形地复习、巩固了一遍,并且在运用的过程中加深了理解。 在日常生活中,我们往往只会出于娱乐的目的去玩一些类似的小游戏,却往往并没有深入地思考这些小游戏背后蕴藏的算法和数据结构,没有去想这些游戏是怎么做出来的。 我当时选题目的时候过于匆忙,没有去选那些更难的题目,而选了这个猜单词游戏,没想到的是,我在完成课程设计的过程中愈发地对这一任务感到充满兴趣,进而强有力地推动了我完成了这次课程设计。 当我在编程时遇到一个个问题时,我并没有感到挫败,我反而更受激励,通过独立思考,翻阅书籍,上网查找资料等各种手段去解决。 当我解决完问题的时候,我的感觉是一种释然。 编程如此,人生亦如此,我更应激励自己,克服一系列的困难,实现我的目标。 最后,感谢张爱军老师对我的指导!
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- C+课程设计实验报告 猜单词游戏 C+ 课程设计 实验 报告 单词 游戏