PHP扑克牌随机发放算法

针对52张扑克牌及4种花色随机发放。

扑克牌算法

/**
 * 随机花色及点数:这种算法能够保证抽几张牌时不会把抽过的排又抽一遍
 * 
 * 牌数:共有52张牌,编号从0到51
 * 花色:分为四种牌【黑桃 / 红桃 / 方块 / 梅花】,每种牌有13张
 * 关系:4种牌分别对应 1-12, 13-25, 26-38, 39-51 的数字和花色
 * 打乱:将上述对应的数组打乱排序,抽出打乱后的数组中的前4个数字
 * 取色:除以13就是这张牌的花色(最开始已经规定好了他们的一一对应关系)
 * 取牌:对13取余,余数就是这张牌的点数
 **/
date_default_timezone_set('Asia/Shanghai');
set_time_limit(0);
header("Content-Type:text/html;charset=UTF-8");

$num = 52; //一副牌54张
$deck = array();

//扑克牌比牌大小
//suits 数组存放花色, 数组下标分别是: 0,1,2,3
$suits = ["黑桃","红桃","梅花","方块"]; //array()
//$suits = ["Spades","Hearts","Clubs","Diamonds"]; //英文对应

//ranks 数组存放点数, 数组下标分别是: 0,1,...11,12
$ranks = ["A","2","3","4","5","6","7","8","9","10","J","Q","K"];
//$ranks = ["Ace","2","3","4","5","6","7","8","9","10","Jack","Queen","King"]; //英文对应

//初始化: 数组deck初始化为1到51
for( $i = 0; $i < $num; $i++ ){
	$deck[$i] = $i;
}


//将牌随机打散: 有两个方案
/*
//方案1: 将数组deck打乱,循环一遍,循环的每个元素deck[i]和任意产生的随机数下标j将deck[i],deck[j]互换。
for( $i=0; $i<$num; $i++ ){
	$index = (int)rand(0, $num - 1);
	$temp = $deck[$i];
	$deck[$i] = $deck[$index];
	$deck[$index] = $temp;
}
*/

//方案2: shuffle()函数像洗扑克牌一样把这个数组里面的元素打乱位置
shuffle($deck);

//发牌 5 张
for($i=0; $i<5; $i++){
	//花色 0,1,2,3
	$suit = $suits[$deck[$i] / 13]; //除以13
	
	//点数 A,2,...11,12
	$rank = $ranks[$deck[$i] % 13];
	
	echo "当前您抽到的是第" . $deck[$i] . "张牌:" . $suit . $rank . " <br/>\r\n";	
}

打印结果

当前您抽到的是第20张牌:梅花8
当前您抽到的是第40张牌:红桃2
当前您抽到的是第4张牌:黑桃5
当前您抽到的是第5张牌:黑桃6
当前您抽到的是第21张牌:梅花9

拓展用法

将某一数组打散,并随机不重复的抽取其中指定个数的元素。

//先从 1~100 中随机读取10个数字生成一个示例数组
$ids = array();
while( count($ids) < 10 ){
	$ids[] = mt_rand(1, 100);
	$ids = array_unique($ids);
}
//$ids = implode(',', $ids);

//shuffle()函数像洗扑克牌一样把这个数组里面的元素打乱位置
shuffle($ids);

//随机抽取其中5个
for($i=0; $i<5; $i++){
	echo $ids[$i] . "\n";
}

参与评论