tami: Optimierung von Code (Spiel 2048)

Beitrag lesen

hi,

aus Lerngründen würde ich gerne folgenden von mir verfassten Code optimieren. Ich hatte bereits versucht, mehrere Funktionen innerhalb andere Funktionen (zB. init) zu deklarierern, weil sie nur dort benötigt werden, aber da schmierte mir der Browser ab. Ich vermute, dass er sich da mit dem Speicher und den closures verhaspelt hat.

Habe jetzt alle Funktionen in einem Objekt gehängt, um den globalen Scope nicht zu verschmutzen. Auch wenn die Funktionen teilweise nur innerhalb einer anderen Funktion einmal benutzt werden. Habe aber auch Funktionen innerhalb von Funktionen (allerdings nur einfach verschachtelt) defniniert, weil sie eben nur da gebraucht werden.

Für Tipps und Tricks (aus Gründen des allgemeinen Verständnisses) wäre ich dankbar. Hier der code:

  
<html>  
<head>  
<style type="text/css">
table, td {  
    border: 1px solid black;  
    margin: auto;  
    font-weight: bold;  
    color: white;  
    font-size: 2em;  
    font-family: arial;	  
}  
td {  
    height: 100px;  
    width: 100px;  
    vertical-align: center;  
    text-align: center;  
}
</style>  
</head>  
<body id="body">  
<div id="div2048"></div>  
<script>
var MyColors = ["white", "red", "green", "blue", "pink", "brown", "purple", "yellow", "orange", "pink", "cyan", "crimson"];  
var My2048 = {  
    "cells" : [],  
    "htmlCells" : [],  
    "tmpTr" : [],  
    "calcRow" : function (row) {  
        "use strict";  
        var tmpRow = [],  
            calc2,  
            i;  
        // calc two cells if equal - tmpRow is read- and writeCell2Htmlable within function  
        calc2 = function (calcPos) {  
            if (tmpRow[calcPos] === tmpRow[calcPos - 1]) {  
                tmpRow[calcPos - 1] *= 2;  
                tmpRow.splice(calcPos, 1);  
            }  
        };  
        //delete empty cells - copy to tmpRow array  
        for (i = 0; i < row.length; i += 1) {  
            if (row[i] !== 1) {  
                tmpRow.push(row[i]);  
            }  
        }  
        // walk through array to call "calc two cells if equal"  
        for (i = 1; i < tmpRow.length; i += 1) {  
            calc2(i);  
        }  
        // fill up with empty cells at the end for return  
        while (tmpRow.length < 4) {  
            tmpRow.push(1);  
        }  
        return tmpRow;  
    },  
    "iterate2Dim" : function (callBack, res) {  
        "use strict";  
        var i,  
            j;  
        for (i = 0; i < 4; i += 1) {  
            for (j = 0; j < 4; j += 1) {  
                callBack(i, j, res);  
            }  
        }  
        return res;  
    },  
    "setNewNumber" : function () {  
        "use strict";  
        var tmpArray = [],  
            collectEmptyCellIndices,  
            myRand;  
        collectEmptyCellIndices = function (i, j, res) {  
            if (My2048.cells[i][j] === 1) {  
                res.push([i, j]);  
            }  
        };  
        tmpArray = My2048.iterate2Dim(collectEmptyCellIndices, tmpArray);  
        if (tmpArray.length === 0) {  
            alert("game over");  
        } else {  
            myRand = Math.floor((Math.random() * tmpArray.length));  
            My2048.cells[tmpArray[myRand][0]][tmpArray[myRand][1]] = 2;  
        }  
    },  
    "writeCell2Html" : function (i, j) {  
        "use strict";  
        My2048.htmlCells[i][j].innerHTML = My2048.cells[i][j];  
        My2048.htmlCells[i][j].style.backgroundColor = MyColors[Math.log(My2048.cells[i][j]) / Math.log(2)];  
    },  
    "move" : function (keyCode) {  
        "use strict";  
        var flipMyCells,  
            i,  
            tmpRow = [],  
            tmpTable = [];  
        flipMyCells = function () {  
            var j,  
                cache;  
            for (i = 0; i < 3; i += 1) {  
                for (j = i + 1; j < 4; j += 1) {  
                    cache = My2048.cells[i][j];  
                    My2048.cells[i][j] = My2048.cells[j][i];  
                    My2048.cells[j][i] = cache;  
                }  
            }  
        };  
        if (keyCode === 38 || keyCode === 40) {  
            flipMyCells();  
        }  
        tmpTable = My2048.cells;  
        for (i = 0; i < 4; i += 1) {  
            tmpRow = tmpTable[i];  
            if (keyCode === 39 || keyCode === 40) {  
                tmpRow.reverse();  
            }  
            tmpRow = My2048.calcRow(tmpRow);  
            if (keyCode === 39 || keyCode === 40) {  
                tmpRow.reverse();  
            }  
            tmpTable[i] = tmpRow;  
            tmpRow = [];  
        }  
        if (keyCode === 38 || keyCode === 40) {  
            flipMyCells();  
        }  
        My2048.cells = tmpTable;  
    },  
    "init" : function () {  
        "use strict";  
        var div2048 = document.getElementById("div2048"),  
            myTable = document.createElement("table"),  
            i,  
            fillCellsAndBuildTable = function (i, j) {  
                var tmpHtmlTd;  
                My2048.cells[i][j] = 1;  
                tmpHtmlTd = document.createElement("td");  
                My2048.tmpTr[i].appendChild(tmpHtmlTd);  
                My2048.htmlCells[i].push(tmpHtmlTd);  
            };  
        div2048.appendChild(myTable);  
        for (i = 0; i < 4; i += 1) {  
            My2048.tmpTr[i] = document.createElement("tr");  
            myTable.appendChild(My2048.tmpTr[i]);  
            My2048.cells[i] = [];  
            My2048.htmlCells[i] = [];  
        }  
        document.getElementsByTagName("body")[0].onkeydown = function (event) {  
            event = event || window.event;  
            if (36 < event.keyCode && event.keyCode < 41) {  
                My2048.move(event.keyCode);  
                My2048.setNewNumber();  
                My2048.iterate2Dim(My2048.writeCell2Html);  
            }  
        };  
        My2048.iterate2Dim(fillCellsAndBuildTable, myTable);  
        My2048.setNewNumber();  
        My2048.iterate2Dim(My2048.writeCell2Html);  
    }  
};  
My2048.init();
</script>  
</body>  

bzw. http://html-ag.wvs-berlin.de/Javascript/2048.js.html.

Mit den Pfeiltasten rauf/runter/rechts/links kann man spielen ;-).

(ach so, der Code ist jslint-konform, ist so ein tick von mir)

mfg

tami