棋牌游戏斗牛

一、引言

棋牌游戏中的斗牛,是一种流行的牌类游戏,主要流行于中国。游戏中通常由2到6名玩家参与,使用一副去掉大小王的52张扑克牌。游戏的目标是通过组合手中的牌来赢得更多的分数,或者通过策略和技巧来阻止对手赢得分数。斗牛也被称为“牛牛”,在不同的地区可能会有不同的玩法和规则。

二、基本规则

1. **牌型组合**玩家需要将得到的五张牌进行三二组合,即其中一组为任意的三张牌,需组成的点数为10的倍数(花牌K、Q、J点数记为10,其余牌的点数为牌的数字大小)如果没有就记为0也就是没牛,最后比较剩下的两张相加的点数的个位数,如4+9记为牛一,8+7记为牛五,4+6记为牛牛(即两张牌点数相加等于10的倍数)等。
2. **牌型大小**牌型的大小顺序通常是比点数大小,如没牛<牛1<牛2<牛3<牛4<牛5<牛6<牛7<牛8<牛9<牛牛。有的玩法中,特定的牌型(如炸弹牛,五小牛,五金牛)会大于普通的牛牛。如果玩家点数相同就比较手上五张牌中最大的那张牌的大小,如K>Q>J等,如果牌的数值大小相同就比较花色大小(黑桃大于红桃大于梅花大于方块)。
3. **游戏过程**游戏开始时,庄家洗牌并发牌给所有玩家五张牌,包括自己。玩家根据自己的牌决定是否叫牌或放弃。叫牌的玩家需要下注,然后所有叫牌的玩家亮牌,比较牌型大小。牌型最大的玩家获得胜利,庄家需要根据游戏规则向获胜玩家支付相应的筹码。如果庄家的牌型最大,则其他玩家向庄家支付筹码。游戏结束后,庄家可以决定是否继续担任庄家,或者轮换其他玩家担任庄家。

三、JAVA代码实现

首先设置一个二维数组存储牌型信息

int[][] poker = new int[14][4];

二维系数表示牌型数值大小,一维系数表示牌型花色

发牌

设计一个随机数从牌库中随机抽取

public int number() {
        Random random = new Random();
        int index = 0;//记录牌数
        while (index < 52) {
            int a, b;
            a = random.nextInt(1, 14);//随机数
            b = random.nextInt(0, 4);
            if (poker[a][b] == 0) {//判断这张牌是否已经出现了,每张牌只能出现一次
                poker[a][b] = 1;//设置状态为1
                return a * 10 + b;//返回值设置为三位数,用来存储牌的信息,前两位表示牌的数字大小,个位数表示牌的花色,利于后续牌的大小比较
            }
            index++;
        }
        System.out.println("牌库见底");//所有牌的状态为1证明52张牌全部发完
        return 0;
    }
返回值设置为三位数,用来存储牌的信息,前两位表示牌的数字大小,个位数表示牌的花色,利于后续牌的大小直接比较

然后随机抽取五张牌,并输出牌型

  public int[] deal() {//随机发牌五张
        int[] num = new int[5];
        for (int i = 0; i < 5; i++) {//调用父类随机抽取的牌
            num[i] = super.number();
        }
        System.out.println("你的手牌为:");
        for (int i = 0; i < 5; i++) {
            int color = num[i] % 10;//取余数代表花色
            int number = num[i] / 10;//代表牌的数值
            if (color == 0) {
                if (number == 1) {
                    System.out.print("方块" + "A\t");
                } else if (number == 11) {
                    System.out.print("方块" + "J\t");
                } else if (number == 12) {
                    System.out.print("方块" + "Q\t");
                } else if (number == 13) {
                    System.out.print("方块" + "K\t");
                } else System.out.print("方块" + number + "\t");
            } else if (color == 1) {
                if (number == 1) {
                    System.out.print("梅花" + "A\t");
                } else if (number == 11) {
                    System.out.print("梅花" + "J\t");
                } else if (number == 12) {
                    System.out.print("梅花" + "Q\t");
                } else if (number == 13) {
                    System.out.print("梅花" + "K\t");
                } else System.out.print("梅花" + number + "\t");
            } else if (color == 2) {
                if (number == 1) {
                    System.out.print("红桃" + "A\t");
                } else if (number == 11) {
                    System.out.print("红桃" + "J\t");
                } else if (number == 12) {
                    System.out.print("红桃" + "Q\t");
                } else if (number == 13) {
                    System.out.print("红桃" + "K\t");
                } else System.out.print("红桃" + number + "\t");
            } else {
                if (number == 1) {
                    System.out.print("黑桃" + "A\t");
                } else if (number == 11) {
                    System.out.print("黑桃" + "J\t");
                } else if (number == 12) {
                    System.out.print("黑桃" + "Q\t");
                } else if (number == 13) {
                    System.out.print("黑桃" + "K\t");
                } else System.out.print("黑桃" + number + "\t");
            }
        }
        System.out.println("");
        return num;
    }

