2017-08-04 23 views
0

我有一個程序,可以從普通卡組中發出10張隨機卡(並且不會將它們放回)。
有時,當我在我收到以下錯誤消息shell中運行該腳本:php - 我收到「未定義的偏移量」錯誤消息,我不知道爲什麼?

PHP Notice: Undefined offset: ..... on line 15

我的代碼如下:

<?php 
    $deck = array(
     array('A', 2, 3, 4, 5, 6, 7, 8, 9, 10, 'J', 'Q', 'K'), //club 
     array('A', 2, 3, 4, 5, 6, 7, 8, 9, 10, 'J', 'Q', 'K'), //spade 
     array('A', 2, 3, 4, 5, 6, 7, 8, 9, 10, 'J', 'Q', 'K'), //heart 
     array('A', 2, 3, 4, 5, 6, 7, 8, 9, 10, 'J', 'Q', 'K') //diamond 
); 

    $i = 0; 
    for ($i = 1; $i <= 10; $i++) { 
     $a = rand(0, 3);  //card's suit 
     $nr = count($deck[$a]); //how many cards of the suit are available? 
     $b = rand(0, $nr--); //pick a random number out of the available ones 
     $card = $deck[$a][$b]; //pick a card [---LINE 15---] 

     switch ($a) { 
      case 0: 
       $c = "club"; 
       break; 
      case 1: 
       $c = "spade"; 
       break; 
      case 2: 
       $c = "heart"; 
       break; 
      case 3: 
       $c = "diamond"; 
       break; 
     } 

     echo $c . " " . $card . "\n" . "remaining: " . $nr . "\n"; 

     unset($deck[$a][$b]); //remove the card you drew 
     array_values($deck[$a]); //rearrange the index of the suit you drew the card from 
    } 
?> 

有人能幫助新手嗎?

+1

爲什麼不打印$ a和$ b來檢查它返回的內容?然後嘗試查找該套牌是否具有該索引 – Exprator

+0

因爲你是'unset()'牌。它們不再存在於數組中。你的腳本可能會嘗試給出重複的卡片。 – BlitZ

+2

'$ nr - '只在調用rand函數後遞減,你必須使用' - $ nr'或者'$ nr-1'。 – xander

回答

2

你有$b = rand(0, --$nr);

這是因爲$foo --是一個後減量替換$b = rand(0, $nr--);:使用後VAR值減少。

而且在最後一行,你不使用你應該這樣做的array_value()結果:http://php.net/manual/en/language.operators.increment.php

+0

@ user3187119看到我編輯array_values($ deck [$ a] );' –

+0

甜,這兩個命題都很好!非常感謝:) – user3187119

0

:對前/後遞增遞減和這裏$deck[$a] = array_values($deck[$a]);

Pre/post increment and decrement

更多信息如果您取消設置$ deck位置數組,並且在其他一些迭代中嘗試訪問同一個位置,它會給您一個未定義的偏移量錯誤,因爲該偏移量不再存在。

+0

這就是我使用array_values($ deck [$ a]);對於 – user3187119

+0

這就是爲什麼函數'array_values()'在循環結束時被調用的原因:它產生一個包含相同值的數組,然後將作爲參數傳遞的數組作爲參數傳遞,但使用連續的數字索引(無論它們的鍵是什麼)。清理其中未設置內容的陣列非常棒。 – ksjohn

0

首先,感謝提供誤差與線暗示線在你proviced的代碼是什麼,真正的讚賞。

count($deck[$a])返回該數組中當前有多少條目。舉個例子,在你開始的時候,它會返回13.因爲數組的第一個索引是0,所以國王的索引將是12.

這意味着每次你的代碼試圖選擇一張卡時,有一個機會出$nr它將使用的抵消將不存在。

$nr = count($deck[$a]) - 1; 通過從開始的數組中刪除1,$nr在設置時具有正確的值。這種方式分配其值應糾正你的問題,同時也刪除下一行遞減它的需要:

$nr = count($deck[$a]) - 1; 
$b = rand(0, $nr); 
0

這將消除您的錯誤:

代碼:(Demo

$ranks=['A',2,3,4,5,6,7,8,9,10,'J','Q','K']; 
$suits=['club','spade','heart','diamond']; // store suit names, avoid switch-case 
foreach($suits as $suit){ 
    shuffle($ranks); // shuffle once, avoid future rand() on subarray 
    $deck[]=$ranks; // store shuffled suit cards 
} 
for($x=0; $x<10; ++$x){ 
    $i=rand(0,3); // pick random suit/subarray key 
    echo $suits[$i],' ',array_pop($deck[$i]),' remaining ',sizeof($deck[$i]),"\n"; 
} 

這不僅可以完成您的工作,還可以減少額外的函數調用。

p.s.我喜歡卡片。

相關問題