资源描述
C++猜单词课程设计——猜单词游戏(完整版)
(文档可以直接使用,也可根据实际需要修改使用,可编辑 欢迎下载)
VC++课程设计报告
——猜单词游戏
VC++课程设计报告
1. 功能:
课程设计题目的功能:
一个猜单词游戏。两人游戏时,由一个玩家给出一个单词,在人与计算机游戏时,由计算机给出一个单词,另一个玩家根据组成单词的字母个数猜出单词,猜的次数可以指定,若猜不中,显示一个上吊的人形。
(1) 将猜单词的函数与相应的数据封装到类中,并改写主程序,使程序简化。
(2) 根据所猜单词的字母个数,给出指定几率的提示字母,显示于单词中的正确位置。
(3) 在进入猜单词的过程后,首先显示菜单询问是开始猜单词还是修改设置,默认的修改次数为4,默认显示字符的几率为20%,若要修改这个设置,在显示菜单中选择设置选项进行修改。
(4) 在人人对抗时,一个玩家给出单词时,单词不显示在屏幕上,字符用“*”显示。
(5) 猜单词时,输入一个单词,判断函数改为判断输入单词的字符是否与所猜单词一一对应,将猜中的字符显示出来。
(6) 在人机对抗时,可以随机读取单词,也可以选择向单词库输入单词,同时,将单词库中单词的个数显示出来,并根据单词库中单词个数的多少决定随机选取的范围。
程序设计的思想和方法
(1) 类的封装
画上吊人形的类已经封装起来,这部分程序基本不用改了,主要是对人人对抗和人及对抗操作部分类的封装。可以定义一个类的两个对象,也可以定义为一个基本类和一个派生类的对象,成员函数可根据对象的不同分别调用,数据结构如下:
Class CGuess
{
private:
string Word; //欲猜的单词
double Proba; //显示字符的概率0—1
int GuessNum;//总共可猜的次数
int WrongNum;//猜错的次数
string DisplayWord;//欲显示的单词
string GuessWord;//第二个玩家输入猜想的单词
int nLen;//输入单词的长度
public:
CGuess();//构造函数
void InitialSet();//修改设置值
void InputWord();//输入单词并初始化成员函数
void InputGuess();//接收用户所猜的单词
int Judge();//判断是否猜中,猜中返回0,猜不中返回1或-(death)
int ShowDisplay();//显示单词及上吊人形,程序结束返回1
int OpenWordFile();//打开单词库,随机取出一个单词赋给Word,成功返回1
int SaveWordFile();//向单词库输入新单词,正确返回1
(2) 程序主体结构的设置
该设置基本上全部修改了原程序的结构,在main函数中分别定义人人对抗和人机对抗的对象。在键入对应的菜单选项后,进入操作函数,操作函数的参数即是对应对象的引用。同样,若有下级菜单的函数一样用该对象的引用参数,这样,可保证对象的唯一性。
主菜单:
1. 人人对抗(以人人对抗对象的引用作为参数调用子程序)
2. 人机对抗(以人机对抗对象的引用作为参数调用子程序)
人人对抗菜单
1. 开始猜单词
2. 设置系统(即设置显示字符的概率和允许猜错的次数)
3. 退出
人机对抗
1. 开始猜单词
2. 设置系统(即设置显示字符的概率和允许猜错的次数)
3. 向单词库中添加单词
4. 退出
(3) 人人对抗时输入欲猜单词的隐藏
一个玩家给出单词时,单词不显示在屏幕上,字符用“*”号显示。本程序在基础上还要有些限制条件,就是接收的字符必须是字母,当字幕为大写时还要转化为小写。如果输入的不是字母要提示重新输入。
(4) C++用于处理字符串变量的新的数据类型——字符串类型(string类型)
在原程序字符串的操作中用了一种新的数据类型——String,该类型是一个字符串类,可以定义对象。它在使用方法上和char,int类型一样,可以用来定义字符串变量,即用一个名字代表一个字符序列。
程序设计的特点
(1) 增设了单词库,并且输入50个单词,以便使用。
(2) 人人对抗和人机对抗时显示是否有重复字母
2. 课程设计的详细设计:
主菜单
人人对抗
人机对抗
退出
开始猜单词
退出
开始猜单词
设置系统
设置系统
退出
向单词库中添加单词
程序主体结构图如下:
程序详细结构:
1.主菜单程序:
void CGuess::GetChoice(){
cout<<endl<<endl<<endl;
cout << " 猜单词游戏 " << endl << endl;
cout <<" 制 刘健莹 " << endl << endl;
cout << "***********************************************************" << endl;
cout << endl;
cout << " 按1 人人对抗模式" << endl;
cout << " 按2 人机对抗模式" << endl;
cout << " 按3 退出" << endl;
cout << endl;
cout << "***********************************************************" << endl << endl;
cout<<" 请您选择: ";
cin>>Choice; // 得到用户选择
while (!cin||Choice <1 || Choice >3) // 简查是否无效
{
cout << " 无效输入" << endl
<< " 请再输入: ";
Flush(cin);
cin>>Choice;
} // 完成简查, 得到有效输入,m_Choice变量的值被修改,清屏
system("cls");
}
2.子菜单程序:
int CGuess::InitialSet()
{
int exit=0;
if(Choice==1)
{
cout<<" 人人对抗"<<endl;
cout << "***********************************************************" << endl;
cout<<"按1开始玩游戏"<<endl;
cout<<"按2修改设置值"<<endl;
cout<<"按3退出"<<endl;
cout<<endl;
cout<<"*************************************************************"<<endl;
cout<<" 你的选择:"<<endl<<endl;
cin>>Choice2; }
else
{
cout<<" 人机对抗"<<endl;
cout << "***********************************************************" << endl;
cout<<"按1开始玩游戏"<<endl;
cout<<"按2修改设置值"<<endl;
cout<<"按3向单词库输入单词"<<endl;
cout<<"按4退出"<<endl;
cout<<endl;
cout << "***********************************************************" << endl;
cout<<" 你的选择:"<<endl<<endl;
cin>>Choice2;
}
while(!cin||Choice2 < 1 || Choice2 > 4)
{
cout<< " 无效输入" << endl
<< " 请再输入: ";
Flush(cin);
cin>>Choice2;
}
system("cls");
if(Choice2==1) cout<<GuessNum<<endl;
if(Choice2==2){
cout<<" 你要几次猜词机会(4 - 10): ";
cin>>GuessNum; //输入猜词次数
while (!cin||GuessNum < 4 || GuessNum > 10)
{
cout << " 无效输入" << endl
<< " 请再输入- 你要几次猜词机会(4 - 10): ";
Flush(cin);
cin >>GuessNum;
}
}
while(!cin||Choice2 < 1 || Choice2 > 4)
{
cout<< " 无效输入" << endl
<< " 请再输入: ";
Flush(cin);
cin>>Choice2;
}
system("cls");
if(Choice2==1) cout<<Proba<<endl;
if(Choice2==2){
cout<<" 你要百分之几的字母显示出来(10 - 80): ";
cin>>Proba; //输入显示字母百分数
while (!cin||Proba < 10 || Proba > 80)
{
cout << " 无效输入" << endl
<< " 请再输入- 你要百分之几的字母显示出来(10 - 80): ";
Flush(cin);
cin >>Proba;
}
}
if(Choice2==3)
{
if(Choice==1)
{
exit=1;
}
else
{
SaveWordFile();
InitialSet();
}
}
if(Choice2==4)
{
exit=1;
}
return exit;
}3.修改默认设置程序:
if(Choice2==1) cout<<GuessNum<<endl;
if(Choice2==2){
cout<<" 你要几次猜词机会(4 - 10): ";
cin>>GuessNum; //输入猜词次数
while (!cin||GuessNum < 4 || GuessNum > 10)
{
cout << " 无效输入" << endl
<< " 请再输入- 你要几次猜词机会(4 - 10): ";
Flush(cin);
cin >>GuessNum;
}
}
while(!cin||Choice2 < 1 || Choice2 > 4)
{
cout<< " 无效输入" << endl
<< " 请再输入: ";
Flush(cin);
cin>>Choice2;
}
system("cls");
if(Choice2==1) cout<<Proba<<endl;
if(Choice2==2){
cout<<" 你要百分之几的字母显示出来(10 - 80): ";
cin>>Proba; //输入显示字母百分数
while (!cin||Proba < 10 || Proba > 80)
{
cout << " 无效输入" << endl
<< " 请再输入- 你要百分之几的字母显示出来(10 - 80): ";
Flush(cin);
cin >>Proba;
}
4.默认的游戏设置程序:
Proba=20; //显示单词字母个数百分比
GuessNum=4; //玩家猜词的机会
5.将单词输入进单词库中的函数:
void GuessGame::saveWordFile()
{
int n=50,i,j;
ofstream out;
out.open("words.txt");
if(!out)
{
cout<<"不能打开单词库"<<endl;
}
cout<<"单词库中有50个单词"<<endl;
cout<<"向单词库中输入多少个单词"<<endl;
cin>>j;
cout<<"请向单词库中输入"<<j<<"个单词"<<endl;
for ( i = 0; i < j; i++)
{string word; // 输入单词
getline(cin,word);
n=n+1;
out<< word;
cout<<"单词库中有"<<n<<"个单词"<<endl;
}
out.close();
}
6.显示猜对的单词:
void GuessGame::test(string word, char letter, int& numwrong, string& temp)
{
static int m;
int check2 = 0; // 判断输入的字符是否为组成单词的字符,正确为1
if (letter == word.at(m)) //若单词中有这一个字符
{
temp.replace(m, 1, 1, letter);
check2 = 1;
}
if (check2 == 0) //若单词中没有这一个字符
{
cout << endl;
cout << "Wrong letter" << endl;
system("pause");
numwrong++;
}
if(m<(word.length()-1)){m++;}
else m=0;
}
7.输出给定几率的字母:
for (i = word.length() * Proba; i < word.length(); i++)
{
temp.replace(i, 1, 1,'*');
}
8.游戏程序主体运行:
int CGuess::Run(){
int exit = 0; //主循环是否退出的变量,1时退出
do { //主循环
system("cls"); // 执行系统命令清屏
GetChoice(); // 给出说明并得到选择
switch(Choice)
{
case 1:
Game(); // 与人对战
break;
case 2:
Game(); // 与电脑对战
break;
case 3:
cout << " 再见" << endl<<endl; // 退出
exit = 1;
break;
default:
cout << " 无效输入 - 请再输入" << endl; // 无效输入
}
} while (exit != 1); //退出主循环
system("pause"); // 执行系统命令:暂停
return 0;
}9.在人人对抗时,一个玩家给出单词时,单词不显示在屏幕上,字符用“*”号显示。
#define N 13 //为任意一个字符(包括空白字符)的ASC||码值
void CGuess::password()
{
char str[20];
char ch;
int i=0,a=0,j=0;
string word,Word,worD;
cout<<"请第二位玩家输入单词: "<<endl;
cout.flush(); //请输出缓冲区
ch=getch();
while(ch!=13)
{
str[i]=ch;
if(str[i]>=97&&str[i]<=122)
{
cout<<'*';j++;
cout.flush();
ch=getch();
}
else if(str[i]>=65&&str[i]<=90)
{
str[i]=str[i]+32;j++;
cout<<'*';
cout.flush();
ch=getch();
}
else if(str[i]<=65||(str[i]>=90&&str[i]<=97)||str[i]>=112)
{
cout<<"*";
cout.flush();
ch=getch();
}
i++;
}a=j;for(i=0;i<a;i++)
{
word.replace(i, 1, 1, str[i]);
}
Word=word;word=worD;
int wordcheck;
do { // 检查用户输入单词是否有误
wordcheck = 0;
for (int i = 0; i <Word.length(); i++)
if (!isalpha(Word.at(i))) //isalpha();word.at();
{
wordcheck = 1;
}
if (wordcheck == 1){
cout << " 无效 - 请第二位玩家重新输入: ";
password();Word=word;word=worD;
}
} while (wordcheck == 1);
w=ch;
}
int CGuess::UserWord()
{
cout<<" 人人对战"<<endl;
cout<< " ---------------------------------------" << endl << endl;
cout<<" 猜词机会:"<<GuessNum<<endl;
cout<<" 显示字母:"<<Proba<<'%'<<endl;
password();
Length=Word.length();
return 1;
}
10.主体的类的定义
class CGuess{
private:
string Word,word,worD; //要猜的单词
string DisplayWord; //用户所见的单词
char *pWord1;
char *pWord2;
int Proba; //显示单词字母个数百分比
int GuessNum; //玩家猜词的机会
int WrongNum; //玩家猜错的次数
int ChosenCounter;//玩家猜过的字母个数
string LetterChosen; //玩家已经猜过的字母
int Choice; //玩家的选择
int ShowNum; //显示字母个数
int Length; //所猜单词的长度
int LetterNum; //单词中的字母个数
int i; //循环的记数变量,使每次游戏都不一样
int Check; //用户输入字母是否正确
int Choice2;
int w;
public:
CGuess();
int InitialSet();
int SaveWordFile();
int UserWord(); //玩家出词
int RndWord(); //电脑出词
void ReplaceWord();
void isChosen(char);
void Judge(char);
int Run(); //运行
void GetChoice(); //得到选择
void Game(); //游戏主要函数
void Set(); //设置
void password();
};
3. 调试程序的过程:
1. 主函数若出现在前面,应将其他函数先定义,或将主函数后置。
2. 在程序开头须将所用函数的文件包含,否则函数不得使用。
3. 人人对抗时,输入单词未显示*,应先设置显示部分,然后输入单词。
4. 当使用getch()时,应先加头文件conic.h,否则无法使用。
5. 人机对抗程序会出现不出现单词,直接显示猜词正确,随机函数rand()应除50求余。
6. 保密部分无法识别大小写,用ASCII码将大写字母转化为小写字母。
7. 人人对抗过程中输入单词,输出*,但是无论退格还是回车都输出*,在保密函数中没有设置输入回车或空格就跳出函数的部分。
8. 运用保密函数时出现输出无效输入。
9. 人人对抗中输入单词后显示*,但是单词没有返回原程序,造成没有猜单词的过程,只有最后结果“恭喜你,猜对了!”
10. 人机对抗无法找到words..txt文件,需要先将words文档转化为文件格式,才能应用。
4. 输入输出数据:
以人人对抗模式输入love为例:
1.运行程序,出现主菜单,输入1
2,.出现人人对抗模式菜单栏,输入2
3.修改默认设置
4.第二个玩家输入单词love
5.出现猜单词程序
6.输出上吊人形
7.出现正确答案
附:猜单词过程:
正确输入
错误输入
向单词库中输入单词:
5. 课程设计总结:
通过这次课程设计,我懂得了如何将所学的知识运用起来,与实际相结合,也让我能够在以后的学习中能够想有所学,学有所用,多多联系实际,用知识帮助他人。课程设计中,我掌握了类的定义和调用,数组的运用,菜单栏的设置等等,同时,程序设计过程中,懂得了如何将不会的知识学会,如何将会的知识灵活熟练地应用,也懂得了以后的学习也要勤动脑思考,把知识转化为自己的,提高了自己的创新能力,动手能力,思考能力,为我今后的学习打下良好的基础。
6. 程序源代码附录
#include <iostream> // 标准输入输出[cin;cout]
#include <string> // 字符串处理[string.length();at();]
#include <cctype> // 字符处理和检测
#include <fstream> // 文件流
#include <cstdlib> // 使用随机函数用
#include <time.h> // 得到更好的随机数用
#include <conio.h>
// draw类定义
#ifndef DRAW_H // 检测是否已经包含
#define DRAW_H
class draw
{
public:
draw(); // 构造函数
// 成员函数
void rope(); // 绳子
void head(); // 头
void neck(); // 颈
void leftarm(); // 左臂
void rightarm(); // 右臂
void waisttop(); // 腰
void leftleg(); // 左腿
void rightleg(); // 右腿
};
#endif
#ifndef GUESS_H
#define GUESS_H
using namespace std;
//程序类定义
class CGuess{
private:
string Word,word,worD; //要猜的单词
string DisplayWord; //用户所见的单词
char *pWord1;
char *pWord2;
int Proba; //显示单词字母个数百分比
int GuessNum; //玩家猜词的机会
int WrongNum; //玩家猜错的次数
int ChosenCounter;//玩家猜过的字母个数
string LetterChosen; //玩家已经猜过的字母
int Choice; //玩家的选择
int ShowNum; //显示字母个数
int Length; //所猜单词的长度
int LetterNum; //单词中的字母个数
int i; //循环的记数变量,使每次游戏都不一样
int Check; //用户输入字母是否正确
int Choice2;
public:
CGuess();
void InitialSet();
int SaveWordFile();
int UserWord(); //玩家出词
int RndWord(); //电脑出词
void ReplaceWord();
void isChosen(char);
void Judge(char);
int Run(); //运行
void GetChoice(); //得到选择
void Game(); //游戏主要函数
void Set(); //设置
void password();
};
#endif
using namespace std; // 用名字空间std
//构造函数
draw::draw(){}
void draw::rope() // 输出上吊绳
{ cout << " |"; }
void draw::head() //头
{ cout << " O";}
void draw::neck() //颈
{ cout << " |"; }
void draw::leftarm() //左臂
{ cout << "//"; }
void draw::rightarm() //右臂
{ cout << " \\"; }
void draw::waisttop() //腰
{ cout << " { }"; }
void draw::leftleg() //左腿
{ cout << "//"; }
void draw::rightleg() //右腿
{ cout << " \\"; }
//-------------------------------------------------------------------------------
//清理输入流
inline istream& Flush(istream& stream)
{
stream.clear();
int chars_to_skip = stream.rdbuf()->in_avail();
return stream.ignore(chars_to_skip);
}
//根据设置的次数和实际猜错的次数画上吊人形
void drawman(int numguess, int numwrong, int i)
{
draw d;
for (i = 0; i <= numwrong; i++)
{
if (numguess == 4)
{
switch(i)
{
case 1: d.rope(); cout << endl; d.head();
cout << endl; d.neck(); break;
case 2: cout << endl; d.leftarm();
d.rightarm(); break;
case 3: cout << endl; d.waisttop(); break;
case 4: cout << endl; d.leftleg(); d.rightleg();
cout << endl << endl << "死翘翘了!" << endl; break;
}
}
else if (numguess == 5)
{
switch(i)
{
case 1: d.rope(); break;
case 2: cout << endl; d.head(); cout << endl; d.neck(); break;
case 3: cout << endl; d.leftarm(); d.rightarm(); break;
case 4: cout << endl; d.waisttop(); break;
case 5: cout << endl; d.leftleg(); d.rightleg();
cout << endl << endl << "死翘翘了!" << endl; break;
}
}
else if (numguess == 6)
{
switch(i)
{
case 1: d.rope(); break;
case 2: cout << endl; d.head(); cout << endl; d.neck(); break;
case 3: cout << endl; d.leftarm(); d.rightarm(); break;
case 4: cout << endl; d.waisttop(); break;
case 5: cout << endl; d.leftleg(); break;
case 6: d.rightleg(); cout << endl << "死翘翘了!" << endl; break;
}
}
else if (numguess == 7)
{
switch(i)
{
case 1: d.rope(); break;
case 2: cout << endl; d.head(); cout << endl; d.neck(); break;
case 3: cout << endl; d.leftarm(); break;
case 4: d.rightarm(); break;
case 5: cout << endl; d.waisttop(); break;
case 6: cout << endl; d.leftleg(); break;
case 7: d.rightleg(); cout << endl << "死翘翘了!" << endl; break;
}
}
else if (numguess == 8)
{
switch(i)
{
case 1: d.rope(); break;
case 2: cout << endl; d.head(); break;
case 3: cout << endl; d.neck(); break;
case 4: cout << endl; d.leftarm(); break;
case 5: d.rightarm(); break;
case 6: cout << endl; d.waisttop(); break;
case 7: cout << endl; d.leftleg(); break;
case 8: d.rightleg(); cout << endl << "死翘翘了!" << endl; break;
}
}
else if (numguess == 9)
{
switch(i)
展开阅读全文