1. 程式人生 > >現代軟體工程第二週作業——黃金點遊戲

現代軟體工程第二週作業——黃金點遊戲

(本博文為現代軟體工程第二週作業——黃金點遊戲結對程式設計總結,本專案的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的最大佇列長度,但統計的輪次太小會導致統計結果無意義,最後我們也並沒有完全解決這個問題,只能稍稍緩和了這個問題。