一、设计思路:
1.物理存储结构:
① 迷宫数据存储于一个结构体中,数据值放置于二维数组中用0表示通路,数据1表示障碍,走过的路变为-1,行列数分别放于不同的整数。
② 路径存储于一个栈中,最好采用顺序栈存储,采用链栈,队列也可,各有好处,本人选择链栈,减少产生溢出情况。
③ 将路径的点,路径的方向,存放于一个结构体中。
2.逻辑算法:
① 迷宫数组的遍历操作与栈的操作相结合。
② 从入口开始,寻找下一个可同行点,只要可同行,将此刻的方向,坐标进栈,存储信息。
③ 设计循环结构,判断四周是否有路。
While(1){
If(){……}
else if(){……}
else if(){……}
else if(){……}
else{……}
}
先判断四个方向是否为0(此处包括-1走过的路),若都不为零,则出栈,出栈一次后,再取栈顶元素,相当于退后了一步,记住,出栈必须判断是否为空,不然回到原点时,若其他方向有出路,会出现报错情况。
二、技巧:
由于数组可能会产生越界问题,故此得强行设定入口,让编写的迷宫比用户输入的多出四周围墙,这样对迷宫进行数组和栈的操作时,不会出现越界问题。 用户友好型:为了给广大用户增加乐趣,本人设定的迷宫操作,有初始化截面,菜单选择,并且在数字迷宫外,设定了动态迷宫的版本,根据动态迷宫,用户可通过操作方向来确定要走的方向,大大增强了迷宫的交互性和友好性。
三、扩展之处:
设定动态迷宫,增强交互性能。拓展多个模式的用户选择。由于用户按键的不确定性,防止用户操作失误,设定按键失误操作,可选择是否退出。在用户进行游戏的同时,进行清屏,不然会造成乱糟糟一团,影响用户体验。
#include
#include
#include
#include
#include
#include
typedef int datatype;
//位置
typedef struct drect {
int x, y;
int dir;
}drect;
//栈
typedef struct node {
struct drect data;
struct node* next;
}node;
//初始化一个栈
node* first()
{
node* p = (node*)malloc(sizeof(node));
p->next= NULL;
return p;
}
//进栈
void push(node* s, int x, int y, int dir) {
node* p =(node*)malloc(sizeof(node));
p->data.x = x;
p->data.y = y;
p->data.dir = dir;
p->next = s->next;
s->next = p;
//return s;
}
//出栈
node* output(node* s, int x, int y, int dir) {
if (s== NULL)
return 0;
node* p ;
p = s->next;
s->next = p->next;
return p;
}
//创建地图
void creatmap(int a[][100], int x, int y) {
int k;
srand(time(0));
for (int i = 0; i < x; i++) {
for (int j = 0; j < y; j++) {
if (i == 0 || i == x - 1) {
a[i][j] = 1;
}
if (j == 0 || j == y - 1) {
a[i][j] = 1;
}
else if ((i != 0 && i != x - 1) && (j != 0 && j != y - 1)) {
a[i][j] = 0;
}
}
}
for (int i = 1; i < x - 1; i++) {
for (int j = 1; j < y - 1; j++) {
if (j < y / 3) {//规范随机数个数产生数量
k = rand() % (y - 1);
a[i][k] = 1;
}
}
}
}
//寻找出路
//right 1 under 2 left 3 on 4
int find(node*s , int a[][100], int w, int h, int x1, int y1, int x2, int y2, int x, int y)
{
node* p;
int dir;// = 1;
push(s, 1, 0, 1);
while ((x!=x2||y!=y2)&& (x != x1 || y != y1))
{
if ( a[x][y + 1] == 0) {
a[x][y] = -1;
dir = 1;
push(s, x, y, dir); y++;
}
else if ( a[x + 1][y] == 0) {
a[x][y] = -1;
dir = 2;
push(s, x, y, dir);x++;
}
else if ( a[x][y - 1] == 0) {
a[x][y] = -1;
dir = 3;
push(s, x, y, dir);y--;
}
else if ( a[x - 1][y] == 0) {
a[x][y] = -1;
dir = 4;
push(s, x, y, dir);x--;
}
else
{
a[x][y] = -1;
p = output(s, x, y, dir);
if (p) {
x = p->data.x;
y = p->data.y;
dir = p->data.dir;
free(p);
}
}
}
if (x == x2 && y == y2) {
push(s, x, y, 0);
return 1;
}
return 0;
}
void print_map(int a[][100],int w,int h) {
printf("迷宫为:\n");
for (int i = 0; i < w + 2; i++) {
for (int j = 0; j < h + 2; j++) {
a[1][0] = 0;
a[1][1] = 0;
a[w + 1][h] = 0;
printf("%d ", a[i][j]);
}
printf("\n");
}
}
void print_foot(node* s,int i) {
if (i) {
printf("迷宫为:\n");
while (s->next != NULL) {
s = s->next;
int a = s->data.x;
int b = s->data.y;
int c = s->data.dir;
printf("(%d,%d)->%d\n", a, b, c);
}
}
else
printf("没有出口!\n");
}
///以下为动态迷宫游戏!!
int find_run_foot(char hyb[][200]) {
int x = 1, y = 1;
char ch;
//hyb[1]=" ";
for (int i = 0; i <= 20; i++)
{
puts(hyb[i]);
}
hyb[1][0] = ' ';
while (1)
{
ch = _getch();
if (ch == 's') {
if (hyb[x + 1][y] == ' ') {
hyb[x][y] = ' ';
x++;
hyb[x][y] = 'o';
}
}
else if (ch == 'w') {
if (hyb[x - 1][y] == ' ') {
hyb[x][y] = ' ';
x--;
hyb[x][y] = 'o';
}
}
else if (ch == 'a') {
if (hyb[x][y - 1] == ' ') {
hyb[x][y] = ' ';
y--;
hyb[x][y] = 'o';
}
}
else if (ch == 'd')
{
if (hyb[x][y + 1] == ' ') {
hyb[x][y] = ' ';
y++;
hyb[x][y] = 'o';
}
}
else {
system("cls");
printf("其他按键会退出游戏,你是否继续?1-是,其他-否\n");
int dle;
scanf_s("%d", &dle);
system("cls");
if (dle == 1) {
break;
}
else{
system("cls");
for (int i = 0; i <= 20; i++)
{
puts(hyb[i]);
}
continue;
}
}
system("cls");
for (int i = 0; i <= 20; i++)
{
puts(hyb[i]);
}
if (x == 19 && y == 27)
{
break;
}
}
system("cls");
Sleep(1000);
printf("游戏结束!\n");
system("cls");
return 0;
}
int run_foot(int slect_slect) {
char hyb1[200][200] = {
"############################",
"o ### ## ### ## ###########",
"## #### #########",
"### #### ## ###### ### ##",
"### ### ######### ### ## ##",
"### ###### ### ## ##",
"### ## #### ###### ## ##",
"# ## #### ########### ##",
"# #### ## ###### ##",
"### ### ## ##### #######",
"### ###### ### # ##",
"# ###### #### ###### ##",
"# # ###### ####### #### # ##",
"# # ## ## #### # ##",
"# ##### ## #### ## ##",
"# ## ## #### ###### # ##",
"#### ## ## ## #### # ##",
"# ## ## ## ## # # #",
"# ##### ## ##### ## # # ####",
"# # ###### # # ",
"############################",
};
char hyb2[200][200] = {
"############################################################################",
"o # ## ### # #### ##### ###### #### ####### ##### #### ## ### ######",
"## ## #### # ### # ##### #### ## ### #######",
"##### ## ### ### ##### ### ## ## ### # ## ####### ##### #### ## ### ### #",
"## # ### ##### ### ## ## ### # ## ## #### ## ### ### ##",
"## ## ## # # ### ##### # #### ## ### # # ## #### ### # ## ## ### ### ###",
"##### ## # # ##### ### ## ## # ## ## ## ## ## ### ## ### ###",
"## ## ## ### # # ## # ## ### #### ## #### ### #### ## # # ### ###",
"## ## ## ### # # ## ## ### # #### ### ## #### ## # # ####",
"## ##### ### # # ## ## # # ###### #### # ### ## #### ## # #####",
"## ## ## ### # ## # ## ###### #### ####### # # # #######",
"## ## ## # ## # # ### ## ## # ## # #### ####### # ### # ## # # #####",
"## ##### ### ### # #### ### # ## # # #### ## ## ### ## ## # # # #####",
"## ## ## ### ### ##### ### # ## # # #### ### ### ##### # # # ## # # #######",
"## ## ## ### # ## ##### # # ## # # #### ## ## #### # ## ## ####",
"## ## ## ### ## ##### ## ## ## # # ### ## #### #### #### ##",
"## ## ## ## # ## ##### ## ## ## # # ## ## ## ##### ##### #####",
"## ##### ### ### ##### ## ## ## # # #### ##### # # ## ### # ##",
"## ## ###### ### ## ## ## ## # # #### ## ## # # ## ## # # ##",
"## ## ## ### ### ## ## # ## # #### #### ## ## ## # ## ## ##### ",
"############################################################################",
};
char hyb[200][200];
for (int i = 0; i < 200; i++) {
for (int j = 0; j < 200; j++) {
if (slect_slect == 1) {
hyb[i][j] = hyb1[i][j];
}
else if (slect_slect == 2) {
hyb[i][j] = hyb2[i][j];
}
}
}
find_run_foot(hyb);
return 0;
}
//主函数
int main()
{
printf("-------欢迎来到迷宫小游戏------\n");
printf("------------版本1.0------------\n");
printf("------------vs2019下运行---------------\n");
printf("说明:本游戏要时间加载,请耐心等待!\n");
Sleep(500);
system("cls");
printf("抵制不良游戏,做优秀的联大学子!\n");
printf("作者:黄渝斌(北京联合大学),计算机科学与技术专业\n");
printf("游戏说明:抵制不良游戏,做优秀的联大学子!\n");
printf("本游戏源代码将上传博客CSDN,搜索用户“梵高的猪v”,借用原代码请标明出处!\n");
Sleep(1000);
system("cls");
printf("等待游戏中………………\n");
printf("游戏说明:用户请先初始化一个迷宫,然后根据自己需要是否要进行其他选择!\n");
Sleep(1000);
system("cls");
node* s;
s = first();
int a[100][100];
int week;
int w, h;
int x1 = 1, y1 = 0,x2,y2, x = 1, y = 1;
int count = 0;
int slect;
while (1) {
printf("--------请选择版本型号----------\n");
printf("--------1-静态迷宫1.0-----------\n");
printf("--------2-动态迷宫1.0--------\n");
printf("--------0-退出游戏-----------\n");
printf("请输入版本型号:\n");
scanf_s("%d",&slect);
system("cls");
if (slect == 1) {
while (1) {
printf("-------1-初始化迷宫------------\n");
printf("-------2-打印迷宫--------------\n");
printf("-------3-出路迷宫--------------\n");
printf("-------0-退出游戏--------------\n");
printf("请输入你要选择的功能:\n");
scanf_s("%d", &week);
system("cls");
if (week == 1) {
printf("请输入你要创建的迷宫大小:\n");
scanf_s("%d%d", &w, &h);
creatmap(a, w + 2, h + 2);
count++;
}
else if (week == 2) {
if (count > 0) {
print_map(a, w, h);
count++;
}
else {
printf("请先初始化一个迷宫!\n");
Sleep(1000);
system("cls");
continue;
}
}
else if (week == 3) {
if (count > 0) {
x2 = w + 1;
y2 = h;
int i = find(s, a, w, h, x1, y1, x2, y2, x, y);
print_foot(s, i);
count++;
}
else {
printf("请先初始化一个迷宫!\n");
Sleep(1000);
system("cls");
continue;
}
}
else if (week == 0) {
system("cls");
printf("---------------游戏结束!--------------\n");
Sleep(1000);
break;
}
int m;
printf("请选择是否执行程序!\n");
printf("1-true,0-fasle\n");
scanf_s("%d", &m);
system("cls");
if (m == 1) {
continue;
}
else
system("cls");
printf("---------------游戏结束!--------------\n");
Sleep(1000);
break;
}
}
else if (slect == 2) {
int slect1;
printf("游戏说明:该游戏控制的方向如下:w(上)s(下)a(左)d(右)。\n若无法移动,可按住alt键在进行操作!\n");
Sleep(1000);
system("cls");
printf("------------请输入选项!----------\n");
printf("------------1-简单模式------------\n");
printf("------------2-困难模式------------\n");
printf(" …… \n");
printf("------------0-退出游戏------------\n");
scanf_s("%d",&slect1);
system("cls");
if (slect1 == 1) {
run_foot(1);
continue;
}
else if (slect1 == 2) {
run_foot(2);
continue;
}
else if (slect1 == 0) {
continue;
}
else {
printf("-----其他选项待开发!----");
Sleep(1000);
continue;
}
}
else if(slect==0){
break;
}
else {
printf("其他大型迷宫待开发中!");
continue;
}
}
return 0;
}