数据结构实训----拯救公主

/***********************************************************
* 版权所有 (C)2016,bigice
*
* 文件名称: main.cpp
* 文件标识:main
* 内容摘要:函数文件
* 其它说明:主函数
* 当前版本: V8.0
* 作 者:何大冰
* 完成日期: 20161226
*
* 修改记录1:
* 修改日期 :20161216
* 版本号: V1.0
* 修改人: 何大冰
* 修改内容:整理思路,创建基本架构
*
* 修改记录2:
* 修改日期:20161217
* 版本号: V2.0
* 修改人: 何大冰
* 修改内容:游戏能够基本正常运行。
*
* 修改记录3:
* 修改日期: 20161219
* 版本号: V3.0
* 修改人: 何大冰
* 修改内容:修复大量的BUG
*
* 修改记录4:
* 修改日期: 20161219
* 版本号: V4.0
* 修改人: 何大冰
* 修改内容:程序复杂度进一步增加
*
* 修改记录5:
* 修改日期: 20161220
* 版本号: V5.0
* 修改人: 何大冰
* 修改内容:对新功能进行探索,失败,转到原来的版本
*
* 修改记录6:
* 修改日期: 20161222
* 版本号: V6.0
* 修改人: 何大冰
* 修改内容:加入了新功能
*
* 修改记录6:
* 修改日期: 20161224
* 版本号: V7.0
* 修改人: 何大冰
* 修改内容:完成游戏的大部分功能
*
* 修改记录6:
* 修改日期: 20161226
* 版本号: V8.0
* 修改人: 何大冰
* 修改内容:将程序添加注释,将初始化数据变成文件存储,修改小部分不完善的地方
**********************************************************/


main.cpp:

#include "ice.h"
void SlowDisplay(char *str)  //字体缓慢显示的函数
{
    char *p = str;
    while(!kbhit())  //检测是否有键盘输入,如果有键盘输入输出就停止
    {
        if(*p!=0)
            printf("%c",*p++);
        else
            break;
        Sleep(50);
    }
}

int main()
{
	SlowDisplay("--------------------------------拯救公主----------------------------------------");
    SlowDisplay("    魔鬼将公主捉进了城堡。英勇的王子得知此事后,");
    SlowDisplay("询问住在森林小屋的老婆婆,老婆婆告诉他城堡的地点,");
    SlowDisplay("并给了他一把威力无比的宝剑和国王的信物,于是王子踏上了拯救公主的路。。。。。。\n");
    system("cls");
    printf("-------------------------------bigice制作-------------------------------\n");
    ALGraph *G;  //邻接表
	MGraph g;  //邻接矩阵
	Ans c;  //存储问题的数组
    int *A;  //矩阵
	A=init(c);
	ArrayToList(A, Max, G);
	ArrayToMat(A, Max, g);  
	VNode p;  //头节点
	p=G->adjlist[1];
	printf("%s\n",p.data);  //游戏开始第一句话
	IFS(G,p,p.cnt,c,g);  //大冰改进的遍历方法IFS
    return 0;
}


ice.cpp:

/*********************************************************
* 版权所有 (C)2016,bigice
*
* 文件名称:ice.cpp
* 文件标识:ice.cpp
* 内容摘要:对各种参数进行初始化
* 其它说明:可以读取txt文件
* 当前版本: V8.0
* 作 者:  何大冰
* 完成日期: 20161226
*
************************************************************/

#include "ice.h"

/*********************************************************
* 功能描述:初始化矩阵,初始化问题,初始化问题的答案
* 输入参数:无
* 输出参数:无
* 返回值  :一个矩阵
* 其它说明:读取txt文件对矩阵、问题以及问题答案进行初始化
************************************************************/

