小直(Yahtzee)算法

Tri*_*y12 1 javascript algorithm

我已经创建了一个工作的javascript函数来检查一个小数字的5个数字的数组,在我正在制作的Yahtzee游戏中.我已经对它进行了测试,并且我确信它可以在100%的时间内正常工作,但它也可能是有效率方面有史以来最差的算法.这是它的样子:

function calcSmstraight() {
        var sum = 0;
        var r = new Array();
        var r2 = new Array();
        var counter = 0;
        var temp;
        var bool = false;
        var bool2 = false;
        r[0] = document.getElementById('setKeep1').value;
        r[1] = document.getElementById('setKeep2').value;
        r[2] = document.getElementById('setKeep3').value;
        r[3] = document.getElementById('setKeep4').value;
        r[4] = document.getElementById('setKeep5').value;

        // Move non-duplicates to new array
        r2[0] = r[0];
        for(var i=0; i<r.length; i++) {
            for(var j=0; j<r2.length; j++) {
                if(r[i] == r2[j]) {
                    bool2 = true;   // Already in new list
                }
            }
            // Add to new list if not already in it
            if(!bool2) {
                r2.push(r[i]);
            }
            bool2 = false;
        }
        // Make sure list has at least 4 different numbers
        if(r2.length >= 4) {
            // Sort dice from least to greatest
            while(counter < r2.length) {
                if(r2[counter] > r2[counter+1]) {
                    temp = r2[counter];
                    r2[counter] = r2[counter+1];
                    r2[counter+1] = temp;
                    counter = 0;
                } else {
                    counter++;
                }
            }
            // Check if the dice are in order
            if(((r2[0] == (r2[1]-1)) && (r2[1] == (r2[2]-1)) && (r2[2] == (r2[3]-1)))
                || ((r2[1] == (r2[2]-1)) && (r2[2] == (r2[3]-1)) && (r2[3] == (r2[4]-1)))) {
                bool = true;
            }
        }

        if(bool) {
            // If small straight give 30 points
            sum = 30;
        }

        return sum;
}
Run Code Online (Sandbox Code Playgroud)

我的策略是:

1) Remove duplicates by adding numbers to a new array as they occur

2) Make sure the new array is at least 4 in length (4 different numbers)

3) Sort the array from least to greatest

4) Check if the first 4 OR last 4 (if 5 in length) numbers are in order
Run Code Online (Sandbox Code Playgroud)

我的问题:

有谁知道我可以改进这种方法的方法?这对我来说似乎很可怕,但我想不出更好的方法来做到这一点,至少可行.

nnn*_*nnn 5

鉴于您正在实施Yahtzee游戏,您可能需要测试除了小直道之外的其他模式,因此在调用函数之前创建值数组会更好,这样您就可以在所有测试中使用它们,而不是获取来自小直线测试中的DOM元素的值.

无论如何,这是我想到的第一种测试代表五个六面骰子值的数组中的小直线的方法:

    // assume r is an array with the values from the dice
    r.sort();
    if (/1234|2345|3456/.test(r.join("").replace(/(.)\1/,"$1") {
        // is a small straight
    }
Run Code Online (Sandbox Code Playgroud)

请注意,您可以使用以下代码对数字数组进行排序:

r2.sort(function(a,b){return a-b;});
Run Code Online (Sandbox Code Playgroud)

...但在您的情况下,数组中的值是字符串,因为它们来自.valueDOM元素的属性,因此默认字符串排序将起作用r2.sort().无论哪种方式,您都不需要自己的排序例程,因为JavaScript 提供了一个例程.

编辑:如果你认为你可以把这五个值作为一个字符串,你可以实现所有可能的组合测试作为一个大的if/else像这样:

r.sort();
r = r.join("");
if (/(.)\1{4}/.test(r)) {
    alert("Five of a Kind");
} else if (/(.)\1{3}/.test(r)) {
    alert("Four of a Kind");
} else if (/(.)\1{2}(.)\2|(.)\3(.)\4{2}/.test(r)) {
    alert("Full House");
} else if (/(.)\1{2}/.test(r)) {
    alert("Three of a Kind");
} else if (/1234|2345|3456/.test( r.replace(/(.)\1/,"$1") ) {
    alert("Small Straight");
} // etc.
Run Code Online (Sandbox Code Playgroud)

演示:http://jsfiddle.net/4Qzfw/

  • @SSH - `else if (/12345|23456/.test(r)) ...` (2认同)