[C++] 纯文本查看 复制代码
#include<stdio.h>
#include<graphics.h>
#include<time.h>
#define N 20 //20*20的游戏地图
#define M 25 //每个区域边长为25
HWND hWnd; //窗口句柄
int win; //记录翻开的个数,用来判断输赢
//函数声明
void game(); //开始游戏
void drawmap(int map[][N + 2], IMAGE* img); //绘制地图
int play(int map[][N + 2]); //玩游戏,主要是鼠标操作
void swap(int map[][N + 2], int x, int y); //翻开0,翻开一片
int main()
{
while (1)
{
game();
if (MessageBox(hWnd, L"再玩一局?", L"退出", MB_RETRYCANCEL) == IDCANCEL)
{
break;
}
}
closegraph();
return 0;
}
void game()
{
//创建窗口
initgraph(M * N, M * N);
//生成一个扫雷地图 20*20
//周围一圈作为辅助,防止数组越界
int map[N + 2][N + 2] = { 0 };
int m, n, i, j;
//随机数种子
srand((unsigned)time(NULL));
//埋雷
for (n = 0; n < 2 * N;)//循环多少次就埋下几个雷
{
i = rand() % N + 1;//生成1-N之间的随机数
j = rand() % N + 1;//作为数组下标
//判断这里是否是空地,如果有雷,就重新选择区域埋雷
if (map[i][j] == 0)
{
map[i][j] = -1;//用-1表示地雷
n++;
}
}
//埋数字
for (i = 1; i <= N; i++)
{
for (j = 1; j <= N; j++)
{
if (map[i][j] != -1) //判断这里是不是雷
{
for (m = i - 1; m <= i + 1; m++) //扫描当前位置的周围区域
{
for (n = j - 1; n <= j + 1; n++)
{
if (map[m][n] == -1)
{
map[i][j]++; //找到一个周围是雷的位置,当前位置就加1
//有几个雷,数组元素的值就为几
}
}
}
}
}
}
//画图 将数组转换为扫雷图
IMAGE img[12];
//加载图片
loadimage(&img[0], L"0.jpg", M, M);
loadimage(&img[1], L"1.jpg", M, M);
loadimage(&img[2], L"2.jpg", M, M);
loadimage(&img[3], L"3.jpg", M, M);
loadimage(&img[4], L"4.jpg", M, M);
loadimage(&img[5], L"5.jpg", M, M);
loadimage(&img[6], L"6.jpg", M, M);
loadimage(&img[7], L"7.jpg", M, M);
loadimage(&img[8], L"8.jpg", M, M);
loadimage(&img[9], L"雷.jpg", M, M);
loadimage(&img[10], L"地图.jpg", M, M);
loadimage(&img[11], L"标记.jpg", M, M);
hWnd = GetHWnd();//Messagebox窗口置前
win = 0;//重置胜利条件
while (1)
{
drawmap(map, img);
if (play(map) == 9)
{
//表示点开了一个雷
drawmap(map, img);
MessageBox(hWnd, L"炸弹来咯", L"BOOM", MB_OK);
return;
}
//游戏是否继续 胜利条件 点开了所有非雷区域
if (win == N*M - 2*N)
{
drawmap(map, img);
MessageBox(hWnd, L"你赢了", L"WELL PLAYED", MB_OK);
break;
}
}
}
//画图
void drawmap(int map[][N + 2], IMAGE *img)
{
for (int i = 1; i <= N; i++)
{
for (int j = 1; j <= N; j++)
{
//右键标记数组元素值+30
if (map[i][j] >= 20)
{
//标记部分额外处理
putimage(M * (i - 1), M * (j - 1), &img[11]);
continue;
}
switch (map[i][j])
{
case 9:
putimage(M * (i - 1), M * (j - 1), &img[9]);//雷 -1为雷
break;
case 10:
putimage(M * (i - 1), M * (j - 1), &img[0]); //点击之后的取值9~19
break;
case 11:
putimage(M * (i - 1), M * (j - 1), &img[1]);
break;
case 12:
putimage(M * (i - 1), M * (j - 1), &img[2]);
break;
case 13:
putimage(M * (i - 1), M * (j - 1), &img[3]);
break;
case 14:
putimage(M * (i - 1), M * (j - 1), &img[4]);
break;
case 15:
putimage(M * (i - 1), M * (j - 1), &img[5]);
break;
case 16:
putimage(M * (i - 1), M * (j - 1), &img[6]);
break;
case 17:
putimage(M * (i - 1), M * (j - 1), &img[7]);
break;
case 18:
putimage(M * (i - 1), M * (j - 1), &img[8]);
break;
default:
putimage(M * (i - 1), M * (j - 1), &img[10]); //初始化都为空(-1~8)标记为空
break;
}
}
}
}
int play(int map[][N + 2])
{
MOUSEMSG msg; //获取鼠标位置
while (1)
{
msg = GetMouseMsg(); //获取鼠标消息
switch (msg.uMsg) //判断当前鼠标消息
{
case WM_LBUTTONDOWN: //左键点开
//>9表示已经点开或者标记,不能再再点击
if (map[msg.x / M + 1][msg.y / M + 1] >9)
{
continue;
}
//=0翻开一片
if (map[msg.x / M + 1][msg.y / M + 1] == 0)
{
swap(map, msg.x / M + 1, msg.y / M + 1);
}
//翻到数字或者雷,直接翻开
else
{
map[msg.x / M + 1][msg.y / M + 1] += 10;
win++;
}
return map[msg.x / M + 1][msg.y / M + 1];
break;
case WM_RBUTTONDOWN: //右键标记,取消标记
//没有翻开的标记,+30
if (map[msg.x / M + 1][msg.y / M + 1]<9)
{
map[msg.x / M + 1][msg.y / M + 1] += 30;
}
//标记了的,取消标记
else if (map[msg.x / M + 1][msg.y / M + 1] >= 20)
{
map[msg.x / M + 1][msg.y / M + 1] -= 30;
}
//点击翻开区域无效
else
{
continue;
}
return 0;
break;
}
}
}
void swap(int map[][N + 2], int x, int y)
{
map[x][y] = 10; //点到0,先翻开点击的位置
win++;
int i, j;
//遍历点击点周围区域
for (i = x - 1; i <= x + 1; i++)
{
for (j = y - 1; j <= y + 1; j++)
{
if (i >= 1 && i <= N && j >= 1 && j <= N) //判断是否越界
{
if (map[i][j]<9) //没有翻开
{
if (map[i][j] == 0) //=0
{
swap(map, i, j); //如果没翻开并且为空就递归
}
else //否则直接翻开
{
map[i][j] += 10;
win++;
}
}
}
}
}
return;
}
以上是全部源代码!
下面的是扫雷的素材以及Easy X图形库工具。