int* init(Ans c)
{
	int i,j;
	char buf[300];
	int m=0;
    int *A=(int *)malloc(sizeof(int)*Max*Max);
	FILE* rc=fopen("init.txt","r"); 
	if(rc==NULL) 
	{ 
        printf("failed to open file\n"); 
        system("pause"); 
        return NULL; 
    } 
	for(i=0;i<Max;i++)
	{
		for(j=0;j<Max;j++)
		{
			fscanf(rc,"%d",A+i*Max+j);//对矩阵的初始化
		}
	}
	FILE* ra =fopen("c[i].question.txt","r"); 
	if(ra==NULL) 
	{ 
        printf("failed to open file\n"); 
        system("pause"); 
        return NULL; 
    } 
	for(m=0;m<6;m++)
	{
		strcpy(c[m].question,fgets(buf,300,ra));  //对问题的初始化
	}
	FILE* rb =fopen("c[i].answer.txt","r"); 
	if(ra==NULL) 
	{ 
        printf("failed to open file\n"); 
        system("pause"); 
        return NULL; 
    } 
	for(m=0;m<6;m++)
	{
		fscanf(rb,"%d",&c[m].answer);  //对问题答案的初始化
	}
	return A;
}

/*********************************************************
* 功能描述:对邻接表中每个顶点的数据域进行初始化
* 输入参数:无
* 输出参数:无
* 返回值  :无
* 其它说明:读取txt文件对邻接表中每个顶点的数据域进行初始化
************************************************************/

void init2(ALGraph *&G)
{
	int i=0;
	char buf[300];
	FILE* ra =fopen("adjlist[i].data.txt","r"); 
	if(ra==NULL) 
	{ 
        printf("failed to open file\n"); 
        system("pause"); 
        return ; 
    } 
	for(i=0;i<16;i++)
	{
		strcpy(G->adjlist[i].data,fgets(buf,300,ra)); //对各个顶点信息的初始化
	}
}

/*********************************************************
* 功能描述:对邻接矩阵中每个顶点的名字进行初始化
* 输入参数:无
* 输出参数:无
* 返回值  :无
* 其它说明:读取txt文件对邻接矩阵中每个顶点的名字进行初始化
************************************************************/

void init2(MGraph &g)
{
	int i=0;
	char buf[300];
	FILE* ra =fopen("g.vexs[i].name.txt","r"); 
	if(ra==NULL) 
	{ 
        printf("failed to open file\n"); 
        system("pause"); 
        return ; 
    } 
	for(i=0;i<16;i++)
	{
		strcpy(g.vexs[i].name,fgets(buf,300,ra));  //对顶点名字的初始化
	}
}


graph.cpp:

#include "ice.h"

/*********************************************************
* 功能描述:矩阵化成邻接表
* 输入参数:无
* 输出参数:无
* 返回值  :无
* 其它说明:图算法库
************************************************************/

void ArrayToList(int *Arr, int n, ALGraph *&G)
{
    int i,j; 
    ArcNode *p;
    G=(ALGraph *)malloc(sizeof(ALGraph));
    G->n=n;
    for (i=0; i<n; i++)                 //给邻接表中所有头节点的指针域置初值
	{
		G->adjlist[i].firstarc=NULL;
		G->adjlist[i].num=i;
	}
	init2(G);
    for (i=0; i<n; i++)                 //检查邻接矩阵中每个元素
        for (j=n-1; j>=0; j--)
            if (Arr[i*n+j]==1)      //存在一条边,将Arr看作n×n的二维数组,Arr[i*n+j]即是Arr[i][j]
            {
                p=(ArcNode *)malloc(sizeof(ArcNode));   //创建一个节点*p
                p->adjvex=j;
                p->info=Arr[i*n+j];                     //给权值
                p->nextarc=G->adjlist[i].firstarc;      //采用头插法插入*p
                G->adjlist[i].firstarc=p;
            }
	total(G);
}

/*********************************************************
* 功能描述:矩阵化为邻接矩阵
* 输入参数:无
* 输出参数:无
* 返回值  :无
* 其它说明:图算法库
************************************************************/

void ArrayToMat(int *Arr, int n, MGraph &g)  
{  
    int i,j,count=0;  //count用于统计边数,即矩阵中非0元素个数  
    g.n=n;  
    for (i=0; i<g.n; i++)  
        for (j=0; j<g.n; j++)  
        {  
            g.edges[i][j]=Arr[i*n+j]; //将Arr看作n×n的二维数组,Arr[i*n+j]即是Arr[i][j],计算存储位置的功夫在此应用  
            if(g.edges[i][j]!=0)  
                count++; 
        }  
    g.e=count; 
	init2(g);
}  

