PUZZLE TROUBLE - 试图保存初始板

时间:2014-10-09 16:32:39

标签: javascript variables javascript-events scope

我为15个拼图编写了这个javascript应用程序。整个申请表包含在下面的文件中。每当我渲染一个新的电路板时,我都试图将初始配置存储在“初始电路板”中。变量,所以我可以稍后重播同一个游戏。然而," initialBoard'变量似乎总是等于' currentBoard'变量。我是javascript的新手,非常感谢任何帮助。

<html>
<head>
    <title>15 Puzzle</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
    <style type="text/css">
        #puzzle-board {
            border: 5px solid;
        }
        .puzzle-tile {
            background:#fff;
            background: -moz-linear-gradient(top, #fff, #eee);
            background: -webkit-gradient(linear,0 0, 0 100%, from(#fff), to(#eee));
            box-shadow: inset 0 0 0 1px #fff;
            -moz-box-shadow: inset 0 0 0 1px #fff;
            -webkit-box-shadow: inset 0 0 0 1px #fff;
            font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
            font-size:60px;
            height: 100px;
            text-align: center;
            text-decoration: none;
            text-shadow:0 1px #fff;
            user-select: none;
            -moz-user-select: none;
            -webkit-user-select: none;
            -ms-user-select: none;
            vertical-align:middle;
            width: 100px;
        }

        #start-stop {
            float: left;
        }

        #timer {
            float: left;
            margin-left: 10px;
        }

        #counter {
            float: left;
            margin-left: 10px;
        }
    </style>
