摘 要:斗地主游戲系統開發使用的是C++語言,系統使用了C/S架構。本系統建立在局域網之上,主要就是建立一個服務器用來存儲數據,然后通過服務器和客戶端之間的通信來實現游戲過程。此游戲系統主要包括建立服務器、建立客戶端與服務器的鏈接、定義紙牌、發牌、搶地主、出牌、紙牌大小比較等功能。其中利用網絡編程相關知識,實現三次握手四次揮手,同時還可以解決客戶端與服務器之間的鏈接問題。實現定義紙牌模塊與發牌、搶地主模塊,通過定義一個K值,取1-54的數字代表整副紙牌,然后加入TYPE、NUM等變量解決出牌和紙牌牌面大小比較算法。由于受時間及技術嫻熟程度的限制,其功能有待進一步完善;但游戲畫面簡潔明了,可進行傻瓜式操作,具有可玩性較高,流暢度高的優勢。
關鍵詞:C++;桌面游戲;斗地主游戲
中圖分類號:TP317 文獻標識碼:A 文章編號:2096-4706(2018)11-0081-03
The Design and Implementation of the Game of the Bucket Landlord
ZHAO Juan,YI Gaizhen
(School of Computer Science,Xianyang Normal University,Xianyang 712000,China)
Abstract:The Landlords game system is developed using the C++ language,and the system uses the C/S architecture. The system is based on LAN,mainly to establish a server to store data,and then through the communication between the server and the client to achieve the game process. The game system mainly includes the establishment of servers,the establishment of client-server links,the definition of cards,licensing,landlords,cards,card size comparison and other functions. The network programming knowledge is used to realize three handshakes and four waving,and the problem of link between client and server can be solved. Realize the definition of card module and licensing,landlord robbery module,through the definition of a K value,take 1-54 digital representation of the whole deck of cards,and then add TYPE,NUM and other variables to solve the card and card size comparison algorithm. Due to the limitations of time and technical proficiency,its function needs to be further improved,but the game screen is concise and clear,can be foolish operation,with high playability,high fluency advantages.
Keywords:C++;table games;bucket landlords game
0 引 言
實現斗地主這個游戲的方法有很多,C/C++/JAVA等都可以在自己的平臺上實現,并且各有其特點和優勢。此游戲主要基于C++,首先需要對其運行機制與界面元素進行控制。在此基礎上,斗地主游戲主要依賴于后臺的算法。C++的文件讀取不同于Android,Android讀取文件需要一個繼承Activity的類,并且只能對屬于自己程序的文件進行操作,如果是原始文件則需在raw文件夾下,對其在Android中所對應的ID進行操作,但C++只需要知道文件目錄任何一個類就可以對文件進行操作,所以使用C++編寫該游戲系統有一定的便捷性[1]。
1 游戲設計中的數據結構及開發流程
初始化游戲的基本屬性:
(1)主加載方法;
(2)NEW3個新的角色,代表玩家;
(3)NEW出54張牌,用i值(1-52)代表1-13的牌,53、54代表大小王;
(4)獲取54個不同的隨機數;
(5)NEW出牌的圖形,使用(i-1)%4表示花色;
(6)排序--牌;
(7)排序--牌(按照4張、3張、2張、1張的順序);
(8)排序--牌圖形;
(9)把牌的值添加到每個角色中;
(10)開始發牌。
游戲實現流程如圖1所示。
按照斗地主游戲約定俗成的規則,使用算法編寫對玩家出的牌進行檢驗的代碼,判斷其是否符合出牌規則。思路:將玩家的牌按從小到大的方式排序,然后把牌拆分開來,分別存放于4個數組中,拆分規則如下:
假設有牌:333\444\555\789
則拆分后數組中的數據如下:
arr[0]:345789
arr[1]:345
arr[2]:345
arr[3]:1
可以看出拆分規則是:如果遇到相同數字的牌則存到下一個數組的末尾。
拆分完后可以根據各數組的存儲情況判定玩家出牌的類型,上面的例子中的arr[3]為空可以排除掉4帶1(2)、炸彈的情況,根據arr[2]為順子且個數大于1,且arr[2]中存放的牌的張數乘以3剛好等于arr[0]的張數+arr[1]的張數,則可以判定是三帶一的飛機。如果不是,那就判定為不符合出牌的規則,系統會判定出牌失敗,需要重新選擇別的牌。
2 游戲規則及相關算法設計
本游戲叫作斗地主游戲,其游戲規則為玩家三人,地主為一方,其余兩家為另一方,雙方對戰,先出完手中牌的一方勝。游戲中的每個玩家都可以起昵稱,使用類name中的Cname方法給后臺傳輸玩家ID及其玩家地址IP,Cname方法傳入一個指針參數,然后定義初始化玩家昵稱為“路人甲”。當玩家運行程序后,彈出是否建立主機白框,如果建立主機,自己的IP地址為172.0.0.1,然后輸出自己的昵稱,創建好主機后等待玩家加入,當玩家湊齊三人且三人都準備好之后就可以開始發牌。創建及加入房間主要是由server類中的CServer方法實現,主要需要傳入的參數即玩家IP及玩家昵稱,當玩家選擇是否創建主機即view類中的if語句來進行判斷時,創建就進入server類中傳入雙參。而玩家加入則是由net類進行鏈接,net類中的CNet方法主要用于鏈接玩家和主機,其中包含3層if,判斷是否在同一臺機器、是否在同一個局域網、玩家和主機是否能鏈接,先判斷是否在同一臺機器,如果是則進行鏈接,如果不是就判斷是否在同一個局域網,如果是則鏈接,不是則判斷是否可以鏈接,再次判斷為否時則提示鏈接失敗。
定義一副紙牌即定義一個變量k,用1-52來表示四種不同花色的1-13的紙牌,用53、54分別表示小王大王,用((k-1)/4)表示牌號,然后發牌。
游戲規則(一副牌規則):
(1)發牌:撲克牌發牌算法包括定義紙牌算法和發牌算法本身,定義紙牌算法:先定義一個int型變量k,初值1,最大54,其中1-13定義為3、4、5、6、7、8、9、10、J、Q、K、A、2這13張牌,1-52是定義為4套A-K,其中用k/13得出來的0、1、2、3代表四種花色,53、54代表小大王。然后根據隨機函數random來給定義的三個玩家數組分配1到13的17張牌,使用for循環來進行分配,如果分配的數字相同的紙牌數量超過4張則跳過本次循環重新分配。
(2)叫地主:誰拿到了紅桃三誰先叫地主,使用一個if語句判斷3個玩家的手牌數組中有沒有K/4=1且K%13等于3的牌,有則先手叫地主,叫地主時可以叫“1分”“2分”“3分”“不叫”。而且每次叫地主只可以比上一次叫地主的人叫的分數更大,或者不叫,使用一個if語句判斷這個玩家叫的分數是否大于上個玩家叫的分數,大于則叫牌成功,小于或等于則使用printf返回提示“請重新選擇更大的分數或者不叫”。叫地主結束后所叫分值最大的玩家為地主;如果有人直接叫了3分,則直接成為地主;如果三個人沒人叫地主,那就洗牌重新開始。使用一個for循環,循環3次,然后用if語句判斷這個人是否比上個人叫的分數大,再用if語句判斷是否到了3分,到了就直接結束if循環,輸出叫3分的人為地主。
(3)出牌:成為地主之后可以得到三張底牌,但是需要展示給其他兩人觀看,即成為地主則他的數組大小為20,由地主第一個出牌,然后逆時針下一個出牌,到誰出牌就選擇好想出的牌然后點擊出牌按鈕,沒有就點擊過牌。每一位玩家的紙牌都存儲在名為card的數組當中,加入判斷語句判斷是否為地主,如果是地主則數組大小變為20,然后出牌則是一個循環,循環出牌,然后看誰的數組先為空,則勝利。
(4)游戲規則:王炸:就是雙王(大王和小王),兩張牌一起出什么牌都可以吃。即k值為53+54的時候,k值為最大,任何牌都可以吃掉。
炸彈:四張一樣數字但不同花色的牌(如四個10)。
單牌:只出一張(如紅桃5)。
對子:數字一樣但花色不同的兩張牌(如梅花4+方塊4)。
三帶一:數字相同的三張牌帶著一張單牌或者一個對子。例如:333+7或444+99
順子:K%值連續的五張牌但最大不可以是雙王和2。
姐妹對:K%值連續并且每個值都有倆個的牌,姐妹對中不帶雙王和2。
飛機:兩個連續的三帶一(如:333444、5556667778 88)。飛機中不帶雙王和2。
四帶二:炸彈不以炸彈的方式出牌,而是帶著兩張單牌或者兩個對子。如:5555+3+8或4444+55+77。
牌面大小判定的算法如下:
(1)定義一個函數,有三個參數num、min、type。num表示出牌有多少張,min表示起作用的牌,type表示出牌類型。比如說對子type值是1,順子是2,3帶1 type值是3,4帶2 type值是4,炸彈type值是5,王炸type是6,其中type值是5和6的可以吃掉type值為1、2、3、4的四種出牌,而type值6的則可以直接吃掉全部,也就是最大的。
(2)在紙牌大小比較中主要依靠的就是使用k%13值大小比較,k%值大的則牌面更大,如果是對子就比較單張k%值的大小,順子則比較最后那張牌的k%值的大小,3帶1比較3張一樣牌k%的大小,4帶2比較4張一樣的。炸彈和其他的牌比較就用type值,和同樣炸彈比較也是用k%13值,王炸則直接是最大的,使用type值的判斷等級更高。
(3)牌面大小比較:王炸最大,能吃掉任何其他的牌。炸彈比王炸小,比其他牌大。同樣是炸彈,誰的牌上數字大誰的炸彈就大。除了炸彈,其他大小比較需要在出牌數量相同的情況下才可以進行。單牌按牌面數字大小進行比較,也就是按照k%13的值的大小進行排列,k%值越大則牌面越大,依次是大王>小王>2>A>K>Q>J>10>9>8>7>6>5>4>3。對子和三帶一都按照牌面數字大小進行比較。順子按照順子的最后一張牌的大小進行比較。飛機和四帶二是按照其中三張一樣的牌的牌面數字大小和四張部分來比,帶的牌不影響大小。勝負判定是看誰先出完,如果地主先出完就地主勝利,其他倆人無論誰先出完都是地主失敗。使用if語句判斷哪個玩家的數組先為空,如果地主手牌數組先為空則彈出提示地主勝利,反之則彈出農民勝利。
3 結 論
斗地主游戲設計主要從游戲的數據結構和游戲規則的實現方面來說明整個實現過程。其中還有很多不足,例如在游戲算法中,可以更深層次地應用貪心算法和剪枝算法,既能找到最優解還能提高算法效率[2]。這些都是在今后的開發中需要注意的方面。
參考文獻:
[1] 潘正輝.基于Android系統手機游戲的設計與開發研究 [J].電子世界,2016(13):128+130.
[2] 李竹林.基于Android系統的斗地主游戲的設計與實現 [J].河南科學,2015,33(2):200-203.
作者簡介:趙娟(1975-),女,漢族,四川成都人,教師,講師,碩士研究生。研究方向:軟件工程。