let y = offset0 % w;
if (!y || y > img_width) {
s = -1;
}
return s;
}
/**
* 行列转为坐标差
* @param r0 行列
* @return {number}
*/
function row2Axis(r0) {
// 暂时只以图片宽度为基准,所以图片宽高必须一致
return r0 * (img_width + board_border);
}
/**
* 判断给定行列是否出界
* @param x0 行
* @param y0 列
* @return {boolean}
*/
function isOutside(x0, y0) {
return (x0 < 0 || x0 >= board_row || y0 < 0 || y0 >= board_col);
}
/**
* 初始化棋盘
*/
function initBoard() {
for (let i = 0; i < board_row; i++) {
for (let j = 0; j < board_col; j++) {
board_states[i][j] = id_normal;
}
}
}
/**
* 随机生成地雷分布
*/
function randomMines() {
for (let i = 0; i < board_row; i++) {
for (let j = 0; j < board_col; j++) {
mine_map[i][j] = 0;
}
}
for (let i = 0, x0, y0; i < mine_count; i++) {
x0 = randomInt(0, board_row);
y0 = randomInt(0, board_col);
if (mine_map[x0][y0]) {
i--;
continue;
}
mine_map[x0][y0] = 1;
}
}
/**
* 获取随机数
* @param low0 下界, 包含
* @param up0 上界, 不包含
* @return {number}
*/
function randomInt(low0, up0) {
return Math.floor(Math.random() * (up0 - low0)) + low0;
}
/**
* 挖开周围的方块, 返回总共挖开的个数, 若为负数说明踩到地雷了
* @param cxt
* @param x0 行
* @param y0 列
* @return {number}
*/
function expandSurround(cxt, x0, y0) {
let x1 = x0 + 1;
let y1 = y0 + 1;
let count0 = 0;
let num;
for (let i = x0 - 1; i <= x1; i++) {
for (let j = y0 - 1; j <= y1; j++) {
num = expandByDFS(cxt, i, j);
if (num < 0) return num;
count0 += num;
}
}
return count0;
}
/**
* 深度搜索并展开空白块, 返回总共展开的个数, 若为负数说明踩到地雷了
* @param cxt
* @param x0 行
* @param y0 列
* @return {number}
*/
function expandByDFS(cxt, x0, y0) {
let expandCount = 0;
if (isOutside(x0, y0)) return expandCount;
let img_id = board_states[x0][y0];
if (img_id !== id_normal && img_id !== id_unknown &&
img_id !== id_normal_light && img_id !== id_unknown_light)
return expandCount;
let num = sweepOne(cxt, x0, y0);
expandCount++;
// 当前块的数字为不为0,不能展开周围,因为有地雷
if (num !== 0) {
if (num < 0) expandCount = num;
return expandCount;
}
num = expandSurround(cxt, x0, y0);
if (num < 0) return num;
expandCount += num;
return expandCount;
}
/**
* 挖开一个块, 返回该块显示的数字, 若为负数说明踩到地雷了
* @param cxt
* @param x0 行
* @param y0 列
* @return {number}
*/
function sweepOne(cxt, x0, y0) {
let img_id;
let num;
if (mine_map[x0][y0]) {
// game over
num = -1;
img_id = id_mine_burst;
} else {
// calculate mine's count surround current block
num = mineCountSurround(x0, y0);
img_id = id_n[num];
}
board_states[x0][y0] = img_id;
drawMineBlock(cxt, x0, y0, img_id);
return num;
}
/**
* 周围地雷个数
* @param x0 行
* @param y0 列
* @return {number}
*/
function mineCountSurround(x0, y0) {
let x1 = x0 + 1;
let y1 = y0 + 1;
let sum = 0;
for (let i = x0 - 1; i <= x1; i++) {
for (let j = y0 - 1; j <= y1; j++) {
if (isOutside(i, j)) continue;
sum += mine_map[i][j];
}
}
return sum;
}
/**
* 周围标记个数
* @param x0 行
* @param y0 列
* @return {number}
*/
function flagCountSurround(x0, y0) {
let x1 = x0 + 1;
let y1 = y0 + 1;
let sum = 0;
for (let i = x0 - 1; i <= x1; i++) {
for (let j = y0 - 1; j <= y1; j++) {
if (isOutside(i, j)) continue;
if (board_states[i][j] === id_flag) sum++;
}
}
return sum;
}
</script>
</body>
</html>
Back to home |
File page
Subscribe |
Register |
Login
| N