</head>
<body>
    <div class="container-fluid">
        <div class="row">
            <br />
        </div>
        <div class="row">
            <div class="col-md-5 col-md-offset-1">
                <table id="puzzle"></table>
            </div>
            <div class="col-md-6">
                <div class="row">
                    <br />
                    <button type="button" class="btn btn-lg btn-success" id="start-stop">START</button>
                    <button type="button" class="btn btn-lg btn-default" id="timer"></button>
                    <button type="button" class="btn btn-lg btn-default" id="counter"></button>
                </div>
           </div>
        </div>
    </div>
    <script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
    <script src="http://code.jquery.com/ui/1.11.1/jquery-ui.min.js"></script>
    <!--<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>-->
    <script>
        /**
         *  Puzzle Object
         */
        puzzle = function(targetId) {

            /************************************************************
             * Private members
             ************************************************************/

            var
                currentBoard,
                initialBoard,
                orderedBoard = [[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,'']];

            function canSwapTiles(source, target) {
                var sourceTileRow = source.attr("data-row");
                var sourceTileCol = source.attr("data-col");
                var sourceTileValue = source.text();

                var targetTileRow = target.attr("data-row");
                var targetTileCol = target.attr("data-col");
                var targetTileValue = target.text();

                if (sourceTileValue != '' && targetTileValue != '') {
                    return false;
                } else if (Math.abs(targetTileRow - sourceTileRow) > 1) {
                    return false;
                } else if (Math.abs(targetTileCol - sourceTileCol) > 1) {
                    return false;
                } else {
                    return true;
                }
            }

            function swapTiles(source, target) {
                var sourceTileRow = source.attr("data-row");
                var sourceTileCol = source.attr("data-col");
                var sourceTileValue = source.text();

                var targetTileRow = target.attr("data-row");
                var targetTileCol = target.attr("data-col");
                var targetTileValue = target.text();

                source.text(targetTileValue);
                currentBoard[sourceTileRow][sourceTileCol] = parseInt(targetTileValue);

                target.text(sourceTileValue);
                currentBoard[targetTileRow][targetTileCol] = parseInt(sourceTileValue);

                $(targetId).trigger('moved');

                console.log("swapped tiles");
                console.log(initialBoard);

                if (isSolved())
                {
                    console.log('solved puzzle');
                    console.log(initialBoard);

                    $(targetId).trigger('solved', {
                        board: initialBoard
                    });
                }
            }

            function renderBoard(board) {
                $("#puzzle-board").empty();
                currentBoard = board;
                //initialBoard = board;

                console.log('rendering board');
                console.log(initialBoard);

                for (i = 0; i < 4; i++) {
                    $("#puzzle-board").append('<tr class="puzzle-row" id="puzzle-row-' + i + '"></tr><br />');
                    for (j = 0; j < 4; j++) {
                        var tile = '<td class="puzzle-tile" data-row="' + i + '" data-col="' + j + '">' +
                                board[i][j] +
                                '</td>';
                        $("#puzzle-row-" + i).append(tile);
                    }
                }

                $(".puzzle-tile").draggable(
                    {
                        revert: true,
                        snap: true,
                        snapMode: "inner",
                        zIndex: 100
                    }
                ).droppable(
                    {
                        drop: function (event, ui) {
                            var sourceTile = ui.draggable;
                            var targetTile = $(this);

                            if (canSwapTiles(sourceTile, targetTile)) {
                                swapTiles(sourceTile, targetTile);
                            }
                        }
                    }
                );
            }

            function randomBoard() {
                var tileValues = [];
                for (i = 0; i < 15; i++) {
                    tileValues[i] = i + 1;
                }

                var randomlyOrderedTileValues = [''];
                do {
                    randomlyOrderedTileValues[(16 - tileValues.length)] = tileValues.splice(Math.floor(Math.random() * tileValues.length), 1).pop();
                } while (tileValues.length > 0);

                var board = [];
                for (i = 0; i < 4; i++) {
                    board[i] = [];
                    for (j = 0; j < 4; j++) {
                        board[i][j] = randomlyOrderedTileValues.pop();
                    }
                }
                return board;
            }

            function isSolved() {
                for (i = 0; i < 4; i++) {
                    for (j = 0; j < 4; j++) {
                        if (isNaN(currentBoard[i][j]))
                        {
                            continue;
                        }
                        if (parseInt(currentBoard[i][j]) != parseInt(orderedBoard[i][j]))
                        {
                            return false;
                        }
                    }
                }
                return true;
            }

            /************************************************************
             * Constructor
             ************************************************************/

            /*
             * Initialize board
             */
            $(targetId).append('<tbody id="puzzle-board"></tbody>');
            renderBoard(orderedBoard);

            /************************************************************
             * Public data and methods
             ************************************************************/

            return {
                reset: function() {
                    renderBoard(orderedBoard);
                },

                shuffle: function() {
                    //initialBoard = randomBoard();
                    initialBoard = [[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,'',15]];
                    renderBoard(initialBoard);
                }
            }
        };

        /**
         *  Timer Object
         */
        timer = function(targetId) {

            /************************************************************
             * Private members
             ************************************************************/

            var
                intervalId,
                totalSeconds = 0;

            function pad(val) {
                var valString = val + "";
                if (valString.length < 2) {
                    return "0" + valString;
                } else {
                    return valString;
                }
            }

            function setTime()
            {
                ++totalSeconds;
                $("#seconds").html(pad(totalSeconds % 60));
                $("#minutes").html(pad(parseInt(totalSeconds / 60)));
            }

            /************************************************************
             * Constructor
             ************************************************************/

            /*
             * Initialize timer
             */
            $(targetId).append('<i>Time: &nbsp;</i><i id="minutes">00</i>:<i id="seconds">00</i>');

            /************************************************************
             * Public data and methods
             ************************************************************/

            return {
                reset: function() {
                    window.clearInterval(intervalId);
                    totalSeconds = 0;
                    $("#minutes").text('00');
                    $("#seconds").text('00');
                },

                start: function () {
                    intervalId = window.setInterval(setTime, 1000);
                },

                getTime: function () {
                    return pad(parseInt(totalSeconds / 60)) + ':' + pad(totalSeconds % 60);
                }
            }
        };

        /**
         *  Counter Object
         */
        counter = function(targetId) {

            /************************************************************
             * Private members
             ************************************************************/

            var
                steps = 0;

            /************************************************************
             * Constructor
             ************************************************************/

            /*
             * Initialize timer
             */
            $(targetId).append('<i id="steps-title">Steps: &nbsp;</i><i id="steps-count">0</i>');

            /************************************************************
             * Public data and methods
             ************************************************************/

            return {
                reset: function() {
                    steps = 0;
                    $("#steps-count").text(steps);
                },

                incr: function () {
                    steps++;
                    $("#steps-count").text(steps);
                },

                getSteps: function () {
                    return steps;
                }
            }
        };

        $(document).ready(function() {

            var Puzzle  = puzzle("#puzzle");
            var Timer   = timer("#timer");
            var Counter = counter("#counter");

            localStorage["games"] = '[]';

            $("#start-stop").click(function() {
                switch ($(this).text()) {
                    case 'START':
                        $(this).removeClass("btn-success").addClass("btn-danger").text("STOP");
                        Puzzle.shuffle();
                        Timer.start();
                        Counter.reset();
                        break;
                    case 'STOP':
                        $(this).removeClass("btn-danger").addClass("btn-success").text("START");
                        Puzzle.reset();
                        Timer.reset();
                        Counter.reset();
                        break;
                }
            });

            $("#puzzle").bind('moved',
                function(e, data) {
                    Counter.incr();
                }
            ).bind('solved',
                function(e, data) {

                    console.log(data);

                    $("#start-stop").removeClass("btn-danger").addClass("btn-success").text("START");
                    Puzzle.reset();
                    Timer.reset();
                    Counter.reset();

                }
            );
        });
    </script>
</body>

1 个答案:

答案 0 :(得分:1)

在此处调用Puzzle.shuffle():

$("#start-stop").click(function() {
    switch ($(this).text()) {
        case 'START':
            $(this).removeClass("btn-success").addClass("btn-danger").text("STOP");
            Puzzle.shuffle();
            Timer.start();
            Counter.reset();
            break;
        case 'STOP':
            $(this).removeClass("btn-danger").addClass("btn-success").text("START");
            Puzzle.reset();
            Timer.reset();
            Counter.reset();
            break;
    }
});

初始化电路板并将其传递给renderBoard

shuffle: function() {
    //initialBoard = randomBoard();
    initialBoard = [[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,'',15]];
    renderBoard(initialBoard);
}

然后renderBoard执行此操作:

currentBoard = board;

这导致两个变量都指向同一个对象。如果要将它们分开,那么在renderBoard中,您应该克隆该对象,而不是分配它。如果你使用jQuery,那么就像这样:

currentBoard = [];
$.extend(currentBoard, board);