天天看点

结对编程——黄金点游戏

      前言:经过一个多月的软件工程这门课的学习,总的来说受益良多。了解到如何才是一个合格的程序,合格的程序员。并不是说一个程序能运行才是程序,而是各方面,诸如界面,简洁,效率,完善都要做到完美。一个好的程序员不仅要满足客户的需求,还要自己寻找以后可能出现的问题,并保证程序可扩充性。本学期我们会有个人项目,结对项目,团队项目的一步一步深入地学习,那么这次我们接到了组队编程的任务。

      任务:本次结对编程的题目如下:黄金点游戏是一个数字小游戏,其游戏规则是:

            N个同学(N通常大于10),每人写一个0~100之间的有理数 (不包括0或100),交给裁判,裁判算出所有数字的平均值,然后乘以0.618(所谓黄金分割常数),得到G值。提交的数字最靠近G(取绝对值)的同学得到N分,离G最远的同学得到-2分,其他同学得0分。玩了几天以后,大家发现了一些很有意思的现象,比如黄金点在逐渐地往下移动。

      1、本作业属于结对编程项目,必须由二人共同完成,并分别将本次作业过程发到博客,同时将本次作业源代码提交到codeing系统;

      2、如果可能的话尽量以C/S或B/S方式实现,即利用服务器接收和处理所有玩家提交的数字,并将结果反馈给各玩家,玩家可以通过客户端提交的数字;

      3、如果采用单机方式实现的话,需要为用户提供便利的输入界面;

      4、该游戏每次至少可以运行10轮以上,并能够保留各轮比赛结果。

      人员:本次结对编程,我的队友是胡林状,他是我的班上唯一的安徽老乡。他做事比较低调,默默勤劳工作。我们这次编程遇到的诸多问题,我们都有积极探讨并交换了意见。

              我的coding地址:https://coding.net/u/lvjianxiong

              胡林状的coding地址:https://coding.net/u/hulinzhuang

              胡林状的博客地址:http://www.cnblogs.com/hulinzhuang/

      编程过程:我们积极地首先对题目开始分析,理解题目究竟是什么意思,玩的是个什么游戏,我们在编程之前自己用笔代替电脑,走了一遍游戏的流程。我觉得这是很有必要的。然后进入编程环节,本次选择的编程语言是C语言(C++没有C语言通俗易懂;JAVA还处于自学阶段,还不足以编程)。N个同学每人输入一个有理数,用scanf函数很容易实现;求和然后取平均值,再算G点值,这是最简单的计算;然后比较每个值与G点的接近程度,但是考虑到不是简单的减法,因为你不知道哪个值大,如果存在绝对值的符号就好了。百度知道,fabs就是求浮点数的绝对值。这也算是一个小小的收获吧,之前还不知道呢;至于给分的模块,我们可以设定一个max和min值,初值均赋为第一个数值,后面的数值挨个和初值比较,最终得到这组数据的最大值和最小值。最大值赋予N分,最小值-2分,其他的值不做任何变动即可。

      程序源代码

#include "stdafx.h"

#include "stdlib.h"

#include "windows.h"

#include "math.h"

typedef struct gameplayer //定义玩家结构体

{

int name;

int score;

float number;

}PLAYER; //含有玩家的姓名,分数,编号,分数信息

      每个玩家涉及信息量较多,我们很自然选用了结构体。

void startgame(FILE *fp); //游戏的初始化

void gamerule(); //游戏规则

void suan_score(PLAYER *p,float ave,int num,FILE *fp);//计算比赛得分的函数

      这里我们主要用到这几个函数。

int main()

system("color 3B");

int choice;

FILE *fp;

while(1)

{

fp=fopen("goldgame.txt","w+");

printf("\n 黄金点游戏 \n\n");

printf(" 1. 游戏规则\n");

printf(" 2. 开始游戏\n");

printf(" 3. 退出游戏\n");

scanf("%d",&choice);

switch(choice)

{

case 1: gamerule(); break;

case 2: startgame(fp); break;

case 3: exit(0); break;

default:

{

printf(" 您的输入有误,请重新输入\n");

break;

}

}

}

