2013-07-01 106 views
0
<!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> 

很明显,这里并不是完整的21点游戏。这只是一个测试,通过在洗牌之前和之后打印两个副本(数组)的内容来查看洗牌数组是否工作正常。 我目前只使用8张卡片,4个2和4个3。 什么我从这个得到的是:洗牌阵列javascript

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中做了类似的工作,并且工作完美,但我不确定这里有什么问题。 感谢您提前任何答案!

回答

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

您可以阅读有关费雪耶茨方法,在这里: 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]); 
      } 
+0

非常感谢!完美工作。现在,它已经可以工作了,我将不得不查看Fisher Yates函数并充分理解它,并且还要了解所有数组方法之间的差异。我认为现在可能需要比我想创建这个21点游戏更长的时间,但我仍会继续进行 –

+0

一个问题:'while(--i)'是什么意思? –

+0

@ DennisCallanan - 'while(--i)'表示减少'i',如果结果为真(例如非零),则继续使用while循环。如果减量后'i'的值为零,则停止'while'循环。 – jfriend00

0

你得到一个随机值,而不是随机指标进入甲板

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

这将导致新的甲板上重复。 –

1

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

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

我对此有点担心 - 虽然它看起来不错,但它有可能(取决于正在使用的排序,我认为),因为它永远不会返回? JavaScript可能使用了一种不适用的排序方式,因为它们通常是最快的,头脑。 – meiamsome

+0

传递给排序的函数应该为任何两个值返回一致结果,而不是随机结果。这可能很麻烦。 – jfriend00

+2

显然它不是那么伟大:http://www.robweir.com/blog/2010/02/microsoft-random-browser-ballot.html –

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

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

r递增r = 1

r小于deck.length ,继续

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

r为增加r = 2

r不低于deck.length再少,循环完成,但只有一半,其中传递的元素!

+1

pop不接受参数。 –

+0

@JoeFrambach正确的是,修复了 – meiamsome

+1

有趣的是,自从我在公车上以后,我在手机上输入了同样的东西。其他人纠正我,我不能让“编辑”按钮工作,所以我刚刚删除它。有一个upvote。 –

0

第一个问题开始于for循环,您可以在该循环中随机化卡组。您需要在之前创建一个新变量,其中包含甲板的长度。请参阅:

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

什么你怎么回事是r增加1在同一时间deck.length减少 1(由于for循环的pop)。所以,这就是为什么你只能在你洗牌的牌组中获得四张“牌”。第二个问题是你没有将卡片插入新卡片组,你自己就是randomindex

此代码应该做的伎俩:

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

(PS:本来,无论是在上述for循环的语句有末分号。)

编辑:你也可以使用while()循环。见meiamsome's answer

编辑2:正如乔在下面提到的,pop()没有参数。 splice()做你想要完成的。

+2

流行音乐没有参数。 –

+0

你也可以这样做'for(var r = deck.length; r> 0; r - )' – meiamsome

+0

根据@JoeFrambach,你应该用'deck.splice(randomindex,1)替换'deck.pop(randomindex) )',以防万一你被卡住了。 – meiamsome

0

这里是阿迪·奥斯马尼的这个实现的选择:

function shuffle(array) { 
    var rand, index = -1, 
    length = array.length, 
    result = Array(length); 
    while (++index < length) { 
    rand = Math.floor(Math.random() * (index + 1)); 
    result[index] = result[rand]; 
    result[rand] = array[index]; 
    } 
    return result; 
}