解释:将牌型大小固定第十位数表示数值,比如,K=130,Q=120,J=110直观看出大小,个位数表示花色大小,如,黑桃为3,红桃为2,梅花为1,方块为0,即 133>130,也就是黑桃K大于方块K

将牌型进行组合计算点数

利用循环遍历找出三张牌的组合为10的倍数,并输出剩下两张牌的点数。

 boolean found = false;
        for (int i = 0; i < 3; i++) {
            for (int j = i + 1; j < 4; j++) {
                for (int k = j + 1; k < 5; k++) {
                    if ((number[i] + number[j] + number[k]) % 10 == 0) {//依次遍历五张牌,选出任意三张牌之和为十的倍数
                        found = true;
                        int result = 0;
                        for (int l = 0; l < 5; l++) {
                            if (l != i && l != j && l != k) { // 只加上不在三个数中的数字,也就是剩下两张牌和的点数
                                result += number[l];
                            }
                        }
                        result = result % 10;//只留各位数代表点数
                        if (result == 0) {//为0代表点数为10意思就是满点
                            System.out.println("玩家点数为:满点");
                            return 10;
                        } else System.out.println("玩家点数为:" + result + "点");
                        return result;
                    }
                }
            }
        }
        if (!found) {//没有点数的情况
            System.out.println("玩家没有点数");
        }

将手牌数据初始化(花牌K、Q、J点数记为10,其余牌的点数为牌的数字大小)

  int[] number = new int[5];
        for (int i = 0; i < 5; i++) {//如果点数大于10按10算
            number[i] = num[i] / 10;
            if (number[i] > 10) {
                number[i] = 10;
            }
        }

点数比较大小

 public int comp(int[] num, int[] max) {//进行最后结果比较
        int number = num[0], record = 0;//赋初值
        for (int i = 0; i < num.length; i++) {
            if (num[i] > number) {//先从点数开始比较
                number = num[i];
                record = i;//记录位置,表示是哪个玩家的点数
            } else if (num[i] == number) {//如果点数相同,就比较花色
                if (max[i] > max[record]) {//max表示五张牌中最大的那张牌,花色大小,0为方块<1为梅花<2为红桃<3为黑桃
                    number = num[i];
                    record = i;
                }
            }
        }
        return record;//玩家几
    }

运行结果:

附录源码

Poker类定义棋牌

package Java基础.Poker;

import java.util.Random;

public class Poker {//扑克牌类
    private int[][] poker = new int[14][4];//第一个数表示纸牌的数字大小从一开始到13,第二个数表示纸牌的四种花色。

    public int[][] getPoker() {
        return poker;
    }

    public void setPoker(int[][] poker) {
        this.poker = poker;
    }

    public Poker() {//赋初值全设为0,如果用到了这张牌就设为1
        for (int i = 1; i < 14; i++) {
            for (int j = 0; j < 4; j++)
                poker[i][3] = 0;
        }
    }

    public int number() {
        Random random = new Random();
        int index = 0;//记录牌数
        while (index < 52) {
            int a, b;
            a = random.nextInt(1, 14);//随机数
            b = random.nextInt(0, 4);
            if (poker[a][b] == 0) {//判断这张牌是否已经出现了,每张牌只能出现一次
                poker[a][b] = 1;//设置状态为1
                return a * 10 + b;//返回值设置为三位数,用来存储牌的信息,前两位表示牌的数字大小,个位数表示牌的花色,利于后续牌的大小比较
            }
            index++;
        }
        System.out.println("牌库见底");//所有牌的状态为1证明52张牌全部发完
        return 0;
    }
}

玩家类Person

package Java基础.Poker;

public class Person {
    private String name;
    private int money = 30;
    public int result;

    public Person(String name) {
        this.name = name;
    }

    public int getMoney() {
        return money;
    }

