2024-12-05 08:54:54 +08:00
..
2024-12-05 08:54:54 +08:00
2024-12-05 08:54:54 +08:00
2024-12-03 10:27:20 +08:00
2024-12-03 10:27:20 +08:00
2024-12-03 10:27:20 +08:00
2024-12-05 08:54:54 +08:00
2024-12-03 10:27:20 +08:00

本案例要求编写一个斗地主的洗牌发牌程序,要求按照斗地主的规则完成洗牌发牌的过程。

任务描述

一副扑克总共有54张牌牌面由花色和数字组成包括J、Q、K、A字母组成花色有♠、♥、♦、♣ 四种,分别表示黑桃、红桃、方块、梅花,小☺、大☻分别表示小王和大王。

斗地主游戏共有3位玩家参与首先将这54张牌的顺序打乱每人轮流摸一次牌剩余3张留作底牌然后在控制台打印3位玩家的牌和3张底牌。

运行结果

实现思路

1. 准备牌面元素

  • 创建扑克牌的基本元素:花色和点数
  • 花色:♠(黑桃)、♥(红桃)、♣(梅花)、♦(方块)
  • 点数2-10、J、Q、K、A
  • 使用ArrayList分别存储花色和点数

2. 生成完整的牌组

  • 使用HashMap建立牌的编号和具体牌面的对应关系
  • 通过两层循环组合花色和点数生成52张普通牌
  • 额外加入大小王总共54张牌
  • 每张牌都有唯一的编号(0-53)

3. 洗牌准备

  • 创建一个包含0-53数字的ArrayList代表54张牌
  • 使用Collections.shuffle()方法随机打乱这些数字的顺序
  • 打乱后的顺序就是发牌的顺序

4. 发牌过程

  • 创建4个ArrayList用于存储发牌结果
    • 3个玩家的牌iPlayer1、iPlayer2、iPlayer3
    • 1个底牌iSecretCards
  • 发牌规则:
    • 前51张牌轮流发给3个玩家i%3来分配
    • 最后3张作为底牌

5. 整理手牌

  • 使用Collections.sort()方法对每个玩家手中的牌进行排序
  • 排序是对牌的编号进行排序,方便后续显示

6. 转换和显示

  • 创建新的ArrayList存储实际的牌面字符串
  • 遍历每个玩家手中的牌号
  • 通过HashMap查找对应的牌面
  • 最后打印每个玩家的牌和底牌

关键技术点

  1. 集合的使用:
    • ArrayList存储花色、点数和牌组
    • HashMap建立编号和牌面的对应关系
  2. 工具类的应用:
    • Collections.shuffle():用于洗牌
    • Collections.sort():用于整理手牌
  3. 循环的应用:
    • 两层循环生成牌组
    • 取余操作(%)实现轮流发牌

示例代码

import java.util.ArrayList;  
import java.util.Collections;  
import java.util.HashMap;  
  
public class Main {  
    public static void main(String[] args) {  
        /* 第一步:准备扑克牌的基本元素 */        
        // 准备4种花色  
        ArrayList<String> colors = new ArrayList<String>();  
        colors.add("♠");  
        colors.add("♥");  
        colors.add("♣");  
        colors.add("♦");  
  
        // TODO 准备13种点数2-10JQKA  
        ArrayList<String> point = new ArrayList<String>(); 
         
  
        /* 第二步组装54张扑克牌 */        
        // 用HashMap将每张牌的编号(0-53)与具体牌面对应起来  
        HashMap<Integer, String> map = new HashMap<Integer, String>();  
        int index = 0;      // 牌的编号从0开始  
  
        // TODO 两层循环生成52张普通牌13点数 × 4花色  
        
  
        // 加入大小王编号为52和53  
        map.put(index++, "小☺");  
        map.put(index++, "大☻");  
  
        /* 第三步:洗牌准备 */        
        // TOOD 准备一个数字序列代表54张牌  
        ArrayList<Integer> cards = new ArrayList<Integer>();  
        
  
        // 使用shuffle方法打乱牌的顺序洗牌  
        Collections.shuffle(cards);  
  
        /* 第四步:发牌 */        
        // 创建4个集合分别存储三个玩家的牌和底牌  
        ArrayList<Integer> iPlayer = new ArrayList<Integer>();  // 玩家1的牌 
        ArrayList<Integer> iPlayer2 = new ArrayList<Integer>(); // 玩家2的牌  
        ArrayList<Integer> iPlayer3 = new ArrayList<Integer>(); // 玩家3的牌  
        ArrayList<Integer> iSecretCards = new ArrayList<Integer>(); // 底牌  
  
        // TODO 发牌规则留3张底牌其余轮流发给3个玩家  
        for (int i = 0; i < cards.size(); i++) {  
            
        }  
  
        /* 第五步:整理手牌 */        
        // 对每个玩家手中的牌排序  
        Collections.sort(iPlayer);  
        Collections.sort(iPlayer2);  
        Collections.sort(iPlayer3);  
  
        /* 第六步:转换牌面并显示 */        
        // iPlayer 中的存储的是每个玩家拥有的牌的编号0-53  
        // 将玩家手中的牌号转换为具体的牌面  
        ArrayList<String> sPlayer = new ArrayList<String>();  
        ArrayList<String> sPlayer2 = new ArrayList<String>();  
        ArrayList<String> sPlayer3 = new ArrayList<String>();  
        ArrayList<String> sSecretCards = new ArrayList<String>();  
  
        // TODO 根据牌号从map中找出对应的牌面  
        for (Integer key : iPlayer) {  
            sPlayer.add(map.get(key));  
        }  
       
  
        // 展示每个玩家的牌  
        System.out.println("玩家1" + sPlayer);  
        System.out.println("玩家2" + sPlayer2);  
        System.out.println("玩家3" + sPlayer3);  
        System.out.println("底牌:" + sSecretCards);  
    }  
}

进阶任务

利用面向对象思想改造程序

类的设计级要求

1. Card类扑克牌

职责:表示一张扑克牌

  • 属性:
    • suit花色字符串类型
    • rank点数字符串类型
    • index编号整型
  • 功能:
    • 构造方法:初始化一张牌
    • toString方法返回牌面字符串
    • 实现Comparable接口用于排序

2. Deck类牌组

职责:管理一副完整的扑克牌

  • 属性:
    • cardsCard类型的ArrayList
    • 花色和点数的常量数组
  • 功能:
    • 初始化54张牌
    • 洗牌方法
    • 发牌方法

3. Player类玩家

职责:管理玩家信息和手牌

  • 属性:
    • name玩家名称
    • hand存储手牌的ArrayList
  • 功能:
    • 接收牌
    • 整理手牌
    • 显示手牌

4. Game类游戏管理

职责:控制游戏流程

  • 属性:
    • deck牌组对象
    • 三个玩家对象
    • bottomCards底牌列表
  • 功能:
    • 初始化游戏
    • 执行游戏流程
    • 显示游戏结果

改造要点

1. 封装性要求

  • 所有类的属性都应该是私有的
  • 必要的属性提供getter/setter方法
  • 对外只暴露必要的方法

2. 类之间的关系

  • Game类包含Deck类和Player类的对象
  • Player类包含Card类的对象
  • Deck类负责Card对象的创建和管理

3. 功能性要求

  • 保持原有程序的所有功能
  • 洗牌和发牌的逻辑不变
  • 结果显示格式保持一致