一、前言

最近在阅读《unix-linux编程实践教程》,这本书很适合学习完Linux基础编程后想码点东西实践的朋友。它主要是通过带领读者学习编写Linux系统中常用的命令(ls、more等)来巩固基础知识。本人从中收获颇丰,在这里推荐给各位想学习Linux系统编程的朋友。下载路径:https://download.csdn.net/download/q1449516487/10724621

二、掷骰子游戏

1.curses库(图形函数库)

(1)这个游戏运用到了curses库,它是一个在Linux/Unix下广泛应用的图形函数库.,作用是可以绘制在终端下的用户界面和漂亮的图形。

(2)安装方法:sudo apt-get install libncurses5-dev

(3)重要函数

curses库函数
函数 功能
initscr()

初始化curses库和ttty

(在开始curses编程之前,必须使用initscr()这个函数来开启curses模式)

endwin()

关闭curses并重置tty

(结束curses编程时,最后调用的一个函数)

move(y,x) 将游标移动至 x,y 的位置
getyx(win,y,x) 得到目前游标的位置(请注意!是 y,x 而不是&y,&x)
clear() and erase() 将整个萤幕清除(请注意配合refresh() 使用)
echochar(ch) 显示某个字元
addch(ch) 在当前位置画字符ch
mvaddch(y,x,ch) 在(x,y) 上显示某个字元。相当於呼叫move(y,x);addch(ch);
addstr(str) 在当前位置画字符串str
mvaddstr(y,x,str) 在(x,y) 上显示一串字串。相当於呼叫move(y,x);addstr(str);
printw(format,str) 类似 printf() ,以一定的格式输出至萤幕
mvprintw(y,x,format,str) 在(x,y) 位置上做 printw 的工作。相当於呼叫move(y,x);printw(format,str);
getch() 从键盘读取一个字元。(注意!传回的是整数值)
getstr() 从键盘读取一串字元。
scanw(format,&arg1,&arg2...) 如同 scanf,从键盘读取一串字元。
beep() 发出一声哔声
box(win,ch1,ch2) 自动画方框
refresh() 使屏幕按照你的意图显示。比较工作屏幕和真实屏幕的差异,然后refresh通过终端驱动送出那些能使真实屏幕于工作屏幕一致的字符和控制码。(工作屏幕就像磁盘缓存,curses中的大部分的函数都只对它进行修改)
standout() 启动standout模式(一般使屏幕发色)
standend()

关闭standout模式

2.时间间隔器

(1)使用到时间间隔器,主要的作用是让电脑自动掷骰子。该时间间隔期的本质是一个时钟信号,我们通过设定间隔时间,内核在到达我们设定的时间时就会向进程发送一个时钟信号,进而程序调用操作函数实现功能。(信号也可以理解为我们熟悉的中断)

(2)操作函数

函数语法
函数 int getitimer(int which, struct itimerval *curr_value);
int setitimer(int which, const struct itimerval *new_value, struct itimerval *old_value);
变量 which ITIMER_REAL:这个计时器计量真实事件,如同手表记录时间。也就是说不管程序在用户态还是核心态用了多少处理器时间它都记录。当这个计时器用尽,发送SIGALRM消息。
ITIMER_VIRTUAL:这个计时器只有进程在用户态运行时才计时。虚拟计时器的30s比实际计时器的30s要长。当虚拟计时器用尽,发送SIGVTALRM消息。
ITIMER_PROF:这个计时器在进程运行于用户态或由该进程调用而陷入核心态时计时。当这个计时器用尽时,发送SIGPROF消息。
new_value it_value:初始时间(第一次执行的时间间隔)
it_interval:重复间隔
old_value 用于获取已存在的时钟。

3.掷骰子游戏的构想

首先这是一个单机游戏,通过curses库来绘制图形,时钟信号来充当电脑的角色。开始游戏后玩家和电脑都有本金100元,每局下注的金额为固定的10元,通过规则会有1倍、3倍和5倍的赔率。

牌型和规则
牌型 五倍牌:三颗骰子都相同
三倍牌:三骰子为顺序排(123、234等)
普通牌:除五倍和三倍以外的牌型
游戏规则 大倍率的牌型胜过小倍率的牌型
牌型相同时,点数大的胜出

4.代码

(1)主函数(main.c)

