结对编程作业
https://github.com/83675299/poker
姓名 | 分工 | 博客链接 |
---|---|---|
蔡炜鑫 | 负责游戏逻辑和AI算法 | https://www.cnblogs.com/caiwx123/p/15449961.html |
侯钦凯 | 负责前端界面和接口调用 | https://www.cnblogs.com/147258369k/p/15449934.html |
一、原型设计
1.原型的链接
https://app.axure.cloud/app/project/7v9afl/overview
采用Axure Rp设计
2.设计思路
这是主界面,点击按钮进入不同的模式,左上方可以放背景音乐。
这是进入本地对战的画面,按右上角的灯泡可以开启按键提示,按牌堆上面的按钮开启记牌器。
左上是放置区,右上是牌堆,左下是p1的手牌区,右下是p2的手牌,轮到谁,谁的区域边框就会亮起来,用这个来判断怎么出牌。
除了本地对战,还可以进入在线对战,先选择使用玩家还是ai开启战斗,再选择创建房间还是加入房间。
点击创建房间和本地对战是一样的画面,等待p2进入房间就可以开始游戏。
点击加入房间是下面的画面,实现了分页和搜索的功能。
遇到的困难有ai不知道如何实现,如果使用机器学习的话对我们难度太高了,最后使用了写一个能处理大部分情况的算法来实现ai功能。
二、原型设计实现
1.代码实现思路
- 网络接口的使用
使用new XMLHttpRequest()来定义一个XMLHttpRequest变量xml,然后通过open(),setRequestHeader(),send(),onreadystatechange()等函数给服务器发送数据和接收数据。
如下面的例子
function execute(type, card, callback){//执行玩家操作接口
var xml = new XMLHttpRequest();
var url = 'http://172.17.173.97:9000/api/game/' + uuid;
xml.open("put", url);
xml.setRequestHeader('Authorization', your_token);
if(type==0)
xml.send('{"type": 0}');
else
xml.send('{"type": 1,"card": "' + card + '"}');
xml.onreadystatechange = function () {
var obj = JSON.parse(xml.responseText);
callback(obj);
};
-
代码组织与内部实现设计
my_main()主函数
User(operations,my_who,name,is_robot)设置按键并判断是否轮到回合和是否是托管状态
function Card_group(name)生成牌堆和取牌翻牌
var robot_do = function(user)托管的算法
var who_changed = function()用于调用人机操作与系统操作user2
var game_over = function()游戏结束
var clear_poker =function()清除界面的牌,用于重开游戏
var game_init = function()设置游戏的模式
var game_start_local = function(type)本地对战
var game_start_online = function(type)显示在线对战里的按钮
var click_create = function()创建对局
var show_match = function()加入对局里的分页和搜索功能
var login = function(student_id, password, callback)登录接口
var createGame =function(flag,callback)创建新的对局接口
var enterGame = function()加入新的对局接口
var execute = function(type, card, callback)执行玩家操作接口
var getLastOperation = function(callback)获取上一步操作的接口
var getGame = function(callback)获取某局信息的接口
var getPlayingGame = function(page_size, page_num, callback)获取所有对局的信息
-
说明算法的关键与关键实现部分流程图
算法的关键:由于这是一个回合制游戏,我们用一个变量who来代表这是谁的回合或谁的回合都不是,然后通过每一次的who改变调用相应的函数,产生让机器或者在线对战系统给回的信息来操纵对应的用户或者等待用户操纵的三种模式,以及相应回合改变时画面的变换。
这是用来生成卡组里面的牌的函数,他可以生成乱序的牌并且依次让每张牌从下到上的z-index依次增加,也可用于在线对战也可生成有序然后让每张牌的z-index都等于0,当我要从卡组抽牌时就可以将对应的牌z-index=1让他浮在其他牌上面。并且给每张牌设置一些信息用于后面的查看。
-
贴出你认为重要的/有价值的代码片段,并解释
this.init_cards = function(){ // 兼容本地对局 与在线对局 // 生成卡组 this.color_number = [13,13,13,13]; this.sum_number = 52; // 生成牌堆 this.colors = "0123"; // 0123分别代表 黑桃 红桃 梅花 方块 this.number = ['A','2','3','4','5','6','7','8','9','10','J','Q','K']; this.color_str=["heitao","hongtao","meihua","fangkuai"]; // colors 于 number 是 生成牌堆使用的 var a = []; for(var i=0;i<52;i++){ a[i] = i+''; } // 生成牌的乱序 if(!this.accurate){ a.sort(function(){ return Math.random() -0.5; }) } var one_poker ; for(var j=0;j<4;j++){ color.className = 'color_size'; color.className += ' ' + this.color_str[j]; for(var i=0;i<13;i++){ one_poker = poker.cloneNode(true); one_poker.setAttribute('index_number',i+1+''); //给每张牌设置 数字提示 one_poker.setAttribute('index_color',this.colors[j]); // 花色提示 one_poker.getElementsByClassName('number')[0].innerText = this.number[i]; //数字 if(!this.accurate) one_poker.style.zIndex = a[j*13+i]; // 乱序排序 给每张牌设置 z-index 从卡组底端依次增加 else one_poker.style.zIndex = 0; // 顺序排序 每张 z-index 都是0 等到 系统给我们要翻那张排时再给他设置zindex this.cards[a[j*13+i]] = one_poker; // 插入牌组 game_container.appendChild(one_poker); // 插入dom结点树 } } this.tip_update(); }
-
性能分析与改进,描述你改进的思路
全部都是由前端完成,没有找到好用的js性能分析工具,但是有改进,我们减少了几个setTimeOut函数,使性能提高。
-
展示出项目部分单元测试代码,并说明测试的函数,构造测试数据的思路
var login = function(student_id, password, callback)登录接口测试,如果能够成功获取到token就是没问题的。
function login('031902505', password, callback) {//登录接口
xml = new XMLHttpRequest();
var url = "http://172.17.173.97:8080/api/user/login";
xml.open('post', url, true);
xml.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xml.send('&student_id=' + student_id + '&password=' + password);
xml.onreadystatechange = function () {
var obj = JSON.parse(xml.responseText);
callback(obj.data.token);
console.log('obj.data.token = ' + obj.data.token);
};
};
2.贴出Github的代码签入记录,合理记录commit信息。
3.遇到的代码模块异常或结对困难及解决方法。
侯钦凯:
在调用接口的时候,会出现明明在函数中接收到了服务器返回的信息,但是出了函数之后,那个接收返回值的变量确实undifined,经过查询资料,了解到了JavaScript是异步编程语言,需要使用回调函数才能获取信息,所以最后使用了回调函数解决了这个难题,但解决的途中依然给我们带来了很大的麻烦。
蔡炜鑫:
在写完本地对战后,本以为在线对战和本地对战逻辑是一样活着差不多的,没想到差了很多,所以之后在线对战的逻辑又花了我们很大的工作量。然后JavaScript的定时功能很不好用,而收到接口返回的信息需要一定的时间,所以我们又经过了大量的学习和修改,才完成了在线对战的功能。
4.评价你的队友。
侯钦凯:
队友十分可靠,我们一直都只是在学习前端,最后一周才开始动工,用了三天就使游戏可以玩了,主要是我的队友炜鑫大佬太强了,主要代码基本都是他打的,我只是写了一点比较简单的代码和接口调用。我需要学习的是他的学习效率和工作态度吧,都是没有基础,同时开始学习前端,炜鑫学的就比我好,而且三天爆肝完成大部分功能,工作态度也是没有问题的。需要改进的可能是做得事情太多了吧,我们有同时开始写代码,他在完成他的代码后,把我的那部分也写完了。。。
蔡炜鑫:
队友学习未知的东西是非常快的,我在调用接口的时候遇到了困难,是由队友解决的。做得不好的地方是我们两人代码比较难整合在一起,两人分别写的都能运行,放到一起就一堆bug,这点需要改进。
5.提供此次结对作业的PSP和学习进度条(每周追加)。
由于我们的作业是全部由前端完成,我们又都没有基础,所以是共同学习的前端,一份PSP表格和学习进度条就足够了。
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 10 | 10 |
· Estimate | · 估计这个任务需要多少时间 | 5 | 5 |
Development | 开发 | 5 | 5 |
· Analysis | · 需求分析 (包括学习新技术) | 3000 | 4500 |
· Design Spec | · 生成设计文档 | 60 | 60 |
· Design Review | · 设计复审 | 30 | 30 |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 30 | 30 |
· Design | · 具体设计 | 120 | 120 |
· Coding | · 具体编码 | 2000 | 2000 |
· Code Review | · 代码复审 | 30 | 60 |
· Test | · 测试(自我测试,修改代码,提交修改) | 500 | 600 |
Reporting | 报告 | 60 | 120 |
· Test Repor | · 测试报告 | 30 | 30 |
· Size Measurement | · 计算工作量 | 10 | 10 |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 30 | 30 |
· 合计 | 6020 | 7610 |
第N周 | 新增代码(行) | 累计代码(行) | 本周学习耗时(小时) | 累计学习耗时(小时) | 重要成长 |
---|---|---|---|---|---|
1 | 0 | 0 | 15 | 15 | 学习了html和css部分用法 |
2 | 0 | 0 | 30 | 45 | 看完了html和css的一个视频教程 |
3 | 0 | 0 | 30 | 75 | 学习了部分JavaScript的用法 |
4 | 2300 | 2300 | 42 | 117 | 看完了JavaScript的一个视频教程,并完成作业 |
三、心得
侯钦凯:
通过本次结对作业,我学习了html,css,和js这些前端语言的基础知识,我曾经在开课的时候很天真的以为每周需要”只需要“用十个小时左右就可以完成作业,但这次几乎每周都用了30个小时,每天除了学习新的前端知识,没有任何时间能做其他的事情了,在最后一周冲刺项目的时候更是每天写到两点,挑战性很大。我在这一个月写这次课程的期间,其他的课都落下了不少,可能是我的学习效率比较低,但真的是被ddl压迫,放学后只能学习前端,每天少则2-3个小时,多则4-5个小时。做完这次结对作业,很想好好休息一下,补一下别的课。从零开始学习一门语言,在一个月内完成一个项目,虽然学到了很多,但难度对我来说有点过大了,身心俱疲。
蔡炜鑫:
通过本次结对作业,我学习了前端的最基本的知识,我也认识到了其实前端也不简单,想要打出可以易于维护的代码也是非常具有挑战性的。这也是我第一次做一个游戏,很多东西都需要去学习,但这也代表着我通过这次结对作业确实学到了很多东西,怎么说呢,可能如果没有这作业的ddl我们可能还真写不出来,毕竟学东西就花了快一个月,也是最后一周才开始写,最大的心得应该是写代码之前得先了解清楚要写什么,不然可能写着写着你就发现你得去大改一次,就像这次结对作业,我一开始不知道要写联机的,理所当然就以为只要写个本地的写出来了就好了,然后到了后面本地都要写完了才发现得写联机的,导致后面一些代码的逻辑都得重新改很耗费时间,还很影响积极性。所以总结来说这次结对作业学到了挺多,挺不错的。