Java模拟炸金花

要实现模拟炸金花,需要满足以下几个条件:
实现扑克牌的创建

洗牌 发牌 大小对比 输出赢家牌

架构思想:

首先需要创建三个集合,用于存储牌面值、牌号与比较规则,再创建一个类作为牌。

其次还需要了解到一个工具类,就是Collections类,该类的所有方法都是由 static 静态关键字修饰的,所以该类的所有方法都可直接使用 类名+. 的方式调用。
Collections类是针对集合的一个工具类,里面的所有方法就是针对集合来写的。

private static HashMap<Integer,poker> pokerBox; // 牌盒
     /*
     存储牌盒中的key键值,与牌盒中的牌一一对应,用于取出牌盒中的牌,对牌号的操作等同于对牌盒操作
     但是对Integer类型操作比对String类型操作更简单。
     同时牌号也能表示不同花色间的大小关系
     */
private static List<Integer> listPoker; // 牌号
private static HashMap<String,Integer> map; // 存储牌面值的大小规则
 
// poker类
// 代表扑克牌便于操作
class poker{
    // 花色与牌面值分离了
    // 汇总就是总值
    String flowerColor; // 花色
    String faceValue;   // 牌面值
    String value;       // 总值
 
    public poker(){}
 
    // 有参构造
    public poker(String flowerColor, String faceValue,String value) {
        this.flowerColor = flowerColor;
        this.faceValue = faceValue;
        this.value=value;
    }
}

扑克牌的创建

使用一个静态代码块来构建牌,初始化牌盒、牌号与大小规则等。
静态代码块是一种特殊的语法结构,它允许你在类加载到JVM时执行某些操作。这种结构常用于一次性的设置或初始化静态变量。

//扑克牌
public class Card {
    private int color;
    private int number;
 
    public Card() {
    }
 
    public Card(int color, int number) {
        this.color = color;
        this.number = number;
    }
 
    public int getColor() {
        return color;
    }
 
    public void setColor(int color) {
        this.color = color;
    }
 
    public int getNumber() {
        return number;
    }
 
    public void setNumber(int number) {
        this.number = number;
    }
 
    @Override
    public String toString() {
        return this.colorToString(this.color) +
                this.numberToString(this.number);
    }
 
//对花色进行字符化,黑桃最大,方块最小,
    private String colorToString(int i){
        String flower = null;
        switch (i){
            case 1:
                flower = "方块";
                break;
            case 2:
                flower = "梅花";
                break;
            case 3:
                flower = "红心";
                break;
            case 4:
                flower = "黑桃";
                break;
        }
        return flower;
    }
//对扑克牌的JQKA进行字符化,A为14,K为13,Q为12,J为11
    private String numberToString(int i){
        String num = null;
        switch (i){
            case 11:
                num = "J";
                break;
            case 12:
                num = "Q";
                break;
            case 13:
                num = "K";
                break;
            case 14:
                num = "A";
                break;
            default:
                if (i >= 2 && i <= 10) {
                    num = new Integer(i).toString();
                }else
                    num = "3";
        }
        return num;
    }
}

创建扑克牌后,创建Cards.java,我们就要把52张扑克牌初始化出来,然后加入到集合当中,代码如下所示:

import java.util.*;
 
//扑克牌
public class Cards {
    public List<Card> initCards(){                      //将52张牌创建并加入List集合中
        List<Card> list = new ArrayList<>();            //创建List集合
        for (int i = 1; i < 5; i++) {                   //i对应为花色
            for (int j = 2; j < 15; j++) {              //j对应为数字
                Card card = new Card();                 //在循环中创建扑克牌对象,该代码执行4*13=52次
                card.setColor(i);                       //设置扑克牌花色
                card.setNumber(j);                      //设置扑克牌数字
                list.add(card);                         //将扑克牌加入List集合
            }
        }
        return list;
    }
}

洗牌


由于牌号内的序号是与牌盒中的牌一一对应的,那么将存储牌号的list集合打乱就可以达到洗牌的效果。

  //洗牌
    public List<Card> shuffle(List<Card> list){
        List<Card> slist = new ArrayList<>();            //创建List集合,保存洗牌后的扑克
        Random random = new Random();
        while (list.size() > 0){
            int r = random.nextInt(list.size());        //生成正整型的随机数
            Card card = list.remove(r);                 //返回list中,随机数位置的元素并且移除对应位置的元素
            slist.add(card);
        }
        return slist;
    }

