6

我用 javascript 制作了一个扫雷游戏,最终运行得非常顺利,直到我添加了“expand()”函数(见下文)。我有3个问题:

  1. 当它展开时,它向“flippedCount”添加了太多(参见下面的代码) - 在右侧 div 下方的图像中显示“flippedCount”,它的 39 而不是 35。
  2. 因此,如果玩家在“expand()”期间超过 90 个方格(获胜金额),则不会显示获胜屏幕。
  3. 它也没有正确展开(见下图)。

相关代码和链接在这两张图片下方

显示部分完成的扫雷场的图像

显示“空”扫雷区的图像

var flippedCount = 0;
var alreadySetAsZero = [];
var columnAmount = 10;

function processClick(clicked) { //i use a "(this)" to pass as "(clicked)"
  nextToBombCheck( parseInt(clicked.id) );
  checkWin();
}

nextToBombCheck( boxNum ) { 
  flippedCount++;
  document.getElementById("flipped").innerHTML = flippedCount;  
  //long function setting "bombCount" to # bombs around clicked square goes here
  if ( bombCount !== 0 ) { 
    //blah blah blah
  } else {
    alreadySetAsZero[ boxNum ] = "yes";
    expand(boxNum);
  } 
}

function expand( emptyBoxId ) {
  checkRightOfEmpty( emptyBoxId + 1 );
  checkLeftOfEmpty( emptyBoxId - 1 );
  checkAboveEmpty( emptyBoxId - columnAmount );
  checkBelowEmpty( emptyBoxId + columnAmount );
} 

function checkRightOfEmpty( boxToTheRightId ) {
  //check if already marked as zero
  if ( alreadySetAsZero[ boxToTheRightId ] === "yes" )
    return;
  //if box is at the edge
  if ( boxToTheRightId % columnAmount === ( 0 ) ) {
    //do nothing
  } else {
    nextToBombCheck( boxToTheRightId );
  }
}

//and the rest are 3 similar functions

我无法找到缺少扩展或添加到翻转计数的数字的模式。

链接在这里

ps对不起标题我不知道还能叫什么

4

3 回答 3

4

您得到的计数不正确,因为您的算法没有考虑已经翻转的方块 - 结果是方块被计算了两次。

保持准确计数的最简单方法是利用“getElementsByClassName”返回活动节点列表这一事实。

注意:getElementsByClassName 有很好的浏览器支持,但是如果您的浏览器要求不同,则需要稍微调整一下。

在输入时,初始化列表(变量名称只是为了与以前的名称区分开来):

var newFlippedCount = document.getElementsByClassName('flipped');

每次使用炸弹计数类更新正方形时,请改用它(也添加翻转类):

document.getElementById(boxNum).className = classList[bombCount] + ' flipped';

当您使用新的翻转计数更新 UI 时,请使用:

document.getElementById("flipped").innerHTML = newFlippedCount.length;

你的计数现在神奇地正确:)

注意:您也可以通过检查框是否在递增之前已翻转来解决此问题flippedCount

您还定期在控制台中收到错误:

Uncaught TypeError: Cannot set property 'className' of null

在这一行(大约行:298):

document.getElementById(boxNum).className = classList[bombCount];

您应该通过检查边界或仅通过在使用它之前检查返回值来保护它:

var ele = document.getElementById(boxNum);
if(!ele) return;

ele.className = classList[bombCount] + ' flipped';

演示

编辑:如果您有兴趣,这里是扫雷级联算法的高级概述

更新 - 发现级联错误

级联在连续重放时无法正常工作的原因之一是用于跟踪已设置为零的单元格的变量在新游戏中没有被重置。修复:

function start() {
   …
   // Reset to empty array
   alreadySetAsZero = [];
   ...
}

用额外的调试语句更新了 fiddle 以帮助找到问题:

演示

于 2013-08-25T20:00:08.143 回答
1

尽管您使用“alreadySetAsZero”来停止多次计算方格,但这并没有考虑到有炸弹计数的方格。这些将在您的扩展方法中计算多次。

于 2013-08-25T20:10:17.747 回答
0

我发现困扰我的问题(计数器)它计算了正方形“-1”和“100”

然后我添加|| boxToTheRightId > ( cellAmount - 1 )checkRightOfEmpty|| boxToTheRightId < 0checkLeftOfEmpty(在他们的if声明中),它工作得很好,谢谢大家。

于 2013-09-29T05:09:08.860 回答