首页 > 其他分享 >C语言实现迷宫游戏

C语言实现迷宫游戏

时间:2023-05-01 20:34:30浏览次数:38  
标签:游戏 int void time 迷宫 C语言 break printf Maze

include<stdio.h>

#include<windows.h>

#include<conio.h>

#include<time.h>

#include<math.h>

 

//地图边长L,包括迷宫主体20,外侧的包围的墙体2,最外侧包围路径2(之后会解释)

//可根据需要修改,有上限

#define L 24

 

#define WALL  0 //墙

#define ROUTE 1 //路径

#define PLAYER 2//玩家

 

//控制迷宫的复杂度,数值越大复杂度越低,最小值为0

//默认为简单难度,可根据需要在degree函数里调整不同难度的复杂度

int Rank = 6;

//时间控制,默认一局游戏120秒

int game_time = 120;//限时

int begin_time;     //开始时间   

int cur_time;   //当前时间

 

void HideCursor(); //隐藏光标

void toxy(int x, int y); //将光标移动到指定位置

void menu();   //主菜单界面

void start();  //开始游戏

void degree(); //游戏难度

void explain();//游戏说明

int init(int** Maze);  //初始化迷宫

void print(int** Maze);//画迷宫

void CreateMaze(int **maze, int x, int y);    //创建迷宫

void move(int** Maze, char t, int *x, int *y);//移动角色

 

int main() {

       SetConsoleTitle("ytr的迷宫test");

       menu();

       return 0;

}

 

void HideCursor() { //隐藏光标

       CONSOLE_CURSOR_INFO cursor_info = { 1,0 };//第二个值为0表示隐藏光标

       SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);

}

 

void toxy(int x, int y){ //将光标移动到指定位置

       HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);

       COORD pos;

       pos.X = x;

       pos.Y = y;

       SetConsoleCursorPosition(handle, pos);

}

 

void menu() { //主菜单

     

       while(1) {

              system("cls"); //清屏

              char t;

              printf("*******(走迷宫)*******");

              printf("\n======================\n");

              printf("\n||   1. 开始 游戏   ||\n");

              printf("\n||   2. 游戏 说明   ||\n");

              printf("\n||   3. 游戏 难度   ||\n");

              printf("\n||   4. 关闭 游戏   ||\n");

              printf("======================\n");

              t=getch();    //不回显函数

              switch(t) {

                     case '1':

                            begin_time = clock(); //获取开始时间,单位为毫秒

                            start();

                            break;  //开始一局游戏

                     case '2':

                            explain();

                            break;  //进入游戏说明界面

                     case '3':

                            degree();

                            break;  //调整游戏难度

                     case '4':

                            printf("\n欢迎下次再玩,再见( ̄︶ ̄)↗");

                            Sleep(1500);

                            exit(0);

                            break;  //结束程序

                     default :

                            break;

              }

       }

}

 

void CreateMaze(int **maze, int x, int y) {//构建迷宫

       maze[x][y] = ROUTE;

       //确保四个方向随机,而不再是固定的上下左右这种排列

       int direction[4][2] = { { 1,0 },{ -1,0 },{ 0,-1 },{ 0,1 } };

       int i, j;

       for (i = 0; i < 4; i++) {

              int r = rand() % 4;

              int temp = direction[0][0];

              direction[0][0] = direction[r][0];

              direction[r][0] = temp;

              temp = direction[0][1];

              direction[0][1] = direction[r][1];

              direction[r][1] = temp;

       }

       //向四个方向开挖

       for (i = 0; i < 4; i++) {

              int dx = x;

              int dy = y;

              //控制挖的距离,由Rank来调整大小

              int range = 1 + (Rank == 0 ? 0 : rand() % Rank);

              while (range > 0) {

                     //计算出将要访问到的坐标

                     dx += direction[i][0];

                     dy += direction[i][1];

                     //排除掉回头路

                     if (maze[dx][dy] == ROUTE) {

                            break;

                     }

                     //判断是否挖穿路径

                     int count = 0, k;

                     for (j = dx - 1; j < dx + 2; j++) {

                            for (k = dy - 1; k < dy + 2; k++) {

                                   //abs(j - dx) + abs(k - dy) == 1 确保只判断九宫格的四个特定位置

                                   if (abs(j - dx) + abs(k - dy) == 1 && maze[j][k] == ROUTE) {

                                          count++;

                                   }

                            }

                     }

                     //count大于1表明墙体会被挖穿,停止

                     if (count > 1)

                            break;

                     //确保不会挖穿时,前进

                     range -= 1;

                     maze[dx][dy] = ROUTE;

              }

              //没有挖穿危险,以此为节点递归

              if (range <= 0) {

                     CreateMaze(maze, dx, dy);

              }

       }

}

 

