第二次结对编程作业

链接及地址

蔡峰博客链接

陈金杰博客链接

项目Github地址

UI视频演示如下:


具体分工

陈金杰负责对接及算法编写,蔡峰负责界面制作。


PSP表格

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 80 90
· Estimate · 估计这个任务需要多少时间 80 90
Development 开发 2930 3520
· Analysis · 需求分析 (包括学习新技术) 800 840
· Design Spec · 生成设计文档 50 30
· Design Review · 设计复审 100 80
· Coding Standard · 代码规范 (为目前的开发制定或选择合适的规范) 30 30
· Design · 具体设计 900 930
· Coding · 具体编码 960 1500
· Code Review · 代码复审 40 30
· Test · 测试(自我测试,修改代码,提交修改) 50 80
Reporting 报告 110 100
· Test Repor · 测试报告 40 30
· Size Measurement · 计算工作量 20 10
· Postmortem & Process Improvement Plan · 事后总结, 并提出改进计划 50 60
  · 合计 3120 3710

解题思路描述与设计实现说明

网络接口的使用

考虑到学习周期以及实际需求,选择了用web实现游戏的UI,用JS中的Ajax发送请求与服务器接口交互。以下为我们使用接口的几个实例:

点击查看
 
```
        function login(){
            var name=document.getElementById('username').value;
            var psw=document.getElementById('userpsw').value;
            var data={
                "username":name,
                "password":psw
            }
            $.ajax({
                url:'https://api.shisanshui.rtxux.xyz/auth/login',
                type:'POST',
                data:JSON.stringify(data),
                headers:{
                    "Content-Type":'application/json'
                },
                success:function(data){
                    localStorage.setItem("token",data['data']['token']);
                    localStorage.setItem("userid",data['data']['user_id']);
                    window.location.href='game.html';
                },
                error:function(data){
                    alert("登录异常,请重试");
                }
            });
        }
        function query(){
            var username=document.getElementById('queryUser').value;
            $.ajax({
                url:'https://api.shisanshui.rtxux.xyz/history?player_id='+username+'&limit=3&page=1',
                type:'GET',
                dataType:'json',
                headers:{
                    'X-Auth-Token':localStorage.getItem('token')
                },
                success:function(data){
                    console.log(data);
                },
                error:function(data){
                    alert('查询失败,请重试');
                }
            });
        }
        function logout(){
            if (localStorage.getItem('token')!=null){
                $.ajax({
                    url:'https://api.shisanshui.rtxux.xyz/auth/logout',
                    type:'POST',
                    headers:{
                        "Content-Type":'application/json',
                        "X-Auth-Token":localStorage.getItem('token')
                    },
                    dataType:'json',
                    success:function(data){
                        localStorage.removeItem('token');
                        localStorage.removeItem('userid');
                        localStorage.removeItem('gameid');
                        localStorage.removeItem('card');
                        window.location.href='login.html';
                    },
                    error:function(data){
                        alert("注销失败,请重试");
                    }
                });  
            }
        }
```

代码组织与内部实现设计(类图)

建了一个类autoPlayer,大概逻辑是通过构造函数来接收手牌,初始化辅助数组,对每类牌型在每墩的情况下的价值就行评估赋值,并存在value矩阵中。然后通过自己设计的calculate函数贪心找出价值和最大的方案并返回

算法思路

* 对于这个问题的求解思路,大概分两步 * 第一步,较高效的枚举出所有的合法出牌方案 * 第二步,对于每个方案评估其价值 * 对于第一步,若靠朴素的全排列枚举搜索,是阶乘的复杂度,即13!。考虑到要面临的数据组数很多,这个复杂度并不好。我们可以发现其实全排列枚举,是会出现很多冗余计算的。因此考虑记忆化,我们可以预先枚举任意五张牌,记录下他们的可以构成的最大等级牌型,再预先枚举任意三张牌,做同样操作。 * 至于枚举和记录,也可以进行相应的小优化。以任选五张牌为例,我们假设对拿到的13张手牌按他们的位置下标进行编码,即0-12。再预先处理出二进制表示下1的个数为5的数(如31)的集合,我们只需枚举这个集合中的数,若当前数的第i位为1(二进制表示下),则表示选了第i张牌,显然这个集合里所有的数分别表示一种选5张牌的方案,从而实现了选牌方案映射到整型数的哈希。对处理任选三张牌也同理。 * 接下来就是通过我们预先记录的信息,枚举3,5,5的所有组合,过程中控制方案的合法性即可,选出认为价值最大的那种方案。 * 第一步的复杂度大概是O(2^13)的预处理+O(C(13,5)\*C(13,3))的枚举组合 * 对于第二步,就各自发挥想象力了,不多说。 * 综上,这种方法的时间复杂度是相当优秀的,但是效果如何就取决于第二步了。

大致算法流程如下


关键代码解释


