2013-07-01 108 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; 
}