#include<graphics.h>
#include<stdio.h>
#include<iostream>
#include<cstdio>
#include<string.h>
#include<cstring>
#include<stack>
#include<vector>
#include<queue>
#include<time.h>
#include<conio.h>
#include<ctime>
#include<algorithm>
using namespace std;
#pragma comment(lib, "MSIMG32.LIB")
typedef struct //自定义一个整形的点
{
int x, y;
} Point;
/
//地图列表
char maze[10][17] =
{
{"----------------"},//1
{"-==============-"},//2
{"-=--=--=------=-"},//3
{"-=====-=-====-=-"},//4
{"-=---==&=-=-===-"},//5
{"-=-===-=-==-=---"},//6
{"-=-=---=--=---=@"},//7
{"-========-=====-"},//8
{"----------------"},//9
};
char maze2[10][17] =
{
{"----------------"},//1
{"-========---===-"},//2
{"-=-=----=====-=-"},//3
{"-=-=-=-=---=--=-"},//4
{"-=---==&==-=----"},//5
{"-=====-=-=-====-"},//6
{"--=----=-=----=@"},//7
{"--======-====-=-"},//8
{"----------------"},//9
};
char maze3[10][17] =
{
{"----------------"},//1
{"-==============-"},//2
{"-==============-"},//3
{"-==============-"},//4
{"-======&=======-"},//5
{"-==============-"},//6
{"-==============@"},//7
{"-==============-"},//8
{"----------------"},//9
};
char maze4[10][17];
//这个是用于画出最短路径的,在此我们规定0为没有走过的,1为最短路径
int book[10][17] =
{
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},//1
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},//2
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},//3
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},//4
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},//5
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},//6
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},//7
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},//8
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}//9
};
int vis[10][17];
// 数据列表
//时间变量
//玩家不能出去的bool变量
bool is_out = false;
//界面跳转逻辑的int类型变量
int is_game_begin = 0;
//时间变量
clock_t start_time, end_time;
double cpu_time_used;
bool is_time_count = true;
int time_1;
//时间变量2
struct TimeRecord
{
int id; //关卡
int cost_time; //耗时
int year; //年
int mouth; //月
int day; //日
int hour; //几点
int fen; //分钟
int sec; //秒
};
struct TimeRecord records[100000];
int numRecords = 0;
//时间变量3.获取现实时间
time_t currentTime;
struct tm* localTime;
//玩家数据
POINT player_pos = { 500,500 }; //玩家位置
const int PLAYER_SPEED = 5; //玩家移动速度
bool exit_l = false; //判定是否到达终点的变量
int re_x, re_y; //用于记录出口的位置
int in_x, in_y; //用于记录入口的位置
IMAGE img_background; //绘制背景
IMAGE player; //绘制玩家
ExMessage msg; //获取数据;
//菜单的常变量
IMAGE img_menu;
//地图长宽度
const int MAX_N = 10; // 最大行数
const int MAX_M = 17; // 最大列数
//时间输出字符
char str[100];
///
// 函数列表
//bfs函数
void bfs(int startX, int startY, int targetX, int targetY, char a[][17]);
//画墙函数
void draw_wall(char a[][17]);
//是玩家的位置在出口
void check_in(char a[][17]);
//检查是否已经出去
void check_out();
//透明化玩家
inline void putimage_alpha(int x, int y, IMAGE* img);
//画圆
void draw_round();
//玩家移动逻辑
void player_process(char a[][17]);
//处理玩家移动后画面
void draw_plyer(char a[][17]);
//菜单数据逻辑
void menu();
//菜单画面逻辑
void draw_menu();
//创建迷宫数据输入函数
void creat_maze();
//创建迷宫图像输出函数
void draw_creat_maze(char a[][17]);
//关闭窗口函数 直接return 0;即可
//排序函数数据输入
void sort_player();
//排序函数图像输出
void draw_sort_player();
//将数据加入到结构体数组中
void addTimeRecord(int id, int cost_time, int year, int mouth, int day, int hour, int fan, int sec);
//将信息保存到文件中
void saveRecordsToFile(const char* filename);
//加载文件信息
void loadRecordsFromFile(const char* filename);
//时间结构体的排序方式
bool cmp(TimeRecord x, TimeRecord y);
//对时间结构体排序
void sort_time();
//创造随机地图函数
void creat_maze_rand();
//主函数部分
int main()
{
//b1.build(100, 0, 100, 25, RED, _T("开始第一关"));
//player_pos_in();
bool runing = true;
loadimage(&player, _T("img/player_left_0.png")); //加载玩家图片
loadimage(&img_background, _T("img/background.png")); //加载背景
loadimage(&img_menu, _T("img/menu.png")); //加载菜单图片
initgraph(1280, 720); //绘制窗口
loadRecordsFromFile("./第一关排序.txt"); //加载文件
BeginBatchDraw(); //双缓冲
数据输入
while (runing) //游戏主循环
{
time(¤tTime); //获取当前时间戳
localTime = localtime(¤tTime); //获取当前时间戳
if (is_game_begin == 0) //如果变量 is_game_begin == 0,就要开始计时
{
start_time = clock(); //使用clock函数来获取时间
}
if (is_game_begin == 0) //如果变量 is_game_begin == 0,就要是游戏的主逻辑跳转到菜单页面
{
menu(); //菜单数据输入函数
}
else if (is_game_begin == 1) //如果变量 is_game_begin == 1,就要是游戏的主逻辑跳转到第一关
{
player_process(maze); //玩家移动数据输入函数
}
else if (is_game_begin == 2) //如果变量 is_game_begin == 2,就要是游戏的主逻辑跳转到第二关
{
player_process(maze2); //玩家移动数据输入函数
}
else if (is_game_begin == 3) //如果变量 is_game_begin == 3,就要是游戏的主逻辑跳转到第自定义关
{
player_process(maze3); //玩家移动数据输入函数
}
else if (is_game_begin == 4) //如果变量 is_game_begin == 4,就要是游戏的主逻辑跳转到自定义
{
creat_maze(); //创建迷宫数据输入函数
}
else if (is_game_begin == 6) //如果变量 is_game_begin == 6,就要是游戏的主逻辑跳转到时间排序函数
{
sort_time(); //时间排序函数
}
else if (is_game_begin == 7) //如果变量 is_game_begin == 7,就要是游戏的主逻辑跳转到新增关卡
{
player_process(maze4); //玩家移动数据输入函数
}
cleardevice();//cleardevice()函数这个作为数据输入和图像输出的分界线
if (is_game_begin == 0) //如果变量 is_game_begin == 0,就要是游戏的主逻辑跳转到菜单
{
draw_menu(); //绘制菜单页面
}
else if (is_game_begin == 1) //如果变量 is_game_begin == 1,就要是游戏的主逻辑跳转到第一关
{
draw_plyer(maze); //绘制玩家移动以及地图函数
///
end_time = clock(); //获取这一关的时间戳
time_1 = (int)((end_time - start_time) / CLOCKS_PER_SEC);
if (time_1 >= 10) //这一关的时间如果超过了10秒就代表失败
is_out = true; //作为全局变量在函数中作为一个监控作用
}
else if (is_game_begin == 2) //如果变量 is_game_begin == 2,就要是游戏的主逻辑跳转到第二关
{
draw_plyer(maze2); //绘制玩家移动以及地图函数
//
end_time = clock(); //获取这一关的时间戳
time_1 = (int)((end_time - start_time) / CLOCKS_PER_SEC);
if (time_1 >= 10) //这一关的时间如果超过了10秒就代表失败
is_out = true; //作为全局变量在函数中作为一个监控作用
}
else if (is_game_begin == 3) //如果变量 is_game_begin == 3,就要是游戏的主逻辑跳转到自定义关卡
{
draw_plyer(maze3); //绘制玩家移动以及地图函数
end_time = clock(); //获取这一关的时间戳
time_1 = (int)((end_time - start_time) / CLOCKS_PER_SEC);
if (time_1 >= 10) //这一关的时间如果超过了10秒就代表失败
is_out = true; //作为全局变量在函数中作为一个监控作用
}
else if (is_game_begin == 4) //如果变量 is_game_begin == 4,就要是游戏的主逻辑跳转到自定义
{
draw_creat_maze(maze3); //绘制自定义的地图
}
else if (is_game_begin == 5) //如果变量 is_game_begin == 5,就要是游戏的主逻辑跳转到结束
{
saveRecordsToFile("./第一关排序.txt"); //结束之前要将我们在第一关,第二关的通关的时间上传到文件中方便我们对以前数据的读取
return 0; //结束游戏
}
else if (is_game_begin == 6) //如果变量 is_game_begin == 6,就要是游戏的主逻辑跳转到结束
{
draw_sort_player(); //绘制新增地图中的玩家移动和地图
}
else if (is_game_begin == 7) //如果变量 is_game_begin == 7,就要是游戏的主逻辑跳转到新增关卡
{
draw_plyer(maze4); //绘制玩家移动以及地图
end_time = clock(); //获取当前时间戳
time_1 = (int)((end_time - start_time) / CLOCKS_PER_SEC);
if (time_1 >= 10) //如果时间大于10就代表超时,玩家失败
is_out = true; //作为一个全局变量起一个监控时间是否超时的变量
}
FlushBatchDraw(); //另外一个双缓冲
}
EndBatchDraw(); //双缓冲
return 0;
}
//函数的具体部分
//画墙
void draw_wall(char a[][17]) //最后这个是要装到玩家移动函数中去的
{
IMAGE img_wall;
loadimage(&img_wall, _T("img/墙.png"));
for (int i = 0; i < 9; i++) //使用一个嵌套循环遍历整个地图数组来看那些是墙,那些是出口,那些是入口
{
for (int j = 0; j < 16; j++)
{
if (a[i][j] == '-')
putimage(j * 80, i * 80, &img_wall);
if (a[i][j] == '@') //我设置'@'为出口,'&'为入口
{
re_x = i;
re_y = j;
setfillcolor(RGB(152, 220, 228));
fillrectangle(j * 80, i * 80, (j + 1) * 80, (i + 1) * 80);
}
if (a[i][j] == '&')
{
setfillcolor(RGB(85, 177, 85));
fillrectangle(j * 80, i * 80, (j + 1) * 80, (i + 1) * 80);
}
}
}
}
//检查入口
void check_in(char a[][17])
{
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 17; j++)
{
if (a[i][j] == '&')
{
player_pos.x = i * 80; //当我们找到出口后一定要记得,将玩家的位置重新赋值给入口,不然下一次就会导致玩家的贴图会移到窗外
player_pos.y = j * 80;
in_x = i; //使用in_x,in_y两个全局变量来记录入口的位置
in_y = j;
}
if (a[i][j] == '@')
{
re_x = i; //使用re_x,re_y两个全局变量来记录出口的位置
re_y = j;
}
}
}
}
//检查出口
void check_out()//接下来只需要将这个作为文本框输出,然后点击确定,使得is_game_begin = 0,这样就会回到主菜单,需要将void draw_plyer(char a[][17])中的位置改变到出生口,然后使得is_game_begin = 0
{
if (is_out)
{
is_out = false; //如果时间到了也算是一种出去,时间一到首先就要是这个变量重新赋值为false 以方便下次使用
addTimeRecord(is_game_begin, time_1, localTime->tm_year + 1900, localTime->tm_mon + 1, localTime->tm_mday,
localTime->tm_hour, localTime->tm_min, localTime->tm_sec);//因为只要游戏一结束就需要将这一段的数据记录到结构题数组中,方便将结构数组的数据存放到文件中
MessageBox(GetHWnd(), _T("玩家失败"), _T("游戏结束"), MB_OK); //弹出对话框提醒玩家游戏结果
is_game_begin = 0; //游戏结束后需要将is_game_begin重新设置为0,是游戏逻辑转跳到菜单界面
}
if ((player_pos.x) / 80 == re_x && (player_pos.y) / 80 == re_y) //如果位置处于出口也算一种游戏结果
{
player_pos.x = in_x * 80; //重新使位置为出口位置
player_pos.y = in_y * 80;
addTimeRecord(is_game_begin, time_1, localTime->tm_year + 1900, localTime->tm_mon + 1, localTime->tm_mday,
localTime->tm_hour, localTime->tm_min, localTime->tm_sec);//因为只要游戏一结束就需要将这一段的数据记录到结构题数组中,方便将结构数组的数据存放到文件中
MessageBox(GetHWnd(), _T("玩家获胜"), _T("游戏结束"), MB_OK);//弹出对话框提醒玩家游戏结果
is_game_begin = 0; //游戏结束后需要将is_game_begin重新设置为0,是游戏逻辑转跳到菜单界面
}
}
//使图形背景透明
inline void putimage_alpha(int x, int y, IMAGE* img)
{
int w = img->getheight();
int h = img->getwidth();
AlphaBlend(GetImageHDC(NULL), x, y, w, h,
GetImageHDC(img), 0, 0, w, h, { AC_SRC_OVER,0,225,AC_SRC_ALPHA });
}
//画圆
void draw_round() //使用嵌套循环来遍历整个二维数组,由于我使用vis数组来代表bfs的经历过程
{
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 17; j++)
{
if (vis[i][j] == 1) //如果vis数组的值为1,就代表bfs之前遍历最短路径的路径
{
setfillcolor(RGB(255, 255, 255)); //画上一个圆在图中
solidcircle(j * 80 + 40, i * 80 + 40, 10);
}
}
}
}
// 执行广度优先搜索
// 方向数组,用于探索相邻节点
int dx[] = { 1, -1, 0, 0 };
int dy[] = { 0, 0, 1, -1 };
//bfs函数
bool isValid(int x, int y, char a[][17]) //检测四周是否越界,是否为墙
{
return (x >= 0 && x < MAX_N && y >= 0 && y < MAX_M && a[x][y] != '-');
}
void bfs(int startX, int startY, int targetX, int targetY, char a[][17])
{
queue<pair<int, int>> q; //设置一个队列,队列里面存的是一个pair类型,就是相当于一个点的x,y坐标
vector<vector<bool>> visited(MAX_N, vector<bool>(MAX_M, false));
vector<vector<pair<int, int>>> parent(MAX_N, vector<pair<int, int>>(MAX_M, { -1, -1 }));
q.push({ startX, startY }); //入队
visited[startX][startY] = true; //将其视为已走过
while (!q.empty()) //如果队列部位空
{
pair<int, int> current = q.front(); //设置一个变量代表队首
q.pop(); //在将队首出队
int x = current.first; //再定义两个变量来代表这个点的x,y坐标 也是为了后面的书写方便
int y = current.second;
if (x == targetX && y == targetY) //如果到了终点
{
// 找到目标节点,回溯路径
vector<pair<int, int>> path; //再定义一个path的数组 类型为pair<int,int>
while (x != startX || y != startY)
{
path.push_back({ x, y }); //使这个数组向前移动一位,如果有一个整数指针就是相当于top--,向前移
pair<int, int> p = parent[x][y]; //向前移直到遇到出口
x = p.first;
y = p.second;
}
path.push_back({ startX, startY }); //向前移动到入口
cout << "Shortest path found:" << endl;
for (int i = path.size() - 1; i >= 0; --i) //由于path数组中存放的使最短路径的值,我们只需要将这个数组全部遍历一遍就可以将最短路径查出来
{
cout << "(" << path[i].first << ", " << path[i].second << ") ";
vis[path[i].first][path[i].second] = 1; //标记最短路径
}
cout << endl;
return;
}
// 探索相邻节点
for (int i = 0; i < 4; ++i) {
int nx = x + dx[i];
int ny = y + dy[i];
if (isValid(nx, ny, a) && !visited[nx][ny])
{
q.push({ nx, ny });
visited[nx][ny] = true;
parent[nx][ny] = { x, y };
}
}
}
// 如果队列为空,表示无法到达目标节点
cout << "No path found!" << endl;
is_out = true; // 如果队列为空,表示无法到达目标节点
}
//玩家移动的数据操作
void player_process(char a[][17])
{
while (peekmessage(&msg))
{
if (msg.message == WM_KEYDOWN)
{
switch (msg.vkcode)
{
case VK_UP:
if (a[(player_pos.x) / 80 - 1][(player_pos.y) / 80] != '-')//玩家移动函数,值得注意的是我们为了不和墙体发生碰撞需要做一个预先性判断,上就是x-1是否墙
player_pos.x -= 80;
break;
case VK_DOWN:
if (a[(player_pos.x) / 80 + 1][(player_pos.y) / 80] != '-')//玩家移动函数,值得注意的是我们为了不和墙体发生碰撞需要做一个预先性判断,下就是x+1是否墙
player_pos.x += 80;
break;
case VK_LEFT:
if (a[(player_pos.x) / 80][(player_pos.y) / 80 - 1] != '-')//玩家移动函数,值得注意的是我们为了不和墙体发生碰撞需要做一个预先性判断,左就是y-1是否墙
player_pos.y -= 80;
break;
case VK_RIGHT:
if (a[(player_pos.x) / 80][(player_pos.y) / 80 + 1] != '-')//玩家移动函数,值得注意的是我们为了不和墙体发生碰撞需要做一个预先性判断,右就是y+1是否墙
player_pos.y += 80;
break;
}
}
}
}
//玩家画面输出的操作
void draw_plyer(char a[][17])
{
putimage(0, 0, &img_background); //由于图片会覆盖,所以我们要先放背景图
draw_wall(a); //再画墙
check_out(); //再检查出口
draw_round(); //再画出最短路径
settextcolor(WHITE); //两个现实时间的文本输出
outtextxy(25, 10, _T("倒时:"));
TCHAR s[5];
_stprintf_s(s, _T("%d"), 10 - time_1);
outtextxy(100, 10, s);
outtextxy(350, 10, _T("玩家耗时:"));
TCHAR s1[5];
_stprintf_s(s1, _T("%d"), time_1);
outtextxy(500, 10, s1);
putimage_alpha(player_pos.y, player_pos.x, &player); //这个图像输出函数能够有效解决图片的背景化问题
Sleep(10); //对于图像都需要延时处理,为了不掉帧
}
//创建界面数据操作
void menu()
{
while (peekmessage(&msg)) //使用一个while循环不断接受鼠标键盘信息
{
if (msg.x >= 50 && msg.x <= 250 && msg.y >= 360 && msg.y <= 480 && msg.message == WM_LBUTTONDOWN)//按钮信息的范围设定
{
check_in(maze);
memset(vis, 0, sizeof(vis));
bfs(in_x, in_y, re_x, re_y, maze);
is_game_begin = 1; //开始第一关
}
else if (msg.x >= 300 && msg.x <= 500 && msg.y >= 360 && msg.y <= 480 && msg.message == WM_LBUTTONDOWN)//按钮信息的范围设定
{
check_in(maze2);
memset(vis, 0, sizeof(vis));
bfs(in_x, in_y, re_x, re_y, maze2);
is_game_begin = 2; //开始第二关
}
else if (msg.x >= 550 && msg.x <= 750 && msg.y >= 360 && msg.y <= 480 && msg.message == WM_LBUTTONDOWN)//按钮信息的范围设定
{
check_in(maze3);
memset(vis, 0, sizeof(vis));
bfs(in_x, in_y, re_x, re_y, maze3);
is_game_begin = 3; //开始第自定义关
}
else if (msg.x >= 50 && msg.x <= 250 && msg.y >= 600 && msg.y <= 720 && msg.message == WM_LBUTTONDOWN)//按钮信息的范围设定
{
is_game_begin = 4; //开始第自定义
}
else if (msg.x >= 300 && msg.x <= 500 && msg.y >= 600 && msg.y <= 720 && msg.message == WM_LBUTTONDOWN)//按钮信息的范围设定
{
is_game_begin = 5; //开始退出
}
else if (msg.x >= 550 && msg.x <= 750 && msg.y >= 600 && msg.y <= 720 && msg.message == WM_LBUTTONDOWN)//按钮信息的范围设定
{
sort_time();
is_game_begin = 6; //开始排序
}
else if (msg.x >= 800 && msg.x <= 1000 && msg.y >= 360 && msg.y <= 480 && msg.message == WM_LBUTTONDOWN)//按钮信息的范围设定
{
creat_maze_rand();
check_in(maze4);
memset(vis, 0, sizeof(vis));
bfs(in_x, in_y, re_x, re_y, maze4);
is_game_begin = 7; //开始新增关卡
}
}
}
//创造界面的的画面操作
void draw_menu()
{
putimage(0, 0, &img_menu);
setcolor(RED);
fillrectangle(50, 360, 250, 480);//1
settextstyle(30, 0, _T("宋体"));
setbkmode(TRANSPARENT);
outtextxy(100, 400, _T("第一关"));//····
fillrectangle(300, 360, 500, 480);//2
outtextxy(350, 400, _T("第二关"));//····
fillrectangle(550, 360, 750, 480);//3
outtextxy(580, 400, _T("自定义关卡"));//·····
fillrectangle(50, 600, 250, 720);//4
outtextxy(85, 650, _T("自定义"));
fillrectangle(300, 600, 500, 720);//5````````````````````
outtextxy(350, 650, _T("退出游戏"));
fillrectangle(550, 600, 750, 720);//6
outtextxy(600, 650, _T("查看排名"));
fillrectangle(800, 360, 1000, 480);
outtextxy(840, 400, _T("新增关卡"));
Sleep(10);
}
//创建迷宫的数据输入
void creat_maze()
{
while (peekmessage(&msg))
{
//检查鼠标左键按下的消息
if (msg.message == WM_LBUTTONDOWN)
{
//尝试落子
if (maze3[msg.y / 80][msg.x / 80] == '-') //如果位于的地方是墙就把墙变成路
{
maze3[msg.y / 80][msg.x / 80] = '=';
}
else if (maze3[msg.y / 80][msg.x / 80] == '=') //如果位于的地方是墙就把路变成墙
{
maze3[msg.y / 80][msg.x / 80] = '-';
}
else if (maze3[msg.y / 80][msg.x / 80] == '&') //如果位于的地方是入口自定义完成
{
is_game_begin = 0; //并且回到菜单
}
}
}
}
//创建迷宫的图像输出函数
void draw_creat_maze(char a[][17])
{
putimage(0, 0, &img_background);
draw_wall(a);
Sleep(10);
}
void draw_sort_player()
{
int count = 1;
int _count = 1;
IMAGE img_sort;
loadimage(&img_sort, "img/排序图.png");
putimage(0, 0, &img_sort);
TCHAR g_1[100] = _T("第一关:");
outtextxy(10, 10, g_1);
TCHAR g_2[100] = _T("第二关:");
outtextxy(640, 10, g_2);
TCHAR h_1[100] = _T("耗时");
outtextxy(10 + 150, 10, h_1);
TCHAR h_2[100] = _T("耗时");
outtextxy(640 + 150, 10, h_2);
TCHAR s_1[100] = _T("时间");
outtextxy(10 + 250, 10, s_1);
TCHAR s_2[100] = _T("时间");
outtextxy(640 + 250, 10, s_2);
for (int i = 0; i < numRecords; i++)
{
if (records[i].id == 1)
{
TCHAR s1[100];
_stprintf_s(s1, _T("%d/%d/%d/%d/%d/%d"), records[i].year, records[i].mouth, records[i].day,
records[i].hour, records[i].fen, records[i].sec);
outtextxy(10 + 250, 30 + 30 * count, s1);
TCHAR s_1[100];
_stprintf_s(s_1, _T("%d"), records[i].cost_time);
outtextxy(10 + 150, 30 + 30 * count, s_1);
count++;
}
else if (records[i].id == 2)
{
TCHAR s2[100];
_stprintf_s(s2, _T("%d/%d/%d/%d/%d/%d"), records[i].year, records[i].mouth, records[i].day,
records[i].hour, records[i].fen, records[i].sec);
outtextxy(640 + 250, 30 + 30 * _count, s2);
TCHAR s_2[100];
_stprintf_s(s_2, _T("%d"), records[i].cost_time);
outtextxy(640 + 150, 30 + 30 * _count, s_2);
_count++;
}
}
Sleep(10);
}
//将数据加入到结构体数组中
void addTimeRecord(int id, int cost_time, int year, int mouth, int day, int hour, int fan, int sec)
{
if (numRecords < 10000 && is_game_begin <= 2 && is_game_begin >= 1)
{
records[numRecords].id = id;
records[numRecords].cost_time = time_1;
records[numRecords].year = localTime->tm_year + 1900;
records[numRecords].mouth = localTime->tm_mon + 1;
records[numRecords].day = localTime->tm_mday;
records[numRecords].hour = localTime->tm_hour;
records[numRecords].fen = localTime->tm_min;
records[numRecords].sec = localTime->tm_sec;
numRecords++;
}
else
{
printf("记录已满,无法添加更多时间。\n");
}
}
//将信息保存到文件中
void saveRecordsToFile(const char* filename)
{
FILE* file = fopen(filename, "w");
if (file == NULL)
{
printf("无法打开文件 %s 进行写入。\n", filename);
return;
}
for (int i = 0; i < numRecords; i++)
{
fprintf(file, "%d %d %d %d %d %d %d %d\n", records[i].id, records[i].cost_time, records[i].year, records[i].mouth,
records[i].day, records[i].hour, records[i].fen, records[i].sec);
}
fclose(file);
}
//加载文件信息
void loadRecordsFromFile(const char* filename)
{
FILE* file = fopen(filename, "r");
if (file == NULL)
{
printf("无法打开文件 %s 进行读取。\n", filename);
return;
}
while (fscanf(file, "%d %d %d %d %d %d %d %d", &records[numRecords].id, &records[numRecords].cost_time, &records[numRecords].year, &records[numRecords].mouth,
&records[numRecords].day, &records[numRecords].hour, &records[numRecords].fen, &records[numRecords].sec) == 8)
{
numRecords++;
if (numRecords >= 10000)
{
printf("文件中的记录数量超过最大限制。\n");
break;
}
}
fclose(file);
}
bool cmp(TimeRecord x, TimeRecord y)
{
return x.cost_time < y.cost_time;
}
//排名数据输入函数
void sort_time()
{
sort(records, records + numRecords, cmp);
while (peekmessage(&msg))
{
if (msg.x >= 0 && msg.y >= 0 && msg.message == WM_LBUTTONDOWN)
{
is_game_begin = 0;
}
}
}
//随机生成地图函数
void creat_maze_rand()
{
// 初始化迷宫
for (int i = 0; i < 9; i++)
{
for (int j = 0; j < 16; j++)
{
if (i == 0 || i == 8 || j == 0 || j == 15)
{
maze4[i][j] = '-'; // 迷宫边缘固定为墙
}
else
{
maze4[i][j] = '='; // 其余位置初始化为空路
}
}
}
// 随机生成迷宫的内部结构
srand((unsigned int)time(NULL));
for (int i = 1; i < 8; i++)
{
for (int j = 1; j < 15; j++)
{
if (rand() % 100 < 30)
{
maze4[i][j] = '-';
}
}
}
// 随机生成入口和出口
player_pos.y = rand() % (9 - 2) + 1;
maze4[player_pos.y][1] = '&';
maze4[6][15] = '@';
}
08-13
04-25
03-08
01-04
07-19