int init(int** Maze) {//初始化迷宫

       int i;

       //最外围层设为路径的原因,为了防止挖路时挖出边界,同时为了保护迷宫主体外的一圈墙体被挖穿

       for (i = 0; i < L; i++) {

              Maze[i][0] = ROUTE;

              Maze[0][i] = ROUTE;

              Maze[i][L - 1] = ROUTE;

              Maze[L - 1][i] = ROUTE;

       }

       //创造迷宫,(2,2)为起点

       CreateMaze(Maze, 2, 2);

       //画迷宫的入口和出口,给出玩家初始位置

       Maze[2][1] = PLAYER;

       //由于算法随机性,出口有一定概率不在(L-3,L-2)处,此时需要寻找出口

       for (i = L - 3; i >= 0; i--) {

              if (Maze[i][L - 3] == ROUTE) {

                     Maze[i][L - 2] = ROUTE;

                     //返回出口所在的纵坐标

                     return i;

              }

       }

}

 

void print(int** Maze) {//画迷宫

       int i, j;

       HideCursor();

       toxy(0, 0);

       for (i = 0; i < L; i++) {

              for (j = 0; j < L; j++) {

                     if (Maze[i][j] == ROUTE)

                            printf("  ");//表示道路

                     else if(Maze[i][j] == WALL)

                            printf("回");//表示墙体

                     else if(Maze[i][j] == PLAYER)

                            printf("十");//表示玩家

              }

              printf("\n");

       }

       cur_time = clock(); //获取当前时间

       int t = (cur_time - begin_time) / 1000 ; //已用时间,单位是毫秒,所以需要除以1000

       printf("剩余时间:%2d", game_time - t);

}

 

void move(int** Maze, char t, int *x, int *y) {//移动角色

       int i = *x, j = *y;//记录原始位置

       switch(t) {

              case 'w': //向上移动

                     *x -= 1;

                     break;

              case 's':   //向下移动

                     *x += 1;

                     break;

              case 'a':  //向左移动

                     *y -= 1;

                     break;

              case 'd':  //向右移动

                     *y += 1;

                     break;

              default:

                     break;

       }

       if(*x>=0 && *x<L-1 && *y>=0 && *y<L-1 && Maze[*x][*y]!=WALL) {//符合条件,移动

              Maze[i][j] = 1;

              Maze[*x][*y] = 2;

       } else {//保持位置不变

              *x = i;

              *y = j;

       }

}

 

void start() { //开始一局游戏

       char t;

       //y,x表示角色横纵坐标, out表示出口的纵坐标

       int *p, *q;

       int x = 2, y = 1, out = 0, i = 0;

       p = &x;

       q = &y;

       //随机数发生器初始化函数

       srand((unsigned)time(NULL));

       //申请数组空间

       int **Maze = (int**)malloc(L * sizeof(int *));

       for (i = 0; i < L; i++) {

              Maze[i] = (int*)calloc(L, sizeof(int));

       }

       //得到出口纵坐标

       out = init(Maze);

       //游戏开始

       system("cls");

       print(Maze);

       while(1) {

              if(kbhit()){ //如果按下键盘某个键

                     t = getch();  //获取输入的值

                     if(t == 27)   //如果输入为ESC键,结束游戏回到主菜单

                            break;

                     move(Maze, t, p, q);//根据输入t进行移动

              }

              print(Maze);//不论是否按下键盘,都重新绘制迷宫,更新倒计时

              if(x == out && y == L-2) {//已经到出口,游戏结束

                     system("cls");

                     printf("=============\n");

                     printf("游 戏 胜 利!\n");

                     printf("=============\n");

                     printf("即将后返回主菜单……");

                     Sleep(1500);//执行挂起一段时间,暂停1.5秒后打印

                     break;

              }

              if (cur_time - begin_time > game_time*1000)

              {                                                       //时间已到,游戏结束

                     system("cls");

                     printf("=============\n");

                     printf("游 戏 失 败!\n");

                     printf("=============\n");

                     printf("即将后返回主菜单……");

                     Sleep(2000);

                     break;

              }

       }

       //一局游戏结束,释放内存

       for (i = 0; i < L; i++) free(Maze[i]);

       free(Maze);

}

 

void explain() { //操作说明

       while(1) {

              char t;

              system("cls");

              printf("=================================================\n");

              printf("感谢您体验本游戏,游戏的操作如下:\n");

              printf("\n1.将输入法调整为英文(小写)\n");

              printf("\n2.通过w,s,a,d四个键控制角色上下左右移动\n");

              printf("\n3.在任意界面均可按“ESC”键返回到主菜单\n");

              printf("\n胜利条件:移动角色到出口处,加油各位( ̄▽ ̄)\"!\n");

              printf("=================================================\n");

              t=getch();  //不回显函数

              switch(t) {

                            //ESC键的ASCII码值

                     case 27:

                            //返回主菜单

                            menu();

                            break;

                     default :

                            break;

              }

       }

}

 