/*********************************************************
* 功能描述:输出邻接表G
* 输入参数:无
* 输出参数:无
* 返回值  :无
* 其它说明:图算法库
************************************************************/

void DispAdj(ALGraph *G)
{
    int i;
    ArcNode *p;
    for (i=0; i<G->n; i++)
    {
		printf("%d:\n",G->adjlist[i].cnt);;
        p=G->adjlist[i].firstarc;
        printf("%3d: ",i);
        while (p!=NULL)
        {
            printf("-->%d",p->adjvex);
            p=p->nextarc;
        }
        printf("\n");
    }
}

/*********************************************************
* 功能描述:本游戏的核心算法,bigice独创,游戏的主要步骤
* 输入参数:玩家选择的选项
* 输出参数:玩家选中的选项的内容
* 返回值  :无
* 其它说明:本游戏的核心算法,由主函数调用
************************************************************/

void IFS(ALGraph *G,VNode p1,int cnt,Ans c,MGraph g)
{
	srand(time(NULL));  
	int w,i;
	int t;
	ArcNode *p=p1.firstarc;
	if(p!=NULL)
	{
		scanf("%d",&t);
		while(t<1||t>cnt)
		{
			if(t==0) 
			{
				help(G,c,g);
				system("cls");
				printf("%s\n",p1.data);
			}
			else printf("你输入的数字有误,请重新输入\n");
			scanf("%d",&t);
		}
		system("cls");
		for(i=0;i<t;i++)
		{
			w=p->adjvex;
			p=p->nextarc;
		}
		cout<<G->adjlist[w].data<<endl;
		if(G->adjlist[w].cnt==1)
		{
			questions((rand()%(5-0+1)+0),c,G,g);
		}
		IFS(G,G->adjlist[w],G->adjlist[w].cnt,c,g);
	}
}

/*********************************************************
* 功能描述:每个头结点所连接的结点个数
* 输入参数:无
* 输出参数:无
* 返回值  :无
* 其它说明:统计每个头结点所连接的结点个数,供其他函数使用
************************************************************/

void total(ALGraph *&G)
{
	int i;
	ArcNode *p;
	p=G->adjlist[0].firstarc;
	for(i=0;i<Max;i++)
	{
		G->adjlist[i].cnt=0;
		p=G->adjlist[i].firstarc;
		while(p!=NULL)
		{
			(G->adjlist[i].cnt)++;
			p=p->nextarc;
		}
	}
}

/*********************************************************
* 功能描述:帮助函数
* 输入参数:选择帮助选项
* 输出参数:相应的操作
* 返回值  :无
* 其它说明:帮助页面,调用其他函数
************************************************************/

void help(ALGraph *G,Ans c,MGraph g)
{
	int a,m;
	printf("欢迎进入帮助页面!\n");
	printf("        ◢████████████◣ \n");
    printf("      ██████████████      \n");
    printf("       ██   ◥██◤   ██  \n");
    printf("   ◢███    ◥◤    ██◣  \n");
    printf("  ▊▎██◣        ◢█▊▊ \n");
    printf("  ▊▎██◤  ●  ●  ◥█▊▊   \n");
    printf("  ▊ ██          █▊▊  \n");
    printf("  ◥▇██ ▊      ▊ █▇◤   \n");
    printf("    ██ ◥▆▄▄▄▄▆◤ █▊   ◢▇▇◣ \n");
    printf(" ◢██◥◥▆▅▄▂▂▂▂▄▅▆███◣ ▊◢ █ \n");
    printf(" █╳               ╳█ ◥◤◢◤ \n");
    printf(" ◥█◣   ˙     ˙   ◢█◤  ◢◤  \n");
    printf("   ▊             ▊    █  \n");
    printf("   ▊             ▊   ◢◤  \n");
    printf("   ▊      ⊕      █▇▇▇◤  \n");
    printf("  ◢█▇▆▆▆▅▅▅▅▆▆▆▇█◣      \n");
    printf("  ▊ ▂ ▊      ▊ ▂ \n"); 
	printf("1 以邻接表的形式展示当前地图\n");
	printf("2 输出问题答案\n");
	printf("3 输出到达各个地方的最短路径\n");
	printf("按其他按钮退出帮助程序 \n");
	scanf("%d",&a);
	switch (a)
	{
		case 1:DispAdj(G);			
			printf("请输1继续游戏:");
			scanf("%d",&m);
			while(m!=1)
			{
				scanf("%d",&m);
			}
			break;
		case 2:
			printf("请输入你想知道的问题的序号:");
			scanf("%d",&m);
			if(m<0||m>5) printf("你输入的序号错误\n");
			else printf("序号为%d的问题答案为:%d\n",m,questions2(m,c));
			printf("请输1继续游戏:");
			scanf("%d",&m);
			while(m!=1)
			{
				scanf("%d",&m);
			}
			break;
		case 3:
			Dijkstra(g,1); 
			printf("请输1继续游戏:");
			scanf("%d",&m);
			while(m!=1)
			{
				scanf("%d",&m);
			}
			break;
		default:break;
	}
}

