2021秋软工实践第二次结对编程作业

这个作业属于哪个课程构建之法-2021秋-福州大学软件工程
这个作业要求在哪里2021秋软工实践第二次结对编程作业
个人学号031902137
结对成员学号031902136
结对小伙伴的作业博客链接队友博客地址
GitHub 仓库地址GitHub地址
视频演示链接视频演示链接

任务拆解


综述

本次的任务是完成对第一次结对作业的原型的开发。由于时间较短,由于相关技能都是速成的,有可能会难以实现联机功能的学习和实现,而在原型设计之中,比较丰富的功能都在联机的模块下展现。
经过讨论,我们决定先完成基本功能的实现,将一部分的功能移植到单机模式之中,最后有能力再考虑联机,尽量保证游戏的完整性。最终我们选择了移植礼物功能在单机模式中。其余诸如成就系统和聊天功能在远程联系的背景下才更加被需要的。

实现过程


代码组织方式

重点代码:骰子点数的产生及结果判定

代码说明

  • 界面的切换
    将一个界面的所有元素写在一个标签中并设置一个类名,这样就可以通过设置标签的显示方式把整个页面一起隐藏起来或显示出来,以达到切换界面的效果。

界面元素类的设置(其中之一,类名为“mainPage”):

<div class="mainPage" >
    <img src="resources/主界面背景.png" />
    <p>中秋博饼 </p>
    <div class="btn">
        <button id="start">开始游戏</button>
        <button id="rule">游戏规则</button>
        <button id="present">设置礼物</button>
    </div>
</div>

点击按钮执行当前界面的隐藏和待切换界面的显示(其中之一,点击“开始游戏”按钮隐藏主界面,显示设置人数界面):

    let start=document.getElementById("start");
    start.onclick=function () {    //点击开始游戏进入人数设置界面
        let mainPage=document.getElementsByClassName("mainPage");    //按类名获取主界面标签
            mainPage[0].style.display="none";    //将主界面显示方式设置为隐藏
        let setNumPage=document.getElementsByClassName("setNumPage");
            setNumPage[0].style.display="block";    //将设置人数界面显示方式设置为显示
    };
  • 骰子结果产生及判定
    用random函数来模拟骰子点数的随机出现,然后根据中奖点数的规律,采用计算特殊点数的出现次数来判定游戏结果:
        var dices=["../source/1.png","../source/2.png","../source/3.png","../source/4.png","../source/5.png","../source/6.png"];    /*骰子贴图路径*/
        var tips=["状元插金花!","六杯红!","六杯黑!","五王!","五子带一秀!","五子登科!","状元!","对堂!","三红!","四进!","二举!","一秀!","yee~啥也没中"];    /*获奖名称*/
        var dicesResult=[];    /*骰子结果*/
        let dicesResultSort=[0,0,0,0,0,0,0];    /*骰子每个点数出现的次数*/

        for(var j=0;j<6;j++){
            dicesResult[j]=(Math.ceil(Math.random()*6));    /*6个骰子随机产生点数*/
            document.getElementById(("d0"+(j+1))).src=dices[dicesResult[j]-1];    /*贴图*/
        }
        for(let j =0;j<6;++j){
            dicesResultSort[dicesResult[j]]++;    /*记录每个点数出现的次数*/
        }
        var grade;    /*获奖等级*/
        if(dicesResultSort[4]===4&&dicesResultSort[1]===2)    /*依据每个点数出现的个数判定获奖等级*/
            grade =0;
        else if(dicesResultSort[4]===6)
            grade =1;
        else if(dicesResultSort[6]===6)
            grade =2;
        else if(dicesResultSort[4]===5)
            grade =3;
        else if(dicesResultSort[3]===5&&dicesResultSort[4]===1)
            grade =4;
        else if(dicesResultSort[3]===5)
            grade =5;
        else if(dicesResultSort[4]===4)
            grade =6;
        else if(dicesResultSort[1]===1&&dicesResultSort[2]===1&&dicesResultSort[3]===1&&dicesResultSort[4]===1&&dicesResultSort[5]===1&&dicesResultSort[6]===1)
            grade =7;
        else if(dicesResultSort[4]===3)
            grade =8;
        else if(dicesResultSort[2]===4)
            grade =9;
        else if(dicesResultSort[4]===2)
            grade =10;
        else if(dicesResultSort[4]===1)
            grade =11;
        else grade =12;
        let showResult=document.getElementById("showResult");
        showResult.innerHTML=tips[grade];    /*在界面上显示中奖的名称*/

