我有一个程序可以从普通牌组中发出10张随机牌(并且不会将它们放回去)。
有时当我在shell中运行脚本时,我收到以下错误消息:
PHP注意:未定义的偏移量:.....第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
}
?>
有人可以帮助新手吗?
答案 0 :(得分:2)
您必须将$b = rand(0, $nr--);
替换为$b = rand(0, --$nr);
这是因为$foo --
是一个后递减:在使用var之后,该值会递减。
同样在最后一行,您不能使用array_value()
的结果,您应该这样做:$deck[$a] = array_values($deck[$a]);
有关前/后递增和递减的更多信息:http://php.net/manual/en/language.operators.increment.php
答案 1 :(得分:0)
如果取消设置$ deck位置数组,并且在for的某些其他迭代中尝试访问同一位置,则会给出未定义的偏移量错误,因为该偏移量不再存在。
答案 2 :(得分:0)
首先,感谢您提供错误行和,暗示您所提供的代码中的行是什么,非常感谢。
count($deck[$a])
返回该数组当前的条目数。例如,在你的for的开头,它将返回13.由于数组的第一个索引是0
,国王的索引将是12。
这意味着每次您的代码尝试选择一张卡时,$nr
都有一次机会,它将使用的偏移量将不存在。
$nr = count($deck[$a]) - 1;
通过从一开始就从数组计数中删除1,$nr
在设置时就具有正确的值。以这种方式分配其值应该可以纠正您的问题,并且还可以在下一行中删除它的需要:
$nr = count($deck[$a]) - 1;
$b = rand(0, $nr);
答案 3 :(得分: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。我喜欢卡片。