目錄javascript
前端編寫與先後端交接:胡康java
後端算法測試與博文編寫:黃宇航python
PSP2.1 | Personal Software Process Stages | 預估耗時(分鐘) | 實際耗時(分鐘) |
---|---|---|---|
Planning | 計劃 | 60 | 100 |
Estimate | 估計這個任務須要多少時間 | 60 | 100 |
Development | 開發 | 600 | 1000 |
Analysis | 需求分析 (包括學習新技術) | 600 | 600 |
Design Spec | 生成設計文檔 | 30 | 40 |
Design Review | 設計複審 | 20 | 20 |
Coding Standard | 代碼規範 (爲目前的開發制定合適的規範) | 20 | 30 |
Design | 具體設計 | 50 | 60 |
Coding | 具體編碼 | 1650 | 1800 |
Code Review | 代碼複審 | 50 | 40 |
Test | 測試(自我測試,修改代碼,提交修改) | 100 | 120 |
Reporting | 報告 | 100 | 100 |
Test Report | 測試報告 | 30 | 30 |
Size Measurement | 計算工做量 | 20 | 20 |
Postmortem & Process Improvement Plan | 過後總結, 並提出過程改進計劃 | 50 | 60 |
合計 | 3440 | 4120 |
前端登陸註冊查看排行榜接口用JavaScript編寫git
//登陸 <script> var username=document.getElementById("i1"); var password=document.getElementById("i2"); function t1(){ var data = JSON.stringify({ "username": username.value, "password": password.value }); if (username.value == "" ||password.value == "" ) { alert("請輸入用戶名或密碼"); return ; } var xhr = new XMLHttpRequest(); xhr.addEventListener("readystatechange", function () { if (this.readyState === this.DONE) { console.log(this.responseText); var JsonObj = JSON.parse(this.responseText); if(JsonObj.status==0) { localStorage.setItem("token",JsonObj.data.token); localStorage.setItem("id",JsonObj.data.user_id); alert("登陸成功"); window.location.href = "game.html"; } else if(JsonObj.status==1003) alert("教務處認證失敗"); else alert("用戶名未註冊或密碼錯誤"); } }); xhr.open("POST","http://api.revth.com/auth/login"); xhr.setRequestHeader("content-type", "application/json"); xhr.send(data); } </script> //註冊 <script> var username=document.getElementById("i1"); var password=document.getElementById("i2"); function t1() { var data = JSON.stringify({ "username": username.value, "password": password.value, "student_number": document.getElementById("ii3").value, "student_password" :document.getElementById("ii4").value }); if (username.value == "" ||password.value == "" ) { alert("請輸入用戶名或密碼"); return ; } if(document.getElementById("ii3").value==""||document.getElementById("ii4").value=="") { alert("請輸入學號或教務處密碼"); return ; } var xhr = new XMLHttpRequest(); //xhr.withCredentials = true; xhr.addEventListener("readystatechange", function () { if (this.readyState === this.DONE) { console.log(this.responseText); var JsonObj = JSON.parse(this.responseText); if(JsonObj.status==0) alert("註冊成功,請登陸"); else if(JsonObj.status==1001) alert("用戶名已被使用"); else if(JsonObj.status==1002) alert("學號已綁定"); else if(JsonObj.status==1003) alert("教務處認證失敗"); else alert(JsonObj.status) } }); xhr.open("POST", "http://api.revth.com/auth/register2"); xhr.setRequestHeader("content-type", "application/json"); xhr.send(data); } </script> //登陸驗證 function check(){ $.ajax({ url:'http://api.revth.com/auth/validate', type:'GET', headers:{ "Content-Type":'application/json', "X-Auth-Token":localStorage.getItem('token') }, dataType:'json', success:function(data){ if (data['data']['user_id']==null){ alert("登陸過時,請重試"); window.location.href='登入.html'; } else{ document.getElementById("chupai").onclick=function () { document.getElementById("fapai").style.display="block" document.getElementById("chupai").style.display="none" } if (localStorage.getItem('card')!=null) showCard(); if (localStorage.getItem('gameid')!=null) document.getElementById('gameid').innerText="房間:"+localStorage.getItem('gameid'); } }, error:function(data){ alert("登陸過時,請重試"); } }); } //開始對局 function openGame(){ $.ajax({ url:'http://api.revth.com/game/open', type:'POST', dataType:'json', headers:{ 'X-Auth-Token':localStorage.getItem('token') }, success:function(data){ document.getElementById("chupai").style.display="block"; document.getElementById("fapai").style.display="none"; document.getElementById('gameid').innerText="房間:"+data['data']['id']; localStorage.setItem("gameid",data['data']['id']); localStorage.setItem("card",data['data']['card']); showCard(); }, error:function(data){ alert("匹配異常,請重試"); } }); } //排行榜 function getRank(){ $.ajax({ url:'http://api.revth.com/rank', type:'GET', dataType:'json', success:function(data){ document.getElementById('paihangbang').style.display=""; for (var i=1;i<=5;++i){ var pid="pid"+i; var s="s"+i; var name="name"+i; document.getElementById(pid).innerText=data[i-1]['player_id']; document.getElementById(s).innerText=data[i-1]['score']; document.getElementById(name).innerText=data[i-1]['name']; } }, error:function(data){ alert("請求出錯,請重試"); } }); } //歷史戰績 function query(){ var username=document.getElementById('queryUser').value; $.ajax({ url:'http://api.revth.com/history/id', type:'GET', dataType:'json', headers:{ 'X-Auth-Token':localStorage.getItem('token') }, success:function(data){ console.log(data); }, error:function(data){ alert('查詢失敗,請重試'); } }); }
後端 開始遊戲接口使用了requests庫github
import requests import cards_division url = 'http://api.revth.com' cards_list = [] max_list = [] '''開始遊戲並出牌''' def newgameplay(): global url global cards_list global max_list f = open('token.txt') token = f.readline() f.close headers = {"X-Auth-Token" : token} r = requests.post(url+'/game/open', headers=headers) print(r.text) data = r.json() status = data['status'] game_id = data.get('data').get('id') cards_string = data.get('data').get('card') cards_list = cards_string.split(' ') max_list = cards_division.divide_cards(cards_list) front = ' '.join(max_list[10:13]) middle = ' '.join(max_list[5:10]) rear = ' '.join(max_list[0:5]) payload = { "id": game_id, "card": [ front, middle, rear ] } headers = { 'content-type': "application/json", "X-Auth-Token": token } r2 = requests.post(url+'/game/submit', json=payload, headers=headers) print(r2.text) data = r2.json() status2 = data.get("status") for i in range(0, 13): if max_list[i][0] == '*': max_list[i] = '^'+max_list[i][1:] return max_list
Step1:將牌’A‘轉變成值爲14的牌,並將獲得的13張牌升序排序ajax
def change_and_sort_cards(list): for i in range(0, 13): if list[i][1]=='A': list[i]=list[i][0]+'14' elif list[i][1]=='J': list[i] = list[i][0]+'11' elif list[i][1]=='Q': list[i]=list[i][0]+'12' elif list[i][1]=='K': list[i]=list[i][0]+'13' list.sort(key=lambda x:int(x[1:]))
Step2:遍歷後墩算法
Step3:遍歷完後墩判斷是否繼續再遍歷中墩,json
Step4:剩下的排歸爲前墩
Step5:判斷各墩的牌的類型
Step6:判斷並選出權值最大的狀況
各類牌型的判斷
def same_flower(list): flag = True if len(list) == 3: return 0 else: for i in range(1, 5): if list[0][0] != list[i][0]: flag = False break if flag: return TONGHUA + int(list[4][1:]) * P else: return 0 def shunzi(list): if len(list) == 3: return 0 else: flag = True for i in range(1, 5): if int(list[i][1:]) - 1 != int(list[i - 1][1:]): flag = False if flag: return SHUNZI + int(list[4][1:]) * P else: return 0 def zhadan(list): flag = True if len(list) == 3: return 0 else: if list[1][1:] != list[2][1:] or list[1][1:] != list[3][1:]: flag = False if list[1][1:] != list[0][1:] and list[4][1:] != list[3][1:]: flag = False if flag: return ZHADAN + int(list[2][1:]) * P else: return 0 def hulu(list): flag = True if len(list) == 3: return 0 else: if list[0][1:] != list[1][1:] or list[3][1:] != list[4][1:]: flag = False if list[3][1:] != list[2][1:] and list[1][1:] != list[2][1:]: flag = False if flag: return HULU+int(list[2][1:])*P else: return 0 def santiao(list): flag = False if list[0][1:] == list[1][1:] and list[0][1:] == list[2][1:]: return SANTIAO+int(list[2][1:])*P elif len(list) == 5: for i in range(0, 3): if list[i][1:] == list[i+1][1:] and list[i][1:] == list[i+2][1:]: flag=True break if flag: return SANTIAO+int(list[2][1:])*P else: return 0 else: return 0 def select_duizi(list): if len(list)==3: if list[0][1:] == list[1][1:] or list[2][1:] == list[1][1:]: return YIDUI+int(list[1][1:])*P else: return SANPAI+int(list[2][1:])*P elif len(list) == 5: tmp = [] i = 0 while i < 4: if list[i][1:] == list[i+1][1:]: tmp.append(i) i += 1 i += 1 if len(tmp) == 1: return YIDUI+int(list[tmp[0]][1:])*P elif len(tmp) == 2: if tmp[1]-tmp[0] == 2 and int(list[tmp[1]][1:])-int(list[tmp[0]][1:]) == 1: return LIANDUI+int(list[tmp[1]][1:])*P else: return ERDUI+int(list[tmp[1]][1:])*P elif len(tmp) == 0: return SANPAI+int(list[4][1:])*P
將牌分堆後找出權值最大的組合
def sort_cards(list): cards = [list[10:13], list[5:10], list[0:5]] scores = [0, 0, 0] for i in range(0, 3): if same_flower(cards[i]) == 0: scores[i] = zhadan(cards[i]) if scores[i] != 0: continue scores[i] = hulu(cards[i]) if scores[i] != 0: continue scores[i] = shunzi(cards[i]) if scores[i] != 0: continue scores[i] = santiao(cards[i]) if scores[i] != 0: continue scores[i] = select_duizi(cards[i]) else: scores[i] = same_flower(cards[i]) if shunzi(cards[i]) != 0: scores[i] += 3 if scores[0] > scores[1] or scores[1] > scores[2]: return [0, 0, 0] else: return scores啊啊
先Profile一下代碼,結果如圖:
import cards_division import cards_sorting import openapi import unittest class test(unittest.TestCase): def test_cards_type(self): self.assertEqual(cards_sorting.select_duizi(['#2', '#2', '#2', '#2', '#2']), 4.25) self.assertEqual(cards_sorting.santiao(['#2', '#4', '#4', '#4', '#7']), 5.25) def test_divide(self): cards_division.divide_cards(['&2', '#3', '&4', '#K', '#4', '^2', '$2', '#5', '&6', '^4', '*$8', '&8', '#A']) self.assertEqual(cards_division.count, 72072) def test_openapi(self): self.assertEqual(openapi.sign_in('Cerberus', 'hyh990723'), 0) self.assertEqual(openapi.newgameplay(), 0) if __name__ == '__main__': unittest.main()
測試函數:
思路:
使用Python中的unittest模塊,對代碼中容易出錯但又沒法直接根據最終結果進行定位的模塊進行測試。
啥也不知道寫了啥就往上丟啥吧
遇到困難:
胡康不會python,我不會java,你們都痛恨C++,而後他說去自學python,後面由於忽然冒出來個接入網考試,時間大大縮水。
兩個算法白癡,都想作前端,後來得知前端能夠用網頁寫,而後胡康恰好會就輪到我這個弟弟寫後端
因爲沒有經驗,代碼規範未作好,在將兩人代碼組合時出現了許多問題
嘗試
嘗試用python的pygame寫前端,後來發現只要python的tkinter就能夠完成,再後來發現python的PyQt挺好用,最後放棄了用python寫前端。
瘋狂用PS設計圖片以知足前端的要求
是否解決
最終解決了雙方語言不通的困難,前端用網頁寫,後端用python寫,最後用什麼ajax整到一塊兒,雖然還沒整好。
收貨
感受前端更好玩一點,直男審美是時候露一手了
更加深刻的學習了python···
黃宇航真的很優秀!不論是第一次結對做業仍是第二次結對做業,他都是挑大頭,頗有責任感,細心,審美也不錯,此次能和他作隊友真的是賺到!缺點是什麼?宇航沒有缺點!
第N周 | 新增代碼(行) | 累計代碼(行) | 本週學習耗時(小時) | 累計學習耗時(小時) | 重要成長 |
---|---|---|---|---|---|
··· | ··· | ··· | ··· | ··· | ··· |
6 | 431 | 431 | 15 | 23 | 經過學習瞭解了python列表一些更有用的使用方法,固然還有pygame和tkinter的白給學習時間 |
7 | 210 | 641 | 13 | 36 | 學習了一些JavaScript和H5的知識,緣由大概就是計算機圖形學要考試了,順便學學前端,由於對前端感興趣哈哈 |
8 | 116 | 757 | 7 | 43 | 嘗試與前端對接,完成全部代碼工做,學習了網絡接口的知識 |