排序

  //对手牌进行排序
    public List<Card> playListSort(List<Card> playList){
        playList.sort(new Comparator<Card>() {
            @Override
            public int compare(Card c1, Card c2) {
                return c1.getNumber() - c2.getNumber();
            }
        });
        return playList;
    }

发牌

List集合与List集合之间是可以嵌套的,使用List<List>作为该方法的返回值,外层的List集合中代码每一个玩家,内层的List中代表玩家的扑克牌数。

public List<List<Integer>> dealCards(int playerNumber){
        // 对人数进行限制
        if((playerNumber*3) > pokerBox.size() || playerNumber <= 0){
            System.out.println("玩家超出限制,最多允许17位玩家、最少1一位玩家参加此游戏,请重新选择人数");
            return null;
        }
 
        // 玩家列表
        List<List<Integer>> playerList=new ArrayList<>();
 
        int k=3;    // 每位玩家牌的张数
 
        for (int i = 0,curIntdex=0; i < playerNumber; i++) {
            List<Integer> curPlayer=new ArrayList<>();
            // 每位玩家发三张牌
            for (int j = 0; j < k; j++) {
                curPlayer.add(listPoker.get(curIntdex++));
            }
            playerList.add(curPlayer); // 将当前玩家添加到玩家列表中
        }
 
        return playerList;
    }

看牌

// 看牌
    public void lookPoker(List<List<Integer>> list){
 
        // 所有玩家
        for(int i=0,end=list.size(); i<end; ++i){
            System.out.print("玩家"+(i+1)+":");
            // 代表当前玩家
            List<Integer> curPople=list.get(i);
            // 玩家手中的牌
            for(int j=0,n=curPople.size(); j<n; ++j){
                // 从当前玩家curPople手中获取牌得序号,根据序号从牌盒PokerBox中取出牌来
                System.out.print(pokerBox.get(curPople.get(j)).value + " ");
            }
            System.out.println();
        }
        System.out.println();
    }

接下来就要对牌型进行判断,判断牌型是否为豹子,代码如下:

//判断牌型是否为豹子(三张牌的数字都是一致的)
    public boolean isTheSameNumber(List<Card> playList){
        if (playList != null && playList.size() == 3){
            if (playList.get(0).getNumber() == playList.get(1).getNumber()
            && playList.get(1).getNumber() == playList.get(2).getNumber()){
                return true;
            }else{
                return false;
            }
        }else {
            System.err.println("手牌不符合规则");
            throw new RuntimeException("手牌不符合规则");
        }
    }

内排序

对每个玩家的手牌内部进行排序。

// 玩家手牌进行排序
    public void playerPokerSort(List<List<Integer>> lists){
        // 最大手牌在第一位,第二次之....
        for (int i = 0; i < lists.size(); i++) {
            // 排序,逆序
            Collections.sort(lists.get(i),((o1, o2) -> (o2-o1)));
        }
    }

牌与牌之间的比较方法

返回值:

  • 大于0:玩家a的手牌 大于 玩家b的手牌
  • 小于0:玩家a的手牌 小于 玩家b的手牌
  • 等于0:玩家a的手牌 等于 玩家b的手牌
// 比较函数
    public int cmp(List<Integer> a,List<Integer> b){
        // O(a.size)
        StringBuilder sbA=new StringBuilder();
        StringBuilder sbB=new StringBuilder();
        // 逆序取
        for(int i=a.size()-1; i>=0; --i){
            sbA.append(pokerBox.get(a.get(i)).faceValue);
            sbB.append(pokerBox.get(b.get(i)).faceValue);
        }
		// 判断是否存在顺子牌等的情况
        Integer numA=map.get(sbA.toString());
        Integer numB=map.get(sbB.toString());
        if((numA != null && null == numB) || (null == numA && numB != null)){
            return (null == numA) ? -1 : 1;
        }else if(numA != null && numB != null){
            return numA-numB;
        }
 
        // O(a.size)
        for(int i=0,end=a.size(); i < end; ++i) {
            // 从两个玩家手中获取牌根号,获取到牌号后再从牌盒中取出牌面值来
            // 再从map中获取牌面值的大小,进行比较
            numA=map.get(pokerBox.get(a.get(i)).faceValue);
            numB=map.get(pokerBox.get(b.get(i)).faceValue);
			
            if (numA == numB) { continue; }
            if (numA > numB) { return 1; }
            else { return -1; }
        }
        // 相等的情况
        return 0;
    }

