一、結對編程題目及其要求
黃金點游戲是一個數字小游戲,其游戲規則是:
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輪以上,并能夠保留各輪比賽結果。
二、需求分析
從題目的要求上來看,這次的結對編程主要是要實現黃金點游戲的編程。而具體的黃金點游戲在上面的題目以及要求里面已經說的很清楚:可以實現N個同學進行黃金點游戲,每個同學隨機給1-99之間的任意有理數,通過計算機計算實現求出平均值以后乘以0.618得到G值,即所謂的黃金分割常數。
各位同學的分數也很有意思,距離G點最近的數字的同學得分最高為N分,最遠的同學為最低分-1分,其他中間的同學為0分。
三、功能分析
由上面的要求以及需求分析來看,我們的編程要實現的功能是很清晰的。首先要實現能夠輸入N個同學的數字并進行存儲,待輸入結束后,可以進行黃金點值的計算,之后將每一位玩家的分數與得到的黃金點值進行比較,即相減之后的絕對值最小的得到的分數最多,為參加游戲的人數;絕對值最大的分數最低,為-2分;其他的分數為0分。分別將各位同學的分數進行統計,并可以在每輪游戲結束后看到該玩家總共得到了多少分以及每輪分數。
四、具體實現
鑒于上面的需求分析以及功能分析,我和我的隊友張威同學進行了討論,基本的小功能我們都能通過已經學過的知識來實現。基于以上的功能板塊的分析,我們決定用C++來實現這個小游戲。看了別的結對編程的小伙伴們的博客,相比較之下就感覺我們的小游戲真的是一個“小”游戲,還是有很多的大神用了很多的高大上的“武器”。羨慕之余想到的是每一個小組都有自己的風格,我們的小程序隨感看起來簡單很“小”,可我們貴在簡煉、精巧。
首先是我們用到的變量:我們用N和M來實現分別控制游戲的輪數和參加游戲的人數,用數組S[100]來存儲我們的玩家輸入的數字num,i,j為循環控制變量,S2和S3數組是后面用來實現對每輪的游戲分數進行統計的。下面的雙精度變量ave、sum、G分別為平均值、玩家數字之和以及判斷點G,max、min為下面為了給出分數而設置的最大值和最小值。
int i, j, num, N, M, S[100], S2[100], S3[100] = { 0};
double S1[100], ave,sum,G;
double max, min;
下面就是一個對于初玩者基本的介紹,這里就不再一一贅述。如圖所示為我們的進入畫面:
整體最主要的部分也就是實現玩家輸入數字計算G值的部分我們是通過兩個嵌套的for循環實現的,實現每一輪的玩家輸入數字并進行計算數字之和sum,平均值ave,然后算出這一輪的G值。到下一輪游戲就重復以上過程。
for (i = 1; i <= N; i++)
{
sum = 0;
G = 0;
cout << "Input the number between 1 to 100." << endl;
for (j = 1; j <= M; j++)
{
cout <<" Player " << j << " input your choose!" << endl;
cin >> num;
S[j] = num;
sum = sum + S[j];
}
ave = sum / num;
G = ave*0.618;
cout << "黃金點是G=" << G << endl;
下圖為輸入的圖片:
下一步就是要實現給出每個玩家評判的分數,我們通過構造了數組S2和S3來分別存儲。利用庫函數math.h函數中的abs()函數實現計算每一位玩家的數字與G值得絕對值大小,從而實現絕對值最小的給N分,最大的給-2分,其他取得都是0分。并且予以顯示。
for (j = 1; j <= M; j++)
{
S1[j] = abs(S[j] - G);
}
max = min = S1[1];
for (j = 1; j <= M; j++)
{
if (S1[j] >= max)
max = S1[j];
else if (S1[j] < min)
min = S1[j];
}
for (j = 1; j <= M; j++)
{
if (S1[j] == max)
S2[j] = -2;
else if (S1[j] == min)
S2[j] = M;
else S2[j] = 0;
}
上面為計算分數的程序。
for (j = 1; j <= M; j++)
{
cout << "本輪分數" << "S2[" << j << "]=" << S2[j] << endl;
S3[j] = S3[j] + S2[j];
cout << "總分數 " << "S3[" << j << "]=" << S3[j] << endl;
}
上面為顯示分數的程序。
以上為運行的圖片顯示。
下面位運行的第二輪游戲:
通過對S3數組的如下操作實現對兩輪分數的求和,并且顯示:
...........
直到輪數運行完畢:
五、結對編程的感悟以及對隊友的評價
以前的時候,當有一個寫程序的任務來了的時候總是會犯“拖延癥”,不到最后一天都不怎么操心去想或者開始著手去準備。進行了結對編程之后,我才發現了這種編程模式的好處,在這種模式下,我和我的小伙伴肩并肩地、平等地、互補地進行編程。看了書上的說法,我們用一臺電腦,面對同一個顯示器,使用同一個鍵盤、同一個鼠標一起工作;一起分析,一起設計,一起改進,一起進步。這樣的結果就是我們都提高了自己的綜合水平。
由于我今年要考研,所以老師提出的要求并沒有做到盡善盡美,像老師說的C/S或B/S即即利用服務器接收和處理所有玩家提交的數字,并將結果反饋給各玩家,玩家可以通過客戶端提交的數字的功能并沒有實現。但是體驗了一把結對編程的樂趣也未嘗不是一種很好的收獲。
我的結對編程隊友是我們班的張威同學,對他在一開始的時候并不是很了解。只是覺得應該是一個很聰明的同學,在一起編程之后才發現原來不僅如此。我在這次結對編程的任務中主要負責的是前期的需求分析和程序整體的設計,以及后期的代碼復審以及功能的補充。張威同學負責完成初次的代碼設計,之后我們在復審以及補充功能上面進行了多次探討以及互換身份的復審,小伙伴是一個雖然看起來不太努力,但是真正努力起來非常認真刻苦,能夠堅持自己的看法,并且也有督促我好好學習的方面。
總之,這是一次雖然中間有許多困難,最終也都被我們一一拿下的經歷,相信會在以后的發展中給與我們很多的幫助。非常感謝老師給我們這樣一次在大學里就體驗了一次結對編程的機會,我們定當努力,不負老師所望。
附圖:
- 結對伙伴博客地址:http://www.cnblogs.com/zw2013040101034/
- 我的coding主頁地址:https://coding.net/u/wanjhon
- 小伙伴coding地址:https://coding.net/u/2013040101034
文章列表