4个人甲乙丙丁在一起玩一副扑克纸牌,每张纸牌按照数字计分,不同花色的相同数字的纸牌分值一样。其中1-10各种花色的纸牌分别为1-10,J、Q、K分别被记为11,12,13,大王和小王分别记为20。四种花色(方片,梅花、红桃、黑桃)分别被记为A、B、C、D。如红桃K表示为13C,分值为13;方片5表示为5A,分值为5。大王表示为20K,分值为20小王表示为20Q,分值为20。54张纸牌叠在一起倒扣在桌子上。
游戏过程如下:
1) 洗牌: 54张纸牌随机顺序组合。
2) 4人排序: 随机产生4人的拿牌顺序,出牌顺序与拿牌顺序相同。第一个人拿牌,即第一个人出牌。
3) 4人排序后两两组队,按照顺序第1人和第3人组成1队,第2人和第4人组成1对
4) 分牌:按拿牌顺序每人轮流拿牌,每人拿13张纸牌,最后两张纸牌留在桌面。
5) 信息:每个人不知道其他人的牌,也不知道留在桌面上的牌,可以获得的信息包括自己持有的牌和4个人出过的牌。队内的成员可以在每一轮沟通出牌的策略。
6) 出牌: 从第一个拿牌的人开始出牌(可以选择最大获胜机会的策略),每一轮4人出牌,然后比大小,拥有牌最大的人获取当前轮次的4张牌。出过的牌后面不可以再出。大小判定规则,纸牌分值(大)>纸牌分值(小),相同纸牌分值,按照黑桃>红桃>梅花>方片的顺序判定大小。例如黑桃9>红桃9。有大王或小王的牌在比较大小时,大小判定的规则是 大王>小王>黑桃13>红桃13>梅花13>方片13>黑桃12...”。举例:第1轮甲出3C,乙出9D,丙出6C,丁出13B,则丁赢取4张牌
(3C,9D,6C,13B)。
7) 判定胜负:每个人手中的牌的分值总和为每个人的得分,每队的得分为两个人得分的和,得分最大的队伍者获胜,如果两队得分相同,则平局。
1.使用面向对象的方法进行编程,可以根据自己偏好自由选择编程语言。
2.代码实现要考虑到扩展性。要在牌的分值,大小比较规则发生变化时,代码能够很容易地扩展和支持。
3.输出结果:每人出牌结果、 每人得分、 获胜选手
拿/出牌顺序:甲丙丁乙。组队,1号队:甲,丁,2号队:丙,乙
甲 3C,6B,8B,11D,7C,7D,2C,8D,5B,12B,12C,4B,10C
丙 6C,1B,4D,2A,10B,13A,2D,5A,11B,20Q,11A,4C,8C
丁 13B,4A,5C,1A,6A,10A,11C,7A,12A,7B,3B,13D,3D
乙 9D,10D,3A,9C,8A,9A,6D,20K,12D,1D,9B,2B,13C
甲 78
丙 110
丁 75
乙 135
下面通过Java语言实现,具体代码如下:
import java.util.*;
//扑克牌类
class Card {
private String suit;
private int rank;
public Card(String suit, int rank) {
this.suit = suit;
this.rank = rank;
}
public String getSuit() {
return suit;
}
public int getRank() {
return rank;
}
@Override
public String toString() {
return rank + suit;
}
}
//玩家类
class Player {
private String name;
private List hand;
private int score;
public Player(String name) {
this.name = name;
this.hand = new ArrayList<>();
this.score = 0;
}
public String getName() {
return name;
}
public List getHand() {
return hand;
}
public int getScore() {
return score;
}
public void addToHand(Card card) {
hand.add(card);
}
public void removeFromHand(Card card) {
hand.remove(card);
}
public void increaseScore(int points) {
score += points;
}
}
//卡牌比较器
class CardComparator implements Comparator {
private Map suitRank = new HashMap<>();
public CardComparator() {
suitRank.put("K", 6); // 大王
suitRank.put("Q", 5); // 小王
suitRank.put("D", 4); // 黑桃
suitRank.put("C", 3); // 红桃
suitRank.put("B", 2); // 梅花
suitRank.put("A", 1); // 方片
}
@Override
public int compare(Card card1, Card card2) {
if (card1.getRank() != card2.getRank()) {
return card2.getRank() - card1.getRank();
}
return suitRank.get(card2.getSuit()) - suitRank.get(card1.getSuit());
}
}
//扑克游戏类
public class PokerGame {
private List deck;
private List players;
private CardComparator cardComparator;
public PokerGame() {
initializeDeck(); // 初始化牌组
initializePlayers();// 初始化玩家
initializePlayerHand(); //给玩家发牌
cardComparator = new CardComparator();
}
private void initializeDeck() {
//花色:A:方片、B:梅花、C:红桃、D:黑桃
List suits = Arrays.asList("A", "B", "C", "D");
//牌面:1-13
List ranks = new ArrayList<>();
for (int i = 1; i <= 13; i++) {
ranks.add(i);
}
//准备一副扑克牌
deck = new ArrayList<>();
for (String suit : suits) {
for (int rank : ranks) {
deck.add(new Card(suit, rank));
}
}
deck.add(new Card("K", 20)); // 大王
deck.add(new Card("Q", 20)); // 小王
//打散扑克,并去除两张底牌
Collections.shuffle(deck);
deck.remove(deck.size() - 1);
deck.remove(deck.size() - 1);
}
private void initializePlayers() {
players = new ArrayList<>();
players.add(new Player("甲"));
players.add(new Player("乙"));
players.add(new Player("丙"));
players.add(new Player("丁"));
//打散玩家顺序
Collections.shuffle(players);
}
private void initializePlayerHand() {
for (int i = 0; i < deck.size(); i++) {
players.get(i % 4).addToHand(deck.get(i));
}
}
private void playRound(int round) {
System.out.println("第 " + round + " 轮开始:");
//存储当前轮次每个玩家出的牌
Map roundCards = new HashMap<>();
//自定义的出牌策略:同组成员中出最大的牌,同组另外成员出最小的牌
//players(0)和players(2)是一组,players(1)和players(3)是一组
compareGroupCards(players.get(0), players.get(2), roundCards);
compareGroupCards(players.get(1), players.get(3), roundCards);
//确定本轮胜者
Player roundWinnerPlayer = determineRoundWinner(roundCards);
System.out.println("本轮胜者: " + roundWinnerPlayer.getName());
//更新玩家分数并从各个玩家手牌中移除本轮出的牌
updateScoresAndRemoveCards(roundWinnerPlayer, roundCards);
}
private void compareGroupCards(Player player1, Player player2, Map roundCards) {
//对palyer1和player2的手牌进行排序
player1.getHand().sort(new CardComparator());
player2.getHand().sort(new CardComparator());
//获取palyer1和player2的手牌中最大和最小的一张牌
Card maxCard1 = player1.getHand().get(0);
Card maxCard2 = player2.getHand().get(0);
Card minCard1 = player1.getHand().get(player1.getHand().size() - 1);
Card minCard2 = player2.getHand().get(player2.getHand().size() - 1);
//比较palyer1和player2的手牌最大的牌,决定如何出牌
int compare = cardComparator.compare(maxCard1, maxCard2);
if (compare < 0) {
//palyer1的手牌最大,palyer1出最大的牌,palyer2出最小的牌
roundCards.put(player1, maxCard1);
roundCards.put(player2, minCard2);
} else {
//palyer2的手牌最大,palyer2出最大的牌,palyer1出最小的牌
roundCards.put(player1, minCard1);
roundCards.put(player2, maxCard2);
}
}
private Player determineRoundWinner(Map roundCards) {
Player roundWinnerPlayer = null;
Card roundMaxCard = null;
for (Map.Entry playerCardEntry : roundCards.entrySet()) {
Card currentCard = playerCardEntry.getValue();
//第一次循环,roundMaxCard为null,直接赋值,后续循环比较大小,找出最大的牌和对应的玩家
if (roundWinnerPlayer == null || cardComparator.compare(currentCard, roundMaxCard) < 0) {
roundWinnerPlayer = playerCardEntry.getKey();
roundMaxCard = currentCard;
}
}
return roundWinnerPlayer;
}
private void updateScoresAndRemoveCards(Player roundWinnerPlayer, Map roundCards) {
for (Map.Entry playerCardEntry : roundCards.entrySet()) {
Player currentPlayer = playerCardEntry.getKey();
Card currentCard = playerCardEntry.getValue();
int points = currentCard.getRank();
//如果当前玩家是本轮胜者,则累加分数
roundWinnerPlayer.increaseScore(points);
//从玩家手牌中移除本轮出的牌
currentPlayer.removeFromHand(currentCard);
}
}
private void determineWinner() {
Player team1Player1 = players.get(0);
Player team1Player2 = players.get(2);
Player team2Player1 = players.get(1);
Player team2Player2 = players.get(3);
int team1Score = team1Player1.getScore() + team1Player2.getScore();
int team2Score = team2Player1.getScore() + team2Player2.getScore();
System.out.println("游戏结束,各玩家得分:");
for (Player player : players) {
System.out.println(player.getName() + ": " + player.getScore());
}
if (team1Score > team2Score) {
System.out.println(team1Player1.getName() + "+" + team1Player2.getName() + " 组获胜");
} else if (team1Score < team2Score) {
System.out.println(team2Player1.getName() + "+" + team2Player2.getName() + " 组获胜");
} else {
System.out.println("平局");
}
}
public static void main(String[] args) {
PokerGame game = new PokerGame();
//打印初始牌组
System.out.println("初始牌组:");
for (Player player : game.players) {
System.out.println(player.getName() + ": " + player.getHand());
}
//比赛开始,共13轮比赛
for (int round = 0; round < 13; round++) {
game.playRound(round + 1);
}
//比赛结束,确定胜者
game.determineWinner();
}
}
以上代码充分利用了面向对象编程的原则,将不同的功能划分到了不同的类中,使得代码结构更加清晰、易于理解和维护。运行结果如下(每次运行代码结果不同):
第 1 轮开始:
本轮胜者: 丁
第 2 轮开始:
本轮胜者: 丁
第 3 轮开始:
本轮胜者: 丙
第 4 轮开始:
本轮胜者: 丙
第 5 轮开始:
本轮胜者: 甲
第 6 轮开始:
本轮胜者: 甲
第 7 轮开始:
本轮胜者: 甲
第 8 轮开始:
本轮胜者: 乙
第 9 轮开始:
本轮胜者: 甲
第 10 轮开始:
本轮胜者: 丙
第 11 轮开始:
本轮胜者: 丙
第 12 轮开始:
本轮胜者: 丁
第 13 轮开始:
本轮胜者: 丁
游戏结束,各玩家得分:
丙: 110
乙: 27
丁: 130
甲: 125
丙+丁 组获胜