目录
1.设置数组储存雷的状态和展示状态
用两个二维数组来分别储存雷的状态及显示的状态。为了方便方格中数字的计算,扩充一个外围,采用11*11的数组(均初始化为0)。用9表示雷(因为一个方格周围的雷最多8个)
#define ROW 9
#define LINE 9
#define MINE 10
char arra[ROW + 2][LINE + 2] = { '?' };
char arrb[ROW + 2][LINE + 2] = { '\0' };
char(*look)[LINE + 2];
char(*unlook)[LINE + 2];
look = arra;
unlook = arrb;
产生随机数来初始化雷的状态。若产生的坐标中没有雷(即不等于9)则将其设置为9并使计数器加1。计算每个方格周围的雷的个数,有方格为9则数字加1.
void putunlook(char(*arr)[LINE + 2])
{
int i, j, a, m, n;
for (i = 0; i <= ROW + 1; i++)
{
for (j = 0; j <= LINE + 1; j++)
{
arr[i][j] = '0';
}
}
a = MINE;
while (a > 0)
{
i = rand() % 9 + 1;
j = rand() % 9 + 1;
if (arr[i][j] != '9')
{
arr[i][j] = '9';
a--;
}
}
for (i = 1; i < ROW + 1; i++)
{
for (j = 1; j < LINE + 1; j++)
{
if (arr[i][j] != '9')
{
for (m = -1; m <= 1; m++)
{
for (n = -1; n <= 1; n++)
{
if ((m != 0 || n != 0) && arr[i + m][j + n] == '9')
{
arr[i][j]++;
}
}
}
}
}
}
}
2.初始化欢迎界面
打开界面,在界面中绘制两个按钮,通过鼠标消息判断对其控制并作出反应
void menu()
{
setfillcolor(RGB(127, 127, 127));
setlinecolor(RGB(227, 180, 128));
fillrectangle(20, 400, 120, 430);
outtextxy(40, 406, "开始游戏");
fillrectangle(280, 400, 380, 430);
outtextxy(300, 406, "退出游戏");
}
ExMessage mouse = { 0 };
initgraph(400, 650, EX_MOUSE);
setbkmode(TRANSPARENT);
setbkcolor(BROWN);
cleardevice();
menu();
while (1)
{
if (peekmessage(&mouse, EX_MOUSE))
{
if (set(mouse)==1)
{
break;
}
else if(!set(mouse))
{
return 0;
}
}
}
3.设置计时时钟
通过程序执行时间来获取游戏所用时间。为保证效果,每一秒在屏幕上刷新一次。
if (a)
{
before = now;
}
now = (int)(clock() - start)/1000;
if (!a)
{
before = now;
}
now = now - now / 1000;
t[0] = now / 100 + '0';
t[1] = (now / 10) % 10 + '0';
t[2] = now % 10 + '0';
if (!a || now - before)
{
clearpolygon(points, 4);
outtextxy(190, 50, t);
}
a=1;
4.加载游戏界面
输出数组中下标1-9的方格
void beside()
{
int i, j;
setlinecolor(WHITE);
setfillcolor(RGB(192, 192, 192));
for (i = 0; i < ROW*25; i += 25)
{
for (j = 0; j < LINE*25; j += 25)
{
fillrectangle(i + 90, j + 130, i + 115, j + 155);
}
}
}
5.判断扫雷状况并进行下一步
若鼠标在某个方格上则将其设为其他颜色以易于区分
if (peekmessage(&mouse, EX_MOUSE))
{
m = (mouse.x - 90) / 25;
n = (mouse.y - 130) / 25;
if (mouse.x > 90 && mouse.x < 315 && mouse.y>130 && mouse.y < 355)
{
for (x = 0; x < ROW; x++)
{
for (y = 0; y < LINE; y++)
{
if ((x != m || y != n) && look[x + 1][y + 1] == '?')
{
setfillcolor(RGB(192, 192, 192));
fillrectangle(x * 25 + 90, y * 25 + 130, x * 25 + 115, y * 25 + 155);
}
}
}
if (look[m + 1][n + 1] == '?')
{
fillrectangle(90 + m * 25, 130 + n * 25, 115 + m * 25, 155 + n * 25);
}
}
}
通过鼠标坐标捕获所选方格。若右键则标记防护,判断这个方格的状态,若未被操作则在相应的方格绘制并把展示的数组中标记对存在方格数减1
if (mouse.message == WM_RBUTTONDOWN && (look[m + 1][n + 1] == '?' || look[m + 1][n + 1] == '#'))
{
look[m + 1][n + 1] = look[m + 1][n + 1] == '?' ? '#' : '?';
outtextxy(99 + m * 25, 135 + n * 25, '#');
}
若左键按下,则先判断其是否为雷,若是雷则显示游戏失败
int judge(char ch1)
{
if (ch1 == '0')
{
return 0;
}
else if (ch1 >= '1' && ch1 < '9')
{
return 1;
}
else if(ch1=='9')
{
return 2;
}
else
{
return 3;
}
}
if (mouse.message == WM_LBUTTONDOWN)
{
setfillcolor(WHITE);
b = judge(unlook[m + 1][n + 1]);
if (b == 2 && look[m + 1][n + 1] != '#')
{
end();
outtextxy(170, 300, "你输了");
while (1)
{
if (peekmessage(&mouse, EX_MOUSE))
{
if (set(mouse) == 1)
{
break;
}
else if (!set(mouse))
{
return 0;
}
}
}
goto begin;
}
}
若不是雷则判断其数字是否为0.若不是0则展示其数字,若是0则递归调用函数,执行过的方格进行标记,直到均不是0或均被标记或遇到边界,每次操作均对剩余方格数减1
void unfold(char(*arr1)[LINE + 2], char(*arr2)[LINE + 2], int x, int y, int* z)
{
int i, j;
if (x >= 0 && x <= ROW-1 && y >= 0 && y <= LINE-1 && arr1[x+1][y+1] != 'o' && arr1[x+1][y+1] != '9' && arr2[x+1][y+1] == '?')
{
arr2[x+1][y+1] = arr1[x+1][y+1];
fillrectangle(90 + x * 25, 130 + y * 25, 115 + x * 25, 155 + y* 25);
outtextxy(99 + x * 25, 135 + y * 25, arr1[x+1][y+1]);
(*z)--;
if (arr1[x+1][y+1] == '0')
{
for (i = -1; i <= 1; i++)
{
for (j = -1; j <= 1; j++)
{
unfold(arr1, arr2, x + i, y + j, z);
}
}
}
arr1[x+1][y+1] = 'o';
}
}
else if (b == 1 && look[m + 1][n + 1] != '#')
{
look[m + 1][n + 1] = unlook[m + 1][n + 1];
d--;
fillrectangle(90 + m * 25, 130 + n * 25, 115 + m * 25, 155 + n * 25);
outtextxy(99 + m * 25, 135 + n * 25, look[m + 1][n + 1]);
}
else if (!b && look[m + 1][n + 1] != '#')
{
unfold(unlook, look, m, n, c);
}
6.显示结果并继续
若剩余的方格数等于0在界面中显示计时器的结果,并设置两个按钮判断
void end()
{
cleardevice();
settextcolor(BLUE);
setfillcolor(RGB(127, 127, 127));
setlinecolor(RGB(227, 180, 128));
fillrectangle(20, 400, 120, 430);
outtextxy(40, 406, "重新开始");
fillrectangle(280, 400, 380, 430);
outtextxy(300, 406, "退出游戏");
}
if (d == 0)
{
end();
outtextxy(135, 300, "你赢了,用时");
outtextxy(220, 300, t);
outtextxy(245, 300, "秒");
while (1)
{
if (peekmessage(&mouse, EX_MOUSE))
{
if (set(mouse) == 1)
{
break;
}
else if (!set(mouse))
{
return 0;
}
}
}
goto begin;
}
7.完整代码
game.h
#pragma once
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <Windows.h>
#include <easyx.h>
#define ROW 9
#define LINE 9
#define MINE 10
founction.cpp
#include "game.h"
void menu()
{
setfillcolor(RGB(127, 127, 127));
setlinecolor(RGB(227, 180, 128));
fillrectangle(20, 400, 120, 430);
outtextxy(40, 406, "开始游戏");
fillrectangle(280, 400, 380, 430);
outtextxy(300, 406, "退出游戏");
}
void beside()
{
int i, j;
setlinecolor(WHITE);
setfillcolor(RGB(192, 192, 192));
for (i = 0; i < ROW*25; i += 25)
{
for (j = 0; j < LINE*25; j += 25)
{
fillrectangle(i + 90, j + 130, i + 115, j + 155);
}
}
}
void putunlook(char(*arr)[LINE + 2])
{
int i, j, a, m, n;
for (i = 0; i <= ROW + 1; i++)
{
for (j = 0; j <= LINE + 1; j++)
{
arr[i][j] = '0';
}
}
a = MINE;
while (a > 0)
{
i = rand() % 9 + 1;
j = rand() % 9 + 1;
if (arr[i][j] != '9')
{
arr[i][j] = '9';
a--;
}
}
for (i = 1; i < ROW + 1; i++)
{
for (j = 1; j < LINE + 1; j++)
{
if (arr[i][j] != '9')
{
for (m = -1; m <= 1; m++)
{
for (n = -1; n <= 1; n++)
{
if ((m != 0 || n != 0) && arr[i + m][j + n] == '9')
{
arr[i][j]++;
}
}
}
}
}
}
}
void putlook(char(*arr)[LINE + 2])
{
int i, j;
for (i = 1; i < ROW + 1; i++)
{
for (j = 1; j < LINE + 1; j++)
{
arr[i][j] = '?';
}
}
}
void unfold(char(*arr1)[LINE + 2], char(*arr2)[LINE + 2], int x, int y, int* z)
{
int i, j;
if (x >= 0 && x <= ROW-1 && y >= 0 && y <= LINE-1 && arr1[x+1][y+1] != 'o' && arr1[x+1][y+1] != '9' && arr2[x+1][y+1] == '?')
{
arr2[x+1][y+1] = arr1[x+1][y+1];
fillrectangle(90 + x * 25, 130 + y * 25, 115 + x * 25, 155 + y* 25);
outtextxy(99 + x * 25, 135 + y * 25, arr1[x+1][y+1]);
(*z)--;
if (arr1[x+1][y+1] == '0')
{
for (i = -1; i <= 1; i++)
{
for (j = -1; j <= 1; j++)
{
unfold(arr1, arr2, x + i, y + j, z);
}
}
}
arr1[x+1][y+1] = 'o';
}
}
int judge(char ch1)
{
if (ch1 == '0')
{
return 0;
}
else if (ch1 >= '1' && ch1 < '9')
{
return 1;
}
else if(ch1=='9')
{
return 2;
}
else
{
return 3;
}
}
int set(ExMessage mouse)
{
if (mouse.x > 20 && mouse.x < 120 && mouse.y>400 && mouse.y < 430 && mouse.message == WM_LBUTTONDOWN)
{
cleardevice();
return 1;
}
else if (mouse.x > 280 && mouse.x < 380 && mouse.y>400 && mouse.y < 430 && mouse.message == WM_LBUTTONDOWN)
{
return 0;
}
else
{
return 2;
}
}
void end()
{
cleardevice();
settextcolor(BLUE);
setfillcolor(RGB(127, 127, 127));
setlinecolor(RGB(227, 180, 128));
fillrectangle(20, 400, 120, 430);
outtextxy(40, 406, "重新开始");
fillrectangle(280, 400, 380, 430);
outtextxy(300, 406, "退出游戏");
}
main.cpp
#include "game.h"
extern void menu();
extern void beside();
extern void putlook(char(*arr)[LINE + 2]);
extern void putunlook(char(*arr)[LINE + 2]);
extern void unfold(char(*arr1)[LINE + 2], char(*arr2)[LINE + 2], int x, int y, int* z);
extern int judge(char ch1);
extern void end();
extern int set(ExMessage mouse);
int main()
{
int a, x, y, b, d,m,n,now,before;
clock_t start;
POINT points[] = {{170,20},{235,20},{170,70},{235,70}};
char t[4] = {'\0'};
m = -1;
n = -1;
a = 0;
begin:
d = ROW * LINE - MINE;
int* c = &d;
srand((unsigned int)time(NULL));
char arra[ROW + 2][LINE + 2] = { '\0' };
char arrb[ROW + 2][LINE + 2] = { '\0' };
char(*look)[LINE + 2];
char(*unlook)[LINE + 2];
look = arra;
unlook = arrb;
ExMessage mouse = { 0 };
initgraph(400, 650, EX_MOUSE);
setbkmode(TRANSPARENT);
setbkcolor(BROWN);
cleardevice();
menu();
putlook(look);
putunlook(unlook);
while (1)
{
if (peekmessage(&mouse, EX_MOUSE))
{
if (set(mouse)==1)
{
break;
}
else if(!set(mouse))
{
return 0;
}
}
}
beside();
settextcolor(GREEN);
start = clock();
while (1)
{
setfillcolor(BLACK);
if (a)
{
before = now;
}
now = (int)(clock() - start)/1000;
if (!a)
{
before = now;
}
now = now - now / 1000;
t[0] = now / 100 + '0';
t[1] = (now / 10) % 10 + '0';
t[2] = now % 10 + '0';
if (!a || now - before)
{
clearpolygon(points, 4);
outtextxy(190, 50, t);
}
a=1;
if (peekmessage(&mouse, EX_MOUSE))
{
m = (mouse.x - 90) / 25;
n = (mouse.y - 130) / 25;
if (mouse.x > 90 && mouse.x < 315 && mouse.y>130 && mouse.y < 355)
{
if (mouse.message == WM_LBUTTONDOWN)
{
setfillcolor(WHITE);
b = judge(unlook[m + 1][n + 1]);
if (b == 2 && look[m + 1][n + 1] != '#')
{
end();
outtextxy(170, 300, "你输了");
while (1)
{
if (peekmessage(&mouse, EX_MOUSE))
{
if (set(mouse) == 1)
{
break;
}
else if (!set(mouse))
{
return 0;
}
}
}
goto begin;
}
else if (b == 1 && look[m + 1][n + 1] != '#')
{
look[m + 1][n + 1] = unlook[m + 1][n + 1];
d--;
fillrectangle(90 + m * 25, 130 + n * 25, 115 + m * 25, 155 + n * 25);
outtextxy(99 + m * 25, 135 + n * 25, look[m + 1][n + 1]);
}
else if (!b && look[m + 1][n + 1] != '#')
{
unfold(unlook, look, m, n, c);
}
}
if (mouse.message == WM_RBUTTONDOWN && (look[m + 1][n + 1] == '?' || look[m + 1][n + 1] == '#'))
{
look[m + 1][n + 1] = look[m + 1][n + 1] == '?' ? '#' : '?';
outtextxy(99 + m * 25, 135 + n * 25, '#');
}
if (look[m + 1][n + 1] == '?')
{
fillrectangle(90 + m * 25, 130 + n * 25, 115 + m * 25, 155 + n * 25);
}
for (x = 0; x < ROW; x++)
{
for (y = 0; y < LINE; y++)
{
if ((x != m || y != n) && look[x + 1][y + 1] == '?')
{
setfillcolor(RGB(192, 192, 192));
fillrectangle(x * 25 + 90, y * 25 + 130, x * 25 + 115, y * 25 + 155);
}
}
}
}
if (d == 0)
{
end();
outtextxy(135, 300, "你赢了,用时");
outtextxy(220, 300, t);
outtextxy(245, 300, "秒");
while (1)
{
if (peekmessage(&mouse, EX_MOUSE))
{
if (set(mouse) == 1)
{
break;
}
else if (!set(mouse))
{
return 0;
}
}
}
goto begin;
}
}
}
}