C语言猜拳游戏代码及分析
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
C语言猜拳游戏代码及分析
猜拳游戏需求分析说明书
1.引言
1.编写目的
小时候,我们喜欢以猜拳来赢得奖励。
现在,我们希望能开发一个猜拳的游戏。
2.定义
需求:用户解决问题或达到目标所需的条件或功能;系统或系统部件要满足合同、标准,规范或其它正式规
定文档所需具有的条件或权能。
而且其很强的交互性及
简单易行性,可以让人在很短时间内熟悉它的操作方法,不论用户文化水平如何,都会很轻松的学会使用它。
2.任务概述
1.目标
2.用户的特点
由于本程序简单易操作,交互性好,对用户没什么
特别要求。
一般用户经过几分钟练系都可以熟悉本系统
的规则。
3.系统功能示例
3.需求细则
1.
对功能的规定
1.1
界面友好
属性:必选
描述:用户的一些操作前后做出一些必要的提示或确认。
所有完成的功能都需要友好,例如:
●
增加失败提示;
●
删除失败和成功提示、删除前的确认;
●
修改失败和成功提示、修改前/后的确认;
●
查找失败提示、查找成功的确认;
●
退出系统时,要提示是否退出;
●
其它方面的界面问题;
1.2
用户注册
属性:必选
描述:登录界面可以用户注册,注册信息包含用户名和密码,例如:
●
不能使用已经存在的用户名
●
密码不能少于6个字符
1.3
用户登录
属性:必选
描述:用户通过登录界面进行登录,必须输入正确的用户名和密码方可进入系统,例如:
●
提示输入用户名
●
提示输入密码
●
用户名和密码验证,都符合则进入系统,不然回到
第一步,超过三次登录,则提示登录次数超过三次,退
出系统
1.4
开始游戏
属性:必选
描述:金额大于1的用户可以开始游戏
●
下注:提示用户下注的金额数
●
猜拳:(必须先下注,如果用户下注金额小于等于0,不能进行游戏)与电脑进行猜拳游戏,如果猜输了,扣除你的金额(由下注决定),胜利将随机获得1~5倍的下注
金额奖励
n提示:电脑随机出拳,胜利奖励也是随机的,例如:
n随机获得1~5数字代码:
nsrand((unsigned)time(NULL));
nint radio = rand() % 5 + 1;//radio 为随机 1~5的整数
●
如果金额少于下注数,将不能进行猜拳,給出充值提示
1.5
充值
属性:必选
描述:用户可以进行充值
●
充值金额
●
充值的时候,必须输入充值密码(由5个字符组成,随机包括数字0~9和所有小写字母)
●
如果充值密码正确,充值成功,不然充值失败
1.6
修改用户信息
属性:必选
描述:用户可以注销(删除)自己的账户、或者修改个人信息
● 修改个人信息
n
修改用户密码
● 注销用户(本人)
n
删除用户所有信息(删除完毕将返回登录界面,用户账号已经不存在)
1.7
查看用户信息
属性:必选
描述:用户登录成功后,可以选择查看用户自己信息或者所有用户信息
● 查看用户自己信息:(本人)用户名密码金额胜率
● 查看所有用户信息:所有用户名金额胜率
1.8
排序
属性:必选
描述:用户可以对所有用户信息进行排序操作,便于查看
● 金额排序
● 胜率排序
对性能的规定
本系统在设计方面本着方便、实用的宗旨,性能方面应遵循如下原则:
●
执行效率(时间):软件运行应该尽量高效;避免没有必要的循环处理、重复处理;
●
资源损耗(空间):设计尽量节约资源(内存、数组、链表等);不用的资源要及时释放;
●
初始化:变量、数组、内存块;
●
健壮性:不能出现野指针、内存泄露、数组越界访
问等等:
◎
声明指针后,立即将指针设置为NULL,防止产生
“野指针”;
◎
函数的入参必须进行有效性判断;用户输入、函数返回值(如果用到的话)都要判断;
◎
switch-case一定要有default;if-else if等后要有else,除非if满足后返回或退出;
◎
不允许出现goto语句;
◎
数组的下标不要溢出。
3.
对排版的规定
●
缩进要对齐;
●
长行拆分;
●
二元操作符的前后应当加空格,包括如下操作符:
赋值操作符、比较操作符、算术操作符、逻辑操作符、位域操作符,如"="、
"+="">;="、"4.
对可维护性的规定
对可维护性的最终要求:别人能够轻松上手你的代码。
●
结构清晰:
◎
模块化:对界面(显示)、菜单管理、逻辑管理、文件操作等等代码要独立,必须多个.c文件,用makefile;
◎
封装:一个函数只做一件事,函数功能要单一;一
个函数不能超过50行;
避免重复、冗余代码;
◎
代码块清晰。
●
命名规范,变量名应该具有自明性:
◎
函数的命名:
使用"动词"或者"动词+名词"(动宾词组)的形式,由一个或多个单词组成且以小写字母开头,以后每个单词之间用下划线隔开
◎
变量的命名与定义
应当使用"名词"或者"形容词+名词",由一个或多个单词组成且以小写字母开头,以后每个单词之间用下划线隔开。
●
注释充分:变量、函数(包括参数、返回值)、代码功能块、一些复杂算法……等都需要
清晰明了地说明;
5.
对个性的规定
把项目做出个性出来。
下列各项中有和比人不同之处、或很有创意,即可认为有个性。
独立设计的软件,一般都会出现一些个性。
参考、抄袭不会出现个性。
●
设计思路:包括软件的整体架构、功能块的设计思路、函数封装等等;
●
功能实现:从用户的角度,使用上发现与众不同的地方;
●
其它方面;
c语言程序代码:
/*
func:猜拳游戏
auth:肖乔
date:2014.02.22
*/
#include;
#include;
#include;
#include;
#define TRUE 1
typedef struct {
charname[30];
//用户名长度最长28
charpassword[30]; //密码长度最长28
doublemoney;
inttimes;
intwin;
}game_t;
//清空缓存
void fflush_in();
//登录菜单函数
void log_menu();
//功能菜单函数
void ctrl_menu();
//登录函数
int log_in(game_t *p,int *count,int *my); //注册函数
int add_user(game_t *p,int *count);
//登录控制函数
void log_ctrl(game_t *p,int *count,int*my); //功能控制函数
void ctrl(game_t *p,int *count,int *my);
//查看函数
void look(game_t *p,int *count,int *my);
//查看菜单
void look_menu();
//查看所有
void look_all(game_t *p,int *count);
//查看个人
void look_my(game_t *p,int *my);
//初始化函数
int log_start(game_t *p,int *count);
//保存函数
int exit_save(game_t *p,int *count);
//充值函数
int pay(game_t *p,int *my);
//修改函数
void alter(game_t *p,int *count,int *my);
//修改菜单
void alter_menu();
//修改密码
int alter_pass(game_t *p,int *my);
//注销用户
int del(game_t *p,int *count,int *my);
//游戏控制函数
void game_ctrl(game_t *p,int *my);
//游戏菜单
void game_menu();
//下注
int game_pay(game_t *p,int *my,double*mon); //游戏函数
void game_play(game_t *p,int *my,double*mon); //游戏
int game();
//排序控制函数
void cmp(game_t *p,int *count);
//排序菜单
void cmp_menu();
//按金额排序函数
int cmp_money(const void *px,const void*py);
//胜率函数
void win_times(game_t *p,int *count);
//按胜率排序函数
int cmp_win(const void *px,const void *py);
int main(){
game_tstu[100]={"\0"}; //最多100个用户
intcount=0;
//count表示用户数
intmy=0;
//my表示本人用户下标
printf("欢迎使用猜拳游戏\n");
if(log_start(stu,&count)==0)
//系统初始化
printf("系统初始化成功\n");
else
printf("系统初始化失败\n");
log_ctrl(stu,&count,&my);
//功能控制函数
return0;
}
//初始化函数 0-成功1-失败
int log_start(game_t *p,int *count){
FILE*fp=NULL;
fp=fopen("data","a+"); if(NULL==fp)
return1;
while(fread(&p[*count],sizeof(game_t),1,fp)) *count+=1;
fclose(fp);
return0;
}
//保存函数 0-成功 1-失败
int exit_save(game_t *p,int *count){
FILE*fp=NULL;
fp=fopen("data","w");
if(NULL==fp)
return1;;
fwrite(p,sizeof(game_t),*count,fp); fclose(fp);
return0;
}
//功能控制函数
void ctrl(game_t *p,int *count,int *my){ intchose=0;
while(TRUE){
chose=0;
ctrl_menu();
printf("请选择:");
scanf("%d",&chose);
fflush_in();
switch(chose){
case1:
//查看
look(p,count,my); break;
case2:
//游戏
game_ctrl(p,my); break;
case3:
//充值
if(pay(p,my)==0)
printf("充值成功\n"); else
printf("充值失败\n"); break;
case4:
//修改
alter(p,count,my);
break;
case5:
//排序
cmp(p,count);
break;
case6:
//返回
return;
break;
default:
printf("输入错误,请重新输入\n"); }
}
}
//排序控制函数
void cmp(game_t *p,int *count){
intchose=0;
while(TRUE){
chose=0;
cmp_menu();
printf("请选择:");
scanf("%d",&chose);
fflush_in();
switch(chose){
case1:
//金额
qsort(p,*count,sizeof(game_t),cmp_money); printf("排序成功\n");
break;
case2:
//胜率
win_times(p,count);
printf("排序成功\n");
break;
case3:
//返回
return;
break;
default:
printf("输入错误,请重新输入\n"); }
}
}
//胜率函数
void win_times(game_t *p,int *count){ doublewins[100]={0.0};
doublei=0,j=0;
intk=0;
for(k=0;k;money>;p2->;money)
return-1;
if(p1->;money;money)
return1;
else
return0;
}
//按金额排序函数
int cmp_money(const void *px,const void*py){ constgame_t *p1=px;
constgame_t *p2=py;
if(p1->;money>;p2->;money)
return-1;
if(p1->;money;money)
return1;
else
return0;
}
//排序菜单
void cmp_menu(){
printf("1.按金额排序 2.按胜率排序 3.返回\n");
}
//游戏控制函数
void game_ctrl(game_t *p,int *my){
intchose=0;
doublemon=0.0;
while(TRUE){
chose=0;
game_menu();
printf("请选择:");
scanf("%d",&chose);
fflush_in();
switch(chose){
case1:
//下注
if(game_pay(p,my,&mon)==0)
printf("下注成功,请开始游戏\n"); else
printf("下注失败\n");
break;
case2:
//猜拳
game_play(p,my,&mon);
break;
case3:
//返回
return;
break;
default:
printf("输入错误,请重新输入\n"); }
}
}
//游戏函数
void game_play(game_t *p,int *my,double*mon){
intresult=0;
intradio=0;
if(*mon==0){
printf("请先下注\n"); return;
}
p[*my].money-=*mon;
result=game();
srand((unsigned)time(NULL));
radio=rand()%5+1;
if(result==0){
p[*my].money+=0;
printf("平局,余
额%.2f\n",p[*my].money);
p[*my].times+=1;
}
elseif(result==1){
p[*my].money+=(*mon)*radio;
printf("您胜利了,奖金:%.2f余额:%.2f\n",(*mon)*radio,p[*my].money);
p[*my].times+=1;
p[*my].win+=1;
}
else{
printf("您输了%.2lf,余
额%.2lf\n",*mon,p[*my].money);
p[*my].times+=1;
}
*mon=0.0;
}
//游戏 0-平局,1-胜,-1-输
int game(){
intmy=0;
intradio=0;
while(my!=1&&my!=2&&my!=3){
printf("1.剪刀 2.石头 3.布\n"); printf("请选择:");
scanf("%d",&my);
fflush_in();
switch(my){
case1:
printf("您出的是剪刀\n"); break;
case2:
printf("您出的是石头\n"); break;
case3:
printf("您出的是布\n");
break;
default:
printf("输入错误,请重新输入\n"); }
}
srand((unsigned)time(NULL));
radio=rand()%3+1;
if(radio==1)
printf("电脑出的是剪刀\n");
elseif(radio==2)
printf("电脑出的是石头\n");
elseif(radio==3)
printf("电脑出的是布\n"); switch(radio-my)
{
case1:
case-2:
return-1;
case2:
case-1:
return1;
default:
return0;
}
}
//下注 0-成功 1-失败
int game_pay(game_t *p,int *my,double*mon){
doublemoney=0.0;
if(p[*my].money==0){
printf("您的余额为0.00,请充值\n"); return1;
}
printf("您的余额为:%.2lf元
\n",p[*my].money);
printf("请下注:");
scanf("%lf",&money);
fflush_in();
if(money;p[*my].money){
printf("余额不足,请充值\n");
return1;
}
*mon=money;
return0;
}
//游戏菜单
void game_menu(){
printf("1.下注 2.猜拳 3.返回\n"); }
//修改函数 0-成功 1-失败
void alter(game_t *p,int *count,int *my){ intchose=0;
while(TRUE){
chose=0;
alter_menu();
printf("请选择:");
scanf("%d",&chose);
fflush_in();
switch(chose){
case1:
//改密
if(alter_pass(p,my)==0)
printf("修改密码成功\n"); else
printf("修改密码失败\n"); break;
case2:
//注销
if(del(p,count,my)==0){
printf("注销成功\n");
log_ctrl(p,count,my);
//功能控制函数
}
else
printf("注销失败\n");
break;
case3:
//返回
return;
break;
default:
printf("输入错误,请重新输入\n"); }
}
}
//注销用户 0-成功 1-失败
int del(game_t *p,int *count,int *my){
charpass[30]="\0";
inti=0,chose=0;
printf("密码:");
fgets(pass,30,stdin);
pass[strlen(pass)-1]='\0';
if(!(strcmp(p[*my].password,pass))==0){
printf("密码输入错误\n");
return1;
}
printf("是否注销?\n1.是 2.否\n");
printf("请选择:");
scanf("%d",&chose);
fflush_in();
if(chose==1){
for(i=*my;i;100){
printf("注册用户已满\n");
return1;
}
printf("提示:用户名长度为3-28\n");
printf("用户名:");
fgets(name,30,stdin);
name[strlen(name)-1]='\0';
if(strlen(name);28){
//用户名长度3-28
printf("用户名长度不合法\n"); return1;
}
for(i=0;i;28){
//密码长度6-28
printf("密码长度不合法\n"); return1;
}
printf("确认密码:");
fgets(pass2,30,stdin);
pass2[strlen(pass2)-1]='\0';
if(!(strcmp(pass,pass2))==0){
printf("两次输入密码不一样\n"); return1;
}
strcpy(p[*count].password,pass);
*count+=1;
return0;
}
//登录菜单函数
void log_menu(){
printf("1.登录 2.注册 3.退出\n"); }
//清空缓存
void fflush_in(){
charc='\0';
c=getchar();
while(c!='\n'){
c=getchar();
}
}。