扑克牌对弈编程考试试题

题目:

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
丙+丁 组获胜

你可能感兴趣的:(随笔,java,面向对象,代码结构设计,封装思想)