1、C+课程设计实验报告 猜单词游戏C+课程设计实验报告姓名 何超翔 学号 9161010E0509 班级 9161010E05 选定题目 2.4 猜单词游戏 评定难易级别 中等 1.实验内容1.1 程序功能介绍一个猜单词游戏。两人游戏时,由一个玩家给出一个单词,在人与计算机游戏时,由计算机给出一个单词,另一个玩家根据组成单词的字母个数猜出单词,猜的次数可以指定,若猜不中,显示一个上吊的人形。1.2 程序设计要求(1)将猜单词的函数与对应的数据封装到类中,并改写主程序,使程序简化。(2)根据所猜单词中的字母个数,给出指定几率的提示字母,显示于单词中的正确位置。(3)在进入猜单词的过程后,首先显示菜
2、单询问是开始猜单词还是修改设置,默认的修改次数为4,默认显示字符的几率为20%,若要修改这个设置,在显示菜单中选择设置选项进行修改。(4)在人人对抗时,一个玩家给出单词时,单词不显示在屏幕上,字符用“*”号显示。(5)在猜单词时,输入一个单词,判断函数改为判断输入单词的字符是否与所猜单词一一对应,将猜中的字符显示出来。(6)在人机对抗时,可以选择随机读取单词,也可以选择向单词库输入单词,同时,将单词库中单词的个数显示出来,并根据单词库中单词个数的多少决定随机选取的范围。2.程序运行结果界面图1 猜单词游戏主菜单图2 人人对抗游戏选项图3 人人对抗玩家出题图4 人人对抗玩家猜单词图5 人机对抗游
3、戏选项图6 修改设置可以猜错的次数图7 修改设置显示字符的几率图8 人机对抗添加新单词图9 人机对抗玩家猜单词图10 玩家猜单词成功图11 玩家猜单词失败图12 失败后显示正确单词图13 切换皮肤选项图14 1号皮肤界面图15 2号皮肤界面图16 3号皮肤界面图17 4号皮肤界面图18 退出游戏界面3.源程序结构流程框图与说明图19 源程序结构流程图4.基本数据结构本程序中用到的主要类有:基类CGuess;派生类UserGame;派生类CompGame。(1)基类CGuessclass CGuessprotected: /只能被本类或本类的派生类中的成员函数访问 int i; /循环变量 in
4、t choice; /接受用户主菜单选择 int sub_choice; /接受用户次级菜单选择 double proba; /显示字符的概率(0-1) int guess_num; /总共可猜的次数 int wrong_num; /猜错的次数 int check; /Lchosen函数中检测输入的单词与已输入的字符是否重复的标识符 int check_2; /Test函数中判断字母是否为正确字母的标识符 int end; /猜单词过程中的循环结束标识符 int chosen_counter; /选对的字符个数 string word; /欲猜的单词 char letter; /玩家输入的字符
5、 string temp; /玩家看见的不断更新的输出 string letter_chosen; /选择过的字符集public: CGuess(); void MainMenu(); /输出程序主菜单,接收用户选择 void MainPro(); /运行程序主菜单,处理用户选择 void SubMenu(); /输出程序次级菜单,处理用户选择 void SubPro(string& word); /人人和人机对抗模式的公共代码部分 void ChangeSkin(); /切换游戏皮肤 void InitialSet(); /修改设置值 void Lchosen(char letter,str
6、ing& letter_chosen,int& check,int& chosen_counter,int i); /判断输入的字符是否是单词的一部分,若不是,将其放入已输入过的错误字符集中 void Test(string word,char letter,int& wrong_num,string& temp,int i); /判断输入的字符是否是单词中的字符,如果是,替换到正确位置 void Drawman(int guess_num,int wrong_num,int i); /画上吊的人形;(2)派生类UserGameclass UserGame:public CGuess priv
7、ate: int word_check; /检查第一个玩家输入的是否是单词 string display_word; /欲显示的单词 string guess_word; /第二个玩家输入猜想的单词public: UserGame(); void Pro_1(); /连接人人对抗与基类成员函数SubPro(string& word) void Password(); /一个玩家给出单词时以密码形式显示;(3)派生类CompGameclass CompGame:public CGuessprivate: int n; /words.txt中的单词个数public: CompGame(); voi
8、d Pro_2(); /连接人机对抗与基类成员函数SubPro(string& word) void WordCounter(); /显示单词库中的单词数量 void OpenWordFile(); /打开单词库,随机取出一个单词赋给word void SaveWordFile(); /向单词库输入新单词;5.课程设计遇到的技术问题与解决思路问题1:光盘文件中的代码过于冗长,尤其是usergame(int i)和compgame(int i)这两个函数,里面有大段的重复代码,应怎样简化该程序?光盘内的程序还是以面向过程为主,除了类draw以外,都使用一个个函数来实现功能。课程设计要求将猜单词的
9、函数与对应的数据封装到类中,并改写主程序,使程序简化,并且书上给出了定义为一个类的两个对象的范例。而我根据实际要求和个人习惯,将程序改写为由一个基类(CGuess)和两个派生类(UserGame和CompGame)组成的程序,具体的结构在报告前文已经说明。经过这样的改写之后,程序的数据结构变得更加清晰合理,更加优化。当然,我的程序也还存在一些缺点,仍需改进。问题2:游戏界面的色彩过于单调,怎样改变游戏界面背景及文字的颜色?CMD中有一种color命令,它可以改变命令行程序的背景与文字的颜色,例如命令color ec,它是让背景颜色变为黄色,文字颜色变为红色。color后面的是两个十六进制数字,
10、第一个对应于背景,第二个对应于文字,各个数字与颜色的对应关系可以在命令行程序中输入color /来查询。当然,在本游戏的程序中,我设计了基类CGuess的成员函数ChangeSkin(),调用system函数执行CMD命令。函数ChangeSkin()中运用dowhile语句和switch语句来处理用户的选择,其具体代码如下:void CGuess:ChangeSkin() int skin; int error; coutendl; cout 猜单词游戏 endl; cout 完成者:何超翔 指导老师:张爱军 endl; coutendl; cout 皮肤列表(输入0切换回默认皮肤) end
11、lendl; cout 1. 绿色背景浅绿文字 2. 绿色背景浅蓝文字 endl; cout 3. 红色背景黄色文字 4. 黄色背景红色文字 endlendl; coutendl; coutskin; do switch(skin) case 0: system(color 07); error=0; break; case 1: system(color 3a); error=0; break; case 2: system(color 3b); error=0; break; case 3: system(color ce); error=0; break; case 4: system(
12、color ec); error=0; break; default: error=1; cerrskin; break; while(error);问题3:在人人对抗模式中,怎样把第一玩家打出的单词以密码的形式显示出来?课程设计要求在人人对抗时,一个玩家给出单词时,单词不显示在屏幕上,字符用“*”号显示,其类似于密码的输入。本程序在基础上还要有些限制条件,就是接收的字符必须是字母,当字母为大写时还要转化为小写;如果输入的不是字母,要提示重新输入。在输入密码时,如果用一般的cin流接收,则密码会显示在屏幕上,起不到保密作用;但如果用getch()函数来接收字符,则输入字符会直接进入内存,然后将
13、其替换成*显示即可。我参考了21点游戏的程序设计思想,设计了派生类UserGame的成员函数Password(),其具体代码如下:void UserGame:Password() char str20; char ch; string blank; string t; i=0; int j=0; cout请第一位玩家先输入一个单词:=97&stri=122) cout=65&stri=90) stri=stri+32;j+; cout*; cout.flush(); ch=getch(); else if(stri=90&stri=112) cout*; cout.flush(); ch=ge
14、tch(); i+; for(i=0;ij;i+) word.replace(i,1,1,stri); t=word; word=blank; do word_check=0; for(i=0;it.length();i+) if(!isalpha(t.at(i) word_check=1; if(word_check=1) coutn你输入的不是单词,请重新输入!endl; Password(); else word=t; while(word_check=1);问题4:在人机对抗模式中,怎样准确地自动统计单词库中的单词个数?我认为,这个问题与上学期的C+上机实践第56页的S16_4类似,由
15、于单词库words.txt是逐行存储单词的,一行一个字符串,因此我们只需要定义一个足够大的多行字符串空间(string10020),然后从文本文件中逐行接收字符串;但与S16_4不同的是,我们需要用eof函数来判断是否读到文本文件的底端。我为此设计了派生类CompGame的成员函数WordCounter(),其具体代码如下:void CompGame:WordCounter() /参考C+上机实践P56 S16_4的方法,有所改动 char string10020; n=0; ifstream count; count.open(words.txt); do count.getline(str
16、ingn,20); n+; while(!count.eof(); coutendlendl单词库中的单词个数为 n 个endl; count.close();6.设计中的感悟在完成此次C+课程设计的过程中,我收获颇丰,体会颇深。实践是认识的目的,上学期我们学习的C+程序设计的基础知识,在这学期的课程设计中得到了充分的运用、巩固,程序设计思维得到了提升。本次课程设计主要涉及了数组、类与对象、继承与派生、文件流等知识与各种函数的灵活运用,实际上我在课程设计的过程中就已经无形地复习、巩固了一遍,并且在运用的过程中加深了理解。在日常生活中,我们往往只会出于娱乐的目的去玩一些类似的小游戏,却往往并没有深入地思考这些小游戏背后蕴藏的算法和数据结构,没有去想这些游戏是怎么做出来的。我当时选题目的时候过于匆忙,没有去选那些更难的题目,而选了这个猜单词游戏,没想到的是,我在完成课程设计的过程中愈发地对这一任务感到充满兴趣,进而强有力地推动了我完成了这次课程设计。当我在编程时遇到一个个问题时,我并没有感到挫败,我反而更受激励,通过独立思考,翻阅书籍,上网查找资料等各种手段去解决。当我解决完问题的时候,我的感觉是一种释然。编程如此,人生亦如此,我更应激励自己,克服一系列的困难,实现我的目标。最后,感谢张爱军老师对我的指导!
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1