Java项目——斗地主小游戏(控制台版)

一、控制台版

1.1 分析

一个完整的斗地主的游戏准备:

首先第一步:斗地主的牌需要准备好!

第二步:有了牌之后,需要洗牌。洗出三张底牌。

第三步:洗好牌之后,进行发牌,一张一张发。

第四步:玩家拿到牌,需要自己整理牌。排序牌。

java 复制代码
package com.lkbhua.douDizhu1;

import java.util.ArrayList;
import java.util.Collections;

public class PokerGame {

    // 用集合当作牌盒
    // 牌盒在全局都需要使用,所以定义为成员变量
    // static: 静态只能访问静态,静态代码块才能使用静态成员变量
    static ArrayList<String> list = new ArrayList<>();


    // 准备牌放在构造方法的外面,不管打多少局,我只准备一副牌,避免内存浪费
    // 准备牌
    // 静态代码块可以解决
    // 特点:随着类的加载而加载,而且只执行一次。
    static {
        String[] colors = {"黑桃","红桃","方块","梅花"};
        String[] numbers = {"3","4","5","6","7","8","9","10","J","Q","K","A","2"};
        for (String c : colors) {
            // c:依次表示每一种花色
            for (String n : numbers) {
                // n:表示每一个牌面数值
                list.add(c + n);
            }
        }
        // 添加大小王
        list.add("小王");
        list.add("大王");
    }

    public PokerGame(){
        // 检验牌盒子是否完整
        // System.out.println(list);

        // 洗牌
        // 这里调用Collections类中的静态方法shuffle就可以打乱集合中的元素
        Collections.shuffle(list);

        // 发牌

        // 同样的思路:
        // 用集合当成每个人手上的牌库
        // lord : 表示底牌
        ArrayList<String> player1 = new ArrayList<>();
        ArrayList<String> player2 = new ArrayList<>();
        ArrayList<String> player3 = new ArrayList<>();
        ArrayList<String> lord = new ArrayList<>();

        // 遍历集合得到每一张牌
        // 注意:
        // 因为这里有三张牌是地主的,需要索引操作,就普通for就可以了
        for (int i = 0; i < list.size(); i++) {
            // i:索引
            String poker = list.get(i);
            if (i <= 2) {
                lord.add(poker);
                // 执行完之后继续执行下一次循环
                continue;
            }

            // 给三个玩家轮留发牌
            // i % 3 == 0 // 表示玩家1
            // i % 3 == 1 // 玩家2
            // i % 3 == 2 // 玩家3
            if (i % 3 == 0) {
                player1.add(poker);
            }
            if (i % 3 == 1) {
                player2.add(poker);
            }
            if (i % 3 == 2) {
                player3.add(poker);
            }
        }

        // 看牌
        // 无非就是遍历集合
        lookPoker("ZengQ",player1);
        lookPoker("LkbHua",player2);
        lookPoker("LaoPeng",player3);
        lookPoker("底牌",lord);

    }

    /*
    参数一:玩家名称
    参数二:玩家手牌
    * */
    public void lookPoker(String name,ArrayList<String> list){
        System.out.print(name + ": ");
        for (String poker : list) {
            // poker:表示玩家手牌
            System.out.print(poker + " ");
        }
        System.out.println();
    }
}

1.2 排序方式一

先手动进行排列,然后再跟12345678910这样的数字一一对应,这样对应起来之后,数字越大,我们认为牌面就越大。那么我们判断大小、洗牌等操作,实际上操作的就是下面的序号!

Map集合元素是一对键值对,这是一个不错的存储方式。

"键" :序号 ;单独使用一个单列集合存储。

"值" :牌面。

这样准备牌的阶段就做好了

洗牌,洗的就是单列集合中的序号;

发牌,发的也是序号,前三张牌作为底牌,后面的牌再依次的发给三个玩家,此时的牌是没有顺序的,这时调正排的顺序。

看牌,拿着序号在最开始的Map集合中去找对应的值即可。此时的排就是有序了。

java 复制代码
package com.lkbhua.douDizhu2;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.TreeSet;

public class PokerGame {

    // 这里只需要产生一个对应的关系,不需要排序
    // 牌盒子 Map集合
    static HashMap<Integer,String> hm = new HashMap<>();
    // 后面操作的全是序号,使用一个单列集合,方便操作
    static ArrayList<Integer> list = new ArrayList<>();

