You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于ThinkJava第14章实现扑克发牌程序的技术求助

嘿,我懂你现在的困境——拿着《ThinkJava》第14章的“对象的对象”基础代码,想扩展出一个能发5张随机牌的扑克程序,却不知道从哪下手对吧?咱们直接从核心结构到代码实现一步步来,全部是原创的Java代码,贴合你说的Hand作为Card集合扩展的要求!

核心逻辑拆解

首先得明确几个核心角色:

  • Card:单张扑克牌,包含花色(黑桃、红桃等)和点数(A到K)
  • Deck:52张完整牌组,负责初始化所有牌、洗牌、发牌
  • Hand:玩家的手牌,本质是Card类型的集合扩展,用来存发给玩家的牌

《ThinkJava》第14章的核心就是用集合管理对象,所以咱们的Hand直接基于Java的ArrayList<Card>来扩展,这样自带集合的增删查方法,不用从零写集合逻辑。

完整代码实现

1. Card类(表示单张扑克牌)

这个类负责存储单张牌的花色和点数,重写toString()方便打印手牌:

public class Card {
    private final String suit;
    private final String rank;

    // 构造方法:初始化花色和点数
    public Card(String suit, String rank) {
        this.suit = suit;
        this.rank = rank;
    }

    // 重写toString,打印牌的信息
    @Override
    public String toString() {
        return rank + " of " + suit;
    }
}

2. Hand类(扩展Card集合的手牌)

这里让Hand继承ArrayList<Card>,这样直接拥有集合的所有功能,再添加自定义的showHand()方法来展示手牌:

import java.util.ArrayList;

public class Hand extends ArrayList<Card> {
    // 展示当前手牌
    public void showHand(String playerName) {
        System.out.println("\n" + playerName + "的手牌:");
        for (Card card : this) {
            System.out.println("- " + card);
        }
    }
}

3. Deck类(52张牌的牌组)

负责初始化所有牌、洗牌、发牌。这里提供两种随机发牌的方式:

  • 方式1:先洗牌,再按顺序发牌(高效且符合真实场景)
  • 方式2:每次随机抽取一张牌并移除(更模拟“抽牌”动作)
import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;

public class Deck {
    private final ArrayList<Card> cards;
    private final Random random = new Random();

    // 构造方法:初始化52张完整牌组
    public Deck() {
        cards = new ArrayList<>();
        String[] suits = {"黑桃", "红桃", "方块", "梅花"};
        String[] ranks = {"A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"};

        // 生成所有组合的牌
        for (String suit : suits) {
            for (String rank : ranks) {
                cards.add(new Card(suit, rank));
            }
        }
    }

    // 洗牌:打乱牌组顺序
    public void shuffle() {
        Collections.shuffle(cards);
        System.out.println("牌组已洗牌!");
    }

    // 方式1:发一张牌(从牌组末尾取,适合先洗牌的场景)
    public Card dealCard() {
        if (cards.isEmpty()) {
            return null;
        }
        return cards.remove(cards.size() - 1);
    }

    // 方式2:随机抽一张牌(直接从牌组随机位置取)
    public Card dealRandomCard() {
        if (cards.isEmpty()) {
            return null;
        }
        int randomIndex = random.nextInt(cards.size());
        return cards.remove(randomIndex);
    }
}

4. 主程序PokerGame(运行逻辑)

创建牌组、洗牌、创建两个玩家手牌,每个发5张牌:

public class PokerGame {
    public static void main(String[] args) {
        // 1. 创建并洗牌
        Deck deck = new Deck();
        deck.shuffle();

        // 2. 创建两个玩家的空手牌
        Hand player1Hand = new Hand();
        Hand player2Hand = new Hand();

        // 3. 给每个玩家发5张牌(这里用方式1:先洗牌再顺序发)
        for (int i = 0; i < 5; i++) {
            player1Hand.add(deck.dealCard());
            player2Hand.add(deck.dealCard());
        }

        // 4. 展示两个玩家的手牌
        player1Hand.showHand("玩家1");
        player2Hand.showHand("玩家2");
    }
}
关键细节说明
  • Hand的扩展逻辑:咱们让Hand继承ArrayList<Card>,完美贴合你说的“Hand是Card Collection的扩展”,这样不用自己实现集合的添加、移除等方法,直接复用ArrayList的功能,同时可以添加自定义的手牌操作(比如showHand())。
  • 随机发牌的两种方式:
    • 如果追求简单高效,用先洗牌再顺序发牌的方式就足够,这也是现实中扑克游戏的常规操作;
    • 如果想更模拟“随机抽牌”的感觉,就用dealRandomCard()方法,每次从牌组随机位置取牌并移除。
  • 代码可扩展性:后续可以轻松添加判断手牌类型(比如同花顺、对子)的方法,或者增加更多玩家,只需要创建更多Hand对象即可。

内容的提问来源于stack exchange,提问作者InkedMom91

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:35:56