在15拼图中调试无效移动

时间:2017-11-09 08:18:32

标签: javascript debugging if-statement logic logical-operators

我做了一点15 puzzle,我想在一开始就洗牌。我从已完成的状态开始,在瓷砖上做1000个随机的“假点击”,其中一些根据我的代码是有效的,大多数不是。有效的“假冒点击”会导致emptyTileselectedTile通过交换topleft值来交换其位置。

一切(除了checkCompleteness()方法之外还没有)似乎有效 - 直到有人试图解决这个难题。小n,我超过50%的时间达到unsolvable game situation

如果在洗牌过程中我只进行有效的移动,这怎么可能?显然,如果一个移动有效,它必须是我的代码检查:

if ((Math.abs(selectedX - emptyX) === tileSize) ^ (Math.abs(selectedY - emptyY) === tileSize)) {

(^(xor)是为了防止对角移动。)

有谁看到问题所在?或者有没有人建议好的调试策略?经过一个多小时的调试,我有点无能为力。

var idList = ["t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9", "t10", "t11", "t12", "t13", "t14", "t15", "t0"];
var tileSize = 100;

var init = function() {
    // place tiles on the board and add listener
    for (var column = 0; column < 4; column++) {
        for (var row = 0; row < 4; row++) {
            var div = document.querySelector("." + idList[row * 4 + column]);
            div.style.top = row * tileSize + "px";
            div.style.left = column * tileSize + "px";
            if (idList[row * 4 + column] !== "t0") {
                div.addEventListener("click", clickListener);
            }
        }
    }
    // shuffle tiles
    for (i = 0; i < 1000; i++) {
        var fakeClick = parseInt(Math.random() * 15);
        swapTiles(idList[fakeClick]);
    }
};

var clickListener = function(e) {
    var selectedTileClass = e.target.classList[1];
    swapTiles(selectedTileClass);
    //checkCompleteness(); // to be done later
};

var swapTiles = function(selectedTileClass) {
    // get empty tile and selected tile
    var selectedTile = document.querySelector("." + selectedTileClass);
    var selectedX = parseInt(selectedTile.style.left);
    var selectedY = parseInt(selectedTile.style.top);
    var emptyTile = document.querySelector(".t0");
    var emptyX = parseInt(emptyTile.style.left);
    var emptyY = parseInt(emptyTile.style.top);
    // only swap tiles  if selected tile "next to" empty tile
    if ((Math.abs(selectedX - emptyX) === tileSize) ^ (Math.abs(selectedY - emptyY) === tileSize)) {
        selectedTile.style.left = emptyX + "px";
        selectedTile.style.top = emptyY + "px";
        emptyTile.style.left = selectedX + "px";
        emptyTile.style.top = selectedY + "px";
    }
};
.board {
    position: relative;
    width: 400px;
    height: 400px;
    margin: auto;
    background-color: firebrick;
    border: 2px firebrick solid;
}

.tile {
    position: absolute;
    width: 100px;
    height: 100px;
    border: 2px firebrick solid;
    box-sizing: border-box;
    background-color: orange;
    line-height: 100px;
    font-size: 2rem;
    font-weight: bold;
    font-family: Arial, sans-serif;
    color: firebrick;
    text-align: center;
    transition: all .25s linear;
    cursor: pointer;
}

.t0 {
    position: absolute;
    width: 96px;
    height: 96px;
    margin: 2px;
    border: 2px orange solid;
    box-sizing: border-box;
    pointer-events: none;
    transition: all .25s linear;
}
<html>
<meta charset="utf-8">

<head>
    <script type="text/javascript" src="js.js"></script>
    <link rel="stylesheet" type="text/css" href="style.css">
</head>

<body onload="init();">
    <div class="wrapper">
        <div class="center">
            <div class="board">
                <div class="tile t1">1</div>
                <div class="tile t2">2</div>
                <div class="tile t3">3</div>
                <div class="tile t4">4</div>
                <div class="tile t5">5</div>
                <div class="tile t6">6</div>
                <div class="tile t7">7</div>
                <div class="tile t8">8</div>
                <div class="tile t9">9</div>
                <div class="tile t10">10</div>
                <div class="tile t11">11</div>
                <div class="tile t12">12</div>
                <div class="tile t13">13</div>
                <div class="tile t14">14</div>
                <div class="tile t15">15</div>
                <div class="t0"></div>
            </div>
        </div>
    </div>
</body>

</html>

1 个答案:

答案 0 :(得分:1)

你是对的,你的考试是错误的。

想象一下在中心有一块选定瓷砖的小板

ooooo
ooooo
ooxoo
ooooo
ooooo

现在看看2个谓词的两个真值表取决于空格子的位置。

ftftf
ftftf
ftxtf
ftftf
ftftf

fffff
ttttt
ffxff
ttttt
fffff

将它们与xor混合,你得到

ftftf
tftft
ftxtf
tftft
ftftf

这意味着您可以在&#34;第一个圆圈&#34;在瓷砖周围,但你得到的反应距离瓷砖的距离不正确。