经典骰子游戏 YACHT
经典骰子游戏 YACHT
游戏需要的道具非常简单,总共五个骰子,加上每人一张积分表。游戏玩法大概是这样的:
游戏有13轮,每一轮按逆时针顺序依次进行每个人的回合。
一个人的回合中他需要投出五个骰子,按照一定的规则尽可能的拼凑出一定的花样来得到更高的分数。一个回合中有三次投骰子的机会。
第一次需要将五个骰子全部投出,第二次和第三次是选择已经投出过的骰子中不满意的进行roll,可以选择任意多个(比如全部重投,也可以不投)
三次机会结束后骰子的花样就确定了。这时候他需要选择积分表上的一项得分项目,将当前骰子计算得到的分数填入。每一个得分项目只能填一次。
得分项目种类是游戏规则的精髓所在,有这样一些得分规则:
任何时候都可以选取的得分项目:
五个骰子中有n个X,就得到X* n分,这被称为“Xs”,比如“1s”,“2s”,该分类总共有六项也就是1~6点可以各使用一次。注意n可以是0,比如投出较差花样而不像占据其他得分项目时可以填“1s”这一项,反正“1s”得分最多也就6分。
取五个骰子点数之和,称为“Dice Total”。虽然可以得到很不错的分数,但是由于只能用一次所以也要谨慎使用。
需要达成条件的得分项目:
有三个相同的X,得到X*3,称为“Three of the Same”
有四个相同的X,得到X*4,称为“Four of the Same”
有两个X和三个Y,得到25分固定得分,称为“Full House”
有四个点数连续的骰子,如1,2,3,4,得到固定得分30,称为“Small Straight”
五个骰子点数都连续,得到固定得分40,称为“Straight”
五个骰子是相同的点数,得到固定得分50,称为“Yahtzee”。这也是这个游戏的最大得分点和最终目的,可惜非常难达成。
这就是这个游戏的全部规则。在13轮之后,大家把总点数加和,决出最终胜者。
这学期我选了一门PSOC的课,期末大作业要求同学们自己搞一个在板子上跑的程序,可以是小游戏,于是我就用C将这个游戏实现了一遍。为什么要用C呢?因为PSOC开发板的编译器只支持C,而且还是非常老版本的C,不支持在for里面定义变量的那种,所有变量都需要在函数的开始定义。所以写这个程序也让我有点蛋疼,毕竟习惯了Python,突然回到C的严格语法让人不太舒服。这个板子还不只这点奇葩,上面CPU居然是8位的,这都快2020年了还在用8位的CPU。而且内存资源也太少了,开个256大小的整数数组就是极限了。不过好在板子的编译器还是支持一些基本库的,比如cmath和cstdlib之类的,不然随机数你叫我咋写。
这个程序是我昨天晚上写的,两个小时洋洋洒洒(大雾)写了400多行,结果跟室友玩的时候出了不少bug,改bug和修改代码又用了两个小时。明明今天就有一个搞不定的ddl,结果我还在写这个,看来我正事干啥啥不行,摸鱼倒是小能手。
因为课程PSOC板子的LCD屏只能显示两行文字,所以本游戏的操作逻辑都是为了PSOC设计的(当然在电脑上也可以运行才行)。得到输入的方式在板子上是触摸板,为了在电脑上能够初步运行并且debug,我将输入和输出都单独实现成函数,这就使得程序有了可移植性,到PSOC开发环境只需要将scanf换成触摸板的API,将printf换成LCD_1_PrCString就可以了。
这里放一张我写代码的界面,我对此非常满意。
代码界面
向大家强烈推荐微软的VSCODE编辑器。曾几何时我一直在寻找一款IDE能够符合我的需求,有好看的高亮(不像CodeBlocks那样亮瞎眼),有自动格式化,可以方便的运行。最后我却发现,最好的选择是VSCODE+WSL。VSCODE可以配置vim编辑器插件(vim是神),加上WSL后可以配置编译脚本并方便运行。唯一的缺点是debug不太方便,需要用gdb,不想Clion的监视窗口那么方便。不过相信大家写久了都已经成了人肉gdb了(笑)。另外最方便的是这段时间在看ARM的AMBA总线协议,需要用verilog仿真,而modelsim跑起来太繁琐了,我就自己写了一个iverilog和gtkwave的脚本,效果超神,让我一下就爱上了VSCODE。
最后把代码放在这里。也paste到了UbuntuPasteBin里面:
如果感兴趣,不妨自己编译玩一下。操作方式比较蛋疼,每次输入一个数字或者字母然后回车,程序会读取你的输入并且给出反应。建议在Linux环境下或者WSL环境下编译运行,否则你需要将delay函数里面的system(cls)改成system(clear),这是因为windows和linux的清屏命令不一样。
#include stdio.h
#include string.h
#include stdlib.h
#include unistd.h
#include time.h
//#define VERIFY_MODE
#define CLEAR_SCREEN
#ifdef VERIFY_MODE
#undef CLEAR_SCREEN
#endif
#define N_TURNS 13
#define N_CHANCES 2
#define N_METHODS 14
//including GIVE_UP
#define N_MAX_PLAYERS 6
#define BUFFER_SIZE 40
#define N_DICES 5
#define DELAY_PHASE 1
#define SHUFFLE_TIMES 50
#define DELAY_STEP 0.0
#define ONES 0
#define TWOS 1
#define THREES 2
#define FOURS 3
#define FIVES 4
#define SIXES 5
#define THREE_SAME 6
#define FOUR_SAME 7
#define FULL_HOUSE 8
#define SMALL_STRAIGHT 9
#define STRAIGHT 10
#define YACHT 11
#define TOTAL 12
#define GIVE_UP 13
int n_players;
char buffer_up[BUFFER_SIZE];
char buffer_down[BUFFER_SIZE];
int dices[N_DICES];
int dices_checked[N_DICES];
const char* methods[N_METHODS]={
ONES,
TWOS,
THREES,
FOURS,
FIVES,
SIXES,
THREE_SAME,
FOUR_SAME,
FULL_HOUSE,
SMALL_STRAIGHT,
STRAIGHT,
YACHT,
TOTAL,
GIVE_UP
};
struct score{
int methods[N_METHODS+1];
} score_board[N_MAX_PLAYERS];
void swap(int*a, int*b){
int temp;
temp=*a;
*a=*b;
*b=temp;
}
void clear_score_board(){
int i_player, i_method;
for(i_player=0;i_playerN_MAX_PLAYERS;i_player++){
for(i_method=0;i_method=N_METHODS;i_method++){
score_board[i_player].methods[i_method]=-1;
}
}
}
void eval_score_board(){
int i_player, i_method;
for(i_player=0;i_playerN_MAX_PLAYERS;i_player++){
for(i_method=0;i_methodN_METHODS;i_method++){
if(score_board[i_player].methods[i_method]==-1)
score_board[i_player].methods[i_method]=0;
}
}
for(i_player=0;i_playerN_MAX_PLAYERS;i_player++){
score_board[i_player].methods[N_METHODS]=0;
for(i_method=0;i_methodN_METHODS;i_method++)
score_board[i_player].methods[N_METHODS]+=score_board[i_player].methods[i_method];
}
}
void render_score_board(){
int i_player;
for(i_player=0;i_playern_players;i_player++){
sprintf(buffer_up+4*i_player,%4d,i_player+1);
sprintf(buffer_down+4*i_player,%4d,score_board[i_player].methods[N_METHODS]);
}
}
void
init() {
//not implemented
}
void
delay(float seconds) {
sleep(seconds);
}
int
get_input() {
char s[10];
scanf(%s, s);
if (s[0]0 || s[0]9)
return -1;
else
return s[0] - 0;
//if not success return -1;
}
void render_display();
void
render_display_up() {
render_display();
}
void
render_display_down() {
render_display();
}
void
render_display() {
#ifdef CLEAR_SCREEN
system(clear);
#endif
printf(%sn, buffer_up);
printf(%sn, buffer_down);
}
void clear_dices_checked(){
int i_dice;
for(i_dice=0;i_diceN_DICES;i_dice++)
dices_checked[i_dice]=0;
}
void check_dice(int i_dice){
dices_checked[i_dice]=!dices_checked[i_dice];
}
void
render_dices_down() {
int i_dice;
for(i_dice=0;i_diceN_DICES;i_dice++){
sprintf(buffer_down+i_dice*3,%1d%c ,dices[i_dice],dices_checked[i_dice]?^: );
}
}
void
shuffle_all_dices() {
int i_dice;
for (i_dice = 0; i_diceN_DICES; i_dice++)
dices[i_dice] = ((int) rand() % 6) + 1;
}
void shuffle_checked_dices(){
int i_dice;
for(i_dice=0;i_diceN_DICES;i_dice++)
if(dices_checked[i_dice])
dices[i_dice]=((int)rand()%6)+1;
}
void bubble_sort(int* base, int n){
int i, j;
for(int i=0;in-1;i++){
for(int j=0;jn-1;j++){
if(base[j]base[j+1])
swap(base[j],base[j+1]);
}
}
}
int validate_method(int i_method){
bubble_sort(dices,5);
if(i_method=ONESi_method=SIXES)
return 1;
else if(i_method==TOTAL || i_method==GIVE_UP)
return 1;
else switch(i_method){
case THREE_SAME:
if(
(dices[0]==dices[1]dices[1]==dices[2])||
(dices[1]==dices[2]dices[2]==dices[3])||
(dices[2]==dices[3]dices[3]==dices[4])
)
return 1;
else return 0;
case FOUR_SAME:
if(
(dices[0]==dices[1]dices[1]==dices[2]dices[2]==dices[3]) ||
(dices[1]==dices[2]dices[2]==dices[3]dices[3]==dices[4])
)
return 1;
else return 0;
case FULL_HOUSE:
if(
(dices[0]==dices[1]dices[1]==dices[2]dices[3]==dices[4]) ||
(dices[0]==dices[1]dices[2]==dices[3]dices[3]==dices[4])
)
return 1;
else return 0;
case SMALL_STRAIGHT:
if(dices[1]+1!=dices[2] || dices[2]+1!=dices[3])
return 0;
if(dices[0]+1==dices[1] || dices[3]+1==dices[4])
return 1;
else return 0;
case STRAIGHT:
if( dices[0]+1==dices[1]
dices[1]+1==dices[2]
dices[2]+1==dices[3]
dices[3]+1==dices[4])
return 1;
else return 0;
case YACHT:
if(
dices[0]==dices[1]
dices[1]==dices[2]
dices[2]==dices[3]
dices[3]==dices[4]
)
return 1;
else return 0;
default:
return 0;
}
}
int calculate_score(int i_method){
int tot=0;
int i_dice;
bubble_sort(dices,N_DICES);
if(i_method=ONESi_method=SIXES){
for(i_dice=0;i_diceN_DICES;i_dice++)
tot+=dices[i_dice]==(i_method+1)?dices[i_dice]:0;
return tot;
}
switch(i_method){
case THREE_SAME:
return dices[2]*3;
case FOUR_SAME:
return dices[2]*4;
case FULL_HOUSE:
if(dices[1]==dices[2])
return dices[2]*3+dices[3]*2;
else
return dices[1]*2+dices[2]*3;
case SMALL_STRAIGHT:
return 30;
case STRAIGHT:
return 40;
case YACHT:
return 50;
case TOTAL:
for(i_dice=0;i_diceN_DICES;i_dice++)
tot+=dices[i_dice];
return tot;
default:
return 0;
}
}
void f(int i_method){
render_dices_down();
render_display();
printf(%s:%snn,methods[i_method],validate_method(i_method)?YES:NO);
}
void verify_mode(){
for(int i=0;iN_DICES;i++)
dices[i]=1;
f(YACHT);
dices[0]=2;
f(YACHT);
for(int i=0;iN_DICES;i++)
dices[i]=i+1;
f(SMALL_STRAIGHT);
f(STRAIGHT);
dices[0]=5;
f(SMALL_STRAIGHT);
f(STRAIGHT);
for(int i=0;iN_DICES;i++)
dices[i]=2;
dices[0]=dices[1]=3;
f(FULL_HOUSE);
dices[0]=1;
f(FULL_HOUSE);
f(FOUR_SAME);
dices[0]=3;
f(FOUR_SAME);
f(THREE_SAME);
dices[1]=3;
f(FOUR_SAME);
f(THREE_SAME);
}
int no_dice_checked(){
int i_dice;
for(i_dice=0;i_diceN_DICES;i_dice++)
if(dices_checked[i_dice])
return 0;
return 1;
}
int
main() {
#ifdef VERIFY_MODE
verify_mode();
get_input();
#endif
srand((unsigned int) time(NULL));
int i_chance;
int i_turn;
int i_player;
int i_method;
int i_shuffle;
int i_misc;
int temp_input;
sprintf(buffer_up, Welcome to YACHT!);
sprintf(buffer_down, How many players?);
render_display();
n_players = get_input();
sprintf(buffer_up, You choosed %d players., n_players);
sprintf(buffer_down,);
render_display();
clear_score_board();
clear_dices_checked();
delay(DELAY_PHASE);
for (i_turn = 0; i_turnN_TURNS; i_turn++) {
for (i_player = 0; i_playern_players; i_player++) {
sprintf(buffer_up, You are the %dth player, i_player + 1);
sprintf(buffer_down, Touch any botton to start.);
render_display();
get_input();
sprintf(buffer_up, Shuffling.);
for (i_shuffle = 0; i_shuffleSHUFFLE_TIMES; i_shuffle++) {
shuffle_all_dices();
render_dices_down();
render_display_down();
delay(DELAY_STEP);
}
clear_dices_checked();
for (i_chance = N_CHANCES; i_chance = 1; i_chance--) {
sprintf(buffer_up, You have %d chance(s) left., i_chance);
render_display_up();
while(1){
temp_input = get_input() - 1;
if(temp_input0 || temp_inputN_DICES)
break;
check_dice(temp_input);
render_dices_down();
render_display();
}
if(no_dice_checked())
break;
for (i_shuffle=0;i_shuffleSHUFFLE_TIMES;i_shuffle++) {
shuffle_checked_dices();
render_dices_down();
render_display_down();
delay(DELAY_STEP);
}
clear_dices_checked();
render_dices_down();
render_display_down();
}
sprintf(buffer_up, The result is:);
render_display_up();
delay(DELAY_PHASE);
sprintf(buffer_up, 1 -choose- 3);
render_display_up();
delay(DELAY_PHASE);
i_method = 0;
while (1) {
if(validate_method(i_method)score_board[i_player].methods[i_method]==-1){
sprintf(buffer_up, %10s[%c] %d points.,
methods[i_method],
,calculate_score(i_method));
}
else{
sprintf(buffer_up, %10s[%c] You cant!,
methods[i_method],
score_board[i_player].methods[i_method] == -1 ?:^);
}
render_display_up();
temp_input = get_input();
if(temp_input == 1){
i_method = (i_method+N_METHODS-1)%N_METHODS;
continue;
}
else if(temp_input==3){
i_method=(i_method+N_METHODS+1)%N_METHODS;
}
else if(temp_input==2){
if(validate_method(temp_input))
break;
else continue;
}
}
sprintf(buffer_up, You choosed %s, methods[i_method]);
render_display_up();
delay(DELAY_PHASE);
if (i_method == GIVE_UP)//giveup
{
sprintf(buffer_up, You choosed GIVE_UP.);
render_display_up();
delay(DELAY_PHASE);
sprintf(buffer_up, You didnt get any point.);
render_display_up();
delay(DELAY_PHASE);
} else {
sprintf(buffer_up, You got %d points, calculate_score(i_method));
render_display_up();
delay(DELAY_PHASE);
score_board[i_player].methods[i_method] = calculate_score(i_method);
}
}
}
sprintf(buffer_up, The Game Ends.);
render_display_up();
delay(DELAY_PHASE);
eval_score_board();
render_score_board();
render_display();
}
以上就是(经典骰子游戏 YACHT)全部内容,收藏起来下次访问不迷路!