- 在文章开头给出结对同学的博客链接、本作业博客的链接、你所Fork的同名仓库的Github项目地址(2分)
本博客链接:https://www.cnblogs.com/huckleberry/p/11708269.html
结对同学链接:https://www.cnblogs.com/zhangweijia1999/p/11767594.html
Github项目:https://github.com/BloodyVampire/thirteenwater
- 给出具体分工(2分)
翟鑫亮负责算法的设计,张伟佳负责接口连接,UI两人共同承担
- 给出PSP表格(2分)
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 80 | 100 |
· Estimate | · 估计这个任务需要多少时间 | 60 | 90 |
Development | 开发 | 1500 | 1600 |
· Analysis | · 需求分析 (包括学习新技术) | 600 | 700 |
· Design Spec | · 生成设计文档 | 50 | 30 |
· Design Review | · 设计复审 | 100 | 80 |
· Coding Standard | · 代码规范 (为目前的开发制定或选择合适的规范) | 30 | 30 |
· Design | · 具体设计 | 800 | 930 |
· Coding | · 具体编码 | 500 | 600 |
· Code Review | · 代码复审 | 40 | 30 |
· Test | · 测试(自我测试,修改代码,提交修改) | 50 | 80 |
Reporting | 报告 | 110 | 100 |
· Test Repor | · 测试报告 | 40 | 30 |
· Size Measurement | · 计算工作量 | 20 | 10 |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出改进计划 | 50 | 60 |
· 合计 | 4030 | 4470 |
- 网络接口的使用(3分)
// 身份验证
function check()
{
$.ajax({
url:'https://api.shisanshui.rtxux.xyz/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='login.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:'https://api.shisanshui.rtxux.xyz/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("匹配异常,请重试");
}
});
}
- 代码组织与内部实现设计(类图)(6分)
- 算法的关键与关键实现部分流程图(6分)
此次的算法主要涉及到制作扑克、洗牌和对前中后三堆牌的选择三部分。
1、制作扑克
利用两个字符串数组将扑克的花色和数值保存起来,再用循环将不同花色所对应
的数值扑克制作出来保存到map<int,string>中并将牌号保存到vector<int> oldarr中。
2、洗牌
调用distribute方法里的随机分配函数将根据系统时间产生随机数,在循环里选择该
扑克号存入vector<int> newarr中。
3、分堆选择
由于十三水中的牌型比较多,所以我们依次从大牌型到小牌型考虑。先分后堆,再分中堆,最后前堆。
- 关键代码解释(3分)
void get_rand_number(vector<int> oldarr, vector<int> &newarr)
{
int value;
srand((int)time(0)); //拿当前系统时间作为种子,由于时间是变化的,种子变化,可以产生不相同的随机数。
/* 发牌的时候对于已经分配的数据不再修改 */
for (int index=52;index>0; index--)
{
value =rand() % index;
newarr.push_back(oldarr[value]);
oldarr.erase(oldarr.begin() + value);
}
}
以上代码中的srand()保证了洗牌的随机性。
void getpoker(vector<string> handPoker)
{
memset(a,'0', sizeof(a));
for (string str : handPoker)
{
int index;
if (str[1] > '1' && str[1] <= '9')
index = (str[1] - '2');
else if (str[1] == '%')index = 8;
else if (str[1] == 'J' )index = 9;
else if (str[1] == 'Q')index = 10;
else if (str[1] == 'K')index = 11;
else index = 12;
y[index]++;
if (str[0] == '&')
{
a[0][index] = str[1];
x[0]++;
}
else if (str[0] == '$')
{
a[1][index] = str[1];
x[1]++;
}
else if (str[0] == '*')
{
a[2][index] =str[1];
x[2]++;
}
else
{
a[3][index] =str[1];
x[3]++;
}
}
}
对扑克数组进行赋值,在构造完后方便后面的各种牌型的判断和牌的“删除”。
- 展示性能分析图和程序中消耗最大的函数(1分)
- 描述你改进的思路(5分)
可以从性能分析图看出,我们的play函数和lookPoker函数所占的消耗最大。我在lookPoker函数先是对扑克复制到
另一个数组,然后再对这个数组进行特殊字符%的判断,这无疑加大了开销,所以将会直接在原来数组里判断并输出。
7、单元测试(5分)
展示出项目部分单元测试代码,并说明测试的函数,构造测试数据的思路
TEST_METHOD(samecolordragon)
{
Operation oper;
vector<string> temp;
temp.push_back("#2"); temp.push_back("#3"); temp.push_back("#4");
temp.push_back("#5"); temp.push_back("#6"); temp.push_back("#7");
temp.push_back("#8"); temp.push_back("#9"); temp.push_back("#%");
temp.push_back("#J"); temp.push_back("#Q"); temp.push_back("#K"); temp.push_back("#A");
oper.getpoker(temp);
Assert::IsTrue(oper.samecolordragon());
}
构造一个存储字符串的向量,向其中存储特殊牌型-----至尊清龙,判断samecolordragon函数是否判断正常。
- 贴出Github的代码签入记录(1)
- 遇到的代码模块异常或结对困难及解决方法(8分)
- 问题描述(2分)
翟鑫亮:对福建十三水这种棋牌游戏的规则很迷,什么各种打枪或者全垒打还有
输赢后如何进行水的划分都不是很清楚。
张伟佳:完全没有这方面的经验和知识,面对问题一头雾水。
- 做过哪些尝试(2分)
翟鑫亮:有从网上看过许多这种十三张类似游戏的规则,发现它们的玩法大差不差
只不过是牌型的叫法不同而已。此外还从网上看了一些关于该游戏的视频。
张伟佳:上网查询资料,去CSDN找帖子,问问题,去哔哩哔哩看各种教学视频,
视频各有倾向,先从简单的入手,再去看一些倾向性比较强的。
- 是否解决(2分 )
基本解决
- 有何收获(2分)
翟:收获的话,大概应该有两点。第一个就是学会了如何打福州十三水,说实话
还是第一次听过这种玩法,一开始还以为是什么旅游胜地呢。其次的话,接触到了
一些游戏规则设计的算法,学会了更加灵活地解决问题。
张:学会了intellij idea的使用,可以自己制作简单的网页。期间遇到的问题很多,
解决的时候感觉很崩溃,但解决完后还是蛮开心的。总的来说还是蛮有意义的,锻炼了
自主学习能力。
- 评价你的队友(4分)
翟鑫亮:张伟佳nb,就是没能带我飞。
张伟佳:翟鑫亮nb,能很好地安排任务和时间。
- 值得学习的地方(2分)
翟鑫亮:对bgm的审美很有品味,做事情超认真。
张伟佳:做事情超认真,可以一做就是好久,虽然遇到问题也能看的出来很痛苦,但还是能坚持着去解决,我
就要干会其他的才能接着敲代码。
- 需要改进的地方(2分)
翟鑫亮:在web设计那块做的还需要改进,没能够很好地规划UI。
张伟佳:一开始还是没太放在心上,考完试到后面时间已经不够了,还有好多没有学习。以后应该早做规划,提前把
事情安排好。
- 学习进度条(2分)
第N周 | 新增代码(行) | 累计代码(行) | 本周学习耗时(小时) | 累计学习耗时(小时) | 重要成长 |
---|---|---|---|---|---|
1 | 0 | 0 | 20 | 20 | 学会了原型设计工具的基本使用方法,学会了十三水的玩法 |
2 | 340 | 340 | 50 | 60 | 开始学习网页制作,并着手于算法设计 |
3 | 520 | 860 | 45 | 100 | 网页制作基本成型,开始交互工作; |
4 | 412 | 1272 | 60 | 130 | 基本完成ai和ui制作 |