PHP一文帶你搞懂游戲中的抽獎(jiǎng)算法
前言
沒有特別幸運(yùn),那么請(qǐng)先特別努力,別因?yàn)閼卸瓒。€矯情地將原因歸于自己倒霉。你必須特別努力,才能顯得毫不費(fèi)力。
希望:所以說,樹倒了,沒有一片雪花是無辜的,抽獎(jiǎng)都是假的,只有人家想讓你中和不想讓你中,如果大家覺得文章有幫助,歡迎點(diǎn)贊。
一、初始化獎(jiǎng)品
- id 獎(jiǎng)品的id
- pid 獎(jiǎng)品的自定義id
- type 獎(jiǎng)品類型,1、虛擬獎(jiǎng)品 2、實(shí)物獎(jiǎng)品 3、禮包碼 待擴(kuò)充
- name 獎(jiǎng)品名稱
- total 獎(jiǎng)品總數(shù)
- chance 獲獎(jiǎng)概率/抽獎(jiǎng)基數(shù)10000
- daynum 每日數(shù)量限制
- pay 充值限制
<?php $prize = [ ['id' => 1, 'pid' => 11, 'type' => 1, 'name' => '典藏英雄', 'total' => 20, 'chance' => 1000, 'daynum' => 10, 'pay' => 2000 ], ['id' => 2, 'pid' => 12, 'type' => 1, 'name' => '史詩(shī)皮膚', 'total' => 40, 'chance' => 1000, 'daynum' => 10, 'pay' => 4000 ], ['id' => 3, 'pid' => 13, 'type' => 1, 'name' => '鉆石獎(jiǎng)勵(lì)', 'total' => 80, 'chance' => 1000, 'daynum' => 10, 'pay' => 4000 ], ['id' => 4, 'pid' => 14, 'type' => 1, 'name' => '榮耀水晶', 'total' => 20, 'chance' => 1000, 'daynum' => 10, 'pay' => 8000 ] ];
獎(jiǎng)品詳情應(yīng)該從數(shù)據(jù)庫(kù)中讀出來
獎(jiǎng)品詳情應(yīng)該加入緩存,避免數(shù)據(jù)庫(kù)的壓力
二、謝謝參與
<?php $thanks_prize = [ 'id' => 0, 'pid' => 0, 'type' => 1, 'name' => '謝謝參與' ];
為填充剩余概率的獎(jiǎng)品
三、過濾抽獎(jiǎng)、如充值條件
<?php $pay_total = 7000; foreach ($prize as $key => $value) { if($value['pay'] > $pay_total) unset($prize[$key]); }
初步過濾一些必要因素,比如充值,角色創(chuàng)建時(shí)間等
四、重組概率
<?php $now_chance = array_sum(array_column($prize, 'chance')); $remain_chance = 10000 - $now_chance; $prize[] = ['id' => 0, 'pid' => 0, 'type' => 1, 'name' => '謝謝參與', 'total' => 0, 'chance' => $remain_chance, 'daynum' => 0, 'pay' => 0]; $award = []; $num = 0; foreach ($prize as $_v) { $num += $_v['chance']; $award[] = ['id' => $_v['id'], 'pid' => $_v['pid'], 'type' => $_v['type'], 'name' => $_v['name'], 'total' => $_v['total'], 'chance' => $num, 'daynum' => $_v['daynum'], 'pay' => $_v['pay']]; }
初步過濾后,重構(gòu)新的抽獎(jiǎng)信息,加入謝謝參與
第二步重組概率
五、進(jìn)行抽獎(jiǎng)
<?php $rand = mt_rand(1, 10000); $result = []; foreach ($award as $_k => $_v) { if ($_k == 0) { if ($rand > 0 && $rand <= $_v['chance']) { $result = $_v; break; } } else { if ($rand > $award[$_k - 1]['chance'] && $rand <= $_v['chance']) { $result = $_v; break; } } }
開始抽獎(jiǎng),并返回抽中的結(jié)果
六、過濾回調(diào)
<?php //此處應(yīng)該查詢數(shù)據(jù)庫(kù),查看該獎(jiǎng)品已經(jīng)抽中的數(shù)量 $yet_num = 50; if($result['pid'] != 0 && $yet_num > $result['total']) { $result = $thanks_prize; } //此處應(yīng)該查詢數(shù)據(jù)庫(kù),查看該獎(jiǎng)品今日已經(jīng)抽中的數(shù)量 $yet_today_num = 50; if($result['pid'] != 0 && $yet_today_num > $result['daynum']) { $result = $thanks_prize; }
二次過濾,獎(jiǎng)品總數(shù)的限制以及獎(jiǎng)品的每日限制等
七、最終抽獎(jiǎng)結(jié)果
<?php //刪除敏感字段 unset($result['total'],$result['chance'],$result['daynum'],$result['pay']); //返回最終抽獎(jiǎng)結(jié)果 echo json_encode([ 'prize' => $award, 'rand' => $rand, 'result' => $result ]);
八、抽獎(jiǎng)封裝成類
<?php /** * Created by PhpStorm. * User: autofelix * Date: 2020/10/30 * Time: 13:14 * Desc: 抽獎(jiǎng)算法 */ class Lottery { /** * 概率基數(shù) * @var int */ private $total_chance = 10000; /** * 謝謝參與獎(jiǎng)勵(lì) * @var array */ private $thanks_prize = [ 'id' => 0, 'pid' => 0, 'type' => 1, 'name' => '謝謝參與' ]; /** * 獎(jiǎng)池 * @var array */ private $prize = [ ['id' => 1, 'pid' => 11, 'type' => 1, 'name' => '典藏英雄', 'total' => 20, 'chance' => 1000, 'daynum' => 10, 'pay' => 2000 ], ['id' => 2, 'pid' => 12, 'type' => 1, 'name' => '史詩(shī)皮膚', 'total' => 40, 'chance' => 1000, 'daynum' => 10, 'pay' => 4000 ], ['id' => 3, 'pid' => 13, 'type' => 1, 'name' => '鉆石獎(jiǎng)勵(lì)', 'total' => 80, 'chance' => 1000, 'daynum' => 10, 'pay' => 4000 ], ['id' => 4, 'pid' => 14, 'type' => 1, 'name' => '榮耀水晶', 'total' => 20, 'chance' => 1000, 'daynum' => 10, 'pay' => 8000 ] ]; /** * Lottery constructor. */ public function __construct() { } /** * @return int */ private function get_user_pay() { //這里應(yīng)該調(diào)用接口,返回用戶正確的充值信息 return 3000; } /** * 重構(gòu)獎(jiǎng)池、重組概率 * @return array */ private function init_lottery_pond() { $award = []; //充值限制 $user_pay = $this->get_user_pay(); foreach ($this->prize as $key => $value) { if($value['pay'] <= $user_pay) unset($this->prize[$key]); } //加入謝謝惠顧 $now_chance = array_sum(array_column($this->prize, 'chance')); $remain_chance = $this->total_chance - $now_chance; $this->prize[] = ['id' => 0, 'pid' => 0, 'type' => 1, 'name' => '謝謝參與', 'total' => 0, 'chance' => $remain_chance, 'daynum' => 0, 'pay' => 0]; //重組概率 $num = 0; foreach ($this->prize as $_v) { $num += $_v['chance']; $award[] = ['id' => $_v['id'], 'pid' => $_v['pid'], 'type' => $_v['type'], 'name' => $_v['name'], 'total' => $_v['total'], 'chance' => $num, 'daynum' => $_v['daynum'], 'pay' => $_v['pay']]; } return $award; } /** * 獲取抽獎(jiǎng)結(jié)果 * @return array */ public function get_prize() { $award = $this->init_lottery_pond(); $rand = mt_rand(1, $this->total_chance); $result = []; foreach ($award as $_k => $_v) { if ($_k == 0) { if ($rand > 0 && $rand <= $_v['chance']) { $result = $_v; break; } } else { if ($rand > $award[$_k - 1]['chance'] && $rand <= $_v['chance']) { $result = $_v; break; } } } $result = $this->filter($result); return $result; } /** * 抽獎(jiǎng)過濾回調(diào)函數(shù) * @param $result * @return array */ public function filter($result) { //獎(jiǎng)品總數(shù)限制,此處應(yīng)該查數(shù)據(jù)庫(kù) $yet_num = 50; if($result['pid'] != 0 && $yet_num > $result['total']) { $result = $this->thanks_prize; } //獎(jiǎng)品每日數(shù)量限制,此處應(yīng)該查數(shù)據(jù)庫(kù) $yet_today_num = 50; if($result['pid'] != 0 && $yet_today_num > $result['daynum']) { $result = $this->thanks_prize; } //不暴露敏感信息 unset($result['total'], $result['chance'], $result['daynum'], $result['pay'] ); return $result; } private function __clone() { } } echo json_encode((new Lottery())->get_prize());
以上就是PHP一文帶你搞懂游戲中的抽獎(jiǎng)算法的詳細(xì)內(nèi)容,更多關(guān)于PHP抽獎(jiǎng)算法的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
一個(gè)簡(jiǎn)單安全的PHP驗(yàn)證碼類 附調(diào)用方法
這篇文章主要為大家分享了一個(gè)簡(jiǎn)單安全的PHP驗(yàn)證碼類,附調(diào)用方法,感興趣的小伙伴們可以參考一下2016-06-06PHP實(shí)踐教程之過濾、驗(yàn)證、轉(zhuǎn)義與密碼詳解
我們?cè)陂_發(fā)應(yīng)用時(shí),一般有個(gè)約定:不要信任任何來自不受自己控制的數(shù)據(jù)源中的數(shù)據(jù)。所以這個(gè)時(shí)候就用到了這篇文章介紹的內(nèi)容,本文主要給大家介紹了關(guān)于PHP實(shí)踐教程之過濾、驗(yàn)證、轉(zhuǎn)義與密碼的相關(guān)資料,需要的朋友可以參考借鑒,下面來一起看看吧。2017-07-07php生成短網(wǎng)址/短鏈接原理和用法實(shí)例分析
這篇文章主要介紹了php生成短網(wǎng)址/短鏈接原理和用法,結(jié)合實(shí)例形式分析了php生成短網(wǎng)址/短鏈接的基本原理、實(shí)現(xiàn)方法與相關(guān)注意事項(xiàng),需要的朋友可以參考下2020-05-05PHP接收json 并將接收數(shù)據(jù)插入數(shù)據(jù)庫(kù)的實(shí)現(xiàn)代碼
這篇文章主要介紹了PHP接收json 并將接收數(shù)據(jù)插入數(shù)據(jù)庫(kù)的實(shí)現(xiàn)代碼,需要的朋友可以參考下2015-12-12PHP輸出圖像imagegif、imagejpeg與imagepng函數(shù)用法分析
這篇文章主要介紹了PHP輸出圖像imagegif、imagejpeg與imagepng函數(shù)用法,結(jié)合實(shí)例形式較為詳細(xì)的分析了imagegif()、imagejpeg()、imagepng()和imagewbmp()函數(shù)的功能、參數(shù)含義及使用技巧,需要的朋友可以參考下2016-11-11shopex中集成的站長(zhǎng)統(tǒng)計(jì)功能的代碼簡(jiǎn)單分析
shopex中集成了一鍵開啟站長(zhǎng)統(tǒng)計(jì)功能,而無需去CNZZ注冊(cè),在phpcms,phpwind等中也都有類似的功能,下面是對(duì)這個(gè)功能的簡(jiǎn)單分析,以后也可以偷偷用在自己的網(wǎng)站中,呵呵。2011-08-08php實(shí)現(xiàn)的微信分享到朋友圈并記錄分享次數(shù)功能
這篇文章主要介紹了php實(shí)現(xiàn)的微信分享到朋友圈并記錄分享次數(shù)功能,結(jié)合實(shí)例形式分析了php微信分享功能接口調(diào)用及分享次數(shù)統(tǒng)計(jì)具體操作技巧,需要的朋友可以參考下2018-01-01PHP調(diào)用MySQL存儲(chǔ)過程并返回值的方法
這篇文章主要介紹了PHP調(diào)用MySQL存儲(chǔ)過程并返回值的方法,較為詳細(xì)的分析了存儲(chǔ)過程的使用技巧,具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2014-12-12