第二次结对编程作业
1、在文章开头给出结对同学的博客链接、本作业博客的链接、你所Fork的同名仓库的Github项目地址(2分)
- 结对同学博客链接:
黄森敏
本作业博客的链接(https://www.cnblogs.com/zhulichen/p/11679994.html)
陈碧芬 - Github项目地址:
13水UI
13水AI
UI视频提取码: 5j7c
2、给出具体分工(2分)
- 陈碧芬:负责UI界面设计以及UI接口连接
- 黄森敏:负责后端代码的编写以及单元测试环节
- 朱丽辰:负责后端服务器接口链接以及代码的完善
3、给出PSP表格(2分)
UI部分
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 100 | 120 |
· Estimate | · 估计这个任务需要多少时间 | 100 | 120 |
Development | 开发 | 2700 | 3300 |
· Analysis | · 需求分析 (包括学习新技术) | 1200 | 1500 |
· Design Spec | · 生成设计文档 | 120 | 120 |
· Design Review | · 设计复审 | 60 | 60 |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 180 | 180 |
· Design | · 具体设计 | 180 | 180 |
· Coding | · 具体编码 | 600 | 900 |
· Code Review | · 代码复审 | 90 | 90 |
· Test | · 测试(自我测试,修改代码,提交修改) | 60 | 60 |
Reporting | 报告 | 60 | 90 |
· Test Repor | · 测试报告 | 0 | 0 |
· Size Measurement | · 计算工作量 | 60 | 60 |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 90 | 60 |
· 合计 | 2800 | 3420 |
AI部分
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 60 | 90 |
· Estimate | · 估计这个任务需要多少时间 | 60 | 90 |
Development | 开发 | 1020 | 1290 |
· Analysis | · 需求分析 (包括学习新技术) | 120 | 180 |
· Design Spec | · 生成设计文档 | 60 | 30 |
· Design Review | · 设计复审 | 30 | 60 |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 30 | 30 |
· Design | · 具体设计 | 240 | 360 |
· Coding | · 具体编码 | 360 | 420 |
· Code Review | · 代码复审 | 60 | 30 |
· Test | · 测试(自我测试,修改代码,提交修改) | 120 | 180 |
Reporting | 报告 | 120 | 120 |
· Test Repor | · 测试报告 | 30 | 30 |
· Size Measurement | · 计算工作量 | 30 | 30 |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 60 | 60 |
· 合计 | 1200 | 1500 |
4、解题思路描述与设计实现说明(15分)
- 网络接口的使用(3分)
登陆接口(UI部分)
function my() {
if(document.getElementById("username").value=="" || document.getElementById("password").value=="")
{alert("账号和密码不能为空");return ;}
else{
var data = JSON.stringify({
"username": document.getElementById("username").value,
"password": document.getElementById("password").value
});
var xhr = new XMLHttpRequest();
xhr.onreadystatechange=function(){
if(xhr.readyState==4&&xhr.status==200){
var json=JSON.parse(xhr.responseText);
alert("登陆成功");
localStorage.removeItem("token");
localStorage.removeItem("user_id");
localStorage.setItem("token",json.data.token);
localStorage.setItem("user_id",json.data.user_id);
window.location.href='start(1).html';
console.log(xhr.responseText);
}
}
xhr.open("POST", "https://api.shisanshui.rtxux.xyz/auth/login",true);
xhr.setRequestHeader("content-type", "application/json");
xhr.send(data);
}
}
注销登录接口(UI部分)
function my() {
var xhr=new XMLHttpRequest();
xhr.onreadystatechange=function () {
if(xhr.readyState==4&&xhr.status==200){
alert(xhr.responseText);
window.location.href="index.html";
}
}
xhr.open("POST", "https://api.shisanshui.rtxux.xyz/auth/logout");
xhr.setRequestHeader("x-auth-token", localStorage.getItem("token"));
xhr.send();
}
历史详情接口(UI部分)
function my(){
dec();
var obj;
var xhr = new XMLHttpRequest();
var num=document.getElementById("number").value;
xhr.onreadystatechange=function(){
if(xhr.readyState==4){
obj=JSON.parse(xhr.responseText);
if(xhr.status==200){
function getJson(json){
var l=0;
for(var j in json.data.detail){
document.getElementById("demo").innerHTML+='<tr><td style="width: 13%">'+json.data.detail [l].player_id+'</td><td style="width: 17%;text-align: center">'+json.data.detail [l].name+'</td><td style="width: 10%">'+json.data.detail [l].score+'</td><td style="width: 60%">'+json.data.detail [l].card+'</td></tr>';
l++;
}
}
getJson(obj);
}
else if(obj.status==2004){alert("战局不存在或已结束");}
else if(obj.status==3001){alert("战局不存在或未结束");}
}
}
xhr.open("GET", "https://api.shisanshui.rtxux.xyz/history/"+num,true);
xhr.setRequestHeader("x-auth-token", localStorage.getItem("token"));
xhr.send();
}
AI:api请求使用的是python里的request库
以下贴出net_api.py文件中的主要函数
import requests
import cards_division
url='https://api.shisanshui.rtxux.xyz'
cards_list = []
max_list = []
def sign_in(username,password):
def register(username,password):
def logout():
def new_game_and_play():
def get_rank():
def get_history_list(limit,page):
def get_history_details(game_id):
if __name__=='__main__':
-
代码组织与内部实现设计(类图)(6分)
我们使用的是纯贪心算法,先出后墩和中墩代码,之后再根据后中墩牌型的类型在避免倒水的情况下出头墩,在后中墩代码实现过程中尽量使牌面平衡,三墩牌面尽量都大 -
说明算法的关键与关键实现部分流程图(6分)
算法关键:
# 获取牌型桶
def getBucket(arr_card):
# 统计同数值花色的多少并统计同花色数值的多少
def CardVal(cards_):
# 判断同花顺 判断同花个数 在判断有无联顺much个
def CardsTHS(cards_, much):
# 后墩,中墩出牌函数
def judge5(_post, _pai, card):
# 进行头墩出牌函数
def judge3(_post1, _post2, _pai, card, ty1, ty2):
# 将自己处理好的代码进行转换发送至服务端
def zhuanCards(chu, much):
# 出牌主函数
def divide_cards(cards_list):
5、关键代码解释(3分)
- 贴出你认为重要的/有价值的代码片段,并解释(3分)
UI:
UI接口部分的使用
var xhr = new XMLHttpRequest();
xhr.onreadystatechange=function(){
if(xhr.readyState==4&&xhr.status==200){
var json=JSON.parse(xhr.responseText);
alert(xhr.responseText);
localStorage.removeItem("token");
localStorage.removeItem("user_id");
localStorage.setItem("token",json.data.token);
localStorage.setItem("user_id",json.data.user_id);
window.location.href='start(1).html';
console.log(xhr.responseText);
}
}
xhr.open("POST", "https://api.shisanshui.rtxux.xyz/auth/login",true);
xhr.setRequestHeader("content-type", "application/json");
xhr.send(data);
AI:
这里贴出比较有特色的片段,为方便阅读先解释如下:
在这个片段前,我们先表达一下处理从服务器接收来的字符串我们是如何处理的:1.我们将字符串中的花色符号全部转换为数字1-4;2.将数值部分提取出来;3.计算公式:牌=值*4+花色。存储方面:建立二维数组,不同行代表花色(四行),不同列代表数值(13列)。
至于讲到普通出牌的判断,咳咳咳我们用的是鸵鸟算法。哈哈哈接下来po出一些片段:
idea:是将同种花色的牌数量存储在每一行的最后一位;将同大小数值的牌数存储在每一列的最后一位。
# 统计同数值花色的多少并统计同花色数值的多少
def CardVal(cards_):
for i in range(2, 15):
sum = 0
for j in range(1, 5):
if cards_[j][i] == 1:
sum = sum + 1
cards_[5][i] = sum
for i in range(1, 5):
sum = 0
for j in range(2, 15):
if cards_[i][j] == 1:
sum = sum + 1
cards_[i][15] = sum
return cards_
这里po出判断同花顺的函数,
idea:much代表的是想要判断3同花还是5同花,直接判断每行最后一位是否足够much,若足够就往回推。
# 判断同花顺 判断同花个数 在判断有无联顺much个
def CardsTHS(cards_, much):
for i in range(1, 5):
if cards_[i][15] >= much:
for j in range(14, much, -1):
count = 0
for k in range(much):
if cards_a[i][j - k] == 1:
count = count + 1
if count == much:
return i, j
return 0, 0
6、性能分析与改进(6分)
- 描述你改进的思路(5分)
我们通过修改算法来试图改进它的性能,举几个小板栗:
一开始我们设想的存牌的方式特别简单粗暴,想说直接转换成一对一对的数值,在对它们的头尾做操作。在后来边打边想到新方法边激烈讨论的过程中,有一种方法被三木想了出来,就是做一个矩阵,因为扑克牌一种花色一个值只能找出一张牌,所以用1来代表有牌,0代表没有。
在这个事件之后,我们又在存储花色桶和数值桶的时候,经过各种尝试,最后又修改成将需要的值存在矩阵中,减轻了不少负担。也提高了速度。 - 展示性能分析图和程序中消耗最大的函数(1分)
消耗最大的是input????input你怎么了,我只是为了单元测试...有没有人曾giao诉我,你怎么了有没有人曾在你input里哭泣啦啦啦
7、单元测试(5分)
- 展示出项目部分单元测试代码,并说明测试的函数,构造测试数据的思路
这五个单元测试是在实现算法的时候,通过本地输入输出来测试我们代码的可行性,测试了判断五张牌的函数Judge5和Judge3,def CardsTHS上文有展示一部分。这样构造的思路是为了测试,五张中的炸弹、同花、葫芦等这种我们在编写函数的时候比较担心的点,以及还有三张中的同花,且通过测试来查看是否会产生倒水。
8、贴出Github的代码签入记录(1分)
- 请合理记录commit信息
9、遇到的代码模块异常或结对困难及解决方法(8分)
- 问题描述(2分)
1.对出牌的技巧不够熟练,多种牌型不同组合虽然不保证每一墩都最大,但是尽可能让多的墩赢,这方面思路比较匮乏
2.半路上车python,有些地方只是初步了解,对接口的使用等等完全没有接触过,一头雾水不知道如何去做 - 做过哪些尝试(2分)
1.刚开始考虑使用组合算法,利用C(13,5),C(8,5)对后墩中墩的牌进行遍历,得到一个评分表,最后统一计算全值,选出最优牌,奈何评分系统想不出合理的方案,故放弃,转用纯贪心算法。
2.利用搜索引擎得到python中requests库的使用方法,使接口问题得到解决参考资料 - 是否解决(2分)
1.最后勉强完成了算法,算是写出来了
2.感谢教程,问题解决 - 有何收获(2分)
1.同一种问题可能有多种解决的方法,有些方法更优但是不会使用,求真务实,学会放弃,只求顺利完成出牌
2.搜索引擎妙啊,很多python不会使用的问题都可以靠它速成
10、评价你的队友(4分)
- 值得学习的地方(2分)
1.黄森敏:代码灌溉机,在作业过程中能把代码中一些不够好、或者比较繁琐的地方修改得更好。在思路方面总能有新的想法。
2.陈碧芬:进度发电机,在作业过程中频繁的邀请我们开会,导致我们很早就很紧张,一直开会,不过最后都在打牌, - 需要改进的地方(2分)
1.黄森敏:(组内的代码灌溉机)有的函数循环的量或者判断语句会比较多,可以以后优化。
2.陈碧芬:(组内的进度发电机)之前字体颜色很迷,但是已经改掉了,哈哈哈哈哈哈哈!以后提高颜色搭配啥的
11、学习进度条(2分)
UI部分
第N周 | 新增代码(行) | 累计代码(行) | 本周学习耗时(小时) | 累计学习耗时(小时) | 重要成长 |
---|---|---|---|---|---|
1 | 0 | 0 | 5 | 5 | 熟悉使用axure,并利用axure设计了产品原型 |
2 | 0 | 0 | 10 | 15 | 简单了解了html,css,和js |
3 | 500 | 500 | 15 | 30 | 学习了html,css,js语言及其使用,开始做网页页面设计,做出了网页雏形 |
4 | 300 | 800 | 27 | 57 | 主要学习了接口的使用,以及规范代码,确定最后的布局 |
AI部分
第N周 | 新增代码(行) | 累计代码(行) | 本周学习耗时(小时) | 累计学习耗时(小时) | 重要成长 |
---|---|---|---|---|---|
1 | 0 | 0 | 5 | 5 | 学了一点js,学习使用axure,尝试做了第一个原型模型 |
1 | 0 | 0 | 5 | 5 | 学习一些JavaScript知识 |
2 | 200 | 200 | 5 | 10 | 学习一些接口知识,理清楚出牌思路 |
3 | 400 | 600 | 10 | 25 | 实现出牌算法,并对一些问题进行修复,学到了很多python算法 |