第二次結對編程做業

第二次結對編程做業

1.博客及倉庫地址

本人倉庫地址
隊友倉庫地址前端

2.具體分工

李至恆:python寫AI
蔡嘉懿:UI界面,AI與服務器的接口python

3.PSP表格

PSP2.1 Personal Software Process Stages 預估耗時(分鐘) 實際耗時(分鐘)
Planning 計劃 30 60
Estimate 估計這個任務須要多少時間 10 10
Development 開發 480 800
Analysis 需求分析 (包括學習新技術) 60 90
Design Spec 生成設計文檔 20 30
Design Review 設計複審 30 45
Coding Standard 代碼規範(爲開發制定合適的規範) 15 25
Design 具體設計 100 110
Coding 具體編碼 120 180
Code Review 代碼複審 30 30
Test 測試(自我測試,修改代碼,提交修改) 150 200
Reporting 報告 40 60
Test Repor 測試報告 10 10
Size Measurement 計算工做量 20 25
Postmortem & Process Improvement Plan 過後總結, 並提出過程改進計劃 20 30
Total 總計 1135 1705

4.解題思路描述和設計實現說明

1.網絡接口的使用

  • 註冊+綁定
def register(self):
        def register_(user, psw, num, numpsw):
            url = 'http://api.revth.com/auth/register2'
            headers = {
                'Content-Type': 'application/json'
            }
            data = {
                "username": user,
                "password": psw,
                "student_number": num,
                "student_password": numpsw
            }
            r = requests.post(url,headers=headers,data=json.dumps(data))
            return r
        r =register_(self.user,self.psw,self.num,self.numpsw)
        status = r.json()['status']

        if status == 0 and 'user_id' in r.json()['data']:
            self.user_id = r.json()['data']['user_id']
            self.is_register = True
            print('register successful')
            print(r.text)
        else:
            print('register failed!')
            report(status)
            print(r.text)
  • 登陸
def login(self):
        def login_(user, psw):
            url = "http://api.revth.com/auth/login"
            headers = {
                'content-type': 'application/json'
            }
            data = {
                "username": user,
                "password": psw
            }
            r = requests.post(url, data=json.dumps(data), headers=headers)
            return r

        r = login_(self.user, self.psw)
        status = r.json()['status']
        if status == 0 and 'user_id' in r.json()['data']:
            self.user_id = r.json()['data']['user_id']
            self.token = r.json()['data']['token']
            self.logged = True
            print('Login successful')
            print(r.text)
        else:
            print('login failed!')
            report(status)
            print(r.text)
  • 註銷
def logout(self):
        def logout_(token):
            url = "http://api.revth.com/auth/logout"
            headers = {
                'x-auth-token': token
            }
            r = requests.post(url, headers=headers)
            return r

        r = logout_(self.token)
        status = r.json()['status']
        if status == 0:
            self.logged = False
            print('Logout successful')
            print(r.text)
        else:
            print('logout failed!')
            report(status)
            print(r.text)
  • 開始戰局
def getCard(self):
        url = 'http://api.revth.com/game/open'
        headers = {'X-Auth-Token': self.token}
        response = requests.post(url, headers=headers)
        response_dict = response.json()
        status = response_dict['status']
        if (status == 0):
            self.roomid = response_dict['data']['id']
            card = response_dict['data']['card'].split(' ')
            self.cards = card
        else:
            print('getCard Failed!')
            print(response.text)
        return card
  • 歷史戰績
def get_history(self, page, limit, play_id):
        def history(token, page, limit, play_id):
            url = "http://api.revth.com/history"
            querystring = {
                "page": page,
                "limit": limit,
                "player_id": play_id
            }
            headers = {
                'x-auth-token': token
            }
            r = requests.get(url, headers=headers, params=querystring)
            return r

        data = []
        r = history(self.token, page, limit, play_id)
        status = r.json()['status']
        if status == 0:
            data = r.json()['data']
        else:
            print('get_history failed!')
            report(status)
            print(r.text)
        print(data)
  • 獲取排行榜
