博饼模拟器
基本题目:
请按照游戏规则,编程实现:随机生成六个筛子点数并判断得奖情况,注意需要考虑到多个奖项的情况,比如四进带一秀。并实现以下功能。
- 提醒用户输入玩家数(6-10)。
- 循环为每个玩家生成六个筛子点数(1-6),根据上图的规则判断所产生的骰子对应的奖项,并输出。
- 游戏结束时(所有奖项已经出完),输出每个玩家所获得的奖项以及每个奖项的个数。
博饼游戏规则如下
具体实现
- 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;
}
}