扫雷的逻辑问题

时间:2018-11-21 03:33:47

标签: javascript jquery

-已解决-

我只是忘了每局比赛后重新设置标志数。

我的扫雷游戏中标志的数量有问题。出于某种原因,有时当我标记一个图块时,标记的数量增加了1个以上。有时它增加了3个,有时增加了4个,有时出现了7个。我在逻辑上找不到问题,因此我希望得到另一个问题一双眼睛。

我看到的唯一一种模式是,它添加了比应有的更多的标志,即flags变量增加了一次以上,是当我标记一个大部分被显示的瓦片包围的瓦片时。

>

Javascript:

var flags = 0;
var trueFlags = 0;

function newGame() {
    var cols = $("#width").val();
    var rows = $("#height").val();

    if (cols < 8 || rows < 8) {
        return;
    }else if (cols > 40 || rows > 30) {
        return;
    }
    boardClear();
    possibleBombs = (rows * cols) - 1;
    numBombs = 0;
    for (var i = 1; i <= rows; i++) {
        for (var j = 1; j <= cols; j++) {
            if (numBombs < possibleBombs) {
                var q = Math.floor(Math.random() * 50);
                if (0 <= q && q <= 2) {
                    numBombs += 1;
                    $("#board").append('<button type="button" class="tile" data-row = ' + i + ' data-col = ' + j + ' data-contains = ' + 0 + ' data-flagged = ' + false + '></button>').prop("revealed", false);
                }
                else {
                    $("#board").append('<button type="button" class="tile" data-row = ' + i + ' data-col = ' + j + ' data-contains = ' + 1 + 'data-flagged = ' + false + '></button>').prop("revealed", false);
                }
            } 
            else {
                $("#board").append('<button type="button" class="tile" data-row = ' + i + ' data-col = ' + j + ' data-contains = ' + 1 + ' data-flagged = ' + false + '></button>').prop("revealed", false);
            }
        }
        $("#board").append("<br/>");
    }
    $(".controls h2").text("Bombs to go: " + numBombs);
    $(".tile").css("background-color", "white");
    $(".tile").width(15);
    $(".tile").height(15);
    console.log("bombs: " + numBombs, "possible: " + possibleBombs);

    $(".tile").click(function(e) {
        if (e.shiftKey) {
            flagKey($(this));
            $(".controls h2").text("Bombs to go: " + (numBombs - flags));
        }
        else if ($(this).data("contains") == 0) {
            console.log("you lose");
            boardClear();
            newGame();
            return;
        }   
        else {
            revealNeighbors($(this));
            // if (gameWon() == true) {
            //     alert("You have won!");
            //     newGame();
            // }
            return;
        }
    });
}

function boardClear() {
    $("#board").empty();
}

function revealNeighbors(tile) {
    var cordsx = tile.data("row");
    var cordsy = tile.data("col");

    // tile has bomb
    if(tile.data("contains") == 0) {return;}
    // tile is flagged
    else if(tile.data("flagged") == true){return;}
    // tile has been revealead already
    else if(tile.prop("revealed") == true) {return;}

    // reveal the tile
    var tileBombs = nearbyBombCount(tile);
    tile.prop("revealed", true);
    tile.text(tileBombs);
    tile.css("background-color", "grey");

    if (tileBombs == 0){tile.text("");}
    else if(tileBombs != 0) {return;}

    for (var i = -1; i <= 1; i++) {
        for (var j = -1; j <= 1; j++) {
            if (cordsx + i < 1 || cordsy + j < 1) {continue;}
            else if (cordsx + i > $("#width").val() || cordsy + j > $("#height").val()) {continue;}
            else if (i == 0 && j == 0) {continue;}
            var neighbor = $('.tile[data-row="' + (cordsx+i) + '"][data-col ="'+(cordsy+j)+'"]');
            revealNeighbors(neighbor);
        }
    }
}

function nearbyBombCount(tile) {
    var cx = tile.data("row");
    var cy = tile.data("col");
    var nearbyBombs = 0;
    for (var n = -1; n < 2; n++) {
        for (var m = -1; m < 2; m++) {
            if (cx + n < 1 || cy + m < 1) {continue;}
            else if (cx + n > $("#width").val() || cy + m > $("#height").val()) {continue;}
            var neighbor = $('.tile[data-row="' + (cx+n) + '"][data-col ="'+(cy+m)+'"]');
            if (neighbor.data("contains") == 0) {
                nearbyBombs++;
            }
        }
    }
    return nearbyBombs;
}

function flagKey(tile) {
    // tile is already revealed
    if (tile.data("revealed") == true) {
        return;
    }
    // tile is already flagged
    else if (tile.data("flagged") == true) {
        tile.data("flagged", false);
        tile.css("background-color", "white");
        flags--;
        // contains bomb
        if (tile.data("contains") == 0) {
            trueFlags--;
        }
        return;
    }
    // tile not flagged
    else if (tile.data("flagged") == false) {
        flags++;
        tile.data("flagged", true);
        tile.css("background-color", "red");
        // contains bomb
        if (tile.data("contains") == 0) {
            trueFlags++;
            console.log(trueFlags);
        }
    }
    else {
        return;
    }
}

