参考博客:https://www.cnblogs.com/xiao-qi-w/p/13031637.html
我用的是Dev-C++
第一次第一次写这么多行的代码,写的很菜
一开始写的是闪屏的,后来学到了不闪屏了
感觉很麻烦很多细节我就不加了
#include<stdio.h>
#include<conio.h>
#include<Windows.h>
#include<time.h>
#include<math.h>
//墙和路径的标识
#define WALL 0
#define ROUTE 1
#define PLAYER 2
int _x[500],_y[500];
//地图长度L,包括迷宫主体40,外侧的包围的墙体2,最外侧包围路径2
int L=10;
//控制迷宫的复杂度,数值越大复杂度越低,最小值为0
int Rank=0;
//行动步数
int cnt;
//积分
int score;
//出口处横坐标
int out;
//无用操作
int useless;
//开始和结束时间
clock_t start1,end1;
void CreateMaze(int **maze, int x, int y);//随机生成迷宫
void print(int** Maze);//打印地图
void start();//开始
int init(int** Maze);//初始化地图,返回出口横坐标
void HideCursor();//隐藏光标
void gotoxy(short y,short x);//不闪屏进行光标移动
int main()
{
HideCursor();//隐藏光标
// system("color 7C");
printf("\t\t\t\t\t\t\t\t 游戏说明:\n\n");
printf("\t\t\t\t\t\t\t★本游戏用wsad键来上下左右移动★\n\n");
printf("\t\t\t\t\t\t\t★游戏中可以按Esc来返回主菜单★\n\n");
printf("\t\t\t\t\t\t\t★玩家应当在有限时间内走出迷宫★\n\n");
system("pause");
while(777)
{
char x;
system("cls");
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
printf("\t\t\t\t\t\t\t★游戏开始前请先设置迷宫大小和难度★\n");
printf("\t\t\t\t\t\t\t\t★按 a 为开始游戏★\n");
printf("\t\t\t\t\t\t\t\t===================\n");
printf("\t\t\t\t\t\t\t\t★按 b 为调整大小★\n");
printf("\t\t\t\t\t\t\t\t===================\n");
printf("\t\t\t\t\t\t\t\t★按 c 为调整难度★\n");
printf("\t\t\t\t\t\t\t\t===================\n");
printf("\t\t\t\t\t\t\t\t★按 d 为退出游戏★\n\n");
printf("\t\t\t\t\t\t\t\t 请按键:\n");
x=getch();
if(x=='b'){
system("cls");
printf("\t\t\t\t\t\t\t\t★请输入迷宫大小★:");
scanf("%d",&L);
continue;
}
else if(x=='c'){
system("cls");
printf("\t\t\t\t\t\t\t\t★请输入迷宫难度(最小为0,越小越困难)★:");
scanf("%d",&Rank);
continue;
}
else if(x=='d'){
break;
}
else if(x=='a'){
start();//开始游戏
}
else break;
}
system("pause");
return 0;
}
void HideCursor()
{
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO CursorInfo;
GetConsoleCursorInfo(handle, &CursorInfo);//获取控制台光标信息
CursorInfo.bVisible = false; //隐藏控制台光标
SetConsoleCursorInfo(handle, &CursorInfo);//设置控制台光标状态
}
void gotoxy(short y,short x){
COORD pos={x,y};
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos);
}
void CreateMaze(int **maze, int x, int y)
{
maze[x][y] = ROUTE;//标记为路径
int direction[4][2] = { { 1,0 },{ -1,0 },{ 0,1 },{ 0,-1 } };//上下右左
//打乱四个方向,使其随机
for (int 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 (int i = 0; i < 4; i++) {
int dx = x;
int dy = y;
//控制挖的距离,由Rank来调整大小,也就是说rank越小,行动的范围range越小,步数越多
//例rank为0时走一步就转向
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;
for (int j = dx - 1; j < dx + 2; j++) {
for (int k = dy - 1; k < dy + 2; k++) {
//abs(j - dx) + abs(k - dy) == 1 确保只判断九宫格的四个特定位置,即dx合dy位置的上下左右
if (abs(j - dx) + abs(k - dy) == 1 && maze[j][k] == ROUTE) {
count++;
}
}
}
//判断是否只有来的那条路时路径
if (count > 1) {
break;
}
//确保不会挖穿时,前进
--range;
maze[dx][dy] = ROUTE;
}
//没有挖穿危险,以此为节点递归
if (range <= 0) {
CreateMaze(maze, dx, dy);
}
}
}
//初始化迷宫
int init(int** Maze)
{
//最外围层设为路径的原因,为了防止挖路时挖出边界,同时为了保护迷宫主体外的一圈墙体被挖穿
//迷宫的最外层为空白墙,即路径1
for (int 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 (int i = L - 3; i >= 0; i--) {
if (Maze[i][L - 3] == ROUTE) {
Maze[i][L - 2] = ROUTE;
return i;//返回出口的纵坐标
}
}
}
void print(int** Maze)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_BLUE);
for (int i = 0; i < L; i++) {
for (int j = 0; j < L; j++) {
// if((i == 2 && j == 0) || (i == out && j == L - 1)) continue;
switch(Maze[i][j])
{
case 0:
printf("■");
break;
case 1:
printf(" ");
break;
case 2:
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED);
printf("◆");
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_BLUE);
break;
}
}
printf("\n");
}
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED);
}
void move(int** Maze,char direction,int x,int y)
{
switch(direction)//后面找光标位置的y坐标时得乘2,因为前边一个空格或者符号占两个位置
{
case 'w':
if(Maze[x-1][y]==0){useless++;break;}
gotoxy(x,2*y);
printf(" ");
gotoxy(x-1,2*y);
printf("◆");
// Maze[x][y] = 1;
// x--;
// Maze[x][y] = 2;
break;
case 's':
if(Maze[x+1][y]==0){useless++;break;}
gotoxy(x,2*y);
printf(" ");
gotoxy(x+1,2*y);
printf("◆");
// Maze[x][y] = 1;
// x++;
// Maze[x][y] = 2;
break;
case 'a':
if(Maze[x][y-1]==0){useless++;break;}
gotoxy(x,2*y);
printf(" ");
gotoxy(x,2*(y-1));
printf("◆");
// Maze[x][y] = 1;
// y--;
// Maze[x][y] = 2;
break;
case 'd':
if(Maze[x][y+1]==0){useless++;break;}
gotoxy(x,2*y);
printf(" ");
gotoxy(x,2*(y+1));
printf("◆");
// Maze[x][y] = 1;
// y++;
// Maze[x][y] = 2;
break;
}
}
void start()
{
//开始一局游戏
//申请数组空间
int **Maze = (int**)malloc(L * sizeof(int *));
for (int i = 0; i < L; i++) {
Maze[i] = (int*)calloc(L, sizeof(int));
}
//得到出口纵坐标
out = init(Maze);
int rt = rand()%20;
for( ; ; ){
cnt= 0;
score = 0;
useless = 0;
char t;
//y,x表示角色横纵坐标, out表示出口的纵坐标
int x = 2, y = 1;
_x[cnt] = 2;
_y[cnt] = 1;
//随机数发生器初始化函数
srand((unsigned)time(NULL));
//游戏开始
x = 2; y = 1;
Maze[2][1] = 2;
Maze[out][L-2] = 1;
system("cls");//清屏
Maze[2][0] = 1;
Maze[out][L - 1] = 1;
gotoxy(L,10);
printf("\t◆您需要在%d秒内走出迷宫◆\n",L/2 + rt);
gotoxy(0,0);
print(Maze);
Maze[2][0] = 0;
Maze[out][L - 1] = 0;
int r=L+3;
printf("步数:%d\n",cnt);
printf("积分:%d\n",score);
printf("无用的操作:%d\n",useless);
// printf("倒计时:%d\n",countdown);
int Maze_[500][500];
memset(Maze_,0,sizeof Maze_);
Maze[2][1] = 1;
start1 = clock();
for( ; ; ){
t=getch();
HideCursor();
if(t == 27) //如果输入为ESC键,结束游戏回到主菜单
break;
move(Maze, t, x, y);//根据输入t进行移动
switch(t)
{
case 'w':
{
if(Maze[x-1][y] == 0)break;
x --;
cnt ++;
_x[cnt] = x;
_y[cnt] = y;
break;
}
case 's':
{
if(Maze[x+1][y] == 0)break;
x ++;
cnt ++;
_x[cnt] = x;
_y[cnt] = y;
break;
}
case 'a':
{
if(Maze[x][y-1] == 0)break;
y --;
cnt ++;
_x[cnt] = x;
_y[cnt] = y;
break;
}
case 'd':
{
if(Maze[x][y+1] == 0)break;
y ++;
cnt ++;
_x[cnt] = x;
_y[cnt] = y;
break;
}
}
if(x == 2 && y == 1){}
else if(!Maze_[x][y]){
Maze_[x][y] = 1;
score ++;
}
gotoxy(L,6);
printf("%d",cnt);
gotoxy(L+1,6);
printf("%d",score);
gotoxy(L+2,12);
printf("%d",useless);
if(x == out && y == L-2) {//已经到出口,游戏结束。
end1 = clock();
if((end1 - start1) / 1000 <= L/2 + rt){
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
system("cls");
printf("\t\t\t\t\t\t\t\t|===========================|\n");
printf("\t\t\t\t\t\t\t\t|恭喜你在有限时间内走到尽头!|\n");
printf("\t\t\t\t\t\t\t\t|===========================|\n\n");
printf("\n\t\t\t\t\t\t\t\t您所用的时间为:%d s\n",(end1 - start1)/1000);
printf("\n\t\t\t\t\t\t\t\t您行走的路线为:");
for(int i = 0;i <= cnt; i ++){
if(i != 0)printf("->");
printf("(%d,%d)",_x[i],_y[i]);
}
printf("\n");
int _Maze[500][500];
memset(_Maze,0,sizeof _Maze);
for(int i = 0;i <= cnt;i ++){
_Maze[_x[i]][_y[i]]=1;
}
printf("\t\t\t\t\t\t\t\t您行走的步数为:%d\n\n",cnt);
printf("\t\t\t\t\t\t\t\t您的积分为:%d\n\n",score);
printf("\t\t\t\t\t\t\t\t您无效操作次数为:%d\n\n",useless);
printf("\t\t\t\t\t\t\t\t您行走的路线图为:\n\n");
for (int i = 0; i < L; i++) {
for (int j = 0; j < L; j++) {
if(i == 0 || i == L - 1 || j == 0 || j == L -1){
printf(" ");
}
else {
switch(_Maze[i][j])
{
case 0:
printf("--");
break;
case 1:
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED);
printf("◆");
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
break;
}
}
}
printf("\n");
}
printf("\n");
system("pause");
system("cls");
break;
}
else {
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
system("cls");
printf("\t\t\t\t\t\t\t\t|=================|\n");
printf("\t\t\t\t\t\t\t\t|很不幸您挑战失败!|\n");
printf("\t\t\t\t\t\t\t\t|=================|\n");
printf("\n\t\t\t\t\t\t\t\t您所用的时间为:%d s\n\n",(end1 - start1)/1000);
printf("\t\t\t\t\t\t\t\t您行走的步数为:%d\n\n",cnt);
printf("\t\t\t\t\t\t\t\t您的积分为:%d\n\n",score);
printf("\t\t\t\t\t\t\t\t您无效操作次数为:%d\n\n",useless);
system("pause");
system("cls");
break;
}
}
}
printf("\n ◆如果想重新玩这个迷宫的话请按r◆\n");
printf("\n");
printf(" ◆如果想回到菜单的话请按g◆\n");
int flag=0;
t=getch();
switch(t)
{
case 'r':
flag=0;
break;
case 'g':
flag=1;
break;
}
if(flag==0)continue;
else break;
}
//一局游戏结束,释放内存
for (int i = 0; i < L; i++) free(Maze[i]);
free(Maze);
}