找出牌最大的玩家

// 输出最大玩家的手牌
public void printWinPlayer(List<List<Integer>> list){
    int maxIndex=0;
    List<Integer> maxPlayer=list.get(0);
 
    // 循环比较出最大玩家
    for(int i=1,end=list.size(); i<end; ++i){
        List<Integer> cur=list.get(i);
        // 根据比较方法来找出牌最大的玩家
        if(cmp(maxPlayer,cur) < 0){
            maxIndex=i;
            maxPlayer=cur;
        }
    }
 
    System.out.print("最大的手牌是玩家"+(maxIndex+1)+":");
 
    List<Integer> ans=list.get(maxIndex);
    for(Integer i : ans){
        System.out.print(pokerBox.get(i).value + " ");
    }
    System.out.println();
}

启动代码

package newGame;
 
public class app {
    public static void main(String[] args) {
        new pokerGame();
    }
}

游戏代码

package newGame;
 
import java.util.*;
 
public class pokerGame {
 
    // 由于牌盒不需要排序,那么使用hashMap即可
    private static HashMap<Integer,poker> pokerBox; // 牌盒
     /*
     存储牌盒中的key键值,与牌盒中的牌一一对应,用于取出牌盒中的牌,对牌号的操作等同于对牌盒操作
     但是对Integer类型操作比对String类型操作更简单。
     同时牌号也能表示不同花色间的大小关系
     */
    private static List<Integer> listPoker; // 牌号
 
    private static HashMap<String,Integer> map; // 存储牌面值的大小规则
 
    // 准备牌
    static {
        map=new HashMap<>();
        pokerBox=new HashMap<>();
        listPoker=new ArrayList<>();
 
        // 将牌号存入map集合,用于比较时的牌大小对比
        map.put("2",2);
        map.put("3",3);
        map.put("4",4);
        map.put("5",5);
        map.put("6",6);
        map.put("7",7);
        map.put("8",8);
        map.put("9",9);
        map.put("10",10);
        map.put("J",11);
        map.put("Q",12);
        map.put("K",13);
        map.put("A",14);
 
        map.put("234",15);
        map.put("345",16);
        map.put("456",17);
        map.put("678",18);
        map.put("789",19);
        map.put("8910",20);
        map.put("910J",21);
        map.put("JQK",22);
        map.put("QKA",23);
 
        map.put("222",24);
        map.put("333",25);
        map.put("444",26);
        map.put("555",27);
        map.put("666",28);
        map.put("777",29);
        map.put("999",30);
        map.put("101010",31);
        map.put("JJJ",32);
        map.put("QQQ",33);
        map.put("KKK",34);
        map.put("AAA",35);
 
        // 最大值(保留)
        map.put("235",1000);
 
        // 花色
        String[] FlowerColor=new String[]{"♦","♣","♥","♠"};
        // 字母牌
        String[] letter=new String[]{"J","Q","K","A"};
 
        // 数字牌部分
        int keyIndex=0;
        for (int i = 2; i < 11; i++) {
            for (int j = 0; j < FlowerColor.length; j++) {
                listPoker.add(keyIndex);    // 存放序号
                pokerBox.put(keyIndex++,new poker(FlowerColor[j],i+"",FlowerColor[j]+i));  // 将序号与牌产生对应关系
            }
        }
 
        // 字母牌部分
        for (int i = 0; i < letter.length; i++) {
            for (int j = 0; j < FlowerColor.length; j++) {
                listPoker.add(keyIndex);
                pokerBox.put(keyIndex++,new poker(FlowerColor[j],letter[i],FlowerColor[j]+letter[i]));
            }
        }
    }
    // 洗牌
    public void pokerShuffle(){
        Collections.shuffle(listPoker); // 打乱牌的序号
    }
    // 发牌
    public List<List<Integer>> dealCards(int playerNumber){
        // 对人数进行限制
        if((playerNumber*3) > pokerBox.size() || playerNumber <= 0){
            System.out.println("玩家超出限制,最多允许17位玩家、最少1一位玩家参加此游戏,请重新选择人数");
            return null;
        }
 
        // 玩家列表
        List<List<Integer>> playerList=new ArrayList<>();
 
        int k=3;    // 每位玩家牌的张数
 
        for (int i = 0,curIntdex=0; i < playerNumber; i++) {
            List<Integer> curPlayer=new ArrayList<>();
            // 每位玩家发三张牌
            for (int j = 0; j < k; j++) {
                curPlayer.add(listPoker.get(curIntdex++));
            }
            playerList.add(curPlayer); // 将当前玩家添加到玩家列表中
        }
 
        return playerList;
    }
 
