【Java学习笔记】斗地主规则抽牌模拟(利用LinkedList集合及Collections集合工具类实现)
【Java學習筆記】斗地主規則抽牌模擬(利用LinkedList集合及Collections集合工具類實現)
在這個需求下,我分別設計了3個類:PokerCard(撲克牌)類、PokerCardDeck(牌堆)類、Player(玩家)類。
一、屬性分析
PokerCard(撲克牌)類中有兩個屬性:
//表示1副撲克牌的編號,整數類型,0-53private int id;//表示撲克牌的值,整數類型,3最小,大王最大,分別對應0-14private int cardValue;PokerCardDeck(牌堆)類中有三個屬性:
//表示牌堆,內容為PokerCard的LinkedList//采用LinkedList集合來表示撲克牌堆,它具有查找慢,增刪快的特點,比較適合表示撲克牌堆private LinkedList<PokerCard> pokerCardDeck = new LinkedList<>();Player(玩家)類中有三個屬性:
//姓名,字符串類型private String name;//用分表示的錢,整數類型private int money;//表示手牌,一個PokerCardDeck類的對象集合private PokerCardDeck handCards = new PokerCardDeck();二、方法分析
(一)PokerCard(撲克牌)類
在PokerCard(撲克牌)類中,除了基本的無參構造、geter、seter方法之外,著重講四個核心方法:
一是有參構造,我可以通過撲克牌的編號來唯一確定其花色和值,那么有參構造只需要傳遞撲克牌的編號即可:
public PokerCard(int id) {this.id = id;//區分大小王,設id值為52、53分別為大小王,其值高于其他的牌,分別設為13、14if(id < 52){this.cardValue = id % 13;}else if(id == 52){this.cardValue = 13;}else {this.cardValue = 14;}}二是翻譯撲克牌的值為牌面值的方法,現實我們看到牌面值比如:“2”、“A”、“K”等等就知道哪張牌大,但計算機需要翻譯一下,反之亦然:
//將撲克牌值轉換成牌面值的字符串的方法private String translateCardValue (){String str = "";switch (this.cardValue){//大王與小王不需要翻譯case 14:break;case 13:break;case 12:str = "2";break;case 11:str = "A";break;case 10:str = "K";break;case 9:str = "Q";break;case 8:str = "J";break;//3是最小的,值為0,所以牌面值就是cardValue值+3在轉換成字符串default:str = (this.cardValue+3+"");}return str;}三是重寫toString方法,將花色+牌面值格式化輸出:
//重寫toString方法,根據id值判斷以方便直接輸出@Overridepublic String toString() {String str = "";switch (this.id / 13){case 0:str += "方塊?";break;case 1:str += "梅花?";break;case 2:str += "紅桃?";break;case 3:str += "黑桃?";break;default :if(id == 52){str += "joker";} else {str += "JOKER";}}str += this.translateCardValue();return str;}四是為方便手牌的排序,我們需要讓PokerCard實現Comparable接口,并重寫其中的CompareTo方法:
public class PokerCard implements Comparable<PokerCard>{...} //實現了Comparable接口,則必須重寫compareTo方法,用于比較兩個PokerCard對象的大小//撲克牌采用降序排序,故用o - this@Overridepublic int compareTo(PokerCard o) {//如果值相等,則比較id值,因為花色大的id值也大,相當于比花色if(o.getCardValue() == this.getCardValue()){return o.getId() - this.getId();}else {return o.getCardValue() - this.getCardValue();}}(二)PokerCardDeck(牌堆)類
在PokerCardDeck(牌堆)類中,除了基本的構造方法、geter、seter方法之外,也著重講四個核心方法:
一是填充牌堆方法:
//初始化填充牌堆,默認有1副牌public void fillDeck(){for (int i = 0; i < 54; i++) {this.pokerCardDeck.add(new PokerCard(i));}//執行一次洗牌方法shuffleDeck();}//fillDeck方法的重載,帶參數n,表示有n副牌,保留功能public void fillDeck(int n){for(int j = 0;j < n ;j++){for (int i = 0; i < 54; i++) {this.pokerCardDeck.add(new PokerCard(i));}}//執行一次洗牌方法shuffleDeck();}二是洗牌方法,Collections集合工具類中有現成的亂序方法shuffle,拿來用即可:
//利用Collections類中shuffle方法來亂序牌堆public void shuffleDeck(){Collections.shuffle(this.pokerCardDeck);}三是排序方法,之前在PokerCard(撲克牌)類中實現接口并重寫方法就為了能夠正常使用Collections集合工具類中有現成的排序方法sort:
//利用Collections類中的sort方法進行排序public void sortDeck(){Collections.sort(this.pokerCardDeck);}四是格式化打印牌堆的方法:
//格式化打印牌堆的方法,每隔5張牌換行public void printDeck(){//LinkedList是有序的,可以通過索引來訪問數據for (int i = 0; i < pokerCardDeck.size(); i++) {if(i != 0 && i%5 == 0){System.out.println();}System.out.print(pokerCardDeck.get(i) + "\t");}System.out.println();}(三)Player(玩家)類
在Player(玩家)類中,除了基本的無參構造、geter、seter方法之外,著重講兩個核心方法:
一是有參構造,錢數屬性在這個例子中沒有實際使用到,但也保留著相應的構造方法:
public Player(String name) {this.name = name;}public Player(String name, int money) {this.name = name;this.money = money;}二是抽牌的方法,這里返回一個布爾值,用來表示抽牌是否成功:
//抽牌方法,從牌堆頂中彈出一張牌,Player手牌增加一張牌public boolean drawCard(PokerCardDeck pokerCardDeck){//抽牌規則采用1副牌的斗地主規則,留三張底牌共地主使用if(pokerCardDeck.getPokerCardDeck().size() == 3){return false;}this.handCards.getPokerCardDeck().add(pokerCardDeck.getPokerCardDeck().pop());return true;}//抽牌方法的重載,適用于n副牌的斗地主public boolean drawCard(PokerCardDeck pokerCardDeck,int n){if(pokerCardDeck.getPokerCardDeck().size() == (3*n)){return false;}this.handCards.getPokerCardDeck().add(pokerCardDeck.getPokerCardDeck().pop());return true;}三、程序入口main
不羅嗦了,上代碼:
public class Application {public static void main(String[] args) {PokerCardDeck deck = new PokerCardDeck();Player player1 = new Player("劉備");Player player2 = new Player("關羽");Player player3 = new Player("張飛");deck.fillDeck();//邊判斷邊執行,drawCard方法返回的是布爾值while (player1.drawCard(deck) && player2.drawCard(deck) && player3.drawCard(deck)){}System.out.println(player1.getName() + "的牌是:");player1.getHandCards().sortDeck();player1.getHandCards().printDeck();System.out.println(player2.getName() + "的牌是:");player2.getHandCards().sortDeck();player2.getHandCards().printDeck();System.out.println(player3.getName() + "的牌是:");player3.getHandCards().sortDeck();player3.getHandCards().printDeck();System.out.println("3張底牌是:");deck.printDeck();} }程序運行的結果如下:
劉備的牌是: joker 黑桃?2 方塊?2 梅花?A 方塊?A 黑桃?K 方塊?K 黑桃?J 梅花?J 黑桃?9 梅花?9 紅桃?8 黑桃?7 梅花?7 紅桃?6 黑桃?4 黑桃?3 關羽的牌是: JOKER 紅桃?2 黑桃?A 紅桃?A 紅桃?K 梅花?K 黑桃?Q 梅花?Q 方塊?Q 紅桃?J 方塊?J 方塊?9 紅桃?7 紅桃?5 紅桃?4 方塊?4 方塊?3 張飛的牌是: 梅花?2 紅桃?Q 黑桃?10 紅桃?10 方塊?10 黑桃?8 梅花?8 方塊?8 方塊?7 黑桃?6 梅花?6 黑桃?5 梅花?5 方塊?5 梅花?4 紅桃?3 梅花?3 3張底牌是: 方塊?6 梅花?10 紅桃?93D這運氣,實錘黑臉了。
20200706
總結
以上是生活随笔為你收集整理的【Java学习笔记】斗地主规则抽牌模拟(利用LinkedList集合及Collections集合工具类实现)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 别给技术人员做绩效考核-推荐管理者读读
- 下一篇: python实现人人网留言获取与一键删除