博饼小游戏

一、实验要求

游戏规则

设计并编程实现博饼小游戏,游戏规则如下:
游戏使用骰子一副(6个),参与游戏的玩家轮流依次掷骰子,看骰子点数得饼:
(1)有1个“四点”,得“一秀”饼;
(2)有2个“四点”,得“二举”饼;
(3)有3个“四点”,得“三红”饼;
(4)有4个相同点数(除四点外),得“四进”饼;
(5)若骰子点数分别为1-6顺序排列,得“对堂”饼;
(6)玩家得“状元”饼的情况有几种,其等级按从小到大排列如下:

  • a)有4个“四点”,得“状元”;
  • b)有5个相同点数的,得“五子登科”;
  • c)有4个“四点”,加上2个“一点”,得“状元插金花”;

(7)特殊情况: 若玩家掷出6个“四点”得“六杯红”,则直接夺得所有奖品。

程序要求

(1):游戏开始时,可由玩家设置奖品数,例如:设“状元”1个,“对堂”2个,“三红”4个,“四进”8个,“二举”16个,“一秀”32个。
(2):游戏开始时,可设定玩家人数,游戏中应提示各位玩家轮流依次掷骰子,例如“1号玩家请掷筛子:y”;
(3)游戏中,应显示玩家每次掷得的点数,并显示得奖情况。例如“1,2,3,5,5,6 无奖,继续努力”;“1,4,4,3,5,6 二举,恭喜”。程序应能保存各位玩家得奖的记录。
(4)游戏设定的“一秀”、“二举”、“三红”、“四进”、“对堂”的奖品若领完,后续玩家若再掷出此类点数,不再得奖。但在上述奖品领完前,“状元饼”采取追饼的方式,即在其他奖品分完前,后一个掷得“状元”的人若比前一个“状元”等级大,则可追得“状元饼”。
(5)所有奖品分完,游戏结束。或者某玩家掷出6个“四点”,夺得所有奖品,其他玩家将同时失去所有奖品,游戏结束。
(6)游戏结束后,应输出所有玩家得奖情况。

二、实验总体设计方案

(1)在控制台运行本程序。
(2)初始化游戏,输入玩家数量,奖池中各种奖励的数量(状元默认数量为1)来初始化奖池。
(3)每一轮所以玩家轮流投掷骰子6次,每轮结束后打印输出每个玩家本轮的6次骰子的点数以及获得的奖品。
(4)当奖池中的奖品被领完后游戏结束,输出所有玩家获得的奖品。

类说明
Prize类:奖品类,每种奖品的数量作为其属性,可以用来描述讲出,以及构成各个玩家获得的奖品情况。
Player类:玩家,每个玩家有其序号、奖品、一轮的骰子点数。
BoCake类:游戏的主类,实现玩家玩游戏的过程(开始到结束)。
GameUtil类:游戏过程的各种工具类函数封装其中,包括玩家的初始化、奖池的初始化、玩家奖品的获得等等。
PrizeJudgeUtil类:用于判别一个玩家一轮投掷的点数所对应的奖品。

三、实验关键代码

以下用BoCake类(主类)的代码来表现出整体的游戏过程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
package com.boCake;

import java.util.Scanner;

public class BoCake {

private Player player[];
private Prize prize;
private GameUtil gameUtil = new GameUtil();
private PrizeJudgeUtil prizeJudgeUtil = new PrizeJudgeUtil();
private Prize originalPrize;

public Prize getPrize() {
return prize;
}

public void setPrize(Prize prize) {
this.prize = prize;
}

public Player[] getPlayer() {
return player;
}

public void setPlayer(Player[] player) {
this.player = player;
}

/*
* 主函数
*/
public static void main(String[] args) {
BoCake boCake = new BoCake();
boCake.initGame();
boCake.playGame();
boCake.gameOver();

}

/**
* 初始化游戏
*/
private void initGame() {
this.player= this.gameUtil.initPlayer();
this.originalPrize= this.gameUtil.initPrize();
this.prize = this.originalPrize;
}

/**
*开始游戏
* @param player
* @param prize
*/
public void playGame() {
int i=1;//i为轮次
int flag=0;//后的六杯红的玩家的id
Scanner input = new Scanner(System.in);
for(i=1;!prizeJudgeUtil.prizeIsEmpty(this.getPrize())&&flag==0;i++) {
System.out.println("第" + i + "轮开始");
//进行一轮的投掷骰子
for(int j=1;j<=6;j++) {
for(int k=0;k<this.gameUtil.getN();k++) {
System.out.println(this.player[k].getId() + "号玩家第" + j + "次掷得筛子:" + this.player[k].setArr(j-1));
}
System.out.println();
}
//一轮结束,打印奖品
for(int k=0;k<this.gameUtil.getN();k++) {
System.out.print(this.player[k].getId() + "号玩家第" + i + "轮掷得点数:");
this.player[k].printArr();
//判断奖品
Prize t_pirce = this.prizeJudgeUtil.prizeJudge(this.player[k].getArr());
Prize r_prize[] = this.gameUtil.prizeResult(prize, t_pirce, player[k].prize);
this.setPrize(r_prize[0]);
this.player[k].setPrize(r_prize[1]);
Prize b_prize = r_prize[2];

//六杯红特殊情况
if(this.prize.getZY_level()==4) {
flag=this.player[k].getId();
break;
}

//打印奖品
b_prize.PrintPrize(1);

//有状元或状元被抢
if(b_prize.ZhuangYuan>0) {
if(this.prize.getZY_id()!=0) {
this.player[this.prize.getZY_id()-1].prize.ZhuangYuan--;
if(this.player[k].getId()!=this.prize.getZY_id()) {
System.out.println(this.prize.getZY_id() + "号玩家的“状元”奖品被" + this.player[k].getId() + "号玩家抢走");
prize.setZY_id(this.player[k].getId());
}
}else {
this.prize.setZY_id(this.player[k].getId());
}
}
}
//六杯红情况处理
if(flag>0) {
System.out.println("恭喜" + flag + "号玩家获得“六杯红”,获得奖池所有奖品!");
this.player=this.gameUtil.LiuBeiHong(this.player, flag, this.gameUtil.getN(), originalPrize);
this.prize=new Prize();
break;
}
this.prize.PrintPrize(0);
System.out.print("按回车键开始下一轮");
System.out.println("----------------------------------");
input.nextLine();
}
}
/**
* 游戏结束,打印奖品
*/
public void gameOver() {
System.out.println("游戏结束");
this.gameUtil.displayPrize(this.player, this.gameUtil.getN());
}
}

四、实验结果

初始化游戏,对玩家数量及奖池进行初始化

某一轮次的执行过程如下

每轮结束后会打印本轮各个玩家的点数和获奖情况已经奖池的剩余奖品情况

奖池清空,游戏结束,打印各个玩家的获奖情况

五、实验总结

本次实验的内容为一个游戏,由于自己第一次接触这个游戏,对于游戏规则的理解花费了一些时间,主要是各种点数对应的奖品的判断逻辑需要理解。
在开始设计是,对于奖池的设计和每位玩家获得的奖品是分开来的,但是这样设计后发觉有些复杂,于是把这两个都用Prize类来表示,简化了一些不必要的设计。对于游戏规则中每种点数对应的奖品的判断是这个游戏的重点,我用的是简单的逻辑判断,每种奖品设计一种判断方法,去除掉一些重叠的部分,所以判断奖品的PrizeJudgeUtil类设计的有些复杂。
可能在整体的框架上可以做得比我这次设计的更加简单,感觉这次写的代码过于冗杂了。