    // 看牌
    public void lookPoker(List<List<Integer>> list){
 
        // 所有玩家
        for(int i=0,end=list.size(); i<end; ++i){
            System.out.print("玩家"+(i+1)+":");
            // 代表当前玩家
            List<Integer> curPople=list.get(i);
            // 玩家手中的牌
            for(int j=0,n=curPople.size(); j<n; ++j){
                // 从当前玩家curPople手中获取牌得序号,根据序号从牌盒PokerBox中取出牌来
                System.out.print(pokerBox.get(curPople.get(j)).value + " ");
            }
            System.out.println();
        }
        System.out.println();
    }
 
    // 玩家手牌进行排序
    public void playerPokerSort(List<List<Integer>> lists){
        // 最大手牌在第一位,第二次之....
        for (int i = 0; i < lists.size(); i++) {
            // 排序,逆序
            Collections.sort(lists.get(i),((o1, o2) -> (o2-o1)));
        }
    }
 
    // 比较函数
    public int cmp(List<Integer> a,List<Integer> b){
        // O(a.size)
        StringBuilder sbA=new StringBuilder();
        StringBuilder sbB=new StringBuilder();
 
        // 逆序取
        for(int i=a.size()-1; i>=0; --i){
            sbA.append(pokerBox.get(a.get(i)).faceValue);
            sbB.append(pokerBox.get(b.get(i)).faceValue);
        }
 
        Integer numA=map.get(sbA.toString());
        Integer numB=map.get(sbB.toString());
        if((numA != null && null == numB) || (null == numA && numB != null)){
            return (null == numA) ? -1 : 1;
        }else if(numA != null && numB != null){
            return numA-numB;
        }
 
        // O(a.size)
        for(int i=0,end=a.size(); i < end; ++i) {
            // 从两个玩家手中获取牌根号,获取到牌号后再从牌盒中取出牌面值来
            // 再从map中获取牌面值的大小,进行比较
            numA=map.get(pokerBox.get(a.get(i)).faceValue);
            numB=map.get(pokerBox.get(b.get(i)).faceValue);
 
            if (numA == numB) { continue; }
            // a玩家大于b玩家的情况
            if (numA > numB) { return 1; }
            // 小于的情况
            else { return -1; }
 
        }
        // 相等的情况
        return 0;
    }
 
    // 输出最大玩家的手牌
    public void printWinPlayer(List<List<Integer>> list){
        int maxIndex=0;
        List<Integer> maxPlayer=list.get(0);
 
        // 循环比较出最大玩家
        for(int i=1,end=list.size(); i<end; ++i){
            List<Integer> cur=list.get(i);
            if(cmp(maxPlayer,cur) < 0){
                maxIndex=i;
                maxPlayer=cur;
            }
        }
 
        System.out.print("最大的手牌是玩家"+(maxIndex+1)+":");
 
        List<Integer> ans=list.get(maxIndex);
        for(Integer i : ans){
            System.out.print(pokerBox.get(i).value + " ");
        }
        System.out.println();
    }
 
    public pokerGame(){
 
        // 同花顺的逻辑没有编写
 
        pokerShuffle(); // 洗牌
        int playyern=3; // 玩家人数
        List<List<Integer>> lists = dealCards(playyern);   // 发牌
 
        if(null == lists){
            System.out.println("玩家数不规范,程序退出");
            System.exit(-1);
        }
 
        lookPoker(lists);   // 看牌
 
        playerPokerSort(lists); // 每个玩家的手牌内进行排序
 
//        lookPoker(lists);
 
        printWinPlayer(lists);  // 输出手牌值最大的玩家
 
    }
 
}
 
class poker{
    // 花色与牌面值分离了
    // 汇总就是总值
    String flowerColor; // 花色
    String faceValue;   // 牌面值
    String value;       // 总值
 
    public poker(){}
 
    // 有参构造
    public poker(String flowerColor, String faceValue,String value) {
        this.flowerColor = flowerColor;
        this.faceValue = faceValue;
        this.value=value;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值