typescript版本的扫雷游戏设计(思路+代码)
Posted 明立
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了typescript版本的扫雷游戏设计(思路+代码)相关的知识,希望对你有一定的参考价值。
思路:
生成图片矩阵
点击格子
如果 第一次 且 新游戏:
生成除该格子外的雷图
统计数字
如果 该格子是雷:
爆炸
否则:
如果 格子数字是0:
深度搜索0区域,加入展示区域
如果格子已经打开:
忽略
如果格子标识旁边有雷
把该格子加入展示区域
打开展示区域
代码(typescript版本)
/**
* 地图数字描述
* 0 空格子,可批量打开
* -1 雷区
* -2 被打开的格子
* >0 描述周围雷区个数
*/
class SaoLei
public map: any[] = [];
public showRec: any[] = [];
public initWidth: number = 10;//控制横坐标个数
public initHeight: number = 50;//控制纵坐标个数
public boomNum: number = 50;//设置随机雷数目
public dirx = [-1, 0, 1, -1, 1, -1, 0, 1]; //八方向x坐标,用以统计旁边有雷的个数
public diry = [-1, -1, -1, 0, 0, 1, 1, 1];//八方向y坐标,用以统计旁边有雷的个数
public shows: number[] = []; //展示区域集合
public deepOpen: number[] = []; //深搜节点集合
public deepDirX = [-1, 1, 0, 0]; //四方向x坐标,用以深搜可批量打开区域
public deepDirY = [0, 0, -1, 1];//四方向y坐标,用以深搜可批量打开区域
public bcreateBoom: boolean = false; //是否生成雷图标识
public booms: number[] = [] //雷区坐标
public constructor()
/**
* 全部初始化为0
* i ->y
* j ->x
*/
public init()
// console.log("init");
for (let i = 0; i < this.initHeight; i++)
this.map[i] = [];
for (let j = 0; j < this.initWidth; j++)
this.map[i][j] = 0;
this.showRec[i][j] = 0;
// console.log("init finish");
/**
* 除(X,Y)不可是雷,避免一点开就爆炸
*/
private createBoom(x, y)
/**
* 把坐标转化成id,公式是x+y*this.initWidth
*/
this.booms = [];
let limit = x * this.initWidth + y;
this.booms = this.getRandom(0, this.initWidth * this.initHeight, limit, this.boomNum);
// console.log("target", target);
for (let t of this.booms)
//id逆向为对应的坐标
let tx = Math.floor(t / this.initWidth);
let ty = Math.floor(t % this.initWidth);
this.map[tx][ty] = -1;
this.bcreateBoom = true;
this.calcMapnum();
this.clickMap(x, y);
/**
* 点击地图响应
*/
public clickMap(x, y)
// console.log("click");
if (!this.bcreateBoom) //如果还没有创建雷图
this.createBoom(x, y);//创建雷图
return;
if (this.showRec[x][y] == 1) //已经被打开了
return;
this.shows = [];
if (this.map[x][y] == -1)
//游戏结束响应
else if (this.map[x][y] > 0)
this.shows.push(x + y * this.initWidth);
else if (this.map[x][y] == 0)
this.deepOpen.push(x + y * this.initWidth);
this.getShows();
for (let show of this.shows)
let sx = Math.floor(show / this.initWidth);
let sy = Math.floor(show % this.initWidth);
this.showRec[sx][sy] = 1;
console.log(this.map);
/**
* 深搜可以批量打开的格子
*/
private getShows()
while (this.deepOpen.length)
let open = this.deepOpen.shift();
this.shows.push(open);
let ox = Math.floor(open / this.initWidth);
let oy = Math.floor(open % this.initWidth);
for (let k = 0; k < this.deepDirX.length; k++)
let nearX = ox + this.deepDirX[k];
let nearY = oy + this.deepDirY[k];
if (!this.bOutOfBoundary(nearX, nearY)) //是否超出边界
let target = nearX + nearY * this.initWidth;
if (this.map[nearX][nearY] == 0) //为0的时候才考虑要不要加入
if (this.showRec[nearX][nearY] == 0) //没有打开的,实际上深度情况下可以不考虑这部分
if (this.shows.indexOf(target) == -1) //没有遍历过
if (this.deepOpen.indexOf(target) == -1) //没有在队列中
this.deepOpen.push(target);
/**
* 根据创建好的雷图,计算每个格子的数值
*/
public calcMapnum()
for (let boom of this.booms)
let bx = Math.floor(boom / this.initWidth);
let by = Math.floor(boom % this.initWidth);
if (this.map[bx][by] == -1) //-1代表雷
//如果有雷,则旁边8个非雷的格子个数都加1
for (let k = 0; k < this.dirx.length; k++)
let nearX = bx + this.dirx[k];
let nearY = by + this.diry[k];
if (!this.bOutOfBoundary(nearX, nearY)) //是否超出边界
if (this.map[nearX][nearY] != -1)
this.map[nearX][nearY]++;
/**
* 是否超出边界
*/
private bOutOfBoundary(x, y)
if (x >= 0 && x < this.initHeight && y >= 0 && y < this.initWidth)
return false;
return true;
/**
* 获取随机数值
*/
private getRandom(start, end, limit, num)
//获取随机数源
let data = [];
for (let i = start; i < end; i++)
if (i != limit && num > 0)
data.push(i);
let DataLen = data.length
let target = [];
for (let i = 0; i < num; i++)
let randomInd = Math.floor(Math.random() * DataLen);
let temp = data[randomInd];
data[randomInd] = data[DataLen - 1];
target.push(temp);
DataLen--;
return target;
说明1:只是写了游戏逻辑代码,没有写界面,具体的可以根据map的状态去实现界面逻辑,为什么要这样?懒~
说明2:重申没有做标识方面的工作,如果要实现,实际上就维护另一个标识矩阵,然后再click里面判定这个格子的状态,再实现对应的逻辑就好,为什么不顺便写了?懒~
说明3:代码未必正确,review代码的时候发现有不合逻辑的时候,会更新一遍,如果发现说这玩意怎么写得这么渣渣,有各种问题的时候,别急,别慌,看下是不是最新的代码,是的话。。。那也莫得法子~建议下方留言通知改正,感谢大佬!
说明4:仅做了简单测试,实际发现有什么bug的话,可探讨解决,不负责维护~(卒)
以上是关于typescript版本的扫雷游戏设计(思路+代码)的主要内容,如果未能解决你的问题,请参考以下文章
扫雷游戏(C语言实现)初级版和优化版(增加了自动展开标记地雷功能,同时排除了第一次排到地雷的情况)