小直(的Yahtzee)算法算法、Yahtzee

2023-09-11 07:04:36 作者:青色发尾

我创建了一个可用的JavaScript函数来检查的5个号码的阵列小直筒,在游戏的Yahtzee我正在做。我测试过它没有结束,我相信它工作的时间100%,但它也可能是所有的时间被有效了最严重的算法。这里是什么样子:

I have created a working javascript function to check an array of 5 numbers for a small straight, in a Yahtzee game I'm making. I've tested it to no end and I'm confident it works 100% of the time, but it is also probably the worst algorithm of all time in terms of being efficient. Here is what it looks like:

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;
}

我的策略是:

My strategy is to:

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

我的问题:

有谁知道我可以改善这种方法的方法吗?这似乎可笑可怕的我,但我想不出更好的方式来做到这一点,至少它的工作原理。

Does anyone know a way that I can improve this method? It seems ridiculously terrible to me but I can't think of a better way to do this and it at least works.

推荐答案

既然你正在实施的Yahtzee游戏您presumably需要测试的不仅仅是小直道等图案,所以这将是更好的创建值调用该函数,这样你可以用它们在所有测试中,而不是越来越小直测试里面的DOM元素值之前数组。

Given that you're implementing a Yahtzee game you presumably need to test for other patterns beyond just small straights, so it would be better to create the array of values before calling the function so that you can use them in all tests, rather than getting the values from the DOM elements inside the small straight test.

不管怎样,下面是来到了我心中的第一种方式直复presenting五六面的骰子值的数组中测试的一个小:

Anyway, here's the first way that came to my mind to test for a small straight within an array representing the values of five six-sided dice:

    // 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
    }

请注意,您可以按使用这个code数字数组:

Note that you can sort an array of numbers using this code:

r2.sort(function(a,b){return a-b;});

...但在你的​​情况下,数组中的值是字符串,因为他们从DOM元素的。价值属性来了,所以默认的字符串的排序将与 r2.sort()。无论哪种方式,你不需要自己的排序例程,因为JavaScript的提供之一。

...but in your case the values in the array are strings because they came from the .value attribute of DOM elements, so a default string sort will work with r2.sort(). Either way you don't need your own sort routine, because JavaScript provides one.

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

If you assume that you can just put the five values as a string as above you can implement tests for all possible combinations as a big if/else like this:

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.

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