上述代码即预处理各种选3张、选5张方案下的最大牌型等级

上述代码通过一些简单的位运算来保证选牌方案的组合的合法性,同时也要保证三墩牌型等级的单调性,然后累加评估价值,尝试更新当前最优方案即可。


性能分析及改进

展示性能分析图和程序中消耗最大的函数



由上可知,用于初始化的构造函数和判断牌型的函数开销最大。

算法的改进

考虑到该算法本身的时间复杂度较优秀,时间开销较小,再深入考虑效率优化,意义不大。 因此着重考虑算法的效果如何。通过百来盘的实战发现,该算法一开始的评估价值的方式过于粗糙,在相当一部分局面下,因小失大,没有顾及全局的最优。因此上网查阅资料,学习参考了前辈对于该游戏牌型的评估方法,重新细化了价值评估矩阵,从原来的两维抽象细分为三维矩阵,对于方案考虑其牌型、墩位、大小三个维度下的综合价值。 通过再次大量实战,发现效果果然明显改善。

单元测试

跑了几组YF大佬服务器返回的数据,感觉效果挺ok。




贴出Github的代码签入记录



遇到的代码模块异常或结对困难及解决方法

蔡峰:

  • 问题描述
      首先当然是关于新技术的学习了。在上次作业里学习了axure9的基本用法后,这次需要学的就是制作网页界面的一些基础知识了。其次就是学习方法和新知识的运用了,学习新技术的方法一直被我认为是一个难点。最后就是这次结对情况到后期有一些匆忙,这完全是我在沟通交流上的的问题。
  • 做过哪些尝试
      一开始先是去到了w3school这个平台去学习,后来发现我的智商和接收能力实在是太弱了,于是在学习了一段时间后,我在学习的中后期来到了B站开启我的网课之旅,那还是比较嗨的。其次在学习方法和运用上,我向在这方面技术精通的学长取经,他给了我很多方向和指导意见,再加上队友的鼓励,辗转于向大佬问答和各种debug中。最后就是这次合作起来的确是有些匆忙,主要还是因为我的沟通问题和自身的知识储备太差了,以致于我们在时间上来不及、分工情况也受到了打击。
  • 是否解决
      问题都基本解决了,主要问题都能得到队友的理解和支持,并且他是一个real man,所以虽然我们这次十分匆忙,但各方面还是朝着好的方向去发展的。
  • 有何收获
      收获太多了,害,首先学到了许多知识吧,但其实这些知识运用起来有点繁琐和浪费时间,所以我感觉这次作业实在是有点累,主要是一波身体状况给我搞得有点自闭了。可能是胖了许多,身体在这段时间状况频发,所以还是给我造成了许多困扰。但是这恰好也是我的收获,在发烧的时候做网页是真滴嗨的一段经历(希望以后再也不要有了)。当然收获了和队友的友谊,第一次和大佬合作,这种感觉不一般。

陈金杰:

  • 问题描述
    之前只学过一点点后端,没有做过前端开发,这次要写能和后端交互的UI,有点无从下手。国庆节基本都在忙着训练,平常也要兼顾算法题练习,因此自由时间其实很少。
  • 做过哪些尝试
    无奈只能两倍速看JS网课速成,然后一边查资料,一边写。
  • 是否解决
    拿生命学习,那可不得解决了嘛
  • 有何收获
    很多事看起来很难做,实际上,它的确做起来也的确会很痛苦。
    但一直做一直搞,好像也就成了。
    这里查一查,那里问一问,动手试一试,扣扣空间骂一骂**软工课,好像也就熬过去了。。。(?)

评价你的队友

  • 值得学习的地方
    蔡峰执行力很强,办事很有效率,说啥干啥。我个人是有拖延症的,碰到这样正面的队友,就不好意思滑水了嘿嘿。然后责任心很强,会一直关注搭档的情况,想的很周到,会尽可能提供帮助,为队伍做出贡献。
  • 需要改进的地方
    感觉客观上也没啥要改进的。硬要说的话,就是由于一些不可抗原因,比较迟才委托我写一下前端与后端交互的部分,我原先预期的工作量是写好算法并且完成本地算法与UI的衔接,忽然多了这么个我不熟悉的活,节奏有点乱。

学习进度条

第N周 新增代码(行) 累计代码(行) 本周学习耗时(小时) 累计学习耗时(小时) 重要成长
1 0 0 18.5 18.5 学会了原型设计工具Axure的基本使用方法,培养了一些审美(或许),学会了十三水的玩法
2 340 340 35 53.5 开始学习网页制作,并着手于算法设计
3 520 860 45 98.5 网页制作基本成型,开始交互工作;算法设计还差边角的修改
4 412 1272 40 138.5 基本完成ai和ui制作,工作收尾
posted @ 2019-10-15 22:34  __orange  阅读(327)  评论(4编辑  收藏  举报