6

javascript で掃海艇ゲームを作成しましたが、「expand()」関数 (以下を参照) を追加するまでは、最終的に非常にスムーズに実行されていました。3 つの問題があります。

  1. 展開すると、「flippedCount」に追加されるものが多すぎます (以下のコードを参照) - 右側の div の下の画像では、「flippedCount」が表示され、35 ではなく 39 が表示されます。
  2. その結果、プレイヤーが「expand()」中に 90 マス (勝つ量) を超えた場合、勝利画面は表示されません。
  3. また、適切に展開されません (下の画像を参照)。

関連するコードとリンクは、これら 2 つの画像の下にあります。

部分的に完成したマインスイーパ フィールドを示す画像

「空の」掃海艇フィールドを示す画像

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

アルゴリズムが既に裏返された正方形を考慮していないため、誤ったカウントが得られます。その結果、正方形が 2 回カウントされます。

の正確なカウントを保持する最も簡単な方法は、「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';

デモ

編集: 興味がある場合は、マインスイーパ カスケード アルゴリズムの概要を以下に示します。

更新 - カスケード バグが見つかりました

カスケードが連続するリプレイで正しく機能しなかった理由の 1 つは、既にゼロに設定されているセルを追跡するために使用される変数が、新しいゲームでリセットされなかったことです。修正するには:

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

問題を見つけるのに役立つように、追加のデバッグ ステートメントでフィドルを更新しました。

デモ

于 2013-08-25T20:00:08.143 に答える
1

「alreadySetAsZero」を使用して正方形が複数回カウントされるのを停止しますが、これは爆弾カウントのある正方形を考慮していません。これらは、expand メソッドで複数回カウントされます。

于 2013-08-25T20:10:17.747 に答える
0

私を悩ませていた問題を見つけました(カウンター)それは「-1」と「100」の四角形を数えました

私はその後に(彼らの声明で)に追加|| boxToTheRightId > ( cellAmount - 1 )しましたがcheckRightOfEmpty、うまくいきました。とにかくみんなに感謝します。|| boxToTheRightId < 0checkLeftOfEmptyif

于 2013-09-29T05:09:08.860 に答える