/*main.c*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <curses.h>
#include "GameLib.h"
#include "dice.h"
#include "unistd.h"extern Player player;      //玩家
extern Computer computer;   //电脑
extern Umpire umpire;       //裁判int main()
{int c;char str[10];dice_init(); //游戏初始化while((c = getchar()) != 'Q')//按键输入{if(c == 'r' && player.status == NoReady) //玩家每局游戏刚开始的时候状态为未准备,输入'r'表示准备完毕{ player.status = Ready;WriteStr(PLAYER_STATUS_X,PLAYER_STATUS_Y,strlen(BLANK),BLANK);WriteStr(PLAYER_STATUS_X,PLAYER_STATUS_Y,strlen(READY),READY);refresh();}else if(player.status == Ready && c == ' ')//玩家每按一下空格键代表摇一个骰子{if(!player.dice1.dice_flag)player.dice1.dice_flag = 1;         //骰子1的标志,置1表示骰子数值确定else if(!player.dice2.dice_flag)player.dice2.dice_flag = 1;  //骰子2的标志,置1表示骰子数值确定else if(!player.dice3.dice_flag)player.dice3.dice_flag = 1;  //骰子3的标志,置1表示骰子数值确定//当三个骰子都确定后,玩家的状态为操作完毕if(player.dice1.dice_flag &&player.dice2.dice_flag &&player.dice3.dice_flag){player.status = Finish;WriteStr(PLAYER_STATUS_X,PLAYER_STATUS_Y,strlen(BLANK),BLANK);WriteStr(PLAYER_STATUS_X,PLAYER_STATUS_Y,strlen(FINISH),FINISH);}}money_rule();//判断输赢if(player.status == Game_Win)//玩家胜利{ClearSCR(1,5,SCR_X/2-1,SCR_Y-11);ClearSCR(SCR_X/2+1,5,SCR_X/2-1,SCR_Y-11);ClearSCR(SCR_X*1/4+1,SCR_Y-7+3,SCR_X/2,7-3);WriteStr(PLAYER_GR_X,PLAYER_GR_Y,strlen(GAME_WIN),GAME_WIN);WriteStr(COMPUTER_GR_X,COMPUTER_GR_Y,strlen(GAME_FAIL),GAME_FAIL);WriteStr(SCR_X/2,SCR_Y-3,12,"'Q' to exit");refresh();stop_shake();}else if(player.status == Game_Fail)//玩家失败{ClearSCR(1,5,SCR_X/2-1,SCR_Y-11);ClearSCR(SCR_X/2+1,5,SCR_X/2-1,SCR_Y-11);ClearSCR(SCR_X*1/4+1,SCR_Y-7+3,SCR_X/2,7-3);WriteStr(PLAYER_GR_X,PLAYER_GR_Y,strlen(GAME_FAIL),GAME_FAIL);WriteStr(COMPUTER_GR_X,COMPUTER_GR_Y,strlen(GAME_WIN),GAME_WIN);WriteStr(SCR_X/2,SCR_Y-3,12,"'Q' to exit");refresh();stop_shake();}//当玩家和电脑都准备好时,裁判状态为开始if(player.status == Ready && computer.status == Ready){umpire.status = Start;WriteStr(UMPIRE_STATUS_X,UMPIRE_STATUS_Y,strlen(BLANK),BLANK);WriteStr(UMPIRE_STATUS_X,UMPIRE_STATUS_Y,strlen(GAME_START),GAME_START);refresh();}//裁判状态为结束时,表示游戏结束,并重置各变量if(umpire.status == Over){umpire.status = NoReady;player.dice1.dice_flag = 0;player.dice2.dice_flag = 0;player.dice3.dice_flag = 0;player.status = NoReady;computer.dice1.dice_flag = 0;computer.dice2.dice_flag = 0;computer.dice3.dice_flag = 0;computer.status = NoReady;computer.ready_ttg = computer.ready_ttm;DrawDice(player.dice1.pos_x,player.dice1.pos_y,'#','?');DrawDice(player.dice2.pos_x,player.dice2.pos_y,'#','?');DrawDice(player.dice3.pos_x,player.dice3.pos_y,'#','?');DrawDice(computer.dice1.pos_x,computer.dice1.pos_y,'#','?');DrawDice(computer.dice2.pos_x,computer.dice2.pos_y,'#','?');DrawDice(computer.dice3.pos_x,computer.dice3.pos_y,'#','?');WriteStr(PLAYER_RESULT_X,PLAYER_RESULT_Y,strlen(TBLANK),TBLANK);WriteStr(COMPUTER_RESULT_X,COMPUTER_RESULT_Y,strlen(TBLANK),TBLANK);WriteStr(PLAYER_TOTAL_X,PLAYER_TOTAL_Y,strlen(BLANK),BLANK);WriteStr(COMPUTER_TOTAL_X,COMPUTER_TOTAL_Y,strlen(BLANK),BLANK);WriteStr(UMPIRE_STATUS_X,UMPIRE_STATUS_Y,strlen(BLANK),BLANK);WriteStr(PLAYER_STATUS_X,PLAYER_STATUS_Y,strlen(NOREADY),NOREADY);WriteStr(COMPUTER_STATUS_X,COMPUTER_STATUS_Y,strlen(NOREADY),NOREADY);}//当玩家和电脑都操作完毕后,计算本局输赢if(player.status == Finish && computer.status == Finish){dice_rule();//计算输赢并计算金钱收益if(player.status == Win)//玩家本局胜利{if(player.dice_status == Ordinary)//普通牌型{WriteStr(PLAYER_RESULT_X,PLAYER_RESULT_Y,strlen(TBLANK),TBLANK);WriteStr(PLAYER_RESULT_X,PLAYER_RESULT_Y,strlen(WIN),WIN);WriteStr(COMPUTER_RESULT_X,COMPUTER_RESULT_Y,strlen(TBLANK),TBLANK);WriteStr(COMPUTER_RESULT_X,COMPUTER_RESULT_Y,strlen(FAIL),FAIL);}else if(player.dice_status == Three_Times)//三倍{WriteStr(PLAYER_RESULT_X,PLAYER_RESULT_Y,strlen(TBLANK),TBLANK);WriteStr(PLAYER_RESULT_X,PLAYER_RESULT_Y,strlen(THREE_TIMES),THREE_TIMES);WriteStr(COMPUTER_RESULT_X,COMPUTER_RESULT_Y,strlen(TBLANK),TBLANK);WriteStr(COMPUTER_RESULT_X,COMPUTER_RESULT_Y,strlen(FAIL),FAIL);}else if(player.dice_status == Five_Times)//五倍{WriteStr(PLAYER_RESULT_X,PLAYER_RESULT_Y,strlen(TBLANK),TBLANK);WriteStr(PLAYER_RESULT_X,PLAYER_RESULT_Y,strlen(FIVE_TIMES),FIVE_TIMES);WriteStr(COMPUTER_RESULT_X,COMPUTER_RESULT_Y,strlen(TBLANK),TBLANK);WriteStr(COMPUTER_RESULT_X,COMPUTER_RESULT_Y,strlen(FAIL),FAIL);}sprintf(str,"%d",player.dice_total);WriteStr(PLAYER_TOTAL_X,PLAYER_TOTAL_Y,strlen(BLANK),BLANK);WriteStr(PLAYER_TOTAL_X,PLAYER_TOTAL_Y,strlen(str),str);sprintf(str,"%d",computer.dice_total);WriteStr(COMPUTER_TOTAL_X,COMPUTER_TOTAL_Y,strlen(BLANK),BLANK);WriteStr(COMPUTER_TOTAL_X,COMPUTER_TOTAL_Y,strlen(str),str);sprintf(str,"%d",player.money);WriteStr(PLAYER_MONEY_X,PLAYER_MONEY_Y,strlen(BLANK),BLANK);WriteStr(PLAYER_MONEY_X,PLAYER_MONEY_Y,strlen(str),str);sprintf(str,"%d",computer.money);WriteStr(COMPUTER_MONEY_X,COMPUTER_MONEY_Y,strlen(BLANK),BLANK);WriteStr(COMPUTER_MONEY_X,COMPUTER_MONEY_Y,strlen(str),str);refresh();}else if(computer.status == Win)//电脑本局胜利{if(computer.dice_status == Ordinary)//普通牌型{WriteStr(PLAYER_RESULT_X,PLAYER_RESULT_Y,strlen(TBLANK),TBLANK);WriteStr(PLAYER_RESULT_X,PLAYER_RESULT_Y,strlen(FAIL),FAIL);WriteStr(COMPUTER_RESULT_X,COMPUTER_RESULT_Y,strlen(TBLANK),TBLANK);WriteStr(COMPUTER_RESULT_X,COMPUTER_RESULT_Y,strlen(WIN),WIN);}else if(computer.dice_status == Three_Times)//三倍{WriteStr(PLAYER_RESULT_X,PLAYER_RESULT_Y,strlen(TBLANK),TBLANK);WriteStr(PLAYER_RESULT_X,PLAYER_RESULT_Y,strlen(FAIL),FAIL);WriteStr(COMPUTER_RESULT_X,COMPUTER_RESULT_Y,strlen(TBLANK),TBLANK);WriteStr(COMPUTER_RESULT_X,COMPUTER_RESULT_Y,strlen(THREE_TIMES),THREE_TIMES);}else if(computer.dice_status == Five_Times)//五倍{WriteStr(PLAYER_RESULT_X,PLAYER_RESULT_Y,strlen(TBLANK),TBLANK);WriteStr(PLAYER_RESULT_X,PLAYER_RESULT_Y,strlen(FAIL),FAIL);WriteStr(COMPUTER_RESULT_X,COMPUTER_RESULT_Y,strlen(TBLANK),TBLANK);WriteStr(COMPUTER_RESULT_X,COMPUTER_RESULT_Y,strlen(FIVE_TIMES),FIVE_TIMES);}sprintf(str,"%d",player.dice_total);WriteStr(PLAYER_TOTAL_X,PLAYER_TOTAL_Y,strlen(BLANK),BLANK);WriteStr(PLAYER_TOTAL_X,PLAYER_TOTAL_Y,strlen(str),str);sprintf(str,"%d",computer.dice_total);WriteStr(COMPUTER_TOTAL_X,COMPUTER_TOTAL_Y,strlen(BLANK),BLANK);WriteStr(COMPUTER_TOTAL_X,COMPUTER_TOTAL_Y,strlen(str),str);sprintf(str,"%d",player.money);WriteStr(PLAYER_MONEY_X,PLAYER_MONEY_Y,strlen(BLANK),BLANK);WriteStr(PLAYER_MONEY_X,PLAYER_MONEY_Y,strlen(str),str);sprintf(str,"%d",computer.money);WriteStr(COMPUTER_MONEY_X,COMPUTER_MONEY_Y,strlen(BLANK),BLANK);WriteStr(COMPUTER_MONEY_X,COMPUTER_MONEY_Y,strlen(str),str);refresh();}else if(player.status == Draw && computer.status == Draw)//本局平局{WriteStr(PLAYER_RESULT_X,PLAYER_RESULT_Y,strlen(BLANK),BLANK);WriteStr(PLAYER_RESULT_X,PLAYER_RESULT_Y,strlen(DRAW),DRAW);WriteStr(COMPUTER_RESULT_X,COMPUTER_RESULT_Y,strlen(BLANK),BLANK);WriteStr(COMPUTER_RESULT_X,COMPUTER_RESULT_Y,strlen(DRAW),DRAW);sprintf(str,"%d",player.dice_total);WriteStr(PLAYER_TOTAL_X,PLAYER_TOTAL_Y,strlen(BLANK),BLANK);WriteStr(PLAYER_TOTAL_X,PLAYER_TOTAL_Y,strlen(str),str);sprintf(str,"%d",computer.dice_total);WriteStr(COMPUTER_TOTAL_X,COMPUTER_TOTAL_Y,strlen(BLANK),BLANK);WriteStr(COMPUTER_TOTAL_X,COMPUTER_TOTAL_Y,strlen(str),str);refresh();}umpire.status = Over;//计算本局输赢结束后表示游戏结束,裁判状态设置为结束WriteStr(UMPIRE_STATUS_X,UMPIRE_STATUS_Y,strlen(BLANK),BLANK);WriteStr(UMPIRE_STATUS_X,UMPIRE_STATUS_Y,strlen(GAME_OVER),GAME_OVER);}     }dice_over();//结束游戏return 0;
}

(2)通用库(GameLib.c和GameLib.h)

/*GameLib.h*/
#ifndef GAMELIB_H_COMMON
#define GAMELIB_H_COMMON#include <stdio.h>
#include <curses.h>/*Draw*/
#define HL 0 //横线
#define VL 1 //直线
/*****************************************************************   函数名:void DrawLine(int how,int x,int y,int len,char ch)   *   功  能:画线                                               *   返回值:无                                                   *   参数值:int how:HL表示画横线,VL表示画竖线                   *          int x,y:起始点坐标                                    *            int len:线长度                                      *           char ch:填充的字符                                    ****************************************************************/
void DrawLine(int how,int x,int y,int len,char ch);/**********************************************************************   函数名:void DrawSquare(int x,int y,int width,int high,char ch)   *   功  能:画方框                                                      *   返回值:无                                                           *   参数值:int x,y:起始点坐标                                        *          int width,high:宽高                                     *          char ch:填充的字符                                         *********************************************************************/
void DrawSquare(int x,int y,int width,int high,char ch);    /*****************************************************************   函数名:void DrawDice(int x,int y,char ch,char number)         *   功  能:画骰子                                                *   返回值:无                                                   *   参数值:int x,y:骰子数值坐标                                  *            char ch:填充的字符                                    *          char number:骰子数值                              ****************************************************************/
void DrawDice(int x,int y,char ch,char number);         /*Color*/
/*****************************************************************   函数名:int  CheckDisplay(void);                           *   功  能:判断终端是否支持颜色显示                               *   返回值:0:失败 1:成功                                       *   参数值:无                                                 ****************************************************************/
int  CheckDisplay(void);                        /*****************************************************************   函数名:void SetColor(int foreColor,int backColor)             *   功  能:设置颜色组合                                         *   返回值:无                                                   *   参数值:int foreColor:前景色                                    *           int backColor:背景色                                ****************************************************************/
void SetColor(int foreColor,int backColor);     /*****************************************************************   函数名:void color(void)                                   *   功  能:开启颜色显示                                         *   返回值:无                                                   *   参数值:无                                                   ****************************************************************/
void color(void);                                       /*****************************************************************   函数名:void nocolor(void)                                     *   功  能:关闭颜色显示                                         *   返回值:无                                                   *   参数值:无                                                   ****************************************************************/
void nocolor(void);                                     /*****************************************************************   函数名:void reverse(void)                                     *   功  能:开启反色显示                                         *   返回值:无                                                   *   参数值:无                                                   ****************************************************************/
void reverse(void);                             /*****************************************************************   函数名:void noreverse(void)                                   *   功  能:关闭反色显示                                         *   返回值:无                                                   *   参数值:无                                                   ****************************************************************/
void noreverse(void);                                   /*****************************************************************   函数名:void blink(void)                                       *   功  能:开始闪烁显示                                         *   返回值:无                                                   *   参数值:无                                                   ****************************************************************/
void blink(void);                                   /*****************************************************************   函数名:void noblink(void)                                     *   功  能:关闭闪烁显示                                         *   返回值:无                                                   *   参数值:无                                                   ****************************************************************/
void noblink(void);                                     /*Word*/
/*****************************************************************   函数名:void WriteCh(int x,int y,char ch)                      *   功  能:写字符                                            *   返回值:无                                                   *   参数值:int x,y:坐标                                           *           char ch:填充的字符                                    ****************************************************************/
void WriteCh(int x,int y,char ch);                  /*****************************************************************   函数名:void WriteStr(int x,int y,int len,char *str)           *   功  能:写字符串                                               *   返回值:无                                                   *   参数值:int x,y:坐标                                           *    int len:字符串长度                                           *    char *str:填充的字符串                                        ****************************************************************/
void WriteStr(int x,int y,int len,char *str);/*Clear*/
/*****************************************************************   函数名:void ClearSCR(int x,int y,int width,int high)     *   功  能:清除屏幕                                           *   返回值:无                                                  *   参数值:int x,y:起始坐标                                      *     int width,high:宽高                                      ****************************************************************/
void ClearSCR(int x,int y,int width,int high);  #endif
/*GameLib.c*/
#include <stdio.h>
#include <stdlib.h>
#include "GameLib.h"/*****************************************************************   函数名:void DrawLine(int how,int x,int y,int len,char ch)  *   功  能:画线                                                  *   返回值:无                                                  *   参数值:int how:HL表示画横线,VL表示画竖线                *          int x,y:起始点坐标                                 *           int len:线长度                                      *           char ch:填充的字符                                    ****************************************************************/
void DrawLine(int how,int x,int y,int len,char ch){int i;if(!how)//Horizontal line{for(i=0;i<=len;i++){mvaddch(y,x+i,ch);}}else//Vertical line{for(i=0;i<=len;i++){mvaddch(y+i,x,ch);}}
}/**********************************************************************   函数名:void DrawSquare(int x,int y,int width,int high,char ch)  *   功  能:画方框                                                     *   返回值:无                                                       *   参数值:int x,y:起始点坐标                                        *          int width,high:宽高                                     *          char ch:填充的字符                                         *********************************************************************/
void DrawSquare(int x,int y,int width,int high,char ch){int i;for(i=x;i<=(x+width);i++){mvaddch(y, i, ch);mvaddch(y+high, i, ch);}for(i=y;i<=(y+high);i++){mvaddch(i, x, ch);mvaddch(i, x+width, ch);}
}/*****************************************************************   函数名:void DrawDice(int x,int y,char ch,char number)    *   功  能:画骰子                                                *   返回值:无                                                  *   参数值:int x,y:骰子数值坐标                                *           char ch:填充的字符                                    *          char number:骰子数值                              ****************************************************************/
void DrawDice(int x,int y,char ch,char number){int i,sx,sy;mvaddch(y,x,number);sx = x - 2;sy = y - 1;for(i=0;i<5;i++){mvaddch(sy,sx+i,ch);mvaddch(sy+2,sx+i,ch);}for(i=0;i<3;i++){mvaddch(sy+i,sx,ch);mvaddch(sy+i,sx+4,ch);}
}/*****************************************************************   函数名:int  CheckDisplay(void);                              *   功  能:判断终端是否支持颜色显示                            *   返回值:0:失败 1:成功                                     *   参数值:无                                                  ****************************************************************/
int CheckDisplay(void)
{return start_color();
}/*****************************************************************   函数名:void SetColor(int foreColor,int backColor)        *   功  能:设置颜色组合                                     *   返回值:无                                                  *   参数值:int foreColor:前景色                             *           int backColor:背景色                                ****************************************************************/
void SetColor(int foreColor,int backColor)
{init_pair(1,foreColor,backColor);
}/*****************************************************************   函数名:void color(void)                                      *   功  能:开启颜色显示                                         *   返回值:无                                                  *   参数值:无                                                    ****************************************************************/
void color(void)
{attron(COLOR_PAIR(1));
}/*****************************************************************   函数名:void nocolor(void)                                *   功  能:关闭颜色显示                                         *   返回值:无                                                  *   参数值:无                                                    ****************************************************************/
void nocolor(void)
{attroff(COLOR_PAIR(1));
}/*****************************************************************   函数名:void reverse(void)                                    *   功  能:开启反色显示                                         *   返回值:无                                                  *   参数值:无                                                    ****************************************************************/
void reverse(void)
{attron(A_REVERSE);
}/*****************************************************************   函数名:void noreverse(void)                              *   功  能:关闭反色显示                                         *   返回值:无                                                  *   参数值:无                                                    ****************************************************************/
void noreverse(void)
{attroff(A_REVERSE);
}/*****************************************************************   函数名:void blink(void)                                  *   功  能:开始闪烁显示                                         *   返回值:无                                                  *   参数值:无                                                    ****************************************************************/
void blink(void)
{attron(A_BLINK);
}/*****************************************************************   函数名:void noblink(void)                                    *   功  能:关闭闪烁显示                                         *   返回值:无                                                 *   参数值:无                                                 ****************************************************************/
void noblink(void)
{attroff(A_BLINK);
}/*****************************************************************   函数名:void WriteCh(int x,int y,char ch)                     *   功  能:写字符                                            *   返回值:无                                                  *   参数值:int x,y:坐标                                        *           char ch:填充的字符                                    ****************************************************************/
void WriteCh(int x,int y,char ch)
{mvaddch(y,x,ch);
}/*****************************************************************   函数名:void WriteStr(int x,int y,int len,char *str)      *   功  能:写字符串                                               *   返回值:无                                                  *   参数值:int x,y:坐标                                        *           int len:字符串长度                                    *           char *str:填充的字符串                             ****************************************************************/
void WriteStr(int x,int y,int len,char *str)
{mvaddstr(y,x-(len/2),str);
}/*****************************************************************   函数名:void ClearSCR(int x,int y,int width,int high)     *   功  能:清除屏幕                                               *   返回值:无                                                  *   参数值:int x,y:起始坐标                                  *           int width,high:宽高                                ****************************************************************/
void ClearSCR(int x,int y,int width,int high)
{int i,j;for(i=x;i<x+width;i++){for(j=y;j<y+high;j++){mvaddch(j,i,' ');}}
}

