闽南特色--Java编写的博饼程序

博饼模拟器

基本题目:

请按照游戏规则,编程实现:随机生成六个筛子点数并判断得奖情况,注意需要考虑到多个奖项的情况,比如四进带一秀。并实现以下功能。

  1. 提醒用户输入玩家数(6-10)。
  2. 循环为每个玩家生成六个筛子点数(1-6),根据上图的规则判断所产生的骰子对应的奖项,并输出。
  3. 游戏结束时(所有奖项已经出完),输出每个玩家所获得的奖项以及每个奖项的个数。

博饼游戏规则如下

具体实现

  • Gamer
    • 用途:存储玩家的唯一编号(code)和玩家获奖情况(prize)。
    • 成员变量
      • int code:玩家的唯一编号。
      • List<String> prize:存储玩家获得的奖品名称。
    • 构造方法
      • Gamer(int code):初始化玩家编号,并创建奖品列表。
    • 主要方法:无。由于本次实验考察的是控制程序,所以没有对Gamer类进行封装,将其以类似c语言结构体的方式调用。
    • 调用关系:Gamer类的实例被存储在Main类的gamers数组中,用于记录每个玩家的获奖情况。
  • Main
    • 用途:实现博饼游戏的主要逻辑,包括奖项初始化、博饼过程、奖品分配、玩家获奖统计等。
    • 成员变量
      • static final int DiceNumber:骰子的数量,固定为6。
      • static final int[] AllPrize:存储各类奖品的数量,下标表示奖品类型。
      • static final int YI_XIU, ER_JU, SI_JIN, SAN_HONG, DUI_TANG, ZHUANG_YUAN:奖品类型的编码,方便通过下标访问奖品数量。
      • static Gamer[] gamers:存储所有玩家的数组。
    • 主要方法
      • main(String[] args):程序入口,与用户交互,读取玩家数量,初始化玩家数组,并调用BoBing方法开始游戏。
      • BoBing(int number):实现博饼的核心逻辑,包括骰子投掷、中奖判断、奖品分配,直到所有奖品分配完毕。
      • PrizeInit():初始化各类奖品的数量。
      • PrizeEmpty():检查是否所有奖品已分配完毕。
      • PrizeCount(List<String> prize):统计玩家获得的奖品及其数量,方便输出结果。返回一个Map,里面有奖品名称和数量的对应关系
      • MyRandom():生成6个骰子的随机结果。
      • JudgeDices(int[] dices):根据骰子结果判断中奖情况。实现思路从统计投出4点的骰子个数出发,先写出主要的分支,在根据四的个数检查其他可能中奖的情况
      • GetPrize(String prize_name):检查奖品是否还有剩余,并分配奖品。
    • 调用关系
      • main方法调用BoBing方法开始游戏。
      • BoBing方法在每次博饼过程中调用MyRandom生成骰子结果,调用JudgeDices判断中奖情况,调用GetPrize分配奖品。
      • JudgeDices方法根据骰子结果调用GetPrize获取奖品。
      • 游戏结束后,main方法调用PrizeCount统计每个玩家的获奖情况并输出。

主要方法的实现逻辑

  • BoBing(int number)方法
    • 初始化奖品数量(调用PrizeInit)。
    • 循环进行博饼过程,模拟博饼时轮流投骰子的过程,直到所有奖品分配完毕(通过PrizeEmpty判断)。
    • 每次博饼时:
      • 生成骰子结果(调用MyRandom)。
      • 判断中奖情况(调用JudgeDices)。
      • 将获得的奖品添加到当前玩家的奖品列表中。
    • 游戏结束后,统计并输出每个玩家的获奖情况(调用PrizeCount)。
  • JudgeDices(int[] dices)方法
    • 统计每个点数的骰子数量。
    • 根据点数分布判断中奖情况,实现思路从统计投出4点的骰子个数出发,先写出主要的分支,在根据四的个数检查其他可能中奖的情况
    • 精心设计分支,使得每次可以进行尽量少的判断,并支持多个奖项同时获奖的情况。
    • 调用GetPrize方法检查奖品是否还有剩余,并获取奖品名称。
    • 返回本次博饼获得的所有奖品名称。
  • GetPrize(String prize_name)方法
    • 根据传入的奖品名称,检查对应奖品是否还有剩余。
    • 如果有剩余,减少奖品数量并返回奖品名称;如果没有剩余,返回null。

Java代码

import java.util.*;
//玩家类,实现玩家的唯一编号识别和玩家获奖情况的存储
class Gamer{
    int code;
//    int[] dice;
    List<String> prize ;
    Gamer(int code){
        this.code=code;
        prize =new ArrayList<>();
    }
}

public class Main {
    static final int DiceNumber=6;
    //为了方便计算剩余的奖品数量,以数组存储各类奖励的数量,下标表示奖品名称
    static final int YI_XIU=0;
    static final int ER_JU=1;
    static final int SI_JIN=2;
    static final int SAN_HONG=3;
    static final int DUI_TANG=4;
    static final int ZHUANG_YUAN=5;
    //所有的奖励存在这里
    static int [] AllPrize=new int[6];

    static Gamer[] gamers;//玩家数组
//    Random rand=new Random();

    public static void main(String[] args) {
        int number ;
        System.out.println("请输入玩家数量(6-10):");
        Scanner in = new Scanner(System.in);
        number= in.nextInt();
        gamers=new Gamer[number];
        for(int i=0;i<number;i++){
            gamers[i]=new Gamer(i);
        }
        BoBing(number);
    }
    //奖项的初始化
    public static void PrizeInit(){
        int base=32;
        for(int i=0;i<6;i++ ){
            AllPrize[i]=base;
            base/=2;
        }
    }
    //检查奖励是否发完
    public static boolean PrizeEmpty(){
        for(int i=0;i<6;i++){
            if(AllPrize[i]>0) return false;
        }
        return true;
    }