    public void setMoney(int money) {
        this.money = money;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int sell(int money) {//扣钱
        if (this.money < money) {
            return 0;//设置状态,便于后期判断余额为空的情况
        } else
            this.money -= money;
        return 1;
    }

    public void buy(int money) {//加钱
        this.money += money;
    }

    public String toString() {
        return "姓名:" + name +
                "\t余额:" + money;
    }
}

斗牛游戏类Bullfight

package Java基础.Poker;

public class Bullfight extends Poker {//斗牛游戏
    public Bullfight() {//构造方法
        super();
    }

    public int comp(int[] num, int[] max) {//进行最后结果比较
        int number = num[0], record = 0;//赋初值
        for (int i = 0; i < num.length; i++) {
            if (num[i] > number) {//先从点数开始比较
                number = num[i];
                record = i;//记录位置,表示是哪个玩家的点数
            } else if (num[i] == number) {//如果点数相同,就比较花色
                if (max[i] > max[record]) {//max表示五张牌中最大的那张牌,花色大小,0为方块<1为梅花<2为红桃<3为黑桃
                    number = num[i];
                    record = i;
                }
            }
        }
        return record;//玩家几
    }

    public int value(int[] num) {//进行点数计算
        int[] number = new int[5];
        for (int i = 0; i < 5; i++) {//如果点数大于10按10算
            number[i] = num[i] / 10;
            if (number[i] > 10) {
                number[i] = 10;
            }
        }
        boolean found = false;
        for (int i = 0; i < 3; i++) {
            for (int j = i + 1; j < 4; j++) {
                for (int k = j + 1; k < 5; k++) {
                    if ((number[i] + number[j] + number[k]) % 10 == 0) {//依次遍历五张牌,选出任意三张牌之和为十的倍数
                        found = true;
                        int result = 0;
                        for (int l = 0; l < 5; l++) {
                            if (l != i && l != j && l != k) { // 只加上不在三个数中的数字,也就是剩下两张牌和的点数
                                result += number[l];
                            }
                        }
                        result = result % 10;//只留各位数代表点数
                        if (result == 0) {//为0代表点数为10意思就是满点
                            System.out.println("玩家点数为:满点");
                            return 10;
                        } else System.out.println("玩家点数为:" + result + "点");
                        return result;
                    }
                }
            }
        }
        if (!found) {//没有点数的情况
            System.out.println("玩家没有点数");
        }
        return 0;
    }

    public int[] deal() {//随机发牌五张
        int[] num = new int[5];
        for (int i = 0; i < 5; i++) {//调用父类随机抽取的牌
            num[i] = super.number();
        }
        System.out.println("你的手牌为:");
        for (int i = 0; i < 5; i++) {
            int color = num[i] % 10;//取余数代表花色
            int number = num[i] / 10;//代表牌的数值
            if (color == 0) {
                if (number == 1) {
                    System.out.print("方块" + "A\t");
                } else if (number == 11) {
                    System.out.print("方块" + "J\t");
                } else if (number == 12) {
                    System.out.print("方块" + "Q\t");
                } else if (number == 13) {
                    System.out.print("方块" + "K\t");
                } else System.out.print("方块" + number + "\t");
            } else if (color == 1) {
                if (number == 1) {
                    System.out.print("梅花" + "A\t");
                } else if (number == 11) {
                    System.out.print("梅花" + "J\t");
                } else if (number == 12) {
                    System.out.print("梅花" + "Q\t");
                } else if (number == 13) {
                    System.out.print("梅花" + "K\t");
                } else System.out.print("梅花" + number + "\t");
            } else if (color == 2) {
                if (number == 1) {
                    System.out.print("红桃" + "A\t");
                } else if (number == 11) {
                    System.out.print("红桃" + "J\t");
                } else if (number == 12) {
                    System.out.print("红桃" + "Q\t");
                } else if (number == 13) {
                    System.out.print("红桃" + "K\t");
                } else System.out.print("红桃" + number + "\t");
            } else {
                if (number == 1) {
                    System.out.print("黑桃" + "A\t");
                } else if (number == 11) {
                    System.out.print("黑桃" + "J\t");
                } else if (number == 12) {
                    System.out.print("黑桃" + "Q\t");
                } else if (number == 13) {
                    System.out.print("黑桃" + "K\t");
                } else System.out.print("黑桃" + number + "\t");
            }
        }
        System.out.println("");
        return num;
    }

