java扫雷的设计思路_扫雷设计思路

int

i,num,tmpx,tmpy,centerX,centerY;

char

num_str[2];

先清空队列

e.x=x;

e.y=y;

Qin(&Q,&e);

Mine_open[y][x]=1; //作上访问标记,利用mine数组作记录

while(!Qempty(&Q)) //当队列空时遍历结束

{

Qout(&Q,&e);

//注意:旋转中心方块的坐标在8次循环中用到

//放入变量centerX、centerY加以保护(由于e.x、e.y在循环中会被更改)

centerX=e.x;

centerY=e.y;

//揭开该方格

draw_3D_rect(hDC,centerX*BSIZE,centerY*BSIZE,1," ");

for(i=0;i<8;i++) //检查周围的8个方格

{

tmpx=centerX+offset_x[i];

tmpy=centerY+offset_y[i];

//对于处于边、角的方格,tmpx和tmpy可能为负数或超出最大值,要进行判断

//注:对于已经标记的位置(mine_mark[tmpy][tmpx]==0)不予处理

if(tmpx>=0

&& tmpx

&& tmpy>=0

&& tmpy

&& mine_mark[tmpy][tmpx]==0)

if(mine_open[tmpy][tmpx]==0) //该格子未挖开

if(mine_show[tmpy][tmpx]>0) //若是区域的边沿(有数字)就揭开该方块

{

num=mine_show[tmpy][tmpx];

_itoa(num,num_str,10);

draw_3D_rect(hDC,tmpx*BSIZE,tmpy*BSIZE,1,num_str);

mine_open[tmpy][tmpx]=1; //作上挖开标记

}

else //否则入队

{

e.x=tmpx;

e.y=tmpy;

Qin(&Q,&e);

Mine_open[tmpy][tmpx]=1; //作上挖开标记

}

}

}

}

初始工作

1.存储地雷摆放位置的矩阵(1表示有雷,0表示无雷)

int mine[ROWS][COLS];

2.用于显示的矩阵(空间换时间,有了这个矩阵,就不用临时去算周围有几个雷了)

-1表示为地雷,其余数字表示周围的地雷个数

int mine_show[ROWS][COLS];

由mine矩阵可以推出mine_show矩阵

0

1

1

1

1

1

1

0

0

1

-1

2

1

0

1

3

-1

2

0

0

2

-1

2

0

0

1

1

1

0

3. 用于标记地雷的矩阵(为1表示未标记,为0表示已标记)

int mine_mark[ROWS][COLS];

4. 用于标记单元格是否挖开的矩阵(为1表示挖开,为0表示未挖开)

int

mine_open[ROWS][COLS];

map[i][j].opened <=> mine_open[i][j]=?

map[i][j].marked <=> mine_mark[i][j]=?

map[i][j].num <=> mine_show[i][j]=?

Map[i][j].isMine

5.某个方格的八个相邻方格x、y方向的偏移量

int offset_x[8]={-1, 0, 1,1,1,0,-1,-1}; //列

int offset_y[8]={-1,-1,-1,0,1,1, 1, 0}; //行

6. 地雷的数目统计

int num_total; //总个数

int num_marked; //标记的个数

鼠标点击处理

1.点击鼠标左键(假设点击的是y行x列)

//对于已经标记的位置不作处理

if(mine_mark[y][x]==1) return;

num=mine_show[y][x];

if(num==-1) //该方格有地雷

{

在y行x列方格中画一个雷,游戏失败,结束。

}

else

//该方格无地雷

{

if(num>0) //周围地雷数大于0

{

先在y行x列方格中显示周围雷的个数

然后设置该单元格为挖开状态 Mine_open[y][x]=1;

}

else //遍历并挖开此空白单元格相邻的空白区域(广度优先遍历)

bfs(x,y,hwnd,hDC);

}

2. 点击鼠标右键(假设点击的是y行x列)

//注:已经挖开的格子(mine_open[y][x]==1)不存在打上或取消标记

if(mine_open[y][x]!=1)

if(mine_mark[y][x]==0)  //打上旗帜标记

{

在y行x列方格中画一个旗帜

mine_mark[y][x]=1;

}

else //取消标记

{

在y行x列方格中取消旗帜

mine_mark[y][x]=0;

}

3.判断任务是否完成

//判断标准:无雷区域是否全部挖开

int Success()

{

int OK=1,x,y;

for(x=0;x

for(y=0;y

//该位置无雷,且没有揭开

if(mine_show[y][x]!=-1 &&

mine_open[y][x]!=1) {OK=0; break;}

return(OK);

}

3.bfs(广度优先搜索)算法

//无雷的连通区域查找(广度优先遍历)///

void bfs(int x,int y)

{

Queue

Q;

Qelement

e;

如果队列空了,则退出循环

出队一个空白单元格(x,y)

挖开该单元格

处理相邻8个单元格,有数字的直接挖开,空白的挖开后入队(将x,y坐标存入队列)

挖开鼠标点击的单元格,并将该单元格坐标入队

int

i,num,tmpx,tmpy,centerX,centerY;

char

num_str[2];

先清空队列

e.x=x;

e.y=y;

Qin(&Q,&e);

Mine_open[y][x]=1; //作上访问标记,利用mine数组作记录

while(!Qempty(&Q)) //当队列空时遍历结束

{

Qout(&Q,&e);

//注意:旋转中心方块的坐标在8次循环中用到

//放入变量centerX、centerY加以保护(由于e.x、e.y在循环中会被更改)

centerX=e.x;

centerY=e.y;

//揭开该方格

draw_3D_rect(hDC,centerX*BSIZE,centerY*BSIZE,1," ");

for(i=0;i<8;i++) //检查周围的8个方格

{

tmpx=centerX+offset_x[i];

tmpy=centerY+offset_y[i];

//对于处于边、角的方格,tmpx和tmpy可能为负数或超出最大值,要进行判断

//注:对于已经标记的位置(mine_mark[tmpy][tmpx]==0)不予处理

if(tmpx>=0

&& tmpx

&& tmpy>=0

&& tmpy

&& mine_mark[tmpy][tmpx]==0)

if(mine_open[tmpy][tmpx]==0) //该格子未挖开

if(mine_show[tmpy][tmpx]>0) //若是区域的边沿(有数字)就揭开该方块

{

num=mine_show[tmpy][tmpx];

_itoa(num,num_str,10);

draw_3D_rect(hDC,tmpx*BSIZE,tmpy*BSIZE,1,num_str);

mine_open[tmpy][tmpx]=1; //作上挖开标记

}

else //否则入队

{

e.x=tmpx;

e.y=tmpy;

Qin(&Q,&e);

Mine_open[tmpy][tmpx]=1; //作上挖开标记

}

}

}

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值