/*********************************************************
* 功能描述:前向递归查找路径上的顶点 
* 输入参数:无
* 输出参数:无
* 返回值  :无
* 其它说明:Dijkstra算法库
************************************************************/

void Ppath(int path[],int i,int v,MGraph g)  
{  
    int k;  
    k=path[i];  
    if (k==v)  return;          //找到了起点则返回  
    Ppath(path,k,v,g);            //找顶点k的前一个顶点  
    printf("%s->",g.vexs[k].name);            //输出顶点k  
}  

/*********************************************************
* 功能描述:输出最短路径
* 输入参数:无
* 输出参数:无
* 返回值  :无
* 其它说明:Dijkstra算法库
************************************************************/

void Dispath(int dist[],int path[],int s[],int n,int v,MGraph g)  
{  
    int i;  
    for (i=0; i<n; i++)  
        if (s[i]==1)  
        {  
			printf("  从%s到%s的最短路径长度为:%d\t路径为:",g.vexs[v].name,g.vexs[i].name,dist[i]);
            printf("%s->",g.vexs[v].name);    //输出路径上的起点  
            Ppath(path,i,v,g);    //输出路径上的中间点  
            printf("%s\n",g.vexs[i].name);   //输出路径上的终点  
        }  
        else  printf("从%d到%d不存在路径\n",v,i);  
}  

/*********************************************************
* 功能描述:Dijkstra算法
* 输入参数:无
* 输出参数:无
* 返回值  :无
* 其它说明:Dijkstra算法库
************************************************************/

void Dijkstra(MGraph g,int v)  
{  
    int dist[MAXV],path[MAXV];  
    int s[MAXV];  
    int mindis,i,j,u=0;  
    for (i=0; i<g.n; i++)  
    {  
        dist[i]=g.edges[v][i];      //距离初始化  
        s[i]=0;                     //s[]置空  
        if (g.edges[v][i]<INF)      //路径初始化  
            path[i]=v;  
        else  
            path[i]=-1;  
    }  
    s[v]=1;  
    path[v]=0;              //源点编号v放入s中  
    for (i=0; i<g.n; i++)               //循环直到所有顶点的最短路径都求出  
    {  
        mindis=INF;                 //mindis置最小长度初值  
        for (j=0; j<g.n; j++)       //选取不在s中且具有最小距离的顶点u  
            if (s[j]==0 && dist[j]<mindis)  
            {  
                u=j;  
                mindis=dist[j];  
            }  
        s[u]=1;                     //顶点u加入s中  
        for (j=0; j<g.n; j++)       //修改不在s中的顶点的距离  
            if (s[j]==0)  
                if (g.edges[u][j]<INF && dist[u]+g.edges[u][j]<dist[j])  
                {  
                    dist[j]=dist[u]+g.edges[u][j];  
                    path[j]=u;  
                }  
    }  
    Dispath(dist,path,s,g.n,v,g);     //输出最短路径  
}  

/*********************************************************
* 功能描述:回答问题的运行程序
* 输入参数:玩家的选项
* 输出参数:回答是否正确
* 返回值  :无
* 其它说明:无
************************************************************/