重点、难点功能及编程思考


  1. 如何自动判定奖品数量设置是否在 0-99 间。
           HTML 的文本框输入之后默认是 String 类型,不能直接比较大小,而且如果用户输入汉字或字符作为奖品数量就不能强制转换为数值类型然后作为计数使用。因此要判断用户输入的字符串是否是纯数字,又鉴于JavaScript 的强制类型转换在遇到非数值时会直接无视,仅提取出数字,所以直接强制转换的方法也不能判断出输入是否为纯数字。最后想到使用正则表达式比较,难点就转到如何用正则表达式表示0-99的数字上来。
  2. 骰子随机出点数和的判定,是游戏的主要内容和重点。
            骰子的过程及结果的出现是博饼游戏的基础、本质,应要求考虑到随机性。我们用 random 函数来模拟骰子点数的随机出现,然后根据中奖点数的规律,采用计算特殊点数的出现次数来判定游戏结果。
  3. JavaScript 的变量类型问题。
           JavaScript 语言的变量类型不能直接看到,又因为初学不太熟,把以为是 Number 类型但实际是String类型的变量直接用来计数并且比大小,编译器也不会报错,导致网页卡住不运行,但也不知道错误在哪,只能在可疑的代码行下加一个 alert 弹窗然后运行查看是否有弹窗来判断代码卡在哪了,最后在查看到循环体下变量的类型时,发现本该是 Number 类型的变量实际上是 String 类型,循环被 String 类型的数值运算比较大小卡住了,类型转换之后就解决了。

单元测试


截图

请添加图片描述

描述

对于没有分支结构的简单的代码,在运行网页游戏的时候就可以得到验证。本次运用QUnit主要对有多种输入情况,多条分支的代码进行了测试。图片展示的是测试结果——所有的代码都通过测试。由于篇幅限制,具体测试代码已经上传GitHub,本文只展开展示了一个测试的运行结果。

大收获事件


  1. 功能何去何从
           由于本次作业需要将我们速成的语言第一次投入实战,在其过程中不可避免地会遇到很多意想不到的情况和接踵而至的挑战。在看到作业的 DDL 后,我们有完成不了联机的担忧。于是权衡之下一致决定首先实现单机部分的功能,并将部分联机实现的功能移植到单机部分。使得单机部分不会因为只有实现博饼这一个主要功能而太过单薄。有三个功能可供迁移:聊天,成就,兑换礼物。聊天首先被排除:单机的背景下参与者面对面,不需要聊天功能。
    接下来,我们对留下成就系统还是礼物功能展开了battle(当天大概就是这么个情形):

    留下成就!:延展游戏在时间上的跨度,让游戏不仅仅只在单次进行时内部开展,多次打开游戏之间有联系。
    留下礼物!:但是单机模式下,所有的玩家共用一台设备,不存在成就属于个人的情况,和成就系统的初衷相违背。
    留下成就!:能记录每一次进行的结果。可是如果每次打开游戏都有上一次的痕迹的话,更容易留住玩家。
    留下礼物!:但是单机游戏的每次参与者并非同一拨人,对在游戏中产生的所有成就做记录,相当于对本台设备的游戏经历做记录,可能达不到预期留住玩家的效果。有礼物系统的话,更贴合现实场景,而且博饼基本上都伴随奖品的兑换,应用场景广泛。
    留下成就!:礼物的兑换同样不能针对单个玩家。
    留下礼物!:礼物兑换应该是站在提供礼物的组织者的角度进行的,也就是说,礼物系统是记录被兑换后仍旧剩余的礼物种类及数量。
    。。。

       最后,因为礼物系统的功能在单机模式下相较成就系统能有更好的发挥,成就系统支持者在 battle 中败下阵来。再一看表,才发现我们两个人用了超出预期的时间来讨论功能的保留。
       虽然好像花费了不少的时间,仅仅就一个游戏中的具体功能讨论,有一点浪费了(事实上一开始我们也觉得蛮可惜的)。但是后来慢慢发觉,在编码之前把改进后的框架完整的搭建出来,避免到具体实现阶段再去考虑,有可能会省去不必要的返工。而且在争论的过程中,双方都绞尽脑汁来举出自己支持的模块的优势以及实现的可行性,无意中也是帮助我们梳理了该模块功能,理清其背后的组织逻辑。未尝是一种对时间的浪费。