    /*
        {1=黑桃3, 2=黑桃4, 3=黑桃5, 4=黑桃6, 5=黑桃7, 6=黑桃8, 7=黑桃9, 8=黑桃10, 9=黑桃J, 10=黑桃Q, 11=黑桃K, 12=黑桃A, 13=黑桃2,
        14=红桃3, 15=红桃4, 16=红桃5, 17=红桃6, 18=红桃7, 19=红桃8, 20=红桃9, 21=红桃10, 22=红桃J, 23=红桃Q, 24=红桃K, 25=红桃A, 26=红桃2,
        27=梅花3, 28=梅花4, 29=梅花5, 30=梅花6, 31=梅花7, 32=梅花8, 33=梅花9, 34=梅花10, 35=梅花J, 36=梅花Q, 37=梅花K, 38=梅花A, 39=梅花2,
        40=方块3, 41=方块4, 42=方块5, 43=方块6, 44=方块7, 45=方块8, 46=方块9, 47=方块10, 48=方块J, 49=方块Q, 50=方块K, 51=方块A, 52=方块2,
        53=小王, 54=大王}
        这是先遍历花色,在嵌套遍历数字
        不是我们想要的排序方式
        应该是先遍历数字,在嵌套遍历花色
        {1=黑桃3, 2=红桃3, 3=梅花3, 4=方块3, 5=黑桃4, 6=红桃4, 7=梅花4, 8=方块4, 9=黑桃5, 10=红桃5, 11=梅花5, 12=方块5, 13=黑桃6, 14=红桃6, 15=梅花6, 16=方块6,
        17=黑桃7, 18=红桃7, 19=梅花7, 20=方块7, 21=黑桃8, 22=红桃8, 23=梅花8, 24=方块8, 25=黑桃9, 26=红桃9, 27=梅花9, 28=方块9,
        29=黑桃10, 30=红桃10, 31=梅花10, 32=方块10, 33=黑桃J, 34=红桃J, 35=梅花J, 36=方块J, 37=黑桃Q, 38=红桃Q, 39=梅花Q, 40=方块Q,
        41=黑桃K, 42=红桃K, 43=梅花K, 44=方块K, 45=黑桃A, 46=红桃A, 47=梅花A, 48=方块A, 49=黑桃2, 50=红桃2, 51=梅花2, 52=方块2,
        53=小王, 54=大王}

    */


    static {
        // 这里花色和数字,一定要从小到大,否则排序会出错
        String[] colors = {"方块","梅花","红桃","黑桃"};
        String[] numbers = {"3","4","5","6","7","8","9","10","J","Q","K","A","2"};

        int serialNumber = 1;
        // 细节:
        for(String n : numbers ){
            // c:依次表示每一个花色
            for(String c :colors ){
                // n:依次表示每一个牌
                hm.put(serialNumber,c+ n);
                list.add(serialNumber);
                serialNumber++;

            }
        }
        hm.put(serialNumber,"小王");
        // 让序号跟牌盒子中的序号一致
        list.add(serialNumber);
        hm.put(serialNumber+1,"大王");
        list.add(serialNumber);

        // 测试代码
        // System.out.println(hm);
        // System.out.println(list);
    }


    public PokerGame(){
        // 洗牌
        Collections.shuffle(list);

        // 发牌
        // 这里使用TreeSet就可以自动排序
        // 当牌发到玩家手上,TreeSet会自动排序(Java内部实现好的)
        TreeSet<Integer> lord = new TreeSet<>();
        TreeSet<Integer> player1 = new TreeSet<>();
        TreeSet<Integer> player2 = new TreeSet<>();
        TreeSet<Integer> player3 = new TreeSet<>();

        for (int i = 0; i < list.size(); i++) {
            // i:索引
            // list.get(i) : 获取索引i处的元素牌面
            Integer serialNumber = list.get(i);
            if(i<=2){
                lord.add(serialNumber);
                continue;
            }
            if(i%3==0){
                player1.add(serialNumber);
            }else if(i%3==1){
                player2.add(serialNumber);
            }else{
                player3.add(serialNumber);
            }
        }
        // 测试代码
        // System.out.println("lord: " + lord);
        // System.out.println("player1: " + player1);
        // System.out.println("player2: " + player2);
        // System.out.println("player3: " + player3);


        // 看牌
        lookPoker("lord",lord);
        lookPoker("ZengQ",player1);
        lookPoker("LaoP",player2);
        lookPoker("lkbHua",player3);

    }

    // 看牌方法
    // 参数一:玩家名称
    // 参数二:TreeSet集合:牌的序号
    public void lookPoker(String name,TreeSet<Integer> ts){
        // 打印玩家的名字
        System.out.print(name + ": ");

        // 遍历TreeSet集合,得到每一个序号
        // 再拿着序号去Map集合中找真正的牌
        for (Integer serialNumber : ts) {
            // 获取每一张牌
            String poker = hm.get(serialNumber);
            System.out.print(poker + " ");
        }
        System.out.println();
    }
}

1.3 排序方式二

人为规定牌面的价值。

java 复制代码
package com.lkbhua.douDizhu3;

public class App {
    public static void main(String[] args) {
        new PokerGame();
    }
}
java 复制代码
package com.lkbhua.douDizhu3;

