当前位置:首页 > 知识 > 

经典骰子游戏 YACHT

经典骰子游戏 YACHT

经典骰子游戏 YACHT 游戏需要的道具非常简单,总共五个骰子,加上每人一张积分表。游戏玩法大概是这样的: 游戏有13轮,每一轮按逆时针顺序依次进行每个人的回合。 一个人的回合

经典骰子游戏 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)全部内容,收藏起来下次访问不迷路!