我的猜测是我的revealNeighbors()函数存在问题,或者是范围问题,但是我一生无法弄清楚它是什么。

1 个答案:

答案 0 :(得分:0)

嗨,我换了一点,效果很好

<html>
<head>
    <style>
        .tile{padding:5px;}
    </style>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
    
   Width : <input type="text" id="width" value="15" /> Height :<input type="text"  id="height" value="15" /><input type="button" onclick="newGame()" id="btnstart" value="start" />
    <br />
    <div>
        <div id="board" >

        </div>
    </div>
<script>
var flags = 0;
var trueFlags = 0;

function newGame() {
    var cols = $("#width").val();
    var rows = $("#height").val();
   
    if (cols < 8 || rows < 8) {
        return;
    }else if (cols > 40 || rows > 30) {
        return;
    }
    boardClear();
    possibleBombs = (rows * cols) - 1;
    numBombs = 0;
    
    for (var i = 1; i <= rows; i++) {
        for (var j = 1; j <= cols; j++) {
            if (numBombs < possibleBombs) {
                var q = Math.floor(Math.random() * 50) + 1;
                
                if (q <= 2) {
                   
                    numBombs += 1;
                    $("#board").append('<button type="button" class="tile" data-row = ' + i + ' data-col = ' + j + ' data-contains = ' + 0 + ' data-flagged = ' + false + '></button>').prop("revealed", false);
                }
                else {
                    $("#board").append('<button type="button" class="tile" data-row = ' + i + ' data-col = ' + j + ' data-contains = ' + 1 + 'data-flagged = ' + false + '></button>').prop("revealed", false);
                }
            } 
            else {
                $("#board").append('<button type="button" class="tile" data-row = ' + i + ' data-col = ' + j + ' data-contains = ' + 1 + ' data-flagged = ' + false + '></button>').prop("revealed", false);
            }
        }
        $("#board").append("<br/>");
    }
    $(".controls h2").text("Bombs to go: " + numBombs);
    $(".tile").css("background-color", "white");
    $(".tile").width(15);
    $(".tile").height(15);
    console.log("bombs: " + numBombs, "possible: " + possibleBombs);

    $(".tile").click(function (e) {
        
        if (e.shiftKey) {
            flagKey($(this));
            $(".controls h2").text("Bombs to go: " + (numBombs - flags));
        }
        else if ($(this).data("contains") == 0) {
            console.log("you lose");
            boardClear();
            newGame();
            return;
        }   
        else {
            revealNeighbors($(this));
            // if (gameWon() == true) {
            //     alert("You have won!");
            //     newGame();
            // }
            return;
        }
    });
}

function boardClear() {
    $("#board").empty();
}

function revealNeighbors(tile) {
    var cordsx = tile.data("row");
    var cordsy = tile.data("col");

    // tile has bomb
    if(tile.data("contains") == 0) {return;}
    // tile is flagged
    else if(tile.data("flagged") == true){return;}
    // tile has been revealead already
    else if(tile.prop("revealed") == true) {return;}

    // reveal the tile
    var tileBombs = nearbyBombCount(tile);
    tile.prop("revealed", true);
    tile.text(tileBombs);
    tile.css("background-color", "grey");

    if (tileBombs == 0){tile.text("");}
    else if(tileBombs != 0) {return;}

    for (var i = -1; i <= 1; i++) {
        for (var j = -1; j <= 1; j++) {
            if (cordsx + i < 1 || cordsy + j < 1) {continue;}
            else if (cordsx + i > $("#width").val() || cordsy + j > $("#height").val()) {continue;}
            else if (i == 0 && j == 0) {continue;}
            var neighbor = $('.tile[data-row="' + (cordsx+i) + '"][data-col ="'+(cordsy+j)+'"]');
            revealNeighbors(neighbor);
        }
    }
}

function nearbyBombCount(tile) {
    var cx = tile.data("row");
    var cy = tile.data("col");
    var nearbyBombs = 0;
    for (var n = -1; n < 2; n++) {
        for (var m = -1; m < 2; m++) {
            if (cx + n < 1 || cy + m < 1) {continue;}
            else if (cx + n > $("#width").val() || cy + m > $("#height").val()) {continue;}
            var neighbor = $('.tile[data-row="' + (cx+n) + '"][data-col ="'+(cy+m)+'"]');
            if (neighbor.data("contains") == 0) {
                nearbyBombs++;
            }
        }
    }
    return nearbyBombs;
}

function flagKey(tile) {
    // tile is already revealed
    if (tile.data("revealed") == true) {
        return;
    }
    // tile is already flagged
    else if (tile.data("flagged") == true) {
        tile.data("flagged", false);
        tile.css("background-color", "white");
        flags--;
        // contains bomb
        if (tile.data("contains") == 0) {
            trueFlags--;
        }
        return;
    }
    // tile not flagged
    else if (tile.data("flagged") == false) {
        flags++;
        tile.data("flagged", true);
        tile.css("background-color", "red");
        // contains bomb
        if (tile.data("contains") == 0) {
            trueFlags++;
            console.log(trueFlags);
        }
    }
    else {
        return;
    }
}
</script>
</body>
</html>