import java.util.*;

public class PokerGame {

    // 牌盒子
    static ArrayList<String> list = new ArrayList<>();
    // 创建一个集合,用来存储牌的价值面
    static HashMap<String,Integer> hm = new HashMap<>();


    static {
        String[] colors = {"黑桃","红桃","方块","梅花"};
        String[] numbers = {"3","4","5","6","7","8","9","10","J","Q","K","A","2"};
        for (String c : colors) {
            // c:依次表示每一种花色
            for (String n : numbers) {
                // n:表示每一个牌面数值
                list.add(c + n);
            }
        }
        // 添加大小王
        list.add("  小王");
        list.add("  大王");

        // 指定牌的牌面价值
        // 这里为什么没有指定3-10?
        // 因为这样我们可以拿着牌面上的数字到Map集合中判断是否存在
        // 存在:获取价值
        // 不存在:本身的数字就是价值
        hm.put("J",11);
        hm.put("Q",12);
        hm.put("K",13);
        hm.put("A",14);
        hm.put("2",15);
        hm.put("小王",16);
        hm.put("大王",17);

    }

    public PokerGame(){
        System.out.println("欢迎来到斗地主游戏");

        // 洗牌
        Collections.shuffle(list);

        // 发牌
        ArrayList<String> lord = new ArrayList<>();
        ArrayList<String> player1 = new ArrayList<>();
        ArrayList<String> player2 = new ArrayList<>();
        ArrayList<String> player3 = new ArrayList<>();

        for (int i = 0; i < list.size(); i++) {
            // i:索引
            String poker = list.get(i);
            if (i <= 2) {
                lord.add(poker);
                continue;
            }
            // 给三个玩家轮留发牌
            if (i % 3 == 0) {
                player1.add(poker);
            }
            if (i % 3 == 1) {
                player2.add(poker);
            }
            if (i % 3 == 2) {
                player3.add(poker);
            }

        }

        // 排序
        order(lord);
        order(player1);
        order(player2);
        order(player3);


        // 显示牌
        lookPoker("lord",lord);
        lookPoker("ZengQ",player1);
        lookPoker("LaoP",player2);
        lookPoker("lkbHua",player3);


    }

    // 利用牌的价值进行排序
    // 参数:集合
    public void order(ArrayList<String> list){
        Collections.sort(list, new Comparator<String>() {
            // 该方法在底层:
            // 通过Array.sort()方法进行排序的即:插入排序+二分查找
            @Override
            public int compare(String o1, String o2) {
                // o1:表示当前要插入到序列中的牌
                // o2:表示已经排序好的序列中的牌
                // 负数:表示o1应该在o2之前,插入前面
                // 正数:表示o1应该在o2之后,插入后面
                // 0:表示o1和o2相等,进行花色排序

                // 1、计算o1的花色和价值
                String o1Color = o1.substring(0,1);
                int value1 = getValue(o1);

                // 2、计算o2的花色和价值
                String o2Color = o2.substring(0,1);
                int value2 = getValue(o2);


                // 3、比较
                int i = value1 - value2;
                return i == 0 ? o1Color.compareTo(o2Color) : i;

            }
        });
    }

    // 计算牌的价值
    // 参数:牌
    // 返回值:牌的价值
    public int getValue(String poker){
        // 获取牌上的数字
        String number = poker.substring(2);
        // 拿着数字到Map集合中判断是否存在
        // 存在:获取价值
        // 不存在:进行类型转换
        if(hm.containsKey( number)){
            return hm.get(number);
        }else{
            return Integer.parseInt(number);
        }
    }


    /*
    参数一:玩家名称
    参数二:玩家手牌
    * */
    public void lookPoker(String name,ArrayList<String> list){
        System.out.print(name + ": ");
        for (String poker : list) {
            // poker:表示玩家手牌
            System.out.print(poker + " ");
        }
        System.out.println();
    }


}
相关推荐
~无忧花开~3 小时前
JavaScript实现PDF本地预览技巧
开发语言·前端·javascript
靠沿3 小时前
Java数据结构初阶——LinkedList
java·开发语言·数据结构
4***99743 小时前
Kotlin序列处理
android·开发语言·kotlin
froginwe113 小时前
Scala 提取器(Extractor)
开发语言
t***D2643 小时前
Kotlin在服务端开发中的生态建设
android·开发语言·kotlin
qq_12498707533 小时前
基于springboot的建筑业数据管理系统的设计与实现(源码+论文+部署+安装)
java·spring boot·后端·毕业设计
一 乐3 小时前
宠物管理|宠物共享|基于Java+vue的宠物共享管理系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·springboot·宠物
yanghuashuiyue3 小时前
windows vue3开发环境搭建
windows
a crazy day3 小时前
Spring相关知识点【详细版】
java·spring·rpc