void questions(int i,Ans c,ALGraph *G,MGraph g)
{
	int m,n;
	n=questions2(i,c);  //n为问题的答案
	scanf("%d",&m);
	while(m!=n)
	{
		if(m<0||m>4)
		{
			printf("你输入的数字有误,请重新输入\n");
			scanf("%d",&m);
		}
		else if(m==0)  //如果为0进入帮助页面
		{
			help(G,c,g);  
			questions2(i,c);
			scanf("%d",&m);
		}
		else
		{
			printf("这个题你都能回答错误,真是猪脑子!请重新输入答案:\n");
			scanf("%d",&m);
		}
	}
	printf("恭喜你,回答正确,按1继续游戏\n");
}

/*********************************************************
* 功能描述:查找i序号上的问题以及答案
* 输入参数:无
* 输出参数:无
* 返回值  :第i个问题的答案
* 其它说明:读取txt文件对邻接矩阵中每个顶点的名字进行初始化
************************************************************/

int questions2(int i,Ans c)  
{
	printf("%s",c[i].question);
	return c[i].answer;
}


graph.h:

#ifndef GRAPH_H_INCLUDED
#define GRAPH_H_INCLUDED
#include <string>
#include <iostream>
using namespace std;
#define MAXV 100         //最大顶点个数
#define INF 32767       //INF表示∞
typedef int InfoType;   //权值的数据类型
#define Max 16
#define Max2 6
#define MaxSize 100 

//以下定义邻接矩阵类型  
typedef struct  
{  
    int no;                     //顶点编号  
    InfoType info;              //顶点其他信息,在此存放带权图权值 
	char name[30];              //顶点名字
} VertexType;                   //顶点类型 
 
typedef struct                  //图的定义  
{  
    int edges[MAXV][MAXV];      //邻接矩阵  
    int n,e;                    //顶点数,弧数
    VertexType vexs[MAXV];      //存放顶点信息  
} MGraph;                       //图的邻接矩阵类型  

//以下定义邻接表类型
//每个顶点
typedef struct ANode            
{
    int adjvex;                 //在矩阵中的列位置
    struct ANode *nextarc;      //指向下一条弧的指针
    InfoType info;              //权值
} ArcNode;

//头节点
typedef struct Vnode        
{
	int num;                //顶点的标号
    char data[300];               //顶点信息
    ArcNode *firstarc;          //指向第一条弧
	int cnt;   //顶点与几个其他顶点相连
} VNode;

//整个邻接表
typedef VNode AdjList[MAXV];    //AdjList是邻接表类型
typedef struct
{
    AdjList adjlist;            //邻接表
    int n,e;                    //图中顶点数n和边数e
} ALGraph;                      //图的邻接表类型


//储存问题的结构体
typedef struct 
{
	char question[500];
	int answer;
} Que;
typedef Que Ans[Max2];

//功能:由一个反映图中顶点邻接关系的二维数组,构造出用邻接矩阵存储的图
//参数:Arr - 数组名,由于形式参数为二维数组时必须给出每行的元素个数,在此将参数Arr声明为一维数组名(指向int的指针)
//      n - 矩阵的阶数
//      g - 要构造出来的邻接矩阵数据结构
void ArrayToList(int *Arr, int n, ALGraph *&); //用普通数组构造图的邻接表
void DispAdj(ALGraph *G);//输出邻接表G
int* init(Ans c);
void init2(ALGraph *&G);
void init2(MGraph &g);
void total(ALGraph *&G);
void IFS(ALGraph *G,VNode p1,int cnt,Ans c,MGraph g);
int questions2(int i,Ans c);
void questions(int i,Ans c,ALGraph *G,MGraph g);
void help(ALGraph *G,Ans c,MGraph g);
void Ppath(int path[],int i,int v,MGraph g);
void Dispath(int dist[],int path[],int s[],int n,int v,MGraph g);
void Dijkstra(MGraph g,int v);
void ArrayToMat(int *Arr, int n, MGraph &g);
#endif // GRAPH_H_INCLUDED


ice.h:

#ifndef ICE_H_INCLUDED
#define ICE_H_INCLUDED

#include <stdio.h>
#include <conio.h>
#include <windows.h>
#include <stdlib.h>
#include <time.h>
#include "graph.h"

#endif // ICE_H_INCLUDED


运行截图:

 

 

初始化各个数据的文件链接:http://download.csdn.net/detail/big_ice/9722618

 

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值