def get_rank(self):
        url = "http://api.revth.com/rank"
        r = requests.get(url)
        print(r.text)

2.類圖

3.算法的關鍵與關鍵實現部分流程圖

我的在熟悉規則後第一個關於算法的想法是git

  • 後墩儘量大
  • 中墩也越大越好
  • 前墩也越大越好

只要足夠大,打槍就追不上我github

本着這個想法,很容易讓人想到貪心算法,這也是個人初版代碼,就是傳入牌型,按照從大到小判斷牌型,將牌從大到小,從前日後排序算法

可是很快就發現實現起來有難度,並且我也感受到這個算法不夠智能編程

因此在隊友的幫助下去看了權值矩陣json

因此肯定了最終算法(其實也是從大佬那裏看來的算法,可是這也是沒辦法的,由於上個班的事情已經證實了這個算法是最優解,留給咱們的發揮空間也很少了......)後端

5.關鍵代碼解釋

取最高權重算法,在外層有一個循環用來選出分數最大的牌型並將得分最大的牌型填入output鏈表中api

for index_hou in range(len(list_2)):
        #print("looping again")
        #print(list_2[index])
        list_2 = list(itertools.combinations(list_1,5))
        score = 0
        get_score(index_hou)
        #print("score:%d" %score)
        #print("score_max:%d" %score_max)
        if(score > score_max):
           score_max = score
           ##print("score_max:%d" %score_max) #這個能夠優先取消註釋
           list_output[0] = list_qian[0]
           list_output[1] = list_qian[1]
           list_output[2] = list_qian[2]
           list_output[3] = list_zhong[0]
           list_output[4] = list_zhong[1]
           list_output[5] = list_zhong[2]
           list_output[6] = list_zhong[3]
           list_output[7] = list_zhong[4]
           list_output[8] = list_hou[0]
           list_output[9] = list_hou[1]
           list_output[10] = list_hou[2]
           list_output[11] = list_hou[3]
           list_output[12] = list_hou[4]

get_score算法其實應該最好是用遞歸寫的,可是由於寫的時候很着急並且只有2層循環,因此用了循環法,核心思想是先肯定一個後墩牌,循環求出在該後墩牌爲後墩的前提下中墩和前墩能取得的最高分數,將得分最高的牌型返回主函數,和最大得分值比較,分值高的被記錄進output鏈表
同時其中有get_weight函數,用來計算各墩的權重,防止出現相公的狀況。服務器

