改组数组javascript

时间:2013-07-01 16:46:42

标签: javascript html html5 javascript-events

<!doctype html>
<html lang="en">
    <head>
        <meta charset="utf=8" />
        <title>Blackjack</title>
        <link rel="stylesheet" href="blackjack.css" />

        <script type="text/javascript">

            var H2 = 2; var S2 = 2; var D2 = 2; var C2 = 2;
            var H3 = 3; var S3 = 3; var D3 = 3; var C3 = 3; 



            var deck = new Array(H2, S2, D2, C2, H3, S3, D3, C3);

            var new_deck = new Array();

            var r;

            document.write("deck = ")

            for (r =0; r<deck.length; r++){
                document.write(deck[r]);
                }

            document.write("</br>")

            document.write("new deck = ")

            for (r=0; r<new_deck.length; r++){
                document.write(new_deck[r]);
                }

            document.write("</br>")

            for (r=0;r<deck.length;r++){
                var randomindex = Math.floor(Math.random()*deck.length);
                new_deck.push(randomindex)
                deck.pop(randomindex)
                }

            document.write("deck = ")

            for (r =0; r<deck.length; r++){
                document.write(deck[r]);
                }

            document.write("</br>")

            document.write("new deck = ")

            for (r=0; r<new_deck.length; r++){
                document.write(new_deck[r]);
                }

            document.write("</br>")


        </script>

    </head>
    <body>
    </body>
</html>

显然这不是这里完整的二十一点游戏。这只是一个测试,看看是否通过在shuffle之前和之后打印两个deck(数组)的内容来改变阵列的工作原理。 我现在只使用8张牌,4张2张和4张牌。 我从中得到的是:

deck = 22223333
new deck = 
deck = 2222
new deck = 7502

我希望得到的是:

deck = 22223333
new deck = 
deck = 
new deck = 23232323 (or any of the 8 numbers, generated randomly)

所以应该洗掉那8张牌,我做错了什么? 我只是javascript的新手,但我之前使用过一些python。我在python中做了类似的事情并且工作得很好,但是我不确定这里有什么问题。 谢谢你提前给出任何答案!!

5 个答案:

答案 0 :(得分:3)

您的new_deck只包含索引,而不是值,并且您在选择下一个随机值之前不会删除先前选择的值。 .pop()不接受参数,因此您无法使用它删除特定索引 - 您必须使用.splice()。总而言之,由于多种原因,您没有获得新值的数组。

如果你只是想要一个简单的方法来随机化一个数组而不重新发明轮子并且知道随机性实际上运行良好,你可以使用它:

function fisherYates ( myArray ) {
  var i = myArray.length;
  if ( i == 0 ) return false;
  while ( --i ) {
     var j = Math.floor( Math.random() * ( i + 1 ) );
     var tempi = myArray[i];
     var tempj = myArray[j];
     myArray[i] = tempj;
     myArray[j] = tempi;
   }
}

您可以在此处阅读Fisher-Yates方法:http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle

您可以阅读有关其他一些随机化方法无效的原因,您可以在此处阅读:http://www.robweir.com/blog/2010/02/microsoft-random-browser-ballot.html

所以,你会替换它:

       for (r=0;r<deck.length;r++){
            var randomindex = Math.floor(Math.random()*deck.length);
            new_deck.push(randomindex)
            deck.pop(randomindex)
            }

        document.write("deck = ")

        for (r =0; r<deck.length; r++){
            document.write(deck[r]);
            }

        document.write("</br>")

        document.write("new deck = ")

        for (r=0; r<new_deck.length; r++){
            document.write(new_deck[r]);
            }

用这个:

        document.write("deck = ")

        for (r =0; r<deck.length; r++){
            document.write(deck[r]);
            }

        document.write("</br>")

        document.write("shuffled deck = ")

        // shuffle the deck and then output it
        fisherYates(deck);

        for (r=0; r<deck.length; r++){
            document.write(deck[r]);
            }

答案 1 :(得分:1)

另一种超级简单的数组排序技术:

 deck.sort(function() { return Math.random()-0.5})

答案 2 :(得分:1)

你想改变你的洗牌:

while(deck.length > 0 ){ //for loop won't work
    var randomindex = Math.floor(Math.random()*deck.length);
    new_deck.push(deck[randomindex]);//Move onto new stack
    deck.splice(randomindex,1); //Take from old.
}

这就是为什么for循环不起作用的原因: 说deck.length = 4

开始for循环:r = 0

一个项目被推到新的堆栈&amp;弹出:deck.length = 3

r递增r = 1

r小于deck.length,继续

一个项目被推到新的堆栈&amp;弹出:deck.length = 2

r递增r = 2

r不再小于deck.length,循环已完成,但只有一半的元素被转移!

答案 3 :(得分:0)

你得到一个随机值,而不是甲板上的随机索引

for (r=0;r<deck.length;r++){
    var randomindex = Math.floor(Math.random()*deck.length);
    new_deck.push(deck[randomindex]);
}

答案 4 :(得分:0)

第一个问题从for循环开始,你随机化甲板。您需要在包含套牌长度的循环之前创建一个新变量。参见:

for (r=0;r<deck.length;r++){
    var randomindex = Math.floor(Math.random()*deck.length);
    new_deck.push(randomindex)
    deck.pop(randomindex)
}

您在此处发现的是rdeck.length 减少的同时增加1(由于pop for循环)。所以,这就是为什么你在洗牌的甲板上只得到四张“牌”。第二个问题是你没有push将卡片放入新套牌中,而是push randomindex本身。{/ p>

这段代码可以解决问题:

var i = deck.length;
for (r=0;r<i;r++){
    var randomindex = Math.floor(Math.random()*deck.length);
    new_deck.push(deck.splice(randomindex, 1));
}

(P.S。:最初,上述for循环中的任何一个陈述都没有分号。)

修改:您还可以使用while()循环。请参阅meiamsome's answer

编辑2:正如Joe在下面提到的那样,pop()没有参与。 splice()执行您要完成的任务。