    //博饼代码
    public  static void BoBing(int number){
        PrizeInit();
        int i=0;
        while(!PrizeEmpty()){
            i++;
            i%=number;
            int []dice=MyRandom();
            List<String> thisPrize= JudgeDices(dice);//本次投骰子获得的奖项
            //由于反复输出博饼过程,会很长,所以注释掉,需要调试可以运行
//            System.out.println("玩家"+(i+1)+":"+Arrays.toString(dice)+thisPrize);
            gamers[i].prize.addAll(thisPrize);
        }
        for(int j=0;j<number;j++){

            System.out.println("玩家"+(j+1)+"获得了奖品:"+PrizeCount(gamers[j].prize));
        }
    }
    //计数每个玩家都获得了哪些奖品以及奖品数量,方便输出
    public static Map<String, Integer> PrizeCount(List<String> prize){
        Map<String,Integer> prizePrint = new HashMap<>();
        prize.forEach(prize_name->{
            Integer counts =prizePrint.get(prize_name);
            prizePrint.put(prize_name,counts==null?1:++counts);
        });
        return prizePrint   ;
    }
    //生成六个骰子的结果,每个都是1-6的随机数
    public static int[] MyRandom(){
        int [] res= new int[DiceNumber];
        Random rand = new Random();
        for (int i=0;i<DiceNumber;i++){
            res[i]=rand.nextInt(6)+1;
        }

        return res;
    }
    //检查一次博饼的中奖情况
    //本函数实现思路从统计投出4点的骰子个数出发,先写出主要的分支,在根据四的个数检查其他可能中奖的情况
    public static List<String> JudgeDices(int [] dices){
        List<String> res =new ArrayList<>();
        int []count=new int [DiceNumber+1];
        for(int i :dices)
            count[i]++;
        int flag=1;
        for(int i=1;flag==1&&i<DiceNumber+1;i++){
            if(flag==1) flag=count[i];
        }
        if(flag==1) {
            res.add(GetPrize("对堂"));//先检查对堂,拿了对堂不可以再拿一秀了
            res.removeIf(Objects::isNull);
            return res;
        }
        switch (count[4]){
            case 1:res.add(GetPrize("一秀"));
                if( count[2]==5||count[3]==5||count[5]==5||count[6]==5)
                    res.add(GetPrize("五子"));
                if(count[1]==4) res.add(GetPrize("四进"));
            break;
            case 2:res.add(GetPrize("二举"));
                if(count[1]==4) res.add(GetPrize("四进"));
            break;
            case 3:res.add(GetPrize("三红"));break;
            case 4:
                if(count[1]==2) res.add(GetPrize("状元插金花"));
                else res.add(GetPrize("四红"));
            break;
            case 5:res.add(GetPrize("五王"));break;
            case 6:res.add(GetPrize("六勃红"));break;
            default:
                if(count[2]==5||count[3]==5||count[5]==5||count[6]==5)res.add(GetPrize("五子"));
                if(count[1]==4) res.add(GetPrize("四进"));
                if(count[2]==6||count[3]==6||count[5]==6||count[6]==6)res.add(GetPrize("六勃黑"));
                if(count[1]==6) res.add(GetPrize("遍地锦"));
        }
        res.removeIf(Objects::isNull);
        return res;
    }
    //检查奖品还够不够并分配奖品,代码复用率有点高,可能还能优化?
    public static String GetPrize(String prize_name){
        if(prize_name.equals("一秀")&&AllPrize[YI_XIU]>0){
            AllPrize[YI_XIU]--;
            return prize_name;
        }
        if(prize_name.equals("二举")&&AllPrize[ER_JU]>0){
            AllPrize[ER_JU]--;
            return prize_name;
        }
        if(prize_name.equals("三红")&&AllPrize[SAN_HONG]>0){
            AllPrize[SAN_HONG]--;
            return prize_name;
        }
        if(prize_name.equals("四进")&&AllPrize[SI_JIN]>0){
            AllPrize[SI_JIN]--;
            return prize_name;
        }
        if(prize_name.equals("对堂")&&AllPrize[DUI_TANG]>0){
            AllPrize[DUI_TANG]--;
            return prize_name;
        }
        if(prize_name.equals("四红")&&AllPrize[ZHUANG_YUAN]>0){
            AllPrize[ZHUANG_YUAN]--;
            return "状元:"+prize_name;
        }
        if(prize_name.equals("五子")&&AllPrize[ZHUANG_YUAN]>0){
            AllPrize[ZHUANG_YUAN]--;
            return "状元:"+prize_name;
        }
        if(prize_name.equals("五王")&&AllPrize[ZHUANG_YUAN]>0){
            AllPrize[ZHUANG_YUAN]--;
            return "状元:"+prize_name;
        }
        if(prize_name.equals("状元插金花")&&AllPrize[ZHUANG_YUAN]>0){
            AllPrize[ZHUANG_YUAN]--;
            return "状元:"+prize_name;
        }
        if(prize_name.equals("六勃红")&&AllPrize[ZHUANG_YUAN]>0){
            AllPrize[ZHUANG_YUAN]--;
            return "状元:"+prize_name;
        }
        if(prize_name.equals("六勃黑")&&AllPrize[ZHUANG_YUAN]>0){
            AllPrize[ZHUANG_YUAN]--;
            return "状元:"+prize_name;
        }
        if(prize_name.equals("遍地锦")&&AllPrize[ZHUANG_YUAN]>0){
            AllPrize[ZHUANG_YUAN]--;
            return "状元:"+prize_name;
        }
        return null;
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值