2. 界面切换
       起初,我们根据已经掌握的知识,认为可以将为每一个界面写一个 HTML 文件,通过 JavaScript 的操控实现点击界面上的按钮后能跳转到另一个网页的另一个界面,以此达到界面切换的效果。但是这种方法除了需要编写许多html文件,更大的问题是,网页间的跳转有可能会带来一小段的空白,直接切断了游戏的连贯性和流畅性,对游戏的体验打了折扣。(哪有一个游戏会不停跳转网页啊喂)
       为了确定简单的网络游戏是否需要编写多个 HTML 网页,我们在一些开源游戏的网站上搜索,发现这些小游戏运行期间是没有网页的切换的,这也让我们确定了方向——用一个网页实现整个游戏的运作。
       接下来一步如何实现作为成为了新的挑战。我们想到了两种方法:其一是通过覆盖的方式,让新出现的界面及其上元素直接覆盖旧界面的元素。虽然理论上可以实现,但是他会给不相邻界面之间的跳转增加难度。经过交流讨论,我们认为这会带来未来较大的工作量,于是,我们采用了第二种方法:让将没有显示的界面及其上元素隐藏。具体的实现过程种,我们结合在b站的一个视频中,学到可以将一个界面的所有元素写在一个标签中并设置一个类名,这样就可以通过设置标签的显示方式把整个页面一起隐藏起来或显示出来以达到切换界面的效果。
总结:其实用多个界面也能实现游戏的功能,只是不够丝滑。可是就是因为这个不合时宜的停顿,让我们十分纠结。 为了能够尽量让游戏的体验更好,我们“傻乎乎”地投入时间研究了许久,最终才找到了解决办法。
3. 界面布局
       首次接触CSS和HTML来进行页面设计,美滋滋打完代码一运行,漫天飞舞的元素猝不及防。根据已有的知识,每一个元素的分布都需要一次次尝试,不断微调测试才能达到令人满意的效果。复审中还发现一个问题——元素会随着页面的缩放变化。页面的过度放大或缩小导致元素分布的错乱,是我们很长一段时间的困扰,一直到4.0版本才得到部分的解决。开展了页面设计,才发现其实关于页面的设计还有挺多有待我们学习的。图像是很大一部分的信息来源。对于网页的小游戏而非专业的功能性软件来说,我们认为画面的美观与否很大程度上决定了小游戏的潜在用户是否点击进入。倘若没有用户进入,任何游戏的体验都将无法呈现,故而在页面的设计上,我们认为不可以松懈。
