请写一段扫雷
时间: 2024-02-19 19:02:27 浏览: 77
下面是一个简单的扫雷游戏的示例代码,代码使用 C++ 和 easyx 库实现:
```c++
#include <graphics.h>
#include <conio.h>
#include <time.h>
#include <stdlib.h>
#define ROWS 10 // 行数
#define COLS 10 // 列数
#define MINES 10 // 雷数
#define WSIZE 30 // 格子尺寸
// 格子状态
enum CellState
{
CELL_HIDDEN, // 隐藏状态
CELL_VISIBLE, // 显示状态
CELL_MARKED // 标记状态
};
// 格子结构体
struct Cell
{
int x, y; // 格子坐标
bool isMine; // 是否是雷
int mineCount; // 周围雷的数量
CellState state; // 格子状态
};
// 地图,二维数组
Cell map[ROWS][COLS];
// 初始化地图
void initMap()
{
// 随机放置雷
srand((unsigned int)time(NULL));
int count = 0;
while (count < MINES)
{
int x = rand() % COLS;
int y = rand() % ROWS;
if (!map[y][x].isMine)
{
map[y][x].isMine = true;
count++;
}
}
// 计算周围雷的数量
for (int y = 0; y < ROWS; y++)
{
for (int x = 0; x < COLS; x++)
{
if (map[y][x].isMine)
continue;
int count = 0;
for (int j = y - 1; j <= y + 1; j++)
{
for (int i = x - 1; i <= x + 1; i++)
{
if (i < 0 || i >= COLS || j < 0 || j >= ROWS)
continue;
if (map[j][i].isMine)
count++;
}
}
map[y][x].mineCount = count;
}
}
}
// 显示地图
void drawMap()
{
setbkcolor(WHITE);
cleardevice();
for (int y = 0; y < ROWS; y++)
{
for (int x = 0; x < COLS; x++)
{
int left = x * WSIZE;
int top = y * WSIZE;
int right = left + WSIZE;
int bottom = top + WSIZE;
if (map[y][x].state == CELL_HIDDEN)
{
setfillcolor(LIGHTGRAY);
fillrectangle(left, top, right, bottom);
}
else if (map[y][x].state == CELL_MARKED)
{
setfillcolor(RED);
fillrectangle(left, top, right, bottom);
}
else if (map[y][x].state == CELL_VISIBLE)
{
if (map[y][x].isMine)
{
setfillcolor(BLACK);
fillrectangle(left, top, right, bottom);
}
else
{
setfillcolor(LIGHTGRAY);
fillrectangle(left, top, right, bottom);
if (map[y][x].mineCount > 0)
{
char text[2] = { 0 };
text[0] = '0' + map[y][x].mineCount;
settextcolor(BLACK);
settextstyle(WSIZE - 2, WSIZE - 2, "宋体");
outtextxy(left + WSIZE / 2 - 4, top + WSIZE / 2 - 8, text);
}
}
}
setlinestyle(PS_SOLID, 1);
setlinecolor(BLACK);
rectangle(left, top, right, bottom);
}
}
}
// 点击格子
void clickCell(int x, int y)
{
if (x < 0 || x >= COLS || y < 0 || y >= ROWS)
return;
Cell& cell = map[y][x];
if (cell.state != CELL_HIDDEN)
return;
cell.state = CELL_VISIBLE;
if (cell.isMine)
{
drawMap();
outtextxy(0, ROWS * WSIZE + 5, "你输了!按任意键重新开始");
getch();
initMap();
drawMap();
return;
}
if (cell.mineCount == 0)
{
clickCell(x - 1, y - 1);
clickCell(x, y - 1);
clickCell(x + 1, y - 1);
clickCell(x - 1, y);
clickCell(x + 1, y);
clickCell(x - 1, y + 1);
clickCell(x, y + 1);
clickCell(x + 1, y + 1);
}
}
int main()
{
initgraph(COLS * WSIZE, ROWS * WSIZE + 40);
setbkcolor(WHITE);
cleardevice();
initMap();
drawMap();
while (1)
{
MOUSEMSG msg = GetMouseMsg();
if (msg.uMsg == WM_LBUTTONDOWN)
{
int x = msg.x / WSIZE;
int y = msg.y / WSIZE;
clickCell(x, y);
drawMap();
}
else if (msg.uMsg == WM_RBUTTONDOWN)
{
int x = msg.x / WSIZE;
int y = msg.y / WSIZE;
Cell& cell = map[y][x];
if (cell.state == CELL_HIDDEN)
cell.state = CELL_MARKED;
else if (cell.state == CELL_MARKED)
cell.state = CELL_HIDDEN;
drawMap();
}
if (_kbhit())
break;
}
closegraph();
return 0;
}
```
在这个示例代码中,我们使用 easyx 库创建了一个 ROWS 行 COLS 列的扫雷游戏,其中包含了 MINES 个雷。我们首先在 `initMap` 函数中随机放置雷,并计算每个格子周围雷的数量。在 `drawMap` 函数中,我们根据格子状态绘制相应的图形,包括隐藏状态、标记状态和显示状态。在 `clickCell` 函数中,我们处理点击格子的逻辑,如果点击到了雷则游戏结束,否则递归地打开周围的格子。在主循环中,我们不断调用 `GetMouseMsg` 函数获取鼠标消息,处理左键点击和右键点击事件。
需要注意的是,在使用 easyx 库时需要在 Visual Studio 中添加 easyx 库的路径和链接库。具体操作可以参考 easyx 官网提供的教程。
阅读全文