void degree() { //调整游戏难度

       while(1) {

              char t;

              system("cls");

              printf("=================================================\n");

              printf("                输入1,2,3进行难度调整:           \n");

              printf("\n||                1.简  单                    ||\n");

              printf("\n||                2.中  等                    ||\n");

              printf("\n||                3.困  难                    ||\n");

            printf("==================================================\n");

              t=getch();  //不回显函数

              switch(t) {

                     case '1':

                            Rank = 6;

                            game_time = 120;

                            printf("\n当前难度:简单,即将返回主菜单……");

                            Sleep(1500);

                            menu();//返回主菜单

                            break;

                     case '2':

                            Rank = 3;

                            game_time = 90;

                            printf("\n当前难度:中等,即将返回主菜单……");

                            Sleep(1500);

                            menu();//返回主菜单

                            break;

                     case '3':

                            Rank = 0;

                            game_time = 60;

                            printf("\n当前难度:困难,即将返回主菜单……");

                            Sleep(1500);

                            menu();//返回主菜单

                            break;

                     case 27:

                            menu();

                            break;

                     default :

                            break;

              }

       }

}

标签:游戏,int,void,time,迷宫,C语言,break,printf,Maze
From: https://www.cnblogs.com/yuooo/p/17366959.html

相关文章

  • c语言实现链表的基本操作——初始化,求长度,添加节点,遍历输出
    #include<stdio.h>#include<stdlib.h>//创建结构体并命名typedefstructNode //typedef用于对struct的重命名{ inti; structNode*next;}LNode,*LinkList; //定义一个结构体指针//链表初始化boolInistList(LinkListL){ L=(LNode*)malloc(sizeof(LNo......
  • c语言基础
    环境设置c程序的源文件通常使用扩展名.cc程序需要编译成机器语言,这样cpu可以按给定指令执行程序。最常用的编译器是gcc(mac上xcode就可以)程序结构#include预处理器指令,类似于import,主要用于告诉编译器,我们要引入什么。.h结尾的是头文件,头文件中一般是定义的结构体和变量#include......
  • 旋转游戏
    题目描述pipi和lili各带来一个正多边形卡片。pipi的卡片是边长为\(A\)的正\(M\)边形,lili的卡片是边长为\(B\)的正\(N\)边形。pipi和lili将两张卡片摆放在一起,其中两张卡片并不重叠,并且有至少一个公共顶点和一条公共边。pipi喜欢旋转,因此她沿lili的卡片顺时......
  • 软件多开器,游戏多开器,窗口多开器,PC端游多开器,PC多开器
      电脑通用多开器是一款游戏多开软件,该软件可以让用户不用再受游戏只能单开的限制,想开几个开几个。用户只需启用该多开器,然后选择游戏路径就可以了,这样每次点击运行按钮就会启动一个游戏客户端了,下载地址:https://www.safeboxie.com/。 【软件功能】1、可解除许多限制......
  • C语言打印上下金字塔的按位取反运算符的精妙用法
    在打印上下金字塔的通常语句用法应该都是像下面这种#include<stdio.h>intmain(){  intn; do{   for(inti=1;i<n;i++){     for(inta=0;a<n-i;a++){       printf("");     }    for(intj=0;j<2*i-1;j++){     ......
  • mac太空射击游戏:Nova Drift (新星漂移)中文版
    NovaDrift是一款激动人心的太空射击游戏。NovaDriftMac整合了现代独立游戏风格和游戏历史上最深的根源。它不仅具有时尚和性感的外观,而且具有平稳的控制功能。玩家控制着一艘不断开发的生物机械船,面对敌人的大量奇怪而致命的疲劳,将垂死的星星驱逐出空隙。NovaDriftMac游戏介......
  • 栈的顺序存储 C语言
    #include<iostream>#include<stdio.h>#defineMAXSIZE50typedefstruct{intdata[MAXSIZE];inttop;}SqStack;//初始化栈voidInitStack(SqStack&s){s.top=-1;}//判断栈空boolStackEmpty(SqStack&s){if(s.top==-1)......
  • C语言链式存储(使用引用传递)
    #include<stdio.h>#include<stdlib.h>typedefstructLinkNode{ intdata; structLinkNode*next;}LinkNode;typedefstructLink{ LinkNode*front,*rear;//frontrear为链表的伴随指针}LinkQueue;voidInitQueue(LinkQueue&Q){Q.front=Q.rear......
  • C语言的存储类别
    存储类别概念对象:硬件中,被存储的每个值都占用一定的物理内存,c语言吧这样的一块内存成为对象标识符:标识符用来指定特定的对象存储期:用来描述对象,描述对象在内存中保留了多长时间作用域、用来描述标识符,描述程序中可以访问标识符的区域链接:用来描述标识符,c语言有3中链接属性:......
  • C语言函数大全-- s 开头的函数(3)
    C语言函数大全本篇介绍C语言函数大全--s开头的函数(3)1.sleep1.1函数说明函数声明函数功能unsignedintsleep(unsignedintseconds);它是C语言标准库中的函数,用于使当前进程挂起一定的时间。在挂起期间,操作系统会将该进程从调度队列中移除,直到指定的时间过去为......