4. 内部命名问题
       这其中还有一项问题是微调中的拦路虎。首次接触前端编程的我们,在开始命名的时候,谨遵设定的命名规范,也能够很好地通过我们的命名来迅速定位相关的元素。但是作为新手,实在是低估了需要命名的元素的个数。对于同一元素在不同时间段不同状态下出现,由于其位置的改变,我们都得重新找一个名字赋给它,逐渐词穷 没有预料到这种情况的我们在后期才发现之前的命名方式不能够有足够的延展性。造成了后期起名困难,甚至用上了同义单词来作为同一元素的不同状态下的命名(除非分得清,不然真是雪上加霜,更艰难了!)不停的翻看和比对元素id,不知不觉消耗掉我们的时间,也提醒我们要吸取教训。要么今后学习更有效的控制方法,要么寻找更加有扩展性的命名方式。
5. git同步和冲突问题导致上传新版本不成功
       在个人编程的阶段有用到git来进行版本的控制,但是轮到真正结对完成时,却因为没有掌握git的精髓而折腾了许久。两人的合作会存在版本不一致的问题,还需要运用到分支进行统一控制。加上时常连不上GitHub,还有之前的仓库进不去的问题,我们临时转移了阵地,换了仓库,模拟了之前的提交(才会给人最后两天进展神速的错觉)学习了git多人合作的原理,才脱离了几种命令都试过去碰碰运气的糟糕方式。深刻反思。

总结本次作业


  • 再一次再一次深刻地体会到编码统一规范的重要性。虽然前期工作中我们已经制定了规范,但是众多需要命名的变量还是在超出我们的预期(详见上文)。给后期的编码过程带来了不小的难度所幸是结对编程,队友就在身边,及时的沟通和交流减少了这个困难带来的阻力。倘若团队编程,恐怕会带来更大的不便。
  • 我们分工学习,结对编程。由于时间的紧迫以及需要快速掌握的内容较多,我们采用分别各自有所侧重的快速学习语言并应用,边查资料边码,相互交流的过程中从对方那学会另外的语言。从而压缩学习时间,尽量给时间到编程功能的实现。
  • 时间的安排和管理。作为学校课程的其中之一,软件工程实践无疑稳稳地占据了我们很大一部分课余时间。在两个人其它科目都纷纷欠债的情况下,压力和熬夜接踵而至,就难以有一个积极团结的结对氛围,进度也会收到影响。在火速意识到这个问题之后,我们根据两个人目前的情况以及在课业,休息方面的要求,重新调整了时间上的安排。结对不能随心所欲,是互相体谅和帮助,注重沟通的技巧,准确表达自己的想法和需求。

结对编程工作经历


请添加图片描述

GitHub 仓库地址


GitHub地址

commit 记录

在这里插入图片描述在这里插入图片描述由于中间转移了一次阵地(详见上文),所以前几次commit记录是模拟出来的(我们两个人怎么可能两天做出来)
因为还是采取结对的方式,一个人坐主驾驶打代码,另一个坐副驾驶,每一次的记录都是在两个人共同的注视下提交的,基本上的进展就是页面的功能的实现和添加,对应1.0至4.0。

PSP表格


PSPPersonal Software Process Stages预估耗时(分钟)实际耗时(分钟)
Planning计划2015
.Estimate.估计这个任务需要多少时间2015
Development开发18702185
.Analysis.需求分析(包括学习新技术)500600
.Design Spec.生成设计文档6075
.Design Review.设计复审 (和同事审核设计文档)6050
.Coding Standard.代码规范 (为目前的开发制定合适的规范)3020
.Design.具体设计2060
.Coding.具体编码720840
.Code Review.代码复审300360
.Test.测试(自我测试,修改代码,提交修改)180180
Reporting报告275210
.Test Report.测试报告12080
.Size Measurement.计算工作量3530
.Postmortem & Process Improvement Plan.事后总结, 并提出过程改进计划120100
合计21652410

学习进度条


031902136:

第N周新增代码(行)累计代码(行)本周学习耗时(小时)累计学习耗时(小时)重要成长
6175017501010有针对性地重点学习JavaScript并运用

031902137:

第N周新增代码(行)累计代码(行)本周学习耗时(小时)累计学习耗时(小时)重要成长
6150015001010有针对性地重点学习CSS和HTML并运用
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值