0

我正在尝试创建一个 Javascript 纸牌游戏,但我需要匹配列表中的 4 个后续数字。但是我总是创建一些疯狂的分层循环,例如:

cards = [{card:'h7'},{card:'c8'},{card:'h9'},{card:'st'}]
var sorted = ['7','8','9','t','j','q','k','a']      

var found4 = false
for(var i =0;i < 5;i++){
    var found = 0;        
    for(var j = 0;j < 4;j++){             
        for(var c in cards){
            if(cards[c].card.charAt(1) == sorted[i+j]){
                found++
            }
        }
    }
    if(found == 4){
        found4 = true
    }
}

有更好的方法来匹配数组吗?

一些输入示例:

'7','8','9','t'  => true
'j','q','k','a'  => true
'7','8','k','a'  => false
'j','k','7','a'  => false

(输入未排序)

4

4 回答 4

1

您可以为 Array 编写一个原型方法(您可以参考以下帖子)为

Array.prototype.contains = function(obj) {
    var i = this.length;
    while (i--) {
        if (this[i] == obj) {
            return i;
        }
    }
    return false;
}

var sorted = ['7', '8', '9', 't', 'j', 'q', 'k', 'a']

function check(arr) {
    index = sorted.contains(arr[0])
    if (index === false) {
        return false;
    }
    count = 1
    for (var i = 1; i < 4; i++) {
            sortedIndex = index + i > sorted.length ? index + i - sorted.length : index + i
        if (sorted[sortedIndex] == arr[i]) count++;
        }
        if (count == 4) {
            return true;
        }
        return false;
    }

console.log(check(['j','q','k','a']))​

你可以看到它在这里工作

于 2012-07-25T10:10:45.557 回答
0

First, your algorithm should work on all arrays (no fixed lengths etc), so lets get chars to find:

var tofind = cards.map(function(c){return c.card.charAt(1);});

When all your pieces have length one, there is a very simple function to help you:

return sorted.join("").indexOf(tofind.join(""))!=-1;

However, I don't understand your approach completely. This loop:

for (var c in cards)
    if (cards[c].card.charAt(1) == sorted[i+j])
        found++

seems odd to me. First, cards is an array, so don't use a for-in-loop. But if you search all cards for the current letter you want to match, how does this have anything to do with order?

于 2012-07-25T10:11:16.180 回答
0

我将有单独的西装和价值字段。这使得测试这些值是否有序变得更加容易。请注意,下面的代码不包括范围检查或其他验证,但我假设已经处理好了。

// Suit is [c]lubs, [d]iamonds, [h]earts, or [s]pades
// Value is from Ace (1) to King (13). Jack is 11, and Queen is 12. 
cards = [
    {suit:'h', value: 7 } // 7 of hearts
    {suit:'c', value: 8 } // 8 of clubs
    {suit:'h', value: 9 } // 9 of hearts
    {suit:'s', value: 10 } // Ten of spades
    {suit:'s', value: 11 } // Jack of spades
]

if (cards.length <= 1) 
{
    // Having 0 or 1 cards means they are, by definition, in order.
    return true;
}

// Test each card (starting with the second) to ensure that it is 
// 1 greater than it's predecessor.
var previousValue = cards[0].value;
for(var i = 1; i < cards.length; i++){
    if (previousValue + 1 != cards[i].value)
    {
         // This card is not the next card in sequence, so 
         // the hand is not in order.
         return false;
    }
}

return true;
于 2012-07-25T09:55:32.360 回答
0

使用下划线并保持数据结构的可能解决方案

function test(seq,expected) {
    var res=isSequence(seq);
    if (res===expected)
        console.log( seq.join(',')+" : success");
    else
        console.log( seq.join(',')+" : fail");
}

function isSequence(seq) {
    var sorted = ['7','8','9','t','j','q','k','a'], l=seq.length, i, ix;
    if (l===0) return true;

    ix=_.indexOf(sorted, seq[0]);
    if (ix===-1) return false;
    if (ix>sorted.length-l) return false;

    for (i=1;i<l;i++) {
        if ( sorted[ix+i]!==seq[i] )
            return false;
    }

    return true;
}

var cards = [{card:'h7'},{card:'c8'},{card:'h9'},{card:'st'}]

test( _.map(cards, function(obj) {
    return obj.card.charAt(1);
}), true );

test(['7','8','9','t'] , true);
test(['j','q','k','a'] , true);
test(['7','8','k','a'] , false);
test(['j','k','7','a'] , false);

还有一个小提琴http://jsfiddle.net/KDrDy/2/

于 2012-07-25T10:14:23.153 回答