非常抱歉,之前寫的代碼有個發牌bug,導致三個人的牌是一樣的,我沒有注意到,感謝
@J_落羽
的提醒,目前這個bug已經修復,代碼中有註釋,位置是CardGame.java
的deal()方法
一、功能介紹
功能需求:
- 創建Card類,定義花色suit和點數rank的屬性
- 創建玩家類 Player類 ,定義名字name ,手牌 cards (List),角色role
- 定義測試類CardGame
- 創建一副撲克牌,54張
- 實現洗牌
- 實現輪流發牌
- 實現理牌
二、功能代碼實現
1. 定義Card類
Card.java
package com.feonix;
/**
* 卡牌類
*
* @author FeoniX
*
*/
public class Card {
/** 花色常量 */
static final String[] SUITS = { "♥", "♠", "♦", "♣", "" };
/** 點數常量 */
static final String[] RANKS = { "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A", "2", "♚", "♔" };
/** 花色 */
private int suit;
/** 點數 */
private int rank;
/**
* 無參構造器
*/
public Card() {
}
/**
* 有參構造器
*
* @param suit
* @param rank
*/
public Card(int suit, int rank) {
this.suit = suit;
this.rank = rank;
}
/**
* 獲取花色
*
* @return
*/
public int getSuit() {
return suit;
}
/**
* 設置花色
*
* @param suit
*/
public void setSuit(int suit) {
this.suit = suit;
}
/**
* 獲取點數
*
* @return
*/
public int getRank() {
return rank;
}
/**
* 設置點數
*
* @param rank
*/
public void setRank(int rank) {
this.rank = rank;
}
@Override
public int hashCode() {
int secret = 0x000031;
int result = 1;
result = getSuit() * result + secret;
result = getRank() * result + secret;
return result;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (this == obj) {
return true;
}
if (obj instanceof Card) {
Card card = (Card) obj;
return card.getSuit() == getSuit() && card.getRank() == getRank();
}
return super.equals(obj);
}
@Override
public String toString() {
return String.format("%s%s", SUITS[getSuit()], RANKS[getRank()]);
}
}
2. 定義Player類
Player.java
package com.feonix;
import java.util.List;
/**
* 玩家類
*
* @author FeoniX
*
*/
public class Player {
/** 玩家名字 */
private String name;
/** 玩家角色 */
private String role;
/** 玩家手牌 */
private List<Card> cards;
/**
* 無參構造器
*/
public Player() {
}
/**
* 有參構造器
*
* @param suit
* @param rank
*/
public Player(String name, List<Card> cards) {
this.name = name;
this.cards = cards;
this.role = "農民";
}
/**
* 獲取名字
*
* @return
*/
public String getName() {
return name;
}
/**
* 設置名字
*
* @param name
*/
public void setName(String name) {
this.name = name;
}
/**
* 獲取角色
*
* @return
*/
public String getRole() {
return role;
}
/**
* 設置角色
*
* @param role
*/
public void setRole(String role) {
this.role = role;
}
/**
* 獲取手牌
*
* @return
*/
public List<Card> getCards() {
return cards;
}
/**
* 設置手牌
*
* @param cards
*/
public void setCards(List<Card> cards) {
this.cards = cards;
}
@Override
public int hashCode() {
int secret = 0x000031;
int result = 1;
result = getName().hashCode() * result + secret;
return result;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (this == obj) {
return true;
}
if (obj instanceof Player) {
Player palyer = (Player) obj;
return palyer.getName().equals(getName());
}
return super.equals(obj);
}
@Override
public String toString() {
return String.format("[%s]%s手上的牌:%s", getRole(), getName(), getCards().toString());
}
}
3. 定義測試類
CardGame.java
package com.feonix;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Random;
/**
* 撲克牌鬥地主
*
* @author FeoniX
*
*/
public class CardGame {
/** 一副牌的集合 */
private static List<Card> poker = new ArrayList<Card>(54);
/** 底牌 */
private static List<Card> handCards = new ArrayList<Card>();
/** 玩家的集合 */
private static List<Player> players = new ArrayList<Player>();
/** 確定地主的那張牌 */
private static Card landlordCard;
public static void main(String[] args) {
initPlayers();
initCards();
deal();
System.out.println("洗牌前:" + poker + "\n");
// 洗牌
Collections.shuffle(poker);
System.out.println("洗牌後:" + poker + "\n");
System.out.println("底牌:" + handCards + "\n");
System.out.println("翻牌:" + landlordCard + "\n");
for (Player player : players) {
// 理牌
player.getCards().sort(new Comparator<Card>() {
@Override
public int compare(Card o1, Card o2) {
return o1.getRank() - o2.getRank();
}
});
// 輸出玩家手上的牌
System.out.println(player + "\n");
}
}
/**
* 初始化玩家
*/
private static void initPlayers() {
players.add(new Player("甜甜", new ArrayList<Card>()));
players.add(new Player("石頭", new ArrayList<Card>()));
players.add(new Player("代代", new ArrayList<Card>()));
}
/**
* 初始化生成一副牌
*/
private static void initCards() {
for (int i = 0; i < Card.RANKS.length; i++) {
Card card = null;
if (!"♚".equals(Card.RANKS[i]) && !"♔".equals(Card.RANKS[i])) {
// 生成其他牌
for (int j = 0; j < Card.SUITS.length - 1; j++) {
card = new Card(j, i);
poker.add(card);
}
} else {
// 生成大小王
card = new Card(4, i);
poker.add(card);
}
}
}
/**
* 發牌
*/
private static void deal() {
Random rand = new Random();
// 隨機生成翻牌索引,確定地主
int landlordIndex = rand.nextInt(poker.size() - 3);
// 發牌
for (int i = 0; i < poker.size() - 3;) {
// Card card = poker.get(i); // 這行代碼寫錯位置了,移到下面去
for (int j = 0; j < players.size(); j++) {
Card card = poker.get(i); // 獲取撲克牌應該寫在內循環中
if (i == landlordIndex) {
// 獲取翻牌
landlordCard = card;
// 設置玩家角色是地主
players.get(j).setRole("地主");
// 獲取底牌
handCards = poker.subList(poker.size() - 3, poker.size());
// 底牌發給地主
players.get(j).getCards().addAll(handCards);
}
// 給玩家發牌
players.get(j).getCards().add(card);
i++;
}
}
}
}
三、演示效果圖
這是一開始的錯誤示例
下面纔是正確的效果圖
一個簡單的撲克牌發牌小功能,今天就先分享到這裏了,下次有了新的想法再拿來和大家分享。
====================================== 分隔線 ==========================================