今天给大家带来扫雷的再次改良版,在easyx的基础上。有一点不好的是,我的代码很冗余
如果也想写这么一个的话可以自己优化。看效果。
附上对应可执行程序:
这里面我们需要的的是easyx图形库的知识
我这里是使用了900480的画布大小,为了能够容纳3016的方块,首先是游戏开始的框架,具体的函数不做过多解释。绝大多数都是easyx图形库里的函数
int main()
{
int main()
{
initgraph(900, 480);
srand((unsigned)time(NULL));
HWND hwnd = GetHWnd(); // 获取绘图窗口句柄,这是后面鼠标获取信息时需要用到的一些参数,可以自己上网查看是什么意思
POINT point;
TCHAR s[10];
start:
setbkcolor(WHITE);
cleardevice();
ExMessage msg;
InitStartInterface();//这个函数是显式开始游戏和退出游戏两个按钮界面
while (1)//游戏开始逻辑
{
GetCursorPos(&point); // 获取鼠标指针位置(屏幕坐标)
ScreenToClient(hwnd, &point); // 将鼠标指针位置转换为窗口坐标
if ((point.x >= 250 && point.x <= 650) && (point.y >= 20 && point.y <= 220))//开始游戏按钮
{//这里是假如鼠标移动到开始游戏或者退出游戏按钮时会做出反应
if (getpixel(270, 40) != RGB(215, 222, 10))
{//这里是当鼠标放到对应按钮上,按钮会变色对应开始游戏按钮
StartDiscolour();
}
if (peekmessage(&msg, EX_MOUSE))//这个是当鼠标左键单机时
{
if (msg.lbutton)
{
opt:
//开始游戏
setbkcolor(WHITE);
cleardevice();//清屏
//选择游戏难度
//.....
}
else if ((point.x >= 250 && point.x <= 650) && (point.y >= 260 && point.y <= 460))//这里是退出游戏的按钮范围
{
if (getpixel(270, 280) != RGB(215, 222, 10))
{//退出游戏按钮变色
EndDiscolour();
}
if (peekmessage(&msg, EX_MOUSE))
{
if (msg.lbutton)
{
//退出游戏
return 0;
}
}
}
else
{
if (getpixel(270, 40) != RGB(247, 255, 10) || getpixel(270, 280) != RGB(247, 255, 10))
{
//这个是为了当鼠标都不在这两个按钮上是,会在检测一遍,把按钮颜色恢复到默认
InitStartInterface();
}
}
}
这里有个知识点就是将我们要打印的一句话或者图形如何垂直水平居中,很简单的数学知识,我们只需要使用想让图形或者话的像素宽度减去对象的宽度然后除以二就是目标的水平居中位置,垂直亦是如此
至于画布按钮的大小颜色参数自己设置,我这里把所有的按钮颜色都设置的浅了一点,为了鼠标移到对应按钮上能够实现变色的目的。
void InitStartInterface()
{
setfillcolor(RGB(247, 255, 10));//按钮颜色
setlinecolor(BLACK);
setlinestyle(PS_SOLID, 10);
fillroundrect(250, 20, 650, 220, 50, 50);
fillroundrect(250, 260, 650, 460, 50, 50);
char start[] = "开始游戏";
char end[] = "退出游戏";
settextcolor(BLACK);//文字颜色
settextstyle(60, 30, "");
int start_w = textwidth(start);
int start_h = textheight(start);
int end_w = textwidth(end);
int end_h = textheight(end);
outtextxy(250 + (400 - start_w) / 2, 20 + (200 - start_h) / 2, start);
outtextxy(250 + (400 - end_w) / 2, 260 + (200 - end_h) / 2, end);
}
这个是开始游戏按钮变色的函数,退出游戏包括以后的变色逻辑基本一样
当鼠标移到按钮后就会进入这个函数打印出一个深色的按钮。
void StartDiscolour()
{
setfillcolor(RGB(215, 222, 10));//按钮变化后的颜色
fillroundrect(250, 20, 650, 220, 50, 50);
char start[] = "开始游戏";
settextcolor(BLACK);
settextstyle(60, 30, "");
int start_w = textwidth(start);
int start_h = textheight(start);
outtextxy(250 + (400 - start_w) / 2, 20 + (200 - start_h) / 2, start);
}
void EndDiscolour()
{
setfillcolor(RGB(215, 222, 10));//按钮变化后的颜色
fillroundrect(250, 260, 650, 460, 50, 50);
char end[] = "退出游戏";
settextcolor(BLACK);
settextstyle(60, 30, "");
int end_w = textwidth(end);
int end_h = textheight(end);
outtextxy(250 + (400 - end_w) / 2, 260 + (200 - end_h) / 2, end);
}
InitDifficultyOptFace();//显式三个困难模块按钮
GoBack();//这个会显示返回提示那句话
while (1)
{
GetCursorPos(&point); // 获取鼠标指针位置(屏幕坐标)
ScreenToClient(hwnd, &point); // 将鼠标指针位置转换为窗口坐标
if (_kbhit())
{//这个是为了按下esc键能随时返回上一级
char esc = _getch();
if (esc == 27)
{
goto start;
}
}
if ((point.x >= 100 && point.x <= 300) && (point.y >= 190 && point.y <= 290))
{
if (getpixel(120, 210) != RGB(6, 179, 9))
{
//简单按钮变色
SimpleDiscolour();
GoBack();
}
if (peekmessage(&msg, EX_MOUSE))
{
if (msg.lbutton)
{
setbkcolor(WHITE);
cleardevice();//清屏
//简单模式游戏开始
//.....
}
}
}
else if ((point.x >= 350 && point.x <= 550) && (point.y >= 190 && point.y <= 290))
{
if (getpixel(370, 210) != RGB(194, 137, 47))
{
//困难按钮变色
difficultyDiscolour();
GoBack();
}
if (peekmessage(&msg, EX_MOUSE))
{
if (msg.lbutton)
{
setbkcolor(WHITE);
cleardevice();//清屏
//困难模式游戏开始
//.....
}
}
}
else if ((point.x >= 600 && point.x <= 800) && (point.y >= 190 && point.y <= 290))
{
if (getpixel(620, 210) != RGB(168, 48, 11))
{
//地狱按钮变色
HellDiscolour();
GoBack();
}
if (peekmessage(&msg, EX_MOUSE))
{
if (msg.lbutton)
{
setbkcolor(WHITE);
cleardevice();//清屏
//地狱模式游戏开始
//....
}
}
}
else
{
if (getpixel(120, 210) == RGB(6, 179, 9)
|| getpixel(620, 210) == RGB(168, 48, 11)
|| getpixel(370, 210) == RGB(194, 137, 47))
{//当鼠标不在三个模块上时,将三个按钮的颜色恢复默认
InitDifficultyOptFace();
GoBack();
}
}
}
void InitDifficultyOptFace()
{
setlinecolor(BLACK);
setlinestyle(PS_SOLID, 10);
setfillcolor(RGB(32, 255, 46));//简单难度按钮颜色
fillroundrect(100, 190, 300, 290, 50, 50);
char simple[] = "简单(9*9)";
settextcolor(BLACK);
settextstyle(30, 15, "");
int simple_w = textwidth(simple);
int simple_h = textheight(simple);
outtextxy(100 + (200 - simple_w) / 2, 190 + (100 - simple_h) / 2, simple);
setfillcolor(RGB(255, 180, 62));//困难难度按钮颜色
fillroundrect(350, 190, 550, 290, 50, 50);
char difficulty[] = "困难(16*16)";
settextcolor(BLACK);
settextstyle(30, 15, "");
int difficulty_w = textwidth(difficulty);
int difficulty_h = textheight(difficulty);
outtextxy(350 + (200 - difficulty_w) / 2, 190 + (100 - difficulty_h) / 2, difficulty);
setfillcolor(RGB(255, 28, 5));//地狱难度按钮颜色
fillroundrect(600, 190, 800, 290, 50, 50);
char hell[] = "地狱(30*16)";
settextcolor(BLACK);
settextstyle(30, 15, "");
int hell_w = textwidth(hell);
int hell_h = textheight(hell);
outtextxy(600 + (200 - hell_w) / 2, 190 + (100 - hell_h) / 2, hell);
}
void SimpleDiscolour()
{
setfillcolor(RGB(6, 179, 9));//简单按钮变化后的颜色
fillroundrect(100, 190, 300, 290, 50, 50);
char simple[] = "简单(9*9)";
settextcolor(BLACK);
settextstyle(30, 15, "");
int simple_w = textwidth(simple);
int simple_h = textheight(simple);
outtextxy(100 + (200 - simple_w) / 2, 190 + (100 - simple_h) / 2, simple);
}
void difficultyDiscolour()
{
setfillcolor(RGB(194, 137, 47));//困难按钮变化后的颜色
fillroundrect(350, 190, 550, 290, 50, 50);
char difficulty[] = "困难(16*16)";
settextcolor(BLACK);
settextstyle(30, 15, "");
int difficulty_w = textwidth(difficulty);
int difficulty_h = textheight(difficulty);
outtextxy(350 + (200 - difficulty_w) / 2, 190 + (100 - difficulty_h) / 2, difficulty);
}
void HellDiscolour()
{
setfillcolor(RGB(168, 48, 11));//地狱按钮变化后的颜色
fillroundrect(600, 190, 800, 290, 50, 50);
char hell[] = "地狱(30*16)";
settextcolor(BLACK);
settextstyle(30, 15, "");
int hell_w = textwidth(hell);
int hell_h = textheight(hell);
outtextxy(600 + (200 - hell_w) / 2, 190 + (100 - hell_h) / 2, hell);
}
void GoBack()
{
char back[] = "若要返回上一级请按:Esc(选择难度后未开始游戏也可返回上一级)";
settextcolor(BLACK);
settextstyle(30, 15, "");
int back_w = textwidth(back);
int back_h = textheight(back);
outtextxy((900 - back_w) / 2, 350, back);
}
这里三个难度的的实现除了参数不同,基本相近,如果想优化的同学可以自己进行优化。
这里只解释一下简单模式的游戏内容:
if (_kbhit())
{
char esc = _getch();
if (esc == 27)
{
goto opt;
}
}
char** simpleboard = (char**)malloc(sizeof(char*) * 9);//设置简单模式的二维数组
if (simpleboard == NULL)
{
perror("simpleboard malloc fail");
return 0;
}
for (int i = 0; i < 9; i++)
{
simpleboard[i] = (char*)malloc(sizeof(char) * 9);
if (simpleboard[i] == NULL)
{
perror("simpleboard_ malloc fail");
return 0;
}
memset(simpleboard[i], '0', 9);
}
SetMineSimple(simpleboard);//设置地雷//地雷的数量由一个全局变量来存储方便后续检查
InitSimpleBoard();//打印方块
while (1)
{
GetCursorPos(&point); // 获取鼠标指针位置(屏幕坐标)
ScreenToClient(hwnd, &point); // 将鼠标指针位置转换为窗口坐标
if (_kbhit())
{
char esc = _getch();
if (esc == 27)
{
goto opt;
}
}
int x = ((point.x - 225) / 50) * 50 + 225;
int y = ((point.y) / 50) * 50;
if ((x >= 225 && x <= 625) && (y >= 0 && y <= 400))
{
if (getpixel(x + 5, y + 5) == RGB(93, 78, 255))
{
SimpleBlockDiscolour(x, y);//方块变色
}
if (peekmessage(&msg, EX_MOUSE))
{
if (msg.lbutton)//简单模式点击
{
if (getpixel(x + 5, y + 5) == RGB(69, 58, 191))
{
if (simpleboard[y / 50][(x - 225) / 50] == '*')
{
GameFail();//扫到雷游戏失败
Sleep(1000);
for (int i = 0; i < 9; i++)
{
free(simpleboard[i]);
}
free(simpleboard);
return 0;
}
else
{
ScanSimple(simpleboard, (x - 225) / 50, y / 50);//扫雷逻辑的实现
}
}
}
}
}
else
{
InitSimpleBoard_();
}
}
void SetMineSimple(char** simpleboard)
{
int mine = 10;
while (mine)
{
int x = rand() % 9;
int y = rand() % 9;
if (simpleboard[y][x] == '0')
{
simpleboard[y][x] = '*';
mine--;
}
}
}
void InitSimpleBoard()
{
int i = 0;
//画方块
setfillcolor(RGB(93, 78, 255));//方块颜色
for (i = 0; i < 450; i += 50)//列
{
for (int j = 225; j < 675; j += 50)//行
{
solidroundrect(j + 1, i + 1, j + 49, i + 49, 5, 5);
}
Sleep(100);
}
}
void InitSimpleBoard_()
{
int i = 0;
//画方块
for (i = 0; i < 450; i += 50)//列
{
for (int j = 225; j < 675; j += 50)//行
{
if (getpixel(j + 5, i + 5) == RGB(69, 58, 191))
{
solidroundrect(j + 1, i + 1, j + 49, i + 49, 5, 5);
}
}
}
}
void SimpleBlockDiscolour(int x, int y)
{
setfillcolor(RGB(69, 58, 191));//方块变化后的颜色
solidroundrect(x + 1, y + 1, x + 49, y + 49, 5, 5);
int i = 0;
for (i = 0; i < 450; i += 50)//列
{
for (int j = 225; j < 675; j += 50)//行
{
if ((j != x || i != y) && getpixel(j + 5, i + 5) == RGB(69, 58, 191))
{
setfillcolor(RGB(93, 78, 255));//方块颜色
solidroundrect(j + 1, i + 1, j + 49, i + 49, 5, 5);
}
}
}
}
这里同样用到了深度优先搜索
int minesimple = 71;
char simpleboard_[9][9] = { 0 };
void ScanSimple(char** simpleboard, int x, int y)
{
minesimple--;
if (minesimple == 0)
{
GameWin();
Sleep(1000);
for (int i = 0; i < 16; i++)
{
free(simpleboard[i]);
}
free(simpleboard);
exit(0);
}
int i = 0;
int count = 0;
int mx = 0;
int my = 0;
for (i = 0; i < 8; i++)//循环判断输入坐标的旁边八个位置有无雷
{
my = y + dy[i], mx = x + dx[i];
if ((mx >= 0 && mx < 9) && (my >= 0 && my < 9) && simpleboard[my][mx] == '*')
{
count++;
}
}
if (count == 0)
{
setfillcolor(WHITE);
setbkcolor(WHITE);
clearroundrect(x * 50 + 225 + 1, y * 50 + 1, x * 50 + 225 + 49, y * 50 + 49, 5, 5);
solidroundrect(x * 50 + 225 + 1, y * 50 + 1, x * 50 + 225 + 49, y * 50 + 49, 5, 5);
Sleep(50);
for (i = 0; i < 8; i++)
{
my = y + dy[i];
mx = x + dx[i];
if ((mx >= 0 && mx < 9) && (my >= 0 && my < 9) && simpleboard_[my][mx] != '#')//标记起作用
{
simpleboard_[y][x] = '#';//同样是做标记的作用,
ScanSimple(simpleboard, mx, my);//进入递归对当前坐标旁边八个位置进行扫描
}
}
}
else//有雷的处理,改成#是为了在后续递归中当扫描这个点时不需要再次扫描,防止死递归
{
simpleboard_[y][x] = '#';
simpleboard[y][x] = count + 48;
setfillcolor(WHITE);
setbkcolor(WHITE);
clearroundrect(x * 50 + 225 + 1, y * 50 + 1, x * 50 + 225 + 49, y * 50 + 49, 5, 5);
solidroundrect(x * 50 + 225 + 1, y * 50 + 1, x * 50 + 225 + 49, y * 50 + 49, 5, 5);
char number = simpleboard[y][x];
settextcolor(BLACK);
settextstyle(20, 10, "");
int number_w = textwidth(number);
int number_h = textheight(number);
outtextxy(x * 50 + 225 + (50 - number_w) / 2, y * 50 + (50 - number_h) / 2, number);
Sleep(50);
}
}
#include
#include
#include
#include
#include
//打印开始界面
void InitStartInterface();
//开始游戏按钮变色
void StartDiscolour();
//退出游戏按钮变色
void EndDiscolour();
//游戏难度选择界面
void InitDifficultyOptFace();
//简单模式变色
void SimpleDiscolour();
//困难模式变色
void difficultyDiscolour();
//地狱难度变色
void HellDiscolour();
//返回上一级
void GoBack();
//设置地雷-简单模式
void SetMineSimple(char** simpleboard);
//简单模式界面
void InitSimpleBoard();
void InitSimpleBoard_();
//简单模式方块变色
void SimpleBlockDiscolour(int x, int y);
//游戏失败
void GameFail();
//游戏成功
void GameWin();
//简单模式扫雷
void ScanSimple(char** simpleboard, int x, int y);
//设置地雷-困难模式
void SetMineDifficulty(char** difficultyboard);
//困难模式界面
void InitDifficultyBoard();
//困难模式方块变色
void DifficultyBlockDiscolour(int x, int y);
void InitDifficultyBoard_();
//困难模式扫雷
void ScanDifficulty(char** difficultyboard, int x, int y);
//设置地雷-地狱模式
void SetMineHell(char** hellboard);
//地狱模式界面
void InitHellBoard();
//地狱模式方块变色
void HellBlockDiscolour(int x, int y);
void InitHellBoard_();
//地狱模式扫雷
void ScanHell(char** hellboard, int x, int y);
#define _CRT_SECURE_NO_WARNINGS 1
#include "mine.h"
void InitStartInterface()
{
setfillcolor(RGB(247, 255, 10));//按钮颜色
setlinecolor(BLACK);
setlinestyle(PS_SOLID, 10);
fillroundrect(250, 20, 650, 220, 50, 50);
fillroundrect(250, 260, 650, 460, 50, 50);
char start[] = "开始游戏";
char end[] = "退出游戏";
settextcolor(BLACK);//文字颜色
settextstyle(60, 30, "");
int start_w = textwidth(start);
int start_h = textheight(start);
int end_w = textwidth(end);
int end_h = textheight(end);
outtextxy(250 + (400 - start_w) / 2, 20 + (200 - start_h) / 2, start);
outtextxy(250 + (400 - end_w) / 2, 260 + (200 - end_h) / 2, end);
}
void StartDiscolour()
{
setfillcolor(RGB(215, 222, 10));//按钮变化后的颜色
fillroundrect(250, 20, 650, 220, 50, 50);
char start[] = "开始游戏";
settextcolor(BLACK);
settextstyle(60, 30, "");
int start_w = textwidth(start);
int start_h = textheight(start);
outtextxy(250 + (400 - start_w) / 2, 20 + (200 - start_h) / 2, start);
}
void EndDiscolour()
{
setfillcolor(RGB(215, 222, 10));//按钮变化后的颜色
fillroundrect(250, 260, 650, 460, 50, 50);
char end[] = "退出游戏";
settextcolor(BLACK);
settextstyle(60, 30, "");
int end_w = textwidth(end);
int end_h = textheight(end);
outtextxy(250 + (400 - end_w) / 2, 260 + (200 - end_h) / 2, end);
}
void InitDifficultyOptFace()
{
setlinecolor(BLACK);
setlinestyle(PS_SOLID, 10);
setfillcolor(RGB(32, 255, 46));//简单难度按钮颜色
fillroundrect(100, 190, 300, 290, 50, 50);
char simple[] = "简单(9*9)";
settextcolor(BLACK);
settextstyle(30, 15, "");
int simple_w = textwidth(simple);
int simple_h = textheight(simple);
outtextxy(100 + (200 - simple_w) / 2, 190 + (100 - simple_h) / 2, simple);
setfillcolor(RGB(255, 180, 62));//困难难度按钮颜色
fillroundrect(350, 190, 550, 290, 50, 50);
char difficulty[] = "困难(16*16)";
settextcolor(BLACK);
settextstyle(30, 15, "");
int difficulty_w = textwidth(difficulty);
int difficulty_h = textheight(difficulty);
outtextxy(350 + (200 - difficulty_w) / 2, 190 + (100 - difficulty_h) / 2, difficulty);
setfillcolor(RGB(255, 28, 5));//地狱难度按钮颜色
fillroundrect(600, 190, 800, 290, 50, 50);
char hell[] = "地狱(30*16)";
settextcolor(BLACK);
settextstyle(30, 15, "");
int hell_w = textwidth(hell);
int hell_h = textheight(hell);
outtextxy(600 + (200 - hell_w) / 2, 190 + (100 - hell_h) / 2, hell);
}
void SimpleDiscolour()
{
setfillcolor(RGB(6, 179, 9));//简单按钮变化后的颜色
fillroundrect(100, 190, 300, 290, 50, 50);
char simple[] = "简单(9*9)";
settextcolor(BLACK);
settextstyle(30, 15, "");
int simple_w = textwidth(simple);
int simple_h = textheight(simple);
outtextxy(100 + (200 - simple_w) / 2, 190 + (100 - simple_h) / 2, simple);
}
void difficultyDiscolour()
{
setfillcolor(RGB(194, 137, 47));//困难按钮变化后的颜色
fillroundrect(350, 190, 550, 290, 50, 50);
char difficulty[] = "困难(16*16)";
settextcolor(BLACK);
settextstyle(30, 15, "");
int difficulty_w = textwidth(difficulty);
int difficulty_h = textheight(difficulty);
outtextxy(350 + (200 - difficulty_w) / 2, 190 + (100 - difficulty_h) / 2, difficulty);
}
void HellDiscolour()
{
setfillcolor(RGB(168, 48, 11));//地狱按钮变化后的颜色
fillroundrect(600, 190, 800, 290, 50, 50);
char hell[] = "地狱(30*16)";
settextcolor(BLACK);
settextstyle(30, 15, "");
int hell_w = textwidth(hell);
int hell_h = textheight(hell);
outtextxy(600 + (200 - hell_w) / 2, 190 + (100 - hell_h) / 2, hell);
}
void GoBack()
{
char back[] = "若要返回上一级请按:Esc(选择难度后未开始游戏也可返回上一级)";
settextcolor(BLACK);
settextstyle(30, 15, "");
int back_w = textwidth(back);
int back_h = textheight(back);
outtextxy((900 - back_w) / 2, 350, back);
}
void SetMineSimple(char** simpleboard)
{
int mine = 10;
while (mine)
{
int x = rand() % 9;
int y = rand() % 9;
if (simpleboard[y][x] == '0')
{
simpleboard[y][x] = '*';
mine--;
}
}
}
void InitSimpleBoard()
{
//划线
//setlinecolor(BLACK);
//setlinestyle(PS_SOLID, 1);
int i = 0;
//for (i = 275; i < 675; i+=50)
//{
// line(i, 0, i, 450);
//}
//for (i = 50; i < 450; i+=50)
//{
// line(225, i, 675, i);
//}
//画方块
setfillcolor(RGB(93, 78, 255));//方块颜色
for (i = 0; i < 450; i += 50)//列
{
for (int j = 225; j < 675; j += 50)//行
{
solidroundrect(j + 1, i + 1, j + 49, i + 49, 5, 5);
}
Sleep(100);
}
}
void InitSimpleBoard_()
{
//划线
//setlinecolor(BLACK);
//setlinestyle(PS_SOLID, 1);
int i = 0;
//for (i = 275; i < 675; i+=50)
//{
// line(i, 0, i, 450);
//}
//for (i = 50; i < 450; i+=50)
//{
// line(225, i, 675, i);
//}
//画方块
for (i = 0; i < 450; i += 50)//列
{
for (int j = 225; j < 675; j += 50)//行
{
if (getpixel(j + 5, i + 5) == RGB(69, 58, 191))
{
solidroundrect(j + 1, i + 1, j + 49, i + 49, 5, 5);
}
}
}
}
void SimpleBlockDiscolour(int x, int y)
{
setfillcolor(RGB(69, 58, 191));//方块变化后的颜色
solidroundrect(x + 1, y + 1, x + 49, y + 49, 5, 5);
int i = 0;
for (i = 0; i < 450; i += 50)//列
{
for (int j = 225; j < 675; j += 50)//行
{
if ((j != x || i != y) && getpixel(j + 5, i + 5) == RGB(69, 58, 191))
{
setfillcolor(RGB(93, 78, 255));//方块颜色
solidroundrect(j + 1, i + 1, j + 49, i + 49, 5, 5);
}
}
}
}
void GameFail()
{
setbkcolor(WHITE);
cleardevice();//清屏
char fail[] = "游戏失败!!!";
settextcolor(BLACK);
settextstyle(50, 25, "");
int fail_w = textwidth(fail);
int fail_h = textheight(fail);
outtextxy((900 - fail_w) / 2, (480 - fail_h) / 2, fail);
}
void GameWin()
{
setbkcolor(WHITE);
cleardevice();//清屏
char fail[] = "游戏胜利!!!";
settextcolor(BLACK);
settextstyle(50, 25, "");
int fail_w = textwidth(fail);
int fail_h = textheight(fail);
outtextxy((900 - fail_w) / 2, (480 - fail_h) / 2, fail);
}
const int dx[] = { -1,-1,-1,0,0,1,1,1 };
const int dy[] = { -1,0,1,-1,1,-1,0,1 };
int minesimple = 71;
char simpleboard_[9][9] = { 0 };
void ScanSimple(char** simpleboard, int x, int y)
{
minesimple--;
if (minesimple == 0)
{
GameWin();
Sleep(1000);
for (int i = 0; i < 16; i++)
{
free(simpleboard[i]);
}
free(simpleboard);
exit(0);
}
int i = 0;
int count = 0;
int mx = 0;
int my = 0;
for (i = 0; i < 8; i++)//循环判断输入坐标的旁边八个位置有无雷
{
my = y + dy[i], mx = x + dx[i];
if ((mx >= 0 && mx < 9) && (my >= 0 && my < 9) && simpleboard[my][mx] == '*')
{
count++;
}
}
if (count == 0)
{
setfillcolor(WHITE);
setbkcolor(WHITE);
clearroundrect(x * 50 + 225 + 1, y * 50 + 1, x * 50 + 225 + 49, y * 50 + 49, 5, 5);
solidroundrect(x * 50 + 225 + 1, y * 50 + 1, x * 50 + 225 + 49, y * 50 + 49, 5, 5);
Sleep(50);
for (i = 0; i < 8; i++)
{
my = y + dy[i];
mx = x + dx[i];
if ((mx >= 0 && mx < 9) && (my >= 0 && my < 9) && simpleboard_[my][mx] != '#')//标记起作用
{
simpleboard_[y][x] = '#';//同样是做标记的作用,
ScanSimple(simpleboard, mx, my);//进入递归对当前坐标旁边八个位置进行扫描
}
}
}
else//有雷的处理,改成#是为了在后续递归中当扫描这个点时不需要再次扫描,防止死递归
{
simpleboard_[y][x] = '#';
simpleboard[y][x] = count + 48;
setfillcolor(WHITE);
setbkcolor(WHITE);
clearroundrect(x * 50 + 225 + 1, y * 50 + 1, x * 50 + 225 + 49, y * 50 + 49, 5, 5);
solidroundrect(x * 50 + 225 + 1, y * 50 + 1, x * 50 + 225 + 49, y * 50 + 49, 5, 5);
char number = simpleboard[y][x];
settextcolor(BLACK);
settextstyle(20, 10, "");
int number_w = textwidth(number);
int number_h = textheight(number);
outtextxy(x * 50 + 225 + (50 - number_w) / 2, y * 50 + (50 - number_h) / 2, number);
Sleep(50);
}
}
void SetMineDifficulty(char** difficultyboard)
{
int mine = 40;
while (mine)
{
int x = rand() % 16;
int y = rand() % 16;
if (difficultyboard[y][x] == '0')
{
difficultyboard[y][x] = '*';
mine--;
}
}
}
void InitDifficultyBoard()
{
//划线
//setlinecolor(BLACK);
//setlinestyle(PS_SOLID, 1);
int i = 0;
//for (i = 275; i < 675; i+=50)
//{
// line(i, 0, i, 450);
//}
//for (i = 50; i < 450; i+=50)
//{
// line(225, i, 675, i);
//}
//画方块
setfillcolor(RGB(93, 78, 255));//方块颜色
for (i = 0; i < 480; i += 40)//列
{
for (int j = 210; j < 690; j += 40)//行
{
solidroundrect(j + 1, i + 1, j + 39, i + 39, 5, 5);
}
Sleep(100);
}
}
void DifficultyBlockDiscolour(int x, int y)
{
setfillcolor(RGB(69, 58, 191));//方块变化后的颜色
solidroundrect(x + 1, y + 1, x + 39, y + 39, 5, 5);
int i = 0;
for (i = 0; i < 480; i += 40)//列
{
for (int j = 210; j < 690; j += 40)//行
{
if ((j != x || i != y) && getpixel(j + 5, i + 5) == RGB(69, 58, 191))
{
setfillcolor(RGB(93, 78, 255));//方块颜色
solidroundrect(j + 1, i + 1, j + 39, i + 39, 5, 5);
}
}
}
}
void InitDifficultyBoard_()
{
//划线
//setlinecolor(BLACK);
//setlinestyle(PS_SOLID, 1);
int i = 0;
//for (i = 275; i < 675; i+=50)
//{
// line(i, 0, i, 450);
//}
//for (i = 50; i < 450; i+=50)
//{
// line(225, i, 675, i);
//}
//画方块
setfillcolor(RGB(93, 78, 255));//方块颜色
for (i = 0; i < 480; i += 40)//列
{
for (int j = 210; j < 690; j += 40)//行
{
if (getpixel(j + 5, i + 5) == RGB(69, 58, 191))
{
solidroundrect(j + 1, i + 1, j + 39, i + 39, 5, 5);
}
}
}
}
int minedifficulty = 256 - 40;
char difficultyboard_[16][16] = { 0 };
void ScanDifficulty(char** difficultyboard, int x, int y)
{
minedifficulty--;
if (minedifficulty == 0)
{
GameWin();
Sleep(1000);
for (int i = 0; i < 16; i++)
{
free(difficultyboard[i]);
}
free(difficultyboard);
exit(0);
}
int i = 0;
int count = 0;
int mx = 0;
int my = 0;
for (i = 0; i < 8; i++)//循环判断输入坐标的旁边八个位置有无雷
{
my = y + dy[i], mx = x + dx[i];
if ((mx >= 0 && mx < 16) && (my >= 0 && my < 16) && difficultyboard[my][mx] == '*')
{
count++;
}
}
if (count == 0)
{
setfillcolor(WHITE);
setbkcolor(WHITE);
clearroundrect(x * 40 + 210 + 1, y * 40 + 1, x * 40 + 210 + 39, y * 40 + 39, 5, 5);
solidroundrect(x * 40 + 210 + 1, y * 40 + 1, x * 40 + 210 + 39, y * 40 + 39, 5, 5);
Sleep(50);
for (i = 0; i < 8; i++)
{
my = y + dy[i];
mx = x + dx[i];
if ((mx >= 0 && mx < 16) && (my >= 0 && my < 16) && difficultyboard_[my][mx] != '#')//标记起作用
{
difficultyboard_[y][x] = '#';//同样是做标记的作用,
ScanDifficulty(difficultyboard, mx, my);//进入递归对当前坐标旁边八个位置进行扫描
}
}
}
else//有雷的处理,改成#是为了在后续递归中当扫描这个点时不需要再次扫描,防止死递归
{
difficultyboard_[y][x] = '#';
difficultyboard[y][x] = count + 48;
setfillcolor(WHITE);
setbkcolor(WHITE);
clearroundrect(x * 40 + 210 + 1, y * 40 + 1, x * 40 + 210 + 39, y * 40 + 39, 5, 5);
solidroundrect(x * 40 + 210 + 1, y * 40 + 1, x * 40 + 210 + 39, y * 40 + 39, 5, 5);
char number = difficultyboard[y][x];
settextcolor(BLACK);
settextstyle(20, 10, "");
int number_w = textwidth(number);
int number_h = textheight(number);
outtextxy(x * 40 + 210 + (40 - number_w) / 2, y * 40 + (40 - number_h) / 2, number);
Sleep(50);
}
}
void SetMineHell(char** hellboard)
{
int mine = 99;
while (mine)
{
int x = rand() % 30;
int y = rand() % 16;
if (hellboard[y][x] == '0')
{
hellboard[y][x] = '*';
mine--;
}
}
}
void InitHellBoard()
{
//划线
//setlinecolor(BLACK);
//setlinestyle(PS_SOLID, 1);
int i = 0;
//for (i = 275; i < 675; i+=50)
//{
// line(i, 0, i, 450);
//}
//for (i = 50; i < 450; i+=50)
//{
// line(225, i, 675, i);
//}
//画方块
setfillcolor(RGB(93, 78, 255));//方块颜色
for (i = 0; i < 480; i += 30)//列
{
for (int j = 0; j < 900; j += 30)//行
{
solidroundrect(j + 1, i + 1, j + 29, i + 29, 5, 5);
}
Sleep(100);
}
}
void HellBlockDiscolour(int x, int y)
{
setfillcolor(RGB(69, 58, 191));//方块变化后的颜色
solidroundrect(x + 1, y + 1, x + 29, y + 29, 5, 5);
int i = 0;
for (i = 0; i < 480; i += 30)//列
{
for (int j = 0; j < 900; j += 30)//行
{
if ((j != x || i != y) && getpixel(j + 5, i + 5) == RGB(69, 58, 191))
{
setfillcolor(RGB(93, 78, 255));//方块颜色
solidroundrect(j + 1, i + 1, j + 29, i + 29, 5, 5);
}
}
}
}
void InitHellBoard_()
{
//划线
//setlinecolor(BLACK);
//setlinestyle(PS_SOLID, 1);
int i = 0;
//for (i = 275; i < 675; i+=50)
//{
// line(i, 0, i, 450);
//}
//for (i = 50; i < 450; i+=50)
//{
// line(225, i, 675, i);
//}
//画方块
setfillcolor(RGB(93, 78, 255));//方块颜色
for (i = 0; i < 480; i += 30)//列
{
for (int j = 0; j < 900; j += 30)//行
{
if (getpixel(j + 5, i + 5) == RGB(69, 58, 191))
{
solidroundrect(j + 1, i + 1, j + 29, i + 29, 5, 5);
}
}
}
}
int minehell = 16 * 30 - 99;
char hellboard_[16][30] = { 0 };
void ScanHell(char** hellboard, int x, int y)
{
minehell--;
if (minehell == 0)
{
GameWin();
Sleep(1000);
for (int i = 0; i < 16; i++)
{
free(hellboard[i]);
}
free(hellboard);
exit(0);
}
int i = 0;
int count = 0;
int mx = 0;
int my = 0;
for (i = 0; i < 8; i++)//循环判断输入坐标的旁边八个位置有无雷
{
my = y + dy[i], mx = x + dx[i];
if ((mx >= 0 && mx < 30) && (my >= 0 && my < 16) && hellboard[my][mx] == '*')
{
count++;
}
}
if (count == 0)
{
setfillcolor(WHITE);
setbkcolor(WHITE);
clearroundrect(x * 30 + 1, y * 30 + 1, x * 30 + 29, y * 30 + 29, 5, 5);
solidroundrect(x * 30 + 1, y * 30 + 1, x * 30 + 29, y * 30 + 29, 5, 5);
Sleep(50);
for (i = 0; i < 8; i++)
{
my = y + dy[i];
mx = x + dx[i];
if ((mx >= 0 && mx < 32) && (my >= 0 && my < 16) && hellboard_[my][mx] != '#')//标记起作用
{
hellboard_[y][x] = '#';//同样是做标记的作用,
ScanHell(hellboard, mx, my);//进入递归对当前坐标旁边八个位置进行扫描
}
}
}
else//有雷的处理,改成#是为了在后续递归中当扫描这个点时不需要再次扫描,防止死递归
{
hellboard_[y][x] = '#';
hellboard[y][x] = count + 48;
setfillcolor(WHITE);
setbkcolor(WHITE);
clearroundrect(x * 30 + 1, y * 30 + 1, x * 30 + 29, y * 30 + 29, 5, 5);
solidroundrect(x * 30 + 1, y * 30 + 1, x * 30 + 29, y * 30 + 29, 5, 5);
char number = hellboard[y][x];
settextcolor(BLACK);
settextstyle(20, 10, "");
int number_w = textwidth(number);
int number_h = textheight(number);
outtextxy(x * 30 + (30 - number_w) / 2, y * 30 + (30 - number_h) / 2, number);
Sleep(50);
}
}
#define _CRT_SECURE_NO_WARNINGS 1
#include "mine.h"
int main()
{
initgraph(900, 480);
srand((unsigned)time(NULL));
HWND hwnd = GetHWnd(); // 获取绘图窗口句柄
POINT point;
TCHAR s[10];
start:
setbkcolor(WHITE);
cleardevice();
ExMessage msg;
InitStartInterface();
while (1)//游戏开始逻辑
{
GetCursorPos(&point); // 获取鼠标指针位置(屏幕坐标)
ScreenToClient(hwnd, &point); // 将鼠标指针位置转换为窗口坐标
if ((point.x >= 250 && point.x <= 650) && (point.y >= 20 && point.y <= 220))//开始游戏按钮
{
if (getpixel(270, 40) != RGB(215, 222, 10))
{
StartDiscolour();
}
if (peekmessage(&msg, EX_MOUSE))
{
if (msg.lbutton)
{
opt:
//开始游戏
setbkcolor(WHITE);
cleardevice();//清屏
//选择游戏难度
InitDifficultyOptFace();
GoBack();
while (1)
{
GetCursorPos(&point); // 获取鼠标指针位置(屏幕坐标)
ScreenToClient(hwnd, &point); // 将鼠标指针位置转换为窗口坐标
if (_kbhit())
{
char esc = _getch();
if (esc == 27)
{
goto start;
}
}
if ((point.x >= 100 && point.x <= 300) && (point.y >= 190 && point.y <= 290))
{
if (getpixel(120, 210) != RGB(6, 179, 9))
{
SimpleDiscolour();
GoBack();
}
if (peekmessage(&msg, EX_MOUSE))
{
if (msg.lbutton)
{
setbkcolor(WHITE);
cleardevice();//清屏
//简单模式游戏开始
if (_kbhit())
{
char esc = _getch();
if (esc == 27)
{
goto opt;
}
}
char** simpleboard = (char**)malloc(sizeof(char*) * 9);
if (simpleboard == NULL)
{
perror("simpleboard malloc fail");
return 0;
}
for (int i = 0; i < 9; i++)
{
simpleboard[i] = (char*)malloc(sizeof(char) * 9);
if (simpleboard[i] == NULL)
{
perror("simpleboard_ malloc fail");
return 0;
}
memset(simpleboard[i], '0', 9);
}
SetMineSimple(simpleboard);
InitSimpleBoard();
while (1)
{
GetCursorPos(&point); // 获取鼠标指针位置(屏幕坐标)
ScreenToClient(hwnd, &point); // 将鼠标指针位置转换为窗口坐标
if (_kbhit())
{
char esc = _getch();
if (esc == 27)
{
goto opt;
}
}
int x = ((point.x - 225) / 50) * 50 + 225;
int y = ((point.y) / 50) * 50;
if ((x >= 225 && x <= 625) && (y >= 0 && y <= 400))
{
if (getpixel(x + 5, y + 5) == RGB(93, 78, 255))
{
SimpleBlockDiscolour(x, y);
}
if (peekmessage(&msg, EX_MOUSE))
{
if (msg.lbutton)//简单模式点击
{
if (getpixel(x + 5, y + 5) == RGB(69, 58, 191))
{
if (simpleboard[y / 50][(x - 225) / 50] == '*')
{
GameFail();
Sleep(1000);
for (int i = 0; i < 9; i++)
{
free(simpleboard[i]);
}
free(simpleboard);
return 0;
}
else
{
ScanSimple(simpleboard, (x - 225) / 50, y / 50);
}
}
}
}
}
else
{
InitSimpleBoard_();
}
}
}
}
}
else if ((point.x >= 350 && point.x <= 550) && (point.y >= 190 && point.y <= 290))
{
if (getpixel(370, 210) != RGB(194, 137, 47))
{
difficultyDiscolour();
GoBack();
}
if (peekmessage(&msg, EX_MOUSE))
{
if (msg.lbutton)
{
setbkcolor(WHITE);
cleardevice();//清屏
//困难模式游戏开始
if (_kbhit())
{
char esc = _getch();
if (esc == 27)
{
goto opt;
}
}
char** difficultyboard = (char**)malloc(sizeof(char*) * 16);
if (difficultyboard == NULL)
{
perror("difficultyboard malloc fail");
return 0;
}
for (int i = 0; i < 16; i++)
{
difficultyboard[i] = (char*)malloc(sizeof(char) * 16);
if (difficultyboard[i] == NULL)
{
perror("difficultyboard_ malloc fail");
return 0;
}
memset(difficultyboard[i], '0', 16);
}
SetMineDifficulty(difficultyboard);
InitDifficultyBoard();
while (1)
{
GetCursorPos(&point); // 获取鼠标指针位置(屏幕坐标)
ScreenToClient(hwnd, &point); // 将鼠标指针位置转换为窗口坐标
if (_kbhit())
{
char esc = _getch();
if (esc == 27)
{
goto opt;
}
}
int x = ((point.x - 210) / 40) * 40 + 210;
int y = ((point.y) / 40) * 40;
if ((x >= 210 && x <= 650) && (y >= 0 && y <= 440))
{
if (getpixel(x + 5, y + 5) == RGB(93, 78, 255))
{
DifficultyBlockDiscolour(x, y);
}
if (peekmessage(&msg, EX_MOUSE))
{
if (msg.lbutton)//简单模式点击
{
if (getpixel(x + 5, y + 5) == RGB(69, 58, 191))
{
if (difficultyboard[y / 40][(x - 210) / 40] == '*')
{
GameFail();
Sleep(1000);
for (int i = 0; i < 16; i++)
{
free(difficultyboard[i]);
}
free(difficultyboard);
return 0;
}
else
{
ScanDifficulty(difficultyboard, (x - 210) / 40, y / 40);
}
}
}
}
}
else
{
InitDifficultyBoard_();
}
}
}
}
}
else if ((point.x >= 600 && point.x <= 800) && (point.y >= 190 && point.y <= 290))
{
if (getpixel(620, 210) != RGB(168, 48, 11))
{
HellDiscolour();
GoBack();
}
if (peekmessage(&msg, EX_MOUSE))
{
if (msg.lbutton)
{
setbkcolor(WHITE);
cleardevice();//清屏
//地狱模式游戏开始
if (_kbhit())
{
char esc = _getch();
if (esc == 27)
{
goto opt;
}
}
char** hellboard = (char**)malloc(sizeof(char*) * 16);
if (hellboard == NULL)
{
perror("hellboard malloc fail");
return 0;
}
for (int i = 0; i < 16; i++)
{
hellboard[i] = (char*)malloc(sizeof(char) * 30);
if (hellboard[i] == NULL)
{
perror("hellboard_ malloc fail");
return 0;
}
memset(hellboard[i], '0', 30);
}
SetMineHell(hellboard);
InitHellBoard();
while (1)
{
GetCursorPos(&point); // 获取鼠标指针位置(屏幕坐标)
ScreenToClient(hwnd, &point); // 将鼠标指针位置转换为窗口坐标
if (_kbhit())
{
char esc = _getch();
if (esc == 27)
{
goto opt;
}
}
int x = ((point.x) / 30) * 30;
int y = ((point.y) / 30) * 30;
if ((x >= 0 && x <= 870) && (y >= 0 && y <= 450))
{
if (getpixel(x + 5, y + 5) == RGB(93, 78, 255))
{
HellBlockDiscolour(x, y);
}
if (peekmessage(&msg, EX_MOUSE))
{
if (msg.lbutton)//简单模式点击
{
if (getpixel(x + 5, y + 5) == RGB(69, 58, 191))
{
if (hellboard[y / 30][x / 30] == '*')
{
GameFail();
Sleep(1000);
for (int i = 0; i < 16; i++)
{
free(hellboard[i]);
}
free(hellboard);
return 0;
}
else
{
ScanHell(hellboard, x / 30, y / 30);
}
}
}
}
}
else
{
InitHellBoard_();
}
}
}
}
}
else
{
if (getpixel(120, 210) == RGB(6, 179, 9)
|| getpixel(620, 210) == RGB(168, 48, 11)
|| getpixel(370, 210) == RGB(194, 137, 47))
{
InitDifficultyOptFace();
GoBack();
}
}
}
}
}
}
else if ((point.x >= 250 && point.x <= 650) && (point.y >= 260 && point.y <= 460))
{
if (getpixel(270, 280) != RGB(215, 222, 10))
{
EndDiscolour();
}
if (peekmessage(&msg, EX_MOUSE))
{
if (msg.lbutton)
{
//退出游戏
return 0;
}
}
}
else/* if((point.x >= 250 && point.x <= 650) && (point.y >= 20 && point.y <= 220) == 0
&& (point.x >= 250 && point.x <= 650) && (point.y >= 260 && point.y <= 460) == 0)*/
{
if (getpixel(270, 40) != RGB(247, 255, 10) || getpixel(270, 280) != RGB(247, 255, 10))
{
InitStartInterface();
}
}
}
closegraph();
return 0;
}