def get_score(i):
    score_max_private = 0
    global score
    global list_2
    global list_2_backup
    list_zhong_private = ['','','','','']
    weight_hou = get_weight(i,0)
    #print("後墩權重:%d" %weight_hou)
    list_hou[0] = list_2[i][0]
    list_hou[1] = list_2[i][1]
    list_hou[2] = list_2[i][2]
    list_hou[3] = list_2[i][3]
    list_hou[4] = list_2[i][4]
    #print("後墩牌:",end = "")
    ##print(list_hou)
    #print("firstscore:%d" %score)
    #print(list_input)
    #list_copyright = copy.copy(list_hou)
    list_copyright = list(set(list_input).difference(set(list_hou)))
    list_copyright.sort(key=func_1)
    #print(list_copyright)
    #os.system("pause")
    list_2 = list(itertools.combinations(list_copyright,5))
    score_copyright = score
    for index_zhong in range(len(list_2)):
        score = score_copyright
        list_2 = list(itertools.combinations(list_copyright,5))
        #print(len(list_2))
        weight_zhong = get_weight(index_zhong,weight_hou)
        #print("中墩權重:%d" %weight_zhong)
        #print("secondscore:%d" %score)
        if(weight_zhong>weight_hou):
            score = 0
            continue
        list_zhong_private[0] = list_2[index_zhong][0]
        list_zhong_private[1] = list_2[index_zhong][1]
        list_zhong_private[2] = list_2[index_zhong][2]
        list_zhong_private[3] = list_2[index_zhong][3]
        list_zhong_private[4] = list_2[index_zhong][4]
        #print("中墩牌private:",end = "")
        #print(list_zhong_private)
        list_copyright_backup = copy.copy(list_copyright)
        list_copyright_backup = list(set(list_copyright).difference(set(list_zhong_private)))
        list_copyright_backup.sort(key=func_1)
        list_2_backup = list_copyright_backup
        weight_qian = get_weight_qian()
        #print("前墩權重:%d" %weight_qian)
        #print(score)
        if(weight_qian>weight_zhong):
            continue
        if(score>score_max_private):
            score_max_private = score
            #print("中墩權重:%d" %weight_zhong)
            list_zhong[0] = list_zhong_private[0]
            list_zhong[1] = list_zhong_private[1]
            list_zhong[2] = list_zhong_private[2]
            list_zhong[3] = list_zhong_private[3]
            list_zhong[4] = list_zhong_private[4]
            #print("中墩牌:",end = "")
            #print(list_zhong)
            #print("score_max_zhong:%d" %score_max_private)
            list_qian[0] = list_2_backup[0]
            list_qian[1] = list_2_backup[1]
            list_qian[2] = list_2_backup[2]
            #print("前墩牌:",end = "")
            #print(list_qian)
            #print("lastscore:%d" %score)
            #print("_______________________")
        score = score_max_private

(這一部分的代碼寫的真的很差看,裏面不少變量的命名也很隨意,基本是想到哪寫到哪。由於最近在準備考試......基本是本着功能實現就好的想法寫的,也沒有去作重構,很抱歉)

6.性能分析與改進

時間佔比最高的函數爲獲取分數的函數,這是由於該函數會進行7w+的循環來找出最優牌組,而獲取分數的函數裏面佔比最高的是func_1函數,這個函數主要是由於使用次數極多,這個的做用是在作數值計算的時候把K轉換成12,A轉換成13,Q轉換成11,以此類推,我以爲這個函數很好的讓個人編寫過程變得愉快,由於元組一直在變換,就算用數值也要不停地作記錄,我以爲並不能簡化時間並且會增長內存,因此這是我目前能採用地最好策略。

7.單元測試

8.貼出github的代碼遷入記錄

9.遇到的代碼異常或結對困難及解決方法

李至恆:

問題描述 作過哪些嘗試 是否解決 有何收穫
怎麼設計出最優良的算法 貪心算法和權值矩陣 未徹底解決 在算法這一塊確實不如別人機靈,寫出來的基本都是套用和平庸的做品
防止相公的狀況出現 添加了weight值,讓中墩的weight不能超事後墩,前墩不能超過中墩 基本解決 在服務器上跑了幾百次基本沒有出現相公的狀況了

蔡嘉懿:

問題描述 作過哪些嘗試 是否解決 有何收穫
剛開始不會調用api 網絡搜索加問詢同窗 解決 學會了api的調用,有助於之後軟件設計
pygame初學,不少概念不懂 學些了網絡的教程 基本解決 學習了pygame一些前端知識,掌握了一些基本技能

10.評價你的隊友

李至恆

隊友真的幹了不少不少活,原本後端應該也要作接口這一塊的,可是他爲了讓我專心去搞算法把這個的活一塊兒拿走了

蔡嘉懿

隊友算法真的頂,分數拿的很高,由於考試緣由時間不夠我ui部分沒作完整,很愧疚對不起隊友。

學習進度條

第N周 新增代碼(行) 累計代碼(行) 本週學習耗時(小時) 累計學習耗時(小時) 重要成長
1 0 0 13 13 學習了axcure RP的使用。
2 300 300 8 18 肯定了基本的後端算法,如何分牌型,如何組牌
3 0 0 20 38 推翻了本來的貪心算法,重構了代碼並進行了測試和調錯,代碼量沒有本質增長,可是作的活很多
相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息