(3)骰子函数(dice.h和dice.c)

/*dice.h*/
#ifndef DICE_H
#define DICE_H#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <curses.h>
#include <signal.h>
#include <sys/time.h>
#include <time.h>
#include "GameLib.h"//屏幕坐标
#define SCR_X (COLS-1)
#define SCR_Y (LINES-1)#define PLAYER_STATUS_X SCR_X*3/8-2
#define PLAYER_STATUS_Y SCR_Y-3
#define PLAYER_MONEY_X  SCR_X*1/8
#define PLAYER_MONEY_Y  SCR_Y-2
#define PLAYER_TOTAL_X  SCR_X*1/4
#define PLAYER_TOTAL_Y  SCR_Y-11
#define PLAYER_RESULT_X SCR_X*1/4
#define PLAYER_RESULT_Y (SCR_Y-11)+4
#define PLAYER_GR_X     SCR_X*1/4
#define PLAYER_GR_Y (SCR_Y-11)*1/2+4#define COMPUTER_STATUS_X SCR_X*5/8+2
#define COMPUTER_STATUS_Y SCR_Y-3
#define COMPUTER_MONEY_X  SCR_X*7/8
#define COMPUTER_MONEY_Y  SCR_Y-2
#define COMPUTER_TOTAL_X  SCR_X*3/4
#define COMPUTER_TOTAL_Y  SCR_Y-11
#define COMPUTER_RESULT_X SCR_X*3/4
#define COMPUTER_RESULT_Y (SCR_Y-11)+4
#define COMPUTER_GR_X     SCR_X*3/4
#define COMPUTER_GR_Y     (SCR_Y-11)*1/2+4#define UMPIRE_STATUS_X SCR_X/2
#define UMPIRE_STATUS_Y SCR_Y-3//字符串
#define TBLANK          "                    "
#define BLANK       "          "
#define GAME_START  "Game Start"
#define GAME_OVER   "Game over"
#define FINISH      "Finish"
#define NOREADY     "NoReady"
#define READY       "Ready"
#define WIN         "You Win!"
#define GAME_WIN    "You Win The Game!"
#define FAIL        "You Fail!"
#define GAME_FAIL   "You Lose The Game!"
#define DRAW        "Game Graw"
#define THREE_TIMES     "You Win Three Times!"
#define FIVE_TIMES      "You Win Five  Times!"
#define MONEY_ADD   "+100"
#define MONEY_DEDUCT    "-100"
#define MONEY_NONE  "+0"//ticker = 100ms
#define COMPUTER_READY  20 //2s
#define COMPUTER_DICE_T 10 //1s#define MAX(a,b) (if(a > b)?(a):(b))
#define MIN(a,b) (if(a < b)?(a):(b))//骰子倍率
typedef enum _dice_status{Ordinary=1,Three_Times,Five_Times
}Dice_Status;//成员状态
typedef enum _status{NoReady=1,Ready,Finish,Start,Over,Win,Fail,Draw,Game_Win,Game_Fail
}Status;//骰子
typedef struct _dice{int dice_num;      //骰子数值char dice_flag;       //骰子标志int pos_x,            //骰子x坐标pos_y;           //骰子y坐标
}Dice;//裁判
typedef struct _umpire{Status status;                   //裁判状态unsigned int dice_multiple;       //倍率
}Umpire;//玩家
typedef struct _player{char name[20];                   //玩家名字int  money;                       //玩家本金Dice dice1;                       //骰子Dice dice2;Dice dice3;int dice_total;                   //骰子数值总和Status status;                  //玩家状态Dice_Status dice_status;      //玩家骰子倍数
}Player;//电脑
typedef struct _computer{char name[20];                 //电脑名称int  money;                       //电脑本金Dice dice1;                       //骰子Dice dice2;Dice dice3;int dice_total;                   //骰子数值总和int ready_ttm,                  //准备时钟初始值ready_ttg,                 //准备时钟计数器dice_ttm,                  //骰子时钟初始值   dice_ttg;                   //骰子时钟计数器Status status;                 //电脑状态Dice_Status dice_status;      //电脑骰子倍数
}Computer;/*****************************************************************   函数名:void dice_init(void)                             *   功  能:游戏初始化                                          *   返回值:无                                                  *   参数值:无                                                    ****************************************************************/
void dice_init(void);/*****************************************************************   函数名:void dice_over(void)                              *   功  能:游戏结束                                           *   返回值:无                                                  *   参数值:无                                                    ****************************************************************/
void dice_over(void);/*****************************************************************   函数名:void start_shake(void)                                *   功  能:开始摇骰子                                          *   返回值:无                                                  *   参数值:无                                                    ****************************************************************/
void start_shake(void);/*****************************************************************   函数名:void stop_shake(void)                               *   功  能:停止摇骰子                                          *   返回值:无                                                  *   参数值:无                                                    ****************************************************************/
void stop_shake(void);/*****************************************************************   函数名:void dice_rule(void)                             *   功  能:判断骰子规则                                         *   返回值:无                                                  *   参数值:无                                                    ****************************************************************/
void dice_rule(void);/*****************************************************************   函数名:void dice_shake(int signum)                           *   功  能:时钟操作函数                                         *   返回值:无                                                  *   参数值:int signum:信号                                 ****************************************************************/
void dice_shake(int signum);/*****************************************************************   函数名:void money_rule(void)                              *   功  能:判断游戏输赢                                         *   返回值:无                                                  *   参数值:无                                                    ****************************************************************/
void money_rule(void);/*****************************************************************   函数名:void dice_sort(int *num,int len)                 *   功  能:骰子排序                                           *   返回值:无                                                  *   参数值:int *num:骰子数组                                 *           int len:骰子个数                                 ****************************************************************/
void dice_sort(int *num,int len);/***************************************************************************   函数名:Dice_Status dice_status_judge(int dice1,int dice2,int dice3) *   功  能:判断牌型                                                     *   返回值:牌型                                                          *   参数值:int dice1,dice2,dice3:骰子数值                               **************************************************************************/
Dice_Status dice_status_judge(int dice1,int dice2,int dice3);/*****************************************************************   函数名:int set_ticker(int n_msecs)                           *   功  能:设置时间间隔器                                        *   返回值:0:成功 -1:失败                                    *   参数值:int n_msecs:毫秒                                   ****************************************************************/
int set_ticker(int n_msecs);#endif
/*dice.c*/
#include "dice.h"#define random(x) (rand()%x)
#define dice_random() (random(6)+1)Player player;
Computer computer;
Umpire umpire;/*****************************************************************   函数名:void dice_init(void)                             *   功  能:游戏初始化                                          *   返回值:无                                                  *   参数值:无                                                    ****************************************************************/
void dice_init()
{char strmoney[10];void dice_shake(int);srand((int)time(0));initscr();noecho();crmode();umpire.status = NoReady;umpire.dice_multiple = 1;strcpy(player.name,"Player1");player.money = 100;player.dice1.dice_flag = 0;player.dice2.dice_flag = 0;player.dice3.dice_flag = 0;player.dice_total = 0;player.dice1.pos_x = SCR_X*1/4;player.dice1.pos_y = (SCR_Y-11)*1/3+4;player.dice2.pos_x = SCR_X*1/8;player.dice2.pos_y = (SCR_Y-11)*2/3+4;player.dice3.pos_x = SCR_X*3/8;player.dice3.pos_y = (SCR_Y-11)*2/3+4;player.status = NoReady;strcpy(computer.name,"Computer");computer.money = 100;computer.dice1.dice_flag = 0;computer.dice2.dice_flag = 0;computer.dice3.dice_flag = 0;computer.dice_total = 0;computer.dice1.pos_x = SCR_X*3/4;computer.dice1.pos_y = (SCR_Y-11)*1/3+4;computer.dice2.pos_x = SCR_X*5/8;computer.dice2.pos_y = (SCR_Y-11)*2/3+4;computer.dice3.pos_x = SCR_X*7/8;computer.dice3.pos_y = (SCR_Y-11)*2/3+4;computer.ready_ttm = computer.ready_ttg = COMPUTER_READY;computer.dice_ttm = computer.dice_ttg = COMPUTER_DICE_T;computer.status = NoReady;signal(SIGINT, SIG_IGN);if(CheckDisplay() == OK){DrawSquare(0,0,SCR_X,SCR_Y,'#');DrawLine(VL,SCR_X/2,3,SCR_Y-9,'#');DrawLine(VL,SCR_X*1/4,SCR_Y-6,6,'#');DrawLine(VL,SCR_X*3/4,SCR_Y-6,6,'#');DrawLine(HL,0,3,SCR_X,'#');DrawLine(HL,0,SCR_Y-6,SCR_X,'#');WriteStr(SCR_X/2,1,9,"Dice Game");WriteStr(7,1,11,"'Q' to EXIT");WriteStr(SCR_X-10,1,12,"'r' to Ready");WriteStr(SCR_X-8,2,16,"'Space' to Next");DrawDice(player.dice1.pos_x,player.dice1.pos_y,'#','?');DrawDice(player.dice2.pos_x,player.dice2.pos_y,'#','?');DrawDice(player.dice3.pos_x,player.dice3.pos_y,'#','?');DrawDice(computer.dice1.pos_x,computer.dice1.pos_y,'#','?');DrawDice(computer.dice2.pos_x,computer.dice2.pos_y,'#','?');DrawDice(computer.dice3.pos_x,computer.dice3.pos_y,'#','?');WriteStr(SCR_X*1/8,SCR_Y-4,strlen(player.name),player.name);sprintf(strmoney,"%d",player.money);WriteStr(SCR_X*1/8,SCR_Y-2,strlen(strmoney),strmoney);WriteStr(SCR_X*7/8,SCR_Y-4,strlen(computer.name),computer.name);sprintf(strmoney,"%d",computer.money);WriteStr(SCR_X*7/8,SCR_Y-2,strlen(strmoney),strmoney);WriteStr(SCR_X/2,SCR_Y-5,6,"Umpire");WriteStr(PLAYER_STATUS_X,PLAYER_STATUS_Y,strlen(NOREADY),NOREADY);WriteStr(COMPUTER_STATUS_X,COMPUTER_STATUS_Y,strlen(NOREADY),NOREADY);move(SCR_X,SCR_Y);refresh();}signal(SIGALRM, dice_shake);set_ticker(100);
}/*****************************************************************   函数名:void dice_over(void)                              *   功  能:游戏结束                                           *   返回值:无                                                  *   参数值:无                                                    ****************************************************************/
void dice_over(void)
{set_ticker(0);endwin();
}/*****************************************************************   函数名:void start_shake(void)                                *   功  能:开始摇骰子                                          *   返回值:无                                                  *   参数值:无                                                    ****************************************************************/
void start_shake(void)
{signal(SIGALRM, dice_shake);set_ticker(100);
}/*****************************************************************   函数名:void stop_shake(void)                             *   功  能:停止摇骰子                                          *   返回值:无                                                  *   参数值:无                                                    ****************************************************************/
void stop_shake(void)
{set_ticker(0);
}/*****************************************************************   函数名:void dice_shake(int signum)                           *   功  能:时钟操作函数                                         *   返回值:无                                                  *   参数值:int signum:信号                                 ****************************************************************/
void dice_shake(int signum)
{char randstr[10];signal(SIGALRM, SIG_IGN);if(!player.dice1.dice_flag && player.status == Ready){player.dice1.dice_num = dice_random();sprintf(randstr,"%d",player.dice1.dice_num);WriteStr(player.dice1.pos_x,player.dice1.pos_y,strlen(randstr),randstr);//refresh();}if(!player.dice2.dice_flag && player.status == Ready){player.dice2.dice_num = dice_random();sprintf(randstr,"%d",player.dice2.dice_num);WriteStr(player.dice2.pos_x,player.dice2.pos_y,strlen(randstr),randstr);//refresh();}if(!player.dice3.dice_flag && player.status == Ready){player.dice3.dice_num = dice_random();sprintf(randstr,"%d",player.dice3.dice_num);WriteStr(player.dice3.pos_x,player.dice3.pos_y,strlen(randstr),randstr);//refresh();}if(!computer.dice1.dice_flag && computer.status == Ready){computer.dice1.dice_num = dice_random();sprintf(randstr,"%d",computer.dice1.dice_num);WriteStr(computer.dice1.pos_x,computer.dice1.pos_y,strlen(randstr),randstr);//refresh();}if(!computer.dice2.dice_flag && computer.status == Ready){computer.dice2.dice_num = dice_random();sprintf(randstr,"%d",computer.dice2.dice_num);WriteStr(computer.dice2.pos_x,computer.dice2.pos_y,strlen(randstr),randstr);//refresh();}if(!computer.dice3.dice_flag && computer.status == Ready){computer.dice3.dice_num = dice_random();sprintf(randstr,"%d",computer.dice3.dice_num);WriteStr(computer.dice3.pos_x,computer.dice3.pos_y,strlen(randstr),randstr);//refresh();}if(computer.ready_ttg-- == 1){computer.status = Ready;WriteStr(COMPUTER_STATUS_X,COMPUTER_STATUS_Y,strlen(BLANK),BLANK);WriteStr(COMPUTER_STATUS_X,COMPUTER_STATUS_Y,strlen(READY),READY);}if(computer.status == Ready)computer.dice_ttg--;if(computer.dice_ttg == 1){computer.dice_ttg = computer.dice_ttm;if(!computer.dice1.dice_flag)computer.dice1.dice_flag = 1;else if(!computer.dice2.dice_flag)computer.dice2.dice_flag = 1;else if(!computer.dice3.dice_flag)computer.dice3.dice_flag = 1;if(computer.dice1.dice_flag && computer.dice2.dice_flag &&computer.dice3.dice_flag){computer.status = Finish;WriteStr(COMPUTER_STATUS_X,COMPUTER_STATUS_Y,strlen(BLANK),BLANK);WriteStr(COMPUTER_STATUS_X,COMPUTER_STATUS_Y,strlen(FINISH),FINISH);}}move(SCR_Y,SCR_X);refresh();signal(SIGALRM, dice_shake);
}/*****************************************************************   函数名:void money_rule(void)                             *   功  能:判断游戏输赢                                         *   返回值:无                                                  *   参数值:无                                                    ****************************************************************/
void money_rule(void)
{if(player.money <= 0){player.status = Game_Fail;}else if(computer.money <= 0){player.status = Game_Win;}
}/*****************************************************************   函数名:void dice_rule(void)                              *   功  能:判断骰子规则                                         *   返回值:无                                                  *   参数值:无                                                    ****************************************************************/
void dice_rule(void)
{player.dice_status = dice_status_judge(player.dice1.dice_num,player.dice2.dice_num,player.dice3.dice_num);computer.dice_status = dice_status_judge(computer.dice1.dice_num,computer.dice2.dice_num,computer.dice3.dice_num);player.dice_total = 0;player.dice_total += player.dice1.dice_num;player.dice_total += player.dice2.dice_num;player.dice_total += player.dice3.dice_num;computer.dice_total = 0;computer.dice_total += computer.dice1.dice_num;computer.dice_total += computer.dice2.dice_num;computer.dice_total += computer.dice3.dice_num;if((player.dice_status == Ordinary && computer.dice_status == Ordinary) ||(player.dice_status == Three_Times && computer.dice_status == Three_Times) ||(player.dice_status == Five_Times && computer.dice_status == Five_Times)){if(player.dice_total > computer.dice_total){player.status = Win;computer.status = Fail;}else if(player.dice_total < computer.dice_total){player.status = Fail;computer.status = Win;}else{player.status = Draw;computer.status = Draw;}}else if((player.dice_status == Three_Times && computer.dice_status == Ordinary) ||(player.dice_status == Five_Times && computer.dice_status == Ordinary)){player.status = Win;computer.status = Fail;}else if((player.dice_status == Ordinary && computer.dice_status == Three_Times) ||(player.dice_status == Ordinary && computer.dice_status == Five_Times)){player.status = Fail;computer.status = Win;}else if(player.dice_status == Three_Times && computer.dice_status == Five_Times){player.status = Fail;computer.status = Win;}else if(player.dice_status == Five_Times && computer.dice_status == Three_Times){player.status = Win;computer.status = Fail;}if(player.status == Win){if(player.dice_status == Ordinary)umpire.dice_multiple = 1;else if(player.dice_status == Three_Times)umpire.dice_multiple = 3;else if(player.dice_status == Five_Times)umpire.dice_multiple = 5;player.money += 10 * umpire.dice_multiple;computer.money -= 10 * umpire.dice_multiple;}else if(computer.status == Win){if(computer.dice_status == Ordinary)umpire.dice_multiple = 1;else if(computer.dice_status == Three_Times)umpire.dice_multiple = 3;else if(computer.dice_status == Five_Times)umpire.dice_multiple = 5;player.money -= 10 * umpire.dice_multiple;computer.money += 10 * umpire.dice_multiple;}else if(player.status == Draw && computer.status == Draw){;}
}/*****************************************************************   函数名:int set_ticker(int n_msecs)                           *   功  能:设置时间间隔器                                        *   返回值:0:成功 -1:失败                                    *   参数值:int n_msecs:毫秒                                   ****************************************************************/
int set_ticker(int n_msecs)
{struct itimerval new_timeset;long n_sec,n_usecs;n_sec = n_msecs / 1000;n_usecs = (n_msecs % 1000) * 1000L;new_timeset.it_interval.tv_sec = n_sec;new_timeset.it_interval.tv_usec = n_usecs;new_timeset.it_value.tv_sec = n_sec;new_timeset.it_value.tv_usec = n_usecs;return setitimer(ITIMER_REAL,&new_timeset,NULL);
}/***************************************************************************   函数名:Dice_Status dice_status_judge(int dice1,int dice2,int dice3) *   功  能:判断牌型                                                     *   返回值:牌型                                                          *   参数值:int dice1,dice2,dice3:骰子数值                               **************************************************************************/
Dice_Status dice_status_judge(int dice1,int dice2,int dice3)
{int i,j;int num[3]={0,0,0};char str[10];num[0] = dice1;num[1] = dice2;num[2] = dice3;dice_sort(num,3);if(num[2] == num[1]+1 && num[1] == num[0]+1 && num[0] == num[2]-2){return Three_Times;}if(dice1 == dice2 && dice2 == dice3)return Five_Times;return Ordinary;
}/*****************************************************************   函数名:void dice_sort(int *num,int len)                  *   功  能:骰子排序                                           *   返回值:无                                                  *   参数值:int *num:骰子数组                                 *           int len:骰子个数                                 ****************************************************************/
void dice_sort(int *num,int len)
{int i,j;int temp;for(i=0;i<len-1;i++)for(j=i+1;j<len;j++){if(num[i] > num[j]){temp = num[i];num[i] = num[j];num[j] = temp;}}
}

4.操作

(1)编译:gcc main.c GameLib.c dice.c -l curses -o main

(2)运行:./main

(3)游戏操作:进入游戏后,按‘r’表示准备,空格摇骰子,‘Q’退出游戏。当其中一方的金钱数小于等于0时,另一方游戏胜利。

(4)源码下载:https://download.csdn.net/download/q1449516487/10749082

(5)游戏截图:

Linux小游戏——单机掷骰子相关推荐

  1. Java小游戏之掷骰子

    掷骰子游戏代码如下,试试你的运气! package zt;/*** ClassName:TestIf01* Package:zt* Description:** 测试if单分支结构* 写一个掷骰子游戏 ...

  2. php 摇骰子,php实现的中秋博饼游戏之掷骰子并输出结果功能详解

    本文实例讲述了php实现的中秋博饼游戏之掷骰子并输出结果功能.分享给大家供大家参考,具体如下: 前面讲述了php实现的中秋博饼游戏之绘制骰子图案功能,纯php实现,就要用php来生成图案,第一步就先绘 ...

  3. Linux小游戏汇总

    Linux小游戏汇总 1.phear 这是一款GPL协议的小游戏,目标是在不被敌人砸到的时候吃到更多的分数. 示例效果: 界面: 下载指令: $sudo apt-get phear 启动 $phear ...

  4. 概率编程:小明小红掷骰子

    1.题目: 小明小红掷骰子,小明有n个骰子,第i个骰子有vi个面,每个面的点数为1.2.3...vi. 小红有m个骰子,第j个骰子有vj个面,每个面的点数为1.2.3...vj. 小明小红将自己的所有 ...

  5. html5游戏 dice掷骰子,使用jQuery实现掷骰子游戏

    本文实例为大家共享了jQuery实现掷骰子游戏的详细代码,供大家参考,详细内容如下 直接新版建一个html网页,需要在head中引入jquery,js,一些css代码以及js代码,如下: .wrap{ ...

  6. 课程设计报告linux小游戏,嵌入式课程设计报告---贪吃蛇游戏.doc

    嵌入式课程设计报告---贪吃蛇游戏 嵌入式系统课程设计报告书 课题题目:贪吃蛇游戏 学 院:核自院 班 级:测控三班 学 号:9 姓 名: 马文铂 第一章 引言- 2 - 1.1关于题目- 2 - 1 ...

  7. python投掷骰子实验_Python小程序--模拟掷骰子

    案例描述 · 通过计算机程序模拟抛掷骰子,并显示各点数的出现次数及频率 · 比如,抛掷2个骰子50次,出现点数为7的次数是8,频率是0.16 版本1.0 1.0功能:模拟抛掷1个骰子,并输出其结果 如 ...

  8. Python小游戏(摇骰子)

    开发软件:PyCharm Community Edition 2022.3.2 无聊的小游戏 当资产不够的时候容易死循环 from random import randint //默认总资产 Init ...

  9. vb用计算机模拟掷骰子游戏,vb掷骰子程序代码

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 Private Sub Command2_Click() Command3.Enabled = True Command4.Enabled = True ...

  10. c 语言掷骰子游戏,C 语言编程学习: 制作掷骰子小游戏

    C 语言编程学习: 制作掷骰子小游戏 问题描述 骰子是一个有六个面的正方体, 每个面分别印有 16 之间的小圆点代表点数. 假设这个游戏的规则是: 两个人轮流掷骰子 6 次, 并将每次投掷的点数累加起 ...

最新文章

  1. 脚本SFTP定时取Linux服务器文件
  2. 【计算理论】上下文无关语法 ( 代数表达式 | 代数表达式示例 | 确定性有限自动机 DFA 转为 上下文无关语法 )
  3. 如何将ipynb转换为html,md,pdf等格式
  4. android surfaceview 大小_Android 使用Camera2 API采集视频数据
  5. linux防火墙ddos,Linux iptables防火墙详解 + 配置抗DDOS***策略实战
  6. 【数论学习笔记】同余
  7. UOS NetworkManager切换Networking
  8. python多重背包_多重背包
  9. JVM-Cpu飙升排查及解决
  10. 为什么宇宙年龄138亿年(哈勃常数的倒数),大小竟有930亿光年?
  11. php面试会考计算机网络,计算机网络常见面试题整理
  12. 补充:混淆矩阵、图像分割指标计算
  13. AI 作图绘画的软件和网址
  14. 机械硬盘(HDD)与固态硬盘(SSD)
  15. C语言——PTA 埃尔米特多项式
  16. Shader Graph 水面制作个人总结
  17. Zigzag和蛇形矩阵
  18. 删除mysql中的函数
  19. IC卡、ID卡、M1卡、射频卡的区别是什么【转】
  20. centos7没有netstat命令的解决方法

热门文章

  1. 左程云 Java 笔记--二叉树
  2. 【时间序列异常检测】Anomaly Detection for IoT Time-Series Data: A Survey
  3. obs多推流地址_如何使用OBS推流直播线上广交会(图文详解) | 文末福利
  4. Steam游戏上线初期的总结与思考
  5. Hi3559AV100移植友方4G模块N720V5(二)
  6. SQL 数据库语句练习
  7. 关于PDF文件加密无法打印的问题
  8. matlab柱状图填充不同的颜色不同,使用matlab绘画柱状图,且使用不同的图案填充...
  9. 十二、React脚手架
  10. 单机游戏mysql启动不了_魔域单机版MySQL数据库启动失败解决办法