目录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 | 尝试与前端对接,完成全部代码工做,学习了网络接口的知识 |