zoukankan      html  css  js  c++  java
  • 结对编程作业

    https://github.com/CNllb/pig_end

    学号 姓名 分工 博客链接
    031902610 刘凌斌 前端界面,模型设计,游戏逻辑 结对编程作业
    131901121 肖清江 AI算法 结对编程作业

    一、原型设计

    (1.1)原型作品链接为:https://app.mockplus.cn/s/WSoYi3myuw7c

    (1.2)原型开发工具:在本次结队编程作业中,我们小组采用了操作起来较为简单的Mockup工具对原型进行设计。

    (1.3)原型简单说明:

    (1)缺点和不足:

    ① 本次原型设计是由两位直男协同完成的,在审美方面或许还有较大的欠缺,希望大家批评指正。

    ② 作品链接中的原型作品的原型组件未进行及时更新,较为简陋,下文博客提供实现前后对比。

    (2)主要页面原型和实际效果对比:、

    原型和小程序实现的机型:iPhone X(812*375)

    主要效果的区别产生在原型设计未导入相关字体库和相关图标,实际界面与原型在实现上存在计算误差。

    登录页

    ① 原型:

    this is image

    ② 实际效果:

    this is image

    首页:

    ① 原型:

    image

    ② 实际效果:

    image

    对战界面:

    ① 原型:

    this is image

    ② 实际效果:

    this is image

    (1.4)遇到的困难和解决方法:

    困难:本次制作原型是我们小组第一次使用原型制作工具,在这过程中最难熬的就是想出一个好的idea,并做好颜色搭配。这对于两个理工男来说并不友好。我们也想过直接使用暴发户气息爆棚的传统斗地主风格,或者直接竖屏实现按钮点击,带出汽配城风格,但还是想着,既然要自己从0开始做一个小程序,那么不管结果如何,总要尽自己的可能,尽可能实现效果好一些。

    解决方法:多次讨论之后,我们决定背道而行,将棋牌游戏打出养生的感觉,所以,在图片方面,选择了色调较为柔和的水墨山水画,再结合莫兰迪色系,调出了属于我们小组的软件设计风格。

    收获:在原型开发的过程中,我们成员之间可以天马行空,可以一次次地进行犯错,颜色搭配有问题就马上更改颜色,再进行分析,这是软件开发中极为有趣的一部分,我们也开始能够理解UI小姐姐没有灵感时候的痛楚。在这过程中,我们又掌握了一个对软件开发非常有帮助的开发工具。

    二、原型设计实现

    简易思维导图:

    this is image

    (2.1)代码实现思路:

    (1)网络接口的使用

    • 登录接口的使用

      • 在实现过程中,使用input进行账号和密码的输入,点击登录实现网络通信,成功获取用户信息

      • 登录函数设置了常规输入检测,保证用户名和密码内容不为空,并对登录返回的status进行了判断。

      login: function (e) {
              var that = this;
              let formData = e.detail.value;
              this.setData({
                  student_id:formData.student_id,
                  password:formData.password
              })
              console.log(formData);
              if (that.data.student_id == ""||that.data.password == "") {
                wx.showModal({
                  title: "错误",
                  content: "用户名或密码不能为空"
                });
                that.isname = false;
                that.ispass = false;
              } else {
                that.isname = true;
                that.ispass = true;
              }
              if (that.ispass && that.isname){
                  wx.request({
                      url: 'http://172.17.173.97:8080/api/user/login',
                      header:{
                          "Content-Type":"application/x-www-form-urlencoded"
                      },
                      data: formData,
                      method: "POST",
                      success: function (res) {
                          console.log(res.data);
                          if (res.data.status == 200) {
                              that.setData({
                                  id_token: res.data.data.token,
                                  response: res
                              }),
                              wx.setStorageSync('id_token', that.data.id_token),
                              wx.navigateTo({
                                  url: '../../pages/home/home',
                              })
                          }else{
                              wx.showModal({
                                  title: "错误",
                                  content: "密码或账号错误"
                                });
                          }
                          
                      },
                      fail: function (res) {
                          console.log(res.data);
                          console.log('is failed');
                          console.log('获取信息失败');
                      }
                  })
              }
          }
      
    • 获取房间信息的实现

    getHome:function (params) {
        var that = this;
        wx.request({
          url: 'http://172.17.173.97:9000/api/game/index',
          method: "get",
          data:{
            page_size:that.data.page_size,
            page_num:that.data.page_num,
          },
          header:{
            "Authorization": wx.getStorageSync('id_token'),
          },
          success: function (res) {
            console.log(res);
            that.setData({
              home_detail:res.data.data.games,
              isOpenHome:false,
              total_home:res.data.data.total,
              total_pages_num:res.data.data.total_page_num
            })
            console.log(that.data.home_detail);
            console.log(that.data.total_pages_num);
          },
          fail:function(err){
            console.log(err)
          }
        })
      }
    
    • 加入房间接口实现
    joinHome: function (e) {
        var that = this;
        console.log(e.currentTarget.dataset.uuid);
        wx.request({
          url: 'http://172.17.173.97:9000/api/game/'+this.data.uuid,
          method: "POST",
          header:{
            "Authorization": wx.getStorageSync('id_token'),
            "content-type":'application/json'
          },
          data:{
            uuid:e.currentTarget.dataset.uuid
          },
          success: function (res) {
            that.setData({
              Gaming:true
            })
          },
          fail:function(err){
            console.log(err)
          }
        })
      },
    
    • 创建房间的接口实现
    createHome: function () {
          var that = this;
          wx.request({
            url: 'http://172.17.173.97:9000/api/game',
            method: "POST",
            data:{
              "private":that.data.private
            },
            header:{
              "Authorization": wx.getStorageSync('id_token'),
            },
            success: function (res) {
              that.setData({
                uuid: res.data.uuid
              })
              console.log(res);
              console.log(that.data.uuid);
            },
            fail:function(err){
              console.log(err)
            }
          })
      },
    

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

    this is image

    (3)贴出你认为重要的/有价值的代码片段,并解释

    ​ 人机对战之中,AI的实现感觉比较有意思,我们小组是采用设置延时进行实现。在实现的时候,经过2000ms之后,自动实现AI的步骤,模拟较为有效

    setTimeout(() => {
          // 延迟后操作
          that.selectWay()
        }, 2000)
    

    (4)描述你改进的思路

    • 在本来的代码中,对战过程只使用一个界面进行展现,但是在传参过程中,多次造成传参错误,或者逻辑混乱的问题。
    • 在这样的前提下,我们决定了重构代码,一个界面实现两次刷新,这样每个数据都能够单独处理,大大降低了发生逻辑错误的概率。

    (5)展示出项目部分单元测试代码,并说明测试的函数,构造测试数据的思路。

    • 本次结队编程项目,我们小组采用的是微信小程序进行实现,出于微信小程序的局限性,并未进行小程序代码的单独单元测试。但对各个函数进行了单独封装,并进行多次单例测试。
    // 封装的抽牌函数
    POP_Get_pork_1: function () {
        var that = this;
        this.data.last_value = this.data.now_value;
        this.data.now_pork = this.data.get_pork_set.pop();
        this.data.now_value = this.data.now_pork.value;
        this.data.set_pork_set.push(this.data.now_pork)
        switch (Math.floor((this.data.now_pork.value - 1) / 13)) {
          case 0:
            this.setData({
              get_pork_black_peach_count: this.data.get_pork_black_peach_count - 1,
            })
            break;
          case 1:
            this.setData({
              get_pork_red_heart_count: this.data.get_pork_red_heart_count - 1,
            })
            break;
          case 2:
            this.setData({
              get_pork_black_flower_count: this.data.get_pork_black_flower_count - 1,
            })
            break;
          default:
            this.setData({
              get_pork_red_block_count: this.data.get_pork_red_block_count - 1
            })
            break;
        };
        that.check_card_1();
        that.check_winner();
        this.setData({
          now_pork: this.data.now_pork,
          now_index: (this.data.now_index + 1) % 2,
          set_pork_block: this.data.set_pork_set.length == 0 ? false : true,
          get_pork_block: this.data.get_pork_set.length == 0 ? false : true,
          player1_black_peach_count: this.data.player1_black_peach.length,
          player1_red_heart_count: this.data.player1_red_heart.length,
          player1_black_flower_count: this.data.player1_black_flower.length,
          player1_red_block_count: this.data.player1_red_block.length
        });
        that.set_top_card_1();
        if (this.data.get_pork_set.length == 0) {
          this.setData({
            get_pork_block: true
          })
        }
      },
    
    // 封装的检查牌堆函数
    check_card_1: function () {
        if (Math.floor((this.data.now_value - 1) / 13) == Math.floor((this.data.last_value - 1) / 13)) {
          while (this.data.set_pork_set.length != 0) {
            var pork_1 = this.data.set_pork_set.pop();
            console.log(pork_1);
            switch (Math.floor((pork_1.value - 1) / 13)) {
              case 0:
                this.data.player1_black_peach.push(pork_1);
                break;
              case 1:
                this.data.player1_red_heart.push(pork_1);
                break;
              case 2:
                this.data.player1_black_flower.push(pork_1);
                break;
              default:
                this.data.player1_red_block.push(pork_1);
                break;
            }
          }
          this.data.last_value = null;
          this.data.now_value = null;
        }
      },
    
    // 封装的设置牌顶的函数
    set_top_card_1: function () {
        this.setData({
          player1_top_black_peach: this.data.player1_black_peach.pop(),
          player1_top_red_heart: this.data.player1_red_heart.pop(),
          player1_top_black_flower: this.data.player1_black_flower.pop(),
          player1_top_red_block: this.data.player1_red_block.pop()
        })
        if (this.data.player1_top_black_peach != null) {
          this.data.player1_black_peach.push(this.data.player1_top_black_peach)
        }
        if (this.data.player1_top_red_heart != null) {
          this.data.player1_red_heart.push(this.data.player1_top_red_heart)
        }
        if (this.data.player1_top_black_flower != null) {
          this.data.player1_black_flower.push(this.data.player1_top_black_flower)
        }
        if (this.data.player1_top_red_block != null) {
          this.data.player1_red_block.push(this.data.player1_top_red_block)
        }
      },
    
    // 封装的检查对局胜利的函数
    check_winner: function () {
        if (this.data.get_pork_set.length == 0) {
          this.setData({
            Gaming: false
          })
          if (this.data.player1_black_peach_count + this.data.player1_red_heart_count + this.data.player1_black_flower_count + this.data.player1_red_block_count > this.data.player2_black_peach_count + this.data.player2_red_heart_count + this.data.player2_black_flower_count + this.data.player2_red_block_count) {
            this.setData({
              winner: this.data.player_2
            })
          } else {
            this.setData({
              winner: this.data.player_1
            })
          }
        }
      }
    

    (2.2)贴出Github的代码签入记录,合理记录commit信息。

    小组的很大的不足:小组成员欠缺日常对Github的使用习惯,没有养成及时push代码的习惯,我们的commit记录并不好

    this is image

    小组有设置todo的习惯,以下是我们小组的todo记录截图(使用的是“敬业签”APP):

    this is image

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

    (1)在代码模块异常方面,前期的网络通信采用Postman进行模拟网络通信,和实际实现校园网通信有很大的不同,微信小程序对局域网通信的不支持也是一个很大的问题。在刚接入校园网的时候,各种报错,是真的头大。

    解决办法:微信开发者工具强行不检查网络的证书和合法性,再接入校园网,成功获取信息。

    (2)结队困难:首先,这是和队友的第一次合作,在实现代码的过程中,没有那么的默契。其次,两个人对各自负责的领域,了解得都不够深刻,前端对微信开发者工具的相关合法性不够了解,后端对框架不够熟练,这就造成了到处碰壁。

    解决方法:通过制定todo进行计划,保证项目顺利地进行。

    (2.4)评价你的队友。

    • 值得学习的地方:

      我的队友是个认真负责的人,能够按照计划顺利完成自己的任务,并且很有发散性思维,能够举一反三。

    • 需要改进的地方:

      希望队友能够给代码加上调用接口的示例代码。

    (2.5)提供此次结对作业的PSP和学习进度条(每周追加)

    N周 新增代码(行) 累计代码(行) 本周学习耗时(小时) 累计学习耗时(小时) 重要成长
    1 0 0 12 12 前端:学习安卓开发和微信小游戏的开发;后端:考虑使用Java进行后端编程,对Java基础知识进行巩固
    2 1000 1000 12 24 前端:学了一周的游戏引擎和微信小游戏开发后,果断放弃,短时间把握不住,做了无用功,第2周,对原型进行设计,并实现微信小程序界面;后端:学习使用flask框架的python后端开发;
    3 2500 3500 8 32 前端:实现微信小程序打牌逻辑,制作简易的人机对战;后端:完成AI的百分80代码。
    4 1000 4500 10 42 前端:对代码进行封装,使得游戏的逻辑清晰明了,遗憾是,在线对战代码重构还未全部完成;后端:完成AI,并制作接口

    三、心得

    刘凌斌:

    作业难度:本次作业给我带来的最大的困难应该是在游戏逻辑的实现,犯了专业性的错误,对各个操作的代码并未实现有效的封装。造成了后期代码需要重构,浪费了很多的时间;其次是对时间的规划不够合理,前期想要实现很多附属功能,后面发现附属功能还未完成,主要功能来不及实现,只能草草的实现,效果很差,这是犯的很致命的错误。

    作业感想:即使本次作业完成的并不完善,但我们小组仍然会在后期将这个项目实现完全,也会开始学会习惯使用GitHub进行代码的pull和push,也借此提高自己的代码能力。

    启发:制定项目需求一定要合理,要与实力相互匹配,不能好高骛远,要一直学下去,我们不会的还有很多东西。

    肖清江:

    作业难度: 这次作业难度我个人感觉较大,因为之前没有开放一个可以联网的功能(在线对战),只做过命令行小游戏,并且也没有做过前后端分离的工作(之前甚至分不清前后端),所以这次的作业对我挑战还是相当大的。
    作业感想: 即使这次作业难度较大,但我还是尽量根据完成作业的需要去学相对应的内容。虽然起步的时候相当困难,但好在b站大学有各种各样的学习资料嘿嘿,终于还是学会了flask框架来实现后端,总而言之,完成这次作业还是相当有满足感的,尤其是看到自己的代码能给成功应用的时候!
    启发: 这次给我最大的启发就是,要勇于尝试新事物,之前一直害怕学来不及,但不管如何,尽力而为,最终一定能得到收获,相信自己,勇于尝试新事物!

  • 相关阅读:
    核函数基础一简单解释
    矩阵的基本性质 之 正规矩阵,矩阵的迹,行列式,伴随矩阵,矩阵的逆,对角矩阵,矩阵求导
    矩阵的基本性质 之 对称矩阵,Hermite矩阵,正交矩阵,酉矩阵
    矩阵的基本性质 之 矩阵加减法,数乘,乘法,转置
    机器学习实战基础(二十七):sklearn中的降维算法PCA和SVD(八)PCA对手写数字数据集的降维
    拉格朗日对偶性
    批处理符号2
    批处理符号1
    set命令
    goto命令
  • 原文地址:https://www.cnblogs.com/CNLLB/p/15456141.html
Copyright © 2011-2022 走看看