#include<iostream>
#include<cstring>
#include<fstream>
using namespace std;
int var;
class Idiom{//定义类类名为Idiom
public:
ifstream a;//相当于input输入操作来定义a,可用于读文件
string item;//定义一个字符串,将所有的成语储存到里面
Idiom()//类里面定义打开文件函数
{
a.open("10.txt");//open函数打开文件
while(getline(a,cy1))//getline获取文件内容(按行获取)
{
item+=cy1.substr(0,8);//储存每行的成语
}
a.close();//关闭打开的文件
}
private:
string cy1;//定义字符串储存成语
};
class Game:public Idiom{//定义游戏类把打开文件的类公共
public:
bool inspectcy(string cy,string eachcy); //检测是否为四字成语 (成语是字符串型)
bool inspectjl(string lastcy,string cy); //检测是否接龙
void ready(); //开始游戏
string tishi(string); //提示功能
void printcy(string); //输出是否为四字成语
bool inspectsamecy(string); //检测是否出现同一个成语
string exist; // 用来储存出现过的成语
};
bool Game::inspectcy(string cy,string eachcy)//检测是否为四字成语
{
if(eachcy.compare(cy)==0 )//"eachidiom.compare(idiom)==0" 这段代码的意思是比较两个成语是否相等。如果两个成语相等,则返回0。
return true;
return false;
}
bool Game::inspectjl(string lastcy,string cy)//检测是否接龙
{
string firsti=cy.substr(0,2);//成语首个字
string endi=lastcy.substr(6,8);//成语末尾字
if(firsti.compare(endi)==0)//对比是否接龙
return true;
else
return false;
}
bool Game::inspectsamecy(string cy)//检测是否出现同一个成语
{
int pos=exist.find(cy); //通过find()函数当exist中含有cy成语时 则查询失败则返回 string::npos
if(pos!=string::npos)
return true;
return false;
}
void Game::ready()//开始游戏
{
string player;//玩家及电脑成语
string beforecy;//储存上一次的成语(从第二个成语开始)
int tag1=0;//标记从第二个开始 -
cout<<"***********功能面板***********"<<endl
<<"* *"<<endl
<<"* 玩家无法接龙退出游戏输入——1 *"<<endl
<<"* ---- 电脑成语输入 ——2 *"<<endl
<<"* *"<<endl
<<"******************************"<<endl;
cout<<"游戏开始,请输入一个四字成语。"<<endl;
do{
cin>>player;//用户输入成语
tag1++;//标记--从第二个成语开始储存
if(player.compare("1")==0) //退出游戏
{
break;
}
if(player.compare("2")==0)//提示功能
{
player=beforecy;//成语等于之前的储存的成语
string zhchar=player.substr(6,8);//截取输入的最后的字放入最后存储的里面
player=tishi(zhchar); //提示的成语以最后储存的字等于电脑成语
cout<<player<<endl;
}
printcy(player); //判断是否为四字成语
if(tag1>=2&&!inspectjl(beforecy,player))//判断输入和之前的比较,就是判断接龙是否成功
//tag1>=2 用于提示功能
{
player=beforecy;//若接龙失败,则为原来的成语接龙
cout<<"接龙失败,以上一个的成语继续"<<endl;
}
exist.append(player); // 用来储存出现过的成语,一直追加内存空间。
if(var)
beforecy=player;//将输入的保存到之前的数组中
}while(1);
}
void Game::printcy(string idiom)//输出是否为四字成语
{
int tag=0;
ifstream eachcy2;//全部的成语
string eachcy; //每行的单个成语
string cy1; //缓存的整行成语
eachcy2.open("10.txt");
while(getline(eachcy2,cy1))
{
eachcy=cy1.substr(0,8);
if(inspectcy(idiom,eachcy)&&!inspectsamecy(idiom)) //inspectcy()检查是否为四字成语。inspectsamecy()检查是否重复。
{
cout<<"==>";
tag=1;
var=1;
break;
}
continue;
}
if(tag!=1)
{
cout<<"非成语或出现重复,请重新输入。"<<endl;
var=0;
}
eachcy2.close();
}
string Game::tishi(string itemts) //提示功能
{
ifstream hangcy;//所有成语
string liecy;//每行成语
string eachidiom; //暂存读取到的四字成语
string baocun1; //存取当前成语的第一个字
int panduan=0; //通过panduan的值判断是否成功找到满足条件的成语。
string backcy; //返回的提示成语
hangcy.open("10.txt");
while(getline(hangcy,liecy)) //将hangcy中的成语按行读取到liecy中
{
eachidiom=liecy.substr(0,8); //读取的成语暂存到eachidiom中
baocun1=eachidiom.substr(0,2);//首字放在保存中
if(itemts.compare(baocun1)==0) //如果 itemts == baocun1则为0 就是之前存储的前一个的最后 个字 与保存的最后一个字做对比
{
backcy=eachidiom; //将成语返回提示的成语中
if(inspectsamecy(backcy)) //判断该成语前是否出现 如果之前出现则直接重新执行while语句
continue;
panduan=1;
break;
}
}
hangcy.close();
if(panduan==1)
return backcy; // 此时 backcy为满足所有条件的的成语。
return "你赢了"; //没有找到成语只能结束游戏
}
int main()
{
Game a; //定义游戏a
a.ready(); //准备游戏
return 0;
}
实 训 报 告
一、实训目的
数据结构与算法设计实训是软件工程专业集中实践环节之一。数据结构与算法设计是本专业一门重要的专业基础课程,是一门关键性核心课程。该课程较系统地介绍了软件设计中常用的数据结构以及相应的存储结构和实现算法,介绍了常用的多种查找和排序技术。该课程将为整个专业的学习以及软件设计水平的提高打下良好的基础。
数据结构与算法设计是一门实践性较强的课程,为了学好这门课程,必须在掌握理论知识的同时,加强上机实践,设置实训环节十分重要。
二、实训项目要求
本次实训我选择的题目是成语接龙小游戏设计。
游戏已经成为当代社会不可或缺的一部分。编程模拟成语接龙游戏。玩家输人一个成语,程序则能输出一个成语,重复上述过程直到一方无法接龙为止。成语接龙游戏规则是程序输出的成语中的第.一个汉字要与玩家输人的成语中的最后一个汉字相同,接着玩家继续输人的成语要保证其中的第一个汉字与前面程序输出的成语中的最后一个汉字相同,如此重复,直到玩家不能继续输人正确的成语或程序不能输出正确的成语,则游戏结束。
本次设计使用的编程语言是C++语言,使用的Dev-C++编译实现。
功能需求:
(1) 计一个四字成语类Idiom,包含成语内容,首字母的拼音,末尾字母 的拼音。
(2) 设计一个成语接龙游戏类Game,系统可以判断用户的回答是否是成语,并且可以按照前一个成语,判断是否接龙成功。如果回答的成语接龙正确,则以新的成语作为新的起点,继续接龙;如果不成功,继续为原有的成语接龙。
(3) 设计提示功能,引导用户接龙成功。
(4) 使用外部文件存储相关数据。
解题思路为:
1.使用外部文件储存,创建一个10.txt文件来储存成语,组成成语数据库,用fstream类导入成语库。
2.分别用两个ifstream,声明出两个变量,分别储存成语与拼音,放在Idiom类里。
3.再定义出一个Game类,声明出6个函数。
l inspectcy函数,用来匹配是否为成语。
l inspectjl函数,用来检测是否接龙。
l inspectsamecy函数,用来检测是否在游戏里存在出现过的成语。
l tishi函数,用来做提示功能。
l printcy函数,用来输出结果。
l ready函数,用来启动游戏。
l String exist成语,用来储存出现过的成语
4.在ready函数里,根据玩家输入1或2来决定是否退出或者提示。 这个项目中最关键的一点就是,第一次输入的成语必须是一个四字成语,否则直接退出。于是,提示功能只能在第二轮输入开始才能使用。在每次输入成语后,printcy函数都会检测是否为四字成语,是否存在出现的成语(当第二次输入时)。当用户需要提示时,输入“2”,printcy函数将输进来的cy又赋值为上一个成语(因为“2”不是成语,这也是需要第二次输入才能使用提示功能的原因)。ready函数里声明出一个变量cy,用来给用户输入成语,然后传入printcy函数输入结果。由于需要判断是否接龙,于是在函数里面加入判断语句if(),把cy放入inspectjl函数里,如果不接龙,则实现if语句里面的内容。
三、实训项目实现
1、功能分析
程序流程图
2、数据结构分析
(1)首先定义类名Idiom,利用ifstream定义a来读取文件,用open和getline函数分别打开文件和按行获取文件内容,定义item储存获取的文件内容,储存完关闭打开的文件。
(2)再定义类Game,里面定义需要的函数分别有 bool inspectcy(string cy,string eachcy)检测是否为四字成语 (成语是字符串型),bool inspectjl(string lastcy,string cy)检测是否接龙 ,void ready()开始游戏;string tishi(string)提示功能 ; void printcy(string)输出是否为四字成语; bool inspectsamecy(string)检测是否出现同一个成语 ; string exist 用来储存出现过的成语;
(3) 在函数中主要涉及类的定义,io流函数的运用,bool函数用于判断的情况 ,定义字符串来存储读取的四字成语,通过数组来提取四字成语的第一个字和最后一个字并用compare函数进行比对,重点是提示功能也就是电脑输入,通过对比最后一个字,放在tishi函数中然后输出即能电脑输出。
3、关键算法
上图为提示成语流程图
该算法通过设计成语的存储进而比较成语的首字与上一个成语的尾字,如果相同则可以输入2来保存到返回提示成语存储中,然后去判断要提示的成语是否之前出现过,没有出现过就判断是否能找到后一个成语,判断为1则有后一个成语输出,没有后一个成语则输出你赢了。
在上面的流程图中如果存储的尾字与输入的首字不相同则会输出接龙失败,以上一个的成语继续(图中未标识)具体效果可以查看运行结果图。
4、运行测试
运行结果展示
(1)玩家胜利
(2)输入非成语
(3)出现重复
(4)电脑接龙
(5)接龙未按首尾相匹配
四、实训总结
通过这次实验,
,最主要的是方法和思路,每一个C程序的编写都必须提前在脑中捋好思路,想好方法,才可以顺畅的进行;其次是耐心和仔细,如分号的使用、大小写的区分、括号的匹配、语句的拼写、for循环的判断等必须认真。
对于这类选择结构程序设计的问题,很容易出现else和if无法配对的情况,在设计算法时应仔细检查括号的问题,做本题时,尝试了很多方法才最终做对,这也告诉我们要努力去尝试,在尝试中找到解决问题的方法