    public int max(int[] num) {//比较五张牌中最大的那张
        int number = num[0];
        for (int num1 : num) {
            if (num1 > number) {
                number = num1;
            }
        }
        return number;
    }
}

测试运行

package Java基础.Poker;

import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.InputMismatchException;
import java.util.Scanner;

import static java.lang.System.exit;

public class Game {
    public static void main(String[] args) {
        try {//输入的异常处理
            Scanner scanner = new Scanner(System.in);
            System.out.println("欢迎来到PokerGame!");
            Person[] play = new Person[4];//对象数组
            System.out.println("请输入你姓名");
            String name = scanner.next();
            play[3] = new Person(name);
            play[0] = new Person("李四");
            play[1] = new Person("王五");
            play[2] = new Person("老六");
            System.out.println("欢迎玩家" + play[3].getName() + "加入!");
            System.out.println("游戏即将开始");
            while (true) {//输入循环判断
                System.out.println("是否开始发牌(是,1/否,0)");
                int start = scanner.nextInt();//开始游戏
                if ((start != 1) && (start != 0)) {//输入判断
                    System.out.println("输入不匹配,请重新输入");
                    continue;
                }
                int index = 1;//记录游戏次数
                while (true) {
                    if (start == 1) {
                        System.out.println("第" + index + "轮发牌开始:");
                        for (int i = 0; i < 4; i++) {//打印玩家信息
                            System.out.println(play[i].toString());
                        }
                        Bullfight bullfight = new Bullfight();//放置循环内,以格式化牌型数组的初值
                        int[] max = new int[4];
                        for (int i = 0; i < 4; i++) {
                            System.out.println("给" + play[i].getName() + "玩家发牌");
                            int[] num = Arrays.copyOf(bullfight.deal(), 5);//拷贝一份
                            play[i].result = bullfight.value(num);//存储玩家的点数
                            max[i] = bullfight.max(num);//记录五张牌中的最大的那一张
                            System.out.println();
                        }
                        int[] num = new int[4];
                        for (int i = 0; i < 4; i++) {
                            num[i] = play[i].result;
                        }
                        int value = bullfight.comp(num, max);//进行大小比对,输出玩家指针号
                        System.out.print("玩家" + play[value].getName() + "获胜\t\t\t");
                        Date now = new Date();
                        // 创建SimpleDateFormat对象,指定日期格式
                        SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss");
                        // 使用format方法将Date对象转换为字符串
                        String formattedDate = formatter.format(now);
                        // 打印当前时间
                        System.out.println("时刻:" + formattedDate);
                        play[value].buy(40);//获胜玩家加40,本来是加30,这里是为了方便计算
                        for (int i = 0; i < 4; i++) {//所有玩家扣10
                            if (play[i].sell(10) == 0) {
                                System.out.println();
                                System.out.print("游戏结束\t玩家" + play[i].getName() + "余额不足\t");//玩家余额不足的情况反馈
                                if (((i + 1)) < 4 && (play[i + 1].sell(10) == 0)) {//判断多位玩家同时余额为0时的输出
                                    System.out.print("玩家" + play[i + 1].getName() + "余额不足\t");
                                }
                                if (((i + 2)) < 4 && (play[i + 1].sell(10) == 0)) {
                                    System.out.print("玩家" + play[i + 2].getName() + "余额不足\t");
                                }
                                if (((i + 3)) < 4 && (play[i + 1].sell(10) == 0)) {
                                    System.out.print("玩家" + play[i + 3].getName() + "余额不足\t");
                                }
                                System.out.println();
                                for (int j = 0; j < 4; j++) {
                                    System.out.println(play[j].toString());//打印最终的玩家信息
                                }
                                exit(0);//结束运行
                            }
                        }
                        System.out.println();
                        index++;
                        int end;
                        while (true) {//输入判断
                            System.out.println("是否继续发牌(是,1/否,0)");
                            end = scanner.nextInt();
                            if ((end != 1) && (end != 0)) {
                                System.out.println("输入不匹配,请重新输入");
                                continue;
                            }
                            break;
                        }
                        if (end == 0) {//结束游戏
                            break;
                        }

                    } else break;
                }
                for (int i = 0; i < 4; i++) {
                    System.out.println(play[i].toString());
                }
                break;
            }
        } catch (InputMismatchException e) {//输入类型不匹配
            System.out.println("输入出错了,游戏结束");
        }
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值