現代軟件工程第二周作業——黃金點遊戲
(本博文為現代軟件工程第二周作業——黃金點遊戲結對編程總結,本項目的Github源碼在這裏)
黃金點遊戲介紹
假設有M個人參與黃金點遊戲,每輪遊戲每個人提兩個(0, 100)間的有理數,共2M個數,求這2M個數的平均數再將這個平均數乘以0.618得到這一輪的黃金點,提出離黃金點最近的數的人得2M分(同樣近的人一起得分),離黃金點最遠的人扣兩分。
在本次實驗中,我們需要寫一個bot來在每輪遊戲中自動提出兩個數,每次遊戲前,bot能拿到之前所有輪次遊戲的每個人提的兩個數和黃金點,每場遊戲共進行400輪,共有上半場和下半場兩場遊戲,累計得分最高的bot獲勝。
我們的策略
我們的策略十分簡單,第一,我們不會需要去預測別人提的數,所以遊戲進行時我們只用黃金點的值來提出下一輪的結果,並沒有用其他人提的數這一個信息。第二,我們是基於統計的方法,統計該次遊戲的前50輪遊戲出現最多的2個黃金點作為我們的輸出,具體做法如下。
- 對於前20輪遊戲,采用擬合函數的策略預測前20輪的實驗結果。
- 對於之後的遊戲,用一個有序列表pred_golden記錄待預測的黃金點,用一個長度為50的隊列que_cnt統計每次黃金點落到待預測的黃金點的附近對應的待預測黃金點在pred_golden裏的下標,將最開始的前20輪遊戲的黃金點都認為是待預測的黃金點,之後每一次遊戲的黃金點若在任意兩個待預測的黃金點中間的1/3區間,則插入為新的待預測黃金點,若在該兩個待預測黃金點的其他的兩個1/3區間,則離這次黃金點近的待預測的黃金點的下標記錄到que_cnt中,並用這次的黃金點對對應的待預測的黃金點做一次滑動平均。如此進行下去,直到history的最後一輪。
- 利用que_cnt的值選出出現最多的兩個下標對應的黃金點作為我們的輸出。
我們利用這一個方案在夏令營的復盤程序中拿了第一,第三(上半場,下半場)的名次,但在我們的比賽時拿了第四,第八(上半場,下半場)的名次,我看了我們比賽時黃金點的波動情況,比夏令營的復雜的多,可能因為我們的參數bot數目比較少的原因吧!
作業要求
2.在開始實現之前,用PSP表格記錄下你預估完成項目需要的時間。
項目一開始,我們先討論了我們的方案,最終討論出這個方案後。因為我們的算法比較簡單,具體實現起來也就100行左右的代碼量,我們花了1個小時左右的時間就寫完了,在夏令營的數據內復盤時我們又發現了我們的方案裏的一些弊端,比如我們一開始是基於之前所有輪次的統計,但這樣的話如果其他人在中間改變策略我們的方法可能反應不過來,討論過後我們決定改進成基於前50輪的統計。就這樣,我們在一邊復盤發現問題,一邊討論改進我們的方案的循環過程中完成了我們的結對編程的作業,總共花時一個晚上左右的時間,但我們並沒有明確的PSP表格。
3.看教科書和其他資料中關於Information Hiding, Interface Design, Loose Coupling的章節,說明你們在結對編程中是如何利用這些方法對接口進行設計的。
編程開始前,我們討論由我來用一個函數來實現對待預測黃金點列表的插入與更新,並在函數內維護前50輪黃金點的統計列表,返回插入和更新後的待預測黃金點列表和近50輪的統計隊列。另一位同學負責主函數來使用這個函數進行遊戲的輸入和輸出,並負責前20輪遊戲的策略。
4.描述重要模塊接口的設計與實現過程。設計包括代碼如何組織,比如會有幾個類、幾個函數,他們之間的關系是如何的,關鍵函數是否需要畫出流程圖?說明你的算法的關鍵(不必列出源代碼),以及獨到之處。
我們主要就一個main函數和一個更新待預測黃金點列表函數[update]函數,主要就是mian函數調用update函數,所以也不需要流程圖。我們的方法關鍵之處在於我們的待預測黃金點列表能夠自適應黃金點的變化,如果黃金點波動十分小,收斂的很好,我們兩個值的預測也會十分接近這個黃金點。如果黃金點在兩個點之間波動,我們也能成功預測到這兩個波動的峰值的位置,從而在這兩個峰值間沖擊黃金點。
5.閱讀有關UML的內容。畫出UML圖顯示計算模塊部分各個實體之間的關系(一個圖即可)。
因為我們的方法裏並沒有類,並沒有采用面向對象編程,我們都是基於面向過程的方法,所以這並不適用我們的方案。
6.看Design by Contract的內容,描述這些做法的優缺點,說明你如何把它們融入結對作業中。
- 優缺點
- 優點:每個類有自己的明確義務,有確定的功能,保證良好的接口,而且功能模塊化的話更有利於代碼的復用和管理。
- 缺點:時間開銷較大,需要大量的時間實踐才能真正體會到契約式設計的好處。
- 我們這次任務實現比較簡單,接口也比較簡單,實踐時並沒有采用這種設計方式。
7.程序的代碼規範、設計規範。你們倆如何達成共識、采用什麽規範?程序中是否有異常處理?你如何處理各種異常?
代碼規範的話我們在實現時並沒強制要求,主要是在容易混淆的地方加註釋就行了,保證代碼的可讀性。程序並沒有出現異常,但在夏令營數據復盤時發現過方案的弊端,經過討論後改進了我們的方案。
8.描述界面模塊的詳細設計過程。你的程序有用戶界面麽?在博客中詳細介紹你如何設計你的界面模塊。
我們並沒有用戶界面,所以這並不適用我們。
9.描述界面模塊與其他模塊的對接。詳細描述UI模塊的設計與其他模塊的對接,並在博客中截圖實現的功能。界面/控制/數據模塊體現了MVC的設計模式了麽?
理由同上
10.描述結對的過程。提供兩人在討論的結對照片。遮擋和美化都是允許的。
11.看教科書和其他參考資料中關於結對編程的章節,說明你們采用了哪種合作方式,以及結對編程的優點和缺點。a) 結對的每個人的優缺點在哪裏(需列出至少三個優點和一個缺點)?b) 你如何說服你的夥伴改進他/她的缺點?請考慮一下三明治方法。
- 我們這次結對過程中采取的是駕駛員與領航員的合作方式,通過指導和監督的方式完成了這次的實驗。這次實驗中,我的另一個夥伴指導並監督我進行編程,在復盤時出現問題後我們又接著討論又進一步改善我們的方案。
- 結對編程的優缺點:優點在於合作編程時我們都會有自己的想法,和別人交流自己的想法可以引發思維上的碰撞,從而得到更好的解決方案,另外與人合作可以提高我們雙方的積極性,而且有助於我們寫出更優質的代碼。
- 我的合作夥伴Jinhua Zhu在討論時很有想法,而且很擅長與人交流,善於表達自己的想法,思維十分敏捷,能快速看到問題並想到解決方案,和他合作真的太愉快了!!
12.在你實現完程序後,請在PSP表格中記錄下你在開發各個步驟上實際花費的時間。說明差異的原因。
我們並沒有采用PSP表格記錄各個步驟的時間,但相比於編程的時間,我們的大部分時間都發在方案的討論和改進上,在實驗時發現原始方案的不足,不斷討論不斷改進方案,最終得到我們的最終版本的bot。
13.其他收獲。例如,如何攻克技術難點,你做了哪些閱讀和探索,可以把資料和經歷描述一下。如果你的項目是和其他同學一起比賽(例如比賽速度),描述一下你的程序和其他程序的優劣。
我們小組的方案是基於統計的方法,實驗結果應該可以達到一個比較中庸的分數,但我想所有基於統計的方案都有的一個弊端,就是對環境變化反應的很慢,如果黃金點變化收斂到另一個值,那麽按我們的方法,我們可能要20輪左右的時間才能反應過來,這是我們的方案的最大的弊端。我們也嘗試了許多方案來解決這個弊端,比如減小que_cnt的最大隊列長度,但統計的輪次太小會導致統計結果無意義,最後我們也並沒有完全解決這個問題,只能稍稍緩和了這個問題。
現代軟件工程第二周作業——黃金點遊戲