return 0;

}

      主函数,我们设计了初始界面:包括开始游戏,游戏规则,退出游戏简单的功能。用SWITCH函数读取玩家的操作。

void startgame(FILE *fp)

PLAYER *p;

int i,playernum,gamenum,j;

int flag=1;

float sum,ave;

char choice;

p=(PLAYER *)malloc(10*sizeof(PLAYER)); //动态分配结构体数组

printf("请输入参与的玩家数:");

scanf("%d",&playernum);

if(playernum>10)

p=(PLAYER *)realloc(p,playernum*sizeof(PLAYER));//空间不足而需要增加空间

printf("请输入比赛轮次:");

scanf("%d",&gamenum);

printf("\n");

for(j=0;j<gamenum;j++)

printf("第%d轮比赛:\n",j+1);

for(i=0,sum=0 ;i<playernum;i++)//sum设为总数和

if(flag==1)

p[i].name=i+1;

p[i].score=0;

p[i].win=0;

p[i].fail=0;

} //初始化初值为0

printf(" 玩家%d: ",p[i].name);

scanf("%f",&p[i].number);

sum+=p[i].number;

ave=sum/playernum; //计算平均值

ave=(float)(ave*0.618); //计算黄金点的值

printf(" 黄金点G的值为:%f\n",ave);

suan_score(p,ave,playernum,fp);

flag=0;

     这是开始化游戏函数,动态分配内存空间,如果不够,需要补充空间。主要进行玩家人数和游戏轮次的设定,然后读取玩家各个数值,计算G点值,进入suan_score函数。

void suan_score(PLAYER *p,float ave,int num,FILE *fp)

int i;

char ch;

float max=(float)fabs(p[0].number-ave);

float min=(float)fabs(p[0].number-ave);

for(i=0;i<num;i++) //统计出本轮最大值,最小值

p[i].b=(float)fabs(p[i].number-ave);

if(max<p[i].b)

max=p[i].b;

if(min>p[i].b)

min=p[i].b;

for(i=0;i<num;i++) //挨个玩家赋予成绩

if(p[i].b==max)

p[i].score-=2;

if(p[i].b==min)

p[i].score+=num;

printf("累计比赛的得分:\n");

for(i=0;i<num;i++) //挨个玩家输出成绩

printf(" 玩家%d: %d\n",p[i].name,p[i].score);

printf("是否继续 Y or N : ");

scanf("%c",&ch);

if(ch=='y'||ch=='Y')

{

break;

}

else if(ch=='n'||ch=='N')

exit(0);

   这是给各玩家赋予成绩的函数,首先max和min均设为第一个玩家的数值,然后后继的数值挨个比较,选出本组数值最大值和最小值。最后比较得到最大值的玩家+N,得到最小值玩家—2,其他玩家我们不进行任何操作。输出每个玩家的成绩并进行下一轮的游戏。

void gamerule()

printf(" N个同学(N通常大于10),每人写一个0~100之间的有理数(不包括0或100),裁判算出所有数字的平均值,然后乘以0.618(所谓黄金分割常数),得到G值。提交的数字最靠近G(取绝对值)的同学得到N分,离G最远的同学得到-2分,其他同学得0分。\n\n");

   这个就是读取游戏规则函数,就是简单的printf就可以完成。

  总结:由于我们小队两个人都是考研的,就连周六周日都有课程,时间相对比较匆忙,本次编程也算抽时间完成了。虽然不够完美,我们也曾想做到完美,但是还是限于自己的能力以及时间的紧张,没有做到心中的完美。但是还是很有收获的,集思广益,团队的力量可以使问题变得简单一些,虽然仅仅是两个人。希望后续的作业,我们都能尽自己最大的努力去完成,一定会有回报的吧。