前言:經過一個多月的軟體工程這門課的學習,總的來說受益良多。了解到如何才是一個合格的程式,合格的程式員。并不是說一個程式能運作才是程式,而是各方面,諸如界面,簡潔,效率,完善都要做到完美。一個好的程式員不僅要滿足客戶的需求,還要自己尋找以後可能出現的問題,并保證程式可擴充性。本學期我們會有個人項目,結對項目,團隊項目的一步一步深入地學習,那麼這次我們接到了組隊程式設計的任務。
任務:本次結對程式設計的題目如下:黃金點遊戲是一個數字小遊戲,其遊戲規則是:
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就可以完成。
總結:由于我們小隊兩個人都是考研的,就連周六周日都有課程,時間相對比較匆忙,本次程式設計也算抽時間完成了。雖然不夠完美,我們也曾想做到完美,但是還是限于自己的能力以及時間的緊張,沒有做到心中的完美。但是還是很有收獲的,集思廣益,團隊的力量可以使問題變得簡單一些,雖然僅僅是兩個人。希望後續的作業,我們都能盡自己最大的努力去完成,一定會有回報的吧。