番外——扫雷

//以下是我的代码
#include<graphics.h>//需要easyx
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
//typedef struct zhadan//我用链表来记录雷的坐标其实并不需要记录雷的坐标我只是想码个链表 括弧笑
//{
// int x, y;
// struct zhadan * p;
//}bo;
//bo h;
IMAGE img[15];
HWND hwnd;
int x2,y2,map[110][110], dx[10] = {1,0,-1,0,1,-1,1,-1}, dy[10] = {0,1,0,-1,-1,-1,1,1 };//整个扫雷图
int b,f[110][110],win;//用来标记显示什么图片0空白 1插旗 2底下数值
void setting()
{
printf_s(“请输入雷的个数:”);
scanf_s("%d", &b);
printf_s(“请输入图的大小(最好按10:7的比例输):\n长:”);
scanf_s("%d", &x2);
printf_s(“宽:”);
scanf_s("%d", &y2);
}
void initial()
{
int i,c,r;
//bo s;
void sum(int xx,int yy);
//h=(bo
)malloc(sizeof(bo));//初始化链表s
//h->p= NULL;
//s = h;
srand((unsigned int)time(NULL));
for (i = 0; i < b; i++)//产生雷
{
//s->p= (bo
)malloc(sizeof(bo));
//s = s->p;
do
{
r = rand() % x2;
c = rand() % y2;
} while (map[r][c]==9);
//s->x = r;s->y = c;
//s->p = NULL;
map[r][c] = 9;
sum(r,c);
}
}
void sum(int xx,int yy)//计算周围雷的个数 也可以没点击一次判断一下是不是雷遍历一下周围有多少雷进行一次累加 相当于这个是预处理
{
int i = 0;
for(;i<8;i++) //也可以i-1到i+1 j-1到j+1遍历这个九宫格
if (xx+dx[i]>=0&& yy + dy[i]>=0&& yy + dy[i] <y2&& xx + dx[i] <x2)//思路很多可以做个辅助框全是0画的时候不画进去 看你怎么写了
if (map[xx + dx[i]][yy + dy[i]] != 9)
map[xx + dx[i]][yy + dy[i]]++;
}
void loadimg()
{
loadimage(&img[10], L"./img/block.png", 1000 / x2, 700 / y2);//放到在哪 地址 大小
loadimage(&img[11], L"./img/flag.png", 1000 / x2, 700 / y2);//L表示宽字符
loadimage(&img[12], L"./img/boom.png", 1000 / x2, 700 / y2);//要把字符集调成Unicode
loadimage(&img[0], L"./img/0.png", 1000 / x2, 700 / y2);
loadimage(&img[1],L"./img/1.png",1000/x2,700/y2);
loadimage(&img[2], L"./img/2.png", 1000 / x2, 700 / y2);
loadimage(&img[3], L"./img/3.png", 1000 / x2, 700 / y2);
loadimage(&img[4], L"./img/4.png", 1000 / x2, 700 / y2);
loadimage(&img[5], L"./img/5.png", 1000 / x2, 700 / y2);
loadimage(&img[6], L"./img/6.png", 1000 / x2, 700 / y2);
loadimage(&img[7], L"./img/7.png", 1000 / x2, 700 / y2);
loadimage(&img[8], L"./img/8.png", 1000 / x2, 700 / y2);
loadimage(&img[9], L"./img/9.png", 1000 / x2, 700 / y2);
hwnd=initgraph(1000, 700);//可以根据x2 y2创建窗口如initgraph(x250,y250); 不过我不想改了
//拿到窗口的句柄
}
void draw(int i, int j)//绘制整个游戏画面
{
//我用f来记录放什么图 也可以一值用map来记录如空白+10 点开-10
switch (f[i][j])
{
case 0:
putimage(i * 1000 / x2, j * 700 / y2, &img[10]);//注意图形界面库里行和列是转置输出的或者说全是反的
break;
case 1:
putimage(i * 1000 / x2, j * 700 / y2, &img[11]);
break;
case 2:
putimage(i * 1000 / x2, j * 700 / y2, &img[map[i][j]]);
break;
default: break;
}
}
//void check()
//{
// int i, j;
// bo s;
// s = h->p;//h是头节点的指针变量或者说头指针
// for (i = 0; i < b; i++)
// {
// printf_s("%d\t%d", s->x, s->y);
// printf_s("\n");
// free(h);
// h = s;
// s = s->p;
// }
// free(h); h = NULL;
//}
void start()
{
int i, j;
win = 0;
memset(map, 0, sizeof(map));//全部清零
memset(f, 0, sizeof(f));//我想知道为什么memset 比{0}时间还快。。。百度没百度到
initial();//把整个图生成 x2
y2的图有b个雷
//check();//检查一下输出雷的坐标
for (i = 0; i < x2; i++)
{
for (j = 0; j < y2; j++)
{
draw(i, j);
//printf_s("%2d “, map[i][j]);//2d对齐两个单位
//system(“CLS”);//清除控制台
}
//printf_s(”\n");
}
}
void dfs(int xx,int yy)
{
int i;
win++;
f[xx][yy] = 2;
draw(xx, yy);
for (i = 0; i <= 4; i++)
if (!map[xx + dx[i]][yy + dy[i]]&&!f[xx + dx[i]][yy + dy[i]]&& xx + dx[i] >= 0 && yy + dy[i] >= 0 && yy + dy[i] < y2&& xx + dx[i] < x2)
dfs(xx + dx[i], yy + dy[i]);
}
void gg()
{
int i, j;
for (i = 0; i < x2; i++)
for (j = 0; j < y2; j++)
{
f[i][j] = 2;
draw(i, j);
}
}
void play()
{
MOUSEMSG ms = { 0 };//鼠标消息
int r, c;
while (1)
{
ms = GetMouseMsg();
switch (ms.uMsg)
{
case WM_LBUTTONDOWN://鼠标左键点击
r = ms.x / (700 / y2);
c = ms.y / (1000 / x2);
f[r][c] = 2;
draw(r,c);
win++;
if (!map[r][c]) { dfs(r, c); win–; }
if (win >= x2 * y2) { MessageBox(hwnd, L"你已经有制作者三分之一的智商了", L"666 你 are winner!", MB_OK); return; }
else if (map[r][c] == 9) //摸到奖了
{
gg();
putimage(r * 1000 / x2, c * 700 / y2, &img[12]);
MessageBox(hwnd, L"Low逼!你收到了来自制作者的鄙视,请注意查收。", L"game over", MB_OK);
return;
}
break;
case WM_RBUTTONDOWN://右键点击
r = ms.x / (700 / y2);
c = ms.y / (1000 / x2);
if (!f[r][c]) { f[r][c] = 1; if (map[r][c] == 9)win++; }
else
{
if (f[r][c] == 1) { f[r][c] = 0; if (map[r][c] == 9)win–;}
else break;
}
draw(r, c);
if (win >= x2 * y2) { MessageBox(hwnd, L"你已经有制作者三分之一的智商了", L"666 你 are winner!", MB_OK); return; }
break;
default:break;
}
}
}
int main()
{
setting();
if (x2*y2 < b) { MessageBox(hwnd,L"呀,小伙子你咋不上天呢!",L"妖妖灵吗!有恐怖分子啊!",MB_OK); return 0; }
loadimg();
start();
while(1)
{
play(); //说不上找雷效率高还是找不是雷效率高最好用贪心做个比较
if(MessageBox(hwnd, L"要再来一发吗?", L"重玩",MB_OKCANCEL)==IDCANCEL)break;//也可以用MB_YESNO 和IDOK IDNO
else start();
}
closegraph();
return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_36323837/article/details/83472514