本文適合入門級技術(shù)男閱讀,大牛請繞過讽挟。
一懒叛、背景:近期,在研究區(qū)塊鏈技術(shù)耽梅。發(fā)現(xiàn)了一種以太坊的代幣GTC薛窥,其落地的項(xiàng)目以游戲?yàn)橹鳎戳讼履壳肮俜紸PP上的小游戲眼姐,感覺不好玩,或者是自己不太喜歡玩诅迷。
怎么辦啊众旗?自己寫唄罢杉。反正閑著也是閑著,動動手防止手生了贡歧。于是把多年以前用.NET寫的一個紙牌游戲找了出來滩租,移植到了ANDROID系統(tǒng)上。就有了下文利朵。
二律想、游戲規(guī)則
先上圖,沒圖你說個……
游戲規(guī)則很簡單:每次首發(fā)五張牌绍弟,玩家可以選擇換一次牌技即,換了牌后,當(dāng)五張牌中出現(xiàn)一對(7以上的牌)樟遣,即可得分而叼,兩對郭脂、三條、順子澈歉、同花展鸡、葫蘆(Full House)、四條埃难、同花小順莹弊、同花大順這幾個牌型,玩家都贏分涡尘,所得分為押注的1忍弛、2、3考抄、5细疚、10、15川梅、20疯兼、50、100贫途、200倍分?jǐn)?shù)吧彪。大小飛機(jī)(大小王)可以當(dāng)成任意牌。
什么丢早?很熟悉姨裸?沒錯,以前在街機(jī)游戲室都見過怨酝,規(guī)則和德州撲克差不多傀缩。經(jīng)典的游戲,屬于80后的回憶农猬。呵呵赡艰。
三、關(guān)鍵代碼解析
有興趣盛险?那好瞄摊,聽我慢慢說勋又。
牌面顯示很簡單苦掘,就是對應(yīng)1-54張牌的序號,可以把這個問題抽象為就是1-54個數(shù)字楔壤,這還不簡單鹤啡?54個數(shù)字啊,只有54個數(shù)字6紫递瑰!
3.1怎么識別花色和牌面祟牲?
首先我們編排的時(shí)候,就按一定的順序抖部,如數(shù)字1表示方塊A说贝,2表示方塊2……,13表示方塊K慎颗,14表示梅花A乡恕,……,26表示梅花K,27表示紅心A……52表示黑桃K,53表示小飛機(jī)(小王)俯萎,54表示大飛機(jī)(大王)傲宜。
根據(jù)這個,寫個函數(shù):用待檢測數(shù)整除于14夫啊,結(jié)果為0就是方塊函卒,1就是梅花,2就是紅心撇眯,3就是黑桃报嵌。待檢測數(shù)除于13,余數(shù)就是牌面的數(shù)字熊榛,因?yàn)榕泼媸菑?開始排序沪蓬,所以余數(shù)為0時(shí),就把它當(dāng)成13来候,即“K”點(diǎn)跷叉。例如:
17整除14等于1,就表示梅花营搅;17除于13云挟,余4,所以17表示的是梅花4转质。
26整除14等于1园欣,就表示梅花;26除于13休蟹,余0沸枯,0就要當(dāng)成13,所以26表示的是梅花K赂弓。
44整除14等于3绑榴,就表示黑桃;44除于13盈魁,余5翔怎,所以44表示的是黑桃5。
理解了嗎?不理解可以自己找副牌赤套,按順序排好飘痛,多琢磨琢磨。原理是這個原理容握,具體實(shí)現(xiàn)的代碼有多種上多樣宣脉,直接上我寫的代碼吧:
3.2怎樣模擬“洗牌”?
我們用一個int型的數(shù)組存放著54個數(shù)剔氏,那洗牌就是對這個數(shù)組進(jìn)行一個隨機(jī)的亂序脖旱。這個實(shí)現(xiàn)就是很多種方式了,我是這樣做的介蛉。
代碼超短萌庆,每次循環(huán)產(chǎn)生兩個0-54的隨機(jī)數(shù),再把這兩個數(shù)對應(yīng)的數(shù)組值進(jìn)行交換币旧。一共循環(huán)54*3=162次践险。為什么要循環(huán)這個數(shù)呢?下文另表吹菱。
3.3怎樣判斷屬于什么牌型巍虫?
從最大牌型依次向下判斷,看屬于什么牌型鳍刷。最先判斷是不是“五條”占遥,是的話就返回。不是的話就看是不是“同花大順”输瓜,……上代碼:
例如:判斷是否是”5條”,先把這5個數(shù)通過whatscards函數(shù)(詳見3.1)返回這五張牌分別對應(yīng)的花色和牌面數(shù)值瓦胎,牌面數(shù)值是否一樣就行。再考慮有大小王的情況就行了尤揣。
例如:判斷是否是”同花順”搔啊, 先把這5個數(shù)通過whatscards函數(shù)(詳見3.1)返回這五張牌分別對應(yīng)的花色和牌面數(shù)值,代表花色的數(shù)字一樣北戏,這五張牌就是同花色负芋。代表牌面的數(shù)字進(jìn)行排序后,順序排列就表示是“順子”嗜愈,兩個條件同時(shí)滿足就是”同花順”
3.4發(fā)牌時(shí)的動畫效果怎么實(shí)現(xiàn)旧蛾?
使用個定時(shí)器,每隔一定時(shí)間顯示牌的正反面蠕嫁。
四锨天、問題引入
這里開始正文部分。是的拌阴,剛才那些只是開篇簡單介紹绍绘。經(jīng)過簡單的游戲測試后,發(fā)現(xiàn)了問題:
經(jīng)統(tǒng)計(jì)迟赃,開出“大牌”的機(jī)率較高陪拘,如下圖所示:
分析原因,是“洗牌”的環(huán)節(jié)不合理纤壁,不能達(dá)到一種合理的值左刽。當(dāng)然,只測試幾十次上百次的數(shù)據(jù)是遠(yuǎn)遠(yuǎn)不夠的酌媒。我們要模擬大量的數(shù)據(jù)去測試欠痴,先后模擬了幾次,每次進(jìn)行10萬次開牌統(tǒng)計(jì)秒咨,統(tǒng)計(jì)結(jié)果的占比基本恒定喇辽,我們以最后一次的結(jié)果為例進(jìn)行簡單分析:
統(tǒng)計(jì)結(jié)果如下:
顯然,倍數(shù)的設(shè)定和出現(xiàn)的次數(shù)有矛盾雨席,“殺牌”只占到了32%菩咨,明顯程序設(shè)定有問題,下面我們利用統(tǒng)計(jì)學(xué)進(jìn)行調(diào)整參數(shù)陡厘。
我們測試的隨機(jī)數(shù)分別從54*1=54抽米,至54*200=10800,一共測試了200組糙置,每組10萬次數(shù)據(jù)云茸,發(fā)現(xiàn)其結(jié)果在隨機(jī)數(shù)為54*3=164次以后就已經(jīng)基本恒定,所以選擇了這個“3”大循環(huán)為參數(shù)谤饭。這就是3.2里提到的答案标捺。
當(dāng)然,從玩家的角度揉抵,這個結(jié)果已經(jīng)可以滿足游戲的需求宜岛,但從數(shù)學(xué)的角度,這不是我們理想的結(jié)果功舀。一是玩家的分?jǐn)?shù)在不斷上升萍倡,這讓開發(fā)者無動力去繼續(xù)以后的維護(hù)和更新(商業(yè)角度考量),二是倍率與機(jī)率不成正比辟汰,所以我們還得繼續(xù)改進(jìn)游戲的設(shè)定列敲。
測試一:模擬10萬次發(fā)牌,統(tǒng)計(jì)前五張牌中帖汞,各張牌出現(xiàn)的機(jī)率戴而,結(jié)果如下:
每張牌出現(xiàn)的機(jī)率基本一樣,“洗牌程序”沒有問題翩蘸。但是所意,這種游戲規(guī)則中,大小王是特殊牌,它出現(xiàn)的機(jī)率與最終的結(jié)果有直接的關(guān)系扶踊。我們來進(jìn)行第二個測試泄鹏。
測試二:抽出大小王后,模擬30萬次開牌秧耗,統(tǒng)計(jì)各種牌型的可能性备籽。結(jié)果如下:
這個結(jié)果顯示玩家輸?shù)臋C(jī)率達(dá)到48.21%,有點(diǎn)接近游戲的結(jié)果了分井。但暴露了兩個問題车猬,一是30萬次都不會出現(xiàn)一次同花大順,那這個牌是有問題的尺锚,要檢查程序珠闰。二是full House比同花和順子都容易出,這種設(shè)定肯定不合理瘫辩。百度了下伏嗜,德州撲克的玩法就是這樣的順序。這個規(guī)則肯定要改杭朱。
經(jīng)檢查阅仔,程序代碼沒有問題,把測試次數(shù)加到500萬次時(shí)弧械,開出了10次同花大順八酒。OK,第二個問題刃唐,把牌倍率的順序調(diào)整一下羞迷,如下:
最后,就是大小王的問題画饥,把這兩張大小王加一個出現(xiàn)概率衔瓮,簡單處理如下:
草草結(jié)束吧,本來是想用機(jī)器學(xué)習(xí)的方法來抖甘,來設(shè)置的一些參數(shù)的热鞍,但在本文中只是用到了統(tǒng)計(jì)來人工調(diào)整。精力和時(shí)間的原因衔彻,感覺寫得很累薇宠,暫時(shí)先這樣吧,希望大家見諒艰额。如果支持我的小伙伴多的話澄港,會考慮繼續(xù)完善代碼并開源(反正代碼也沒加混淆和加固,有興趣的小伙伴可以擬出源碼供參考柄沮。)
APK下載鏈接: https://pan.baidu.com/s/1ZKqPJq_8KpNPpXgplclVpw&qrfrom=1&qrtype=apk
(記住回梧,在手機(jī)上要用瀏覽器打開废岂,微信打開會要求登錄)
有問題和意見建議可發(fā)郵件和我交流。
有大家支持的話狱意,下個程序考慮寫個“炸金花”游戲湖苞,打算嘗試使用機(jī)器學(xué)習(xí)的方法,通過玩家大量的下注數(shù)據(jù)髓涯,分析玩家底牌大小袒啼,用“機(jī)器學(xué)習(xí)”來識別“打假”哈扮。
等會兒纬纪,區(qū)塊鏈、GTC什么的滑肉,沒有下文了包各?呵呵,以后再說吧靶庙。^_^!