2022软工K班结对编程任务

github
bilibili

一、结对探索

1.1 队伍基本信息

结对编号:40;队伍名称:知天易,逆天男

学号姓名作业博客链接具体分工
032002539张凯昕ui设计,前后端代码编写
032002542朱智浩ui设计,绘制原型图

1.2 描述结对的过程

A: 你组队了吗

B: 还没

A: 那咱俩一组

1.3 非摆拍的两人在讨论设计或结对编程过程的照片(2分)

二、原型设计(16分)

2.1 原型工具的选择(2分)

(在此处说明选择了什么原型设计工具?为什么选择这一款原型软件?)

2.2 遇到的困难与解决办法(3分)

(原型设计过程中的困难描述、解决尝试、是否解决、有何收获)

2.3 原型作品链接(5分)

(静态原型作品得2分,交互性强的原型作品得5分)

2.4 原型界面图片展示(6分)

(尽可能图文并茂地在此处介绍你们队伍设计的各功能模块,创新点也在此处展示说明)

三、编程实现

3.1 网络接口的使用

使用了ajax与websocket,websocket主要用于匹配对决的实现,通过websocket来不断发送地图信息以及对手的落子,

ajax用于除游戏外一些不经常发送的请求,例如登陆注册等。

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

  • 前端部分
    在这里插入图片描述请添加图片描述

  • 后端部分
    在这里插入图片描述

    • backend部分
      在这里插入图片描述在这里插入图片描述
    • matchingsystem部分
      在这里插入图片描述

3.3 说明算法的关键与关键实现部分流程图(2分)

在这里插入图片描述

  • 由于我不会机器学习,所以只能用普通的算法实现
  • 算法的实现主要是贪心,每次下子时遍历一遍,找出分差最有利的落子位置
  • 若有复数位置,先落于行空格最多位置,避免将所有位置堵死,使得原本可以消除对方的落子没
    得落子
  • 再判断点数与对方行空格最少的位置
    • 使点数较小的位置落于对方行空格最大的地方,被对方消除时损失较小
    • 使点数较大的位置落于对方行空格最小的地方,不容易被消除

3.4 贴出重要的/有价值的代码片段并解释(2分)

package com.example.matchingsystem.service.impl.utils;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.ReentrantLock;
@Component
public class MatchingPool extends Thread{
    private static List<Player> players = new ArrayList<>();
    private ReentrantLock lock = new ReentrantLock();

    private static RestTemplate restTemplate;
    private final static String startGameUrl = "http://localhost:3000/pk/start/game/";


    @Autowired
    public void setRestTemplate(RestTemplate restTemplate){
        MatchingPool.restTemplate = restTemplate;
    }
    public void addPlayer(Integer userId,Integer rating){
        lock.lock();
        try {
            for (Player player:players){
                if (player.getUserId().equals(userId)){
                    return;
                }
            }
            players.add(new Player(userId,rating,0));
        }finally {
            lock.unlock();
        }
    }
    public void removePlayer(Integer useId){
        lock.lock();
        try {
            List<Player> newPlayers = new ArrayList<>();
            for (Player player:players){
                if (!player.getUserId().equals(useId)){
                    newPlayers.add(player);
                }
            }
            players = newPlayers;
        }finally {
            lock.unlock();
        }
    }

    private void increaseWaitingTime(){//所有玩家等待时间加一
        for (Player player:players){
            player.setWaitingTime(player.getWaitingTime() + 1);
        }
    }
    private boolean checkMatched(Player a,Player b){
        int ratingDelta = Math.abs(a.getRating() - b.getRating());
        int waitingTime = Math.min(a.getWaitingTime(),b.getWaitingTime());
        return ratingDelta <= waitingTime *10;
    }
    private void sendResult(Player a,Player b ){
        MultiValueMap<String,String> data = new LinkedMultiValueMap<>();
        data.add("a_id", a.getUserId().toString());
        data.add("b_id",b.getUserId().toString());
        restTemplate.postForObject(startGameUrl,data,String.class);
    }
    private void matchPlayers(){
        System.out.println("match players: " + players.toString());
        boolean[] used = new boolean[players.size()];
        for (int i = 0; i < players.size(); i ++){
            if (used[i]) continue;
            for (int j = i + 1;j < players.size(); j++){
                if (used[j]) continue;
                Player a = players.get(i),b = players.get(j);
                if (checkMatched(a , b)){
                    used[i] = used[j] = true;
                    sendResult(a , b);
                    break;
                }
            }
        }
        List<Player> newPlayer = new ArrayList<>();
        for (int i = 0; i < players.size(); i ++){
            if (!used[i]){
                newPlayer.add(players.get(i));
            }
        }
        players = newPlayer;
    }
    @Override
    public void run() {
        while (true){
            try {
                Thread.sleep(1000);
                lock.lock();
                try {
                    increaseWaitingTime();
                    matchPlayers();
                }finally {
                    lock.unlock();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
                break;
            }
        }
    }
}

这部分代码是用于匹配池的实现
restTemplate用于于另一模块backend交互
addPlayer 当前端发送请求时,程序先遍历匹配池,发现没有该用户,再把用户加入匹配池中,
防止用户自己匹配到自己。
removePlayer当前端发送请求或者匹配到对象时,将玩家移除匹配池
increaseWaitingTime,checkMatched,matchPlayers分别用于当玩家等待时间增加时,checkMatched中允许的分差也会逐渐增大,当增大一定程度,两个对象就会匹配,并更新匹配池
sendResult是在当匹配成功时将匹配信息发送给backend
run则是在每秒扫描一次匹配池,执行程序
由于该程序是异步程序,所以需要lock函数对函数进行上锁。

3.5 性能分析与改进(2分)

请添加图片描述
在这里插入图片描述

占用资源最多的函数是tomcat,我的优化的思路是将一些可以在前端实现的功能直接在前端实现
减少前后端的交互。

3.6 单元测试(2分)

请添加图片描述
利用apipost测试接口,用sout以及assert进行单元测试

3.7 贴出GitHub的代码签入记录,合理记录commit信息(2分)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

四、总结反思

4.1 本次任务的PSP表格(2分)

PSP2.1Personal Software Process Stages预估耗时(分钟)实际耗时(分钟)
Planning计划55
· Estimate· 估计这个任务需要多少时间55
Development开发51135796
· Analysis· 需求分析 (包括学习新技术)27002800
· Design Spec· 生成设计文档1515
· Design Review· 设计复审53
· Coding Standard· 代码规范 (为目前的开发制定合适的规范)33
· Design· 具体设计3015
· Coding· 具体编码20002500
· Code Review· 代码复审6060
· Test· 测试(自我测试,修改代码,提交修改)300400
Reporting报告8550
· Test Report· 测试报告1515
· Size Measurement· 计算工作量105
· Postmortem & Process Improvement Plan· 事后总结, 并提出过程改进计划6030
· 合计52035851

4.2 学习进度条(每周追加)

N周新增代码(行)累计代码(行)本周学习耗时(小时)累计学习耗时(小时)重要成长
1004545学习通过springboot+vue编写前后端
21580java+1681vue+309js3262247通过实践编写项目了解了许多看教学学不到的知识
361java+610vue+18js4259148小试了用CSS编写动画,但效果不尽如人意

4.3 最初想象中的产品形态、原型设计作品、软件开发成果三者的差距如何?(2分)

(也就是谈一谈本次任务中**“理想与现实的差距”**,是哪些因素造成了这些差距?)

4.4 评价你的队友

  • 值得学习的地方:临危不惧,步步为营

  • 需要改进的地方:过于临危不惧

4.5 结对编程作业心得体会

  • 作业难度

    • 没做前:好难好难好难好难好难好难
    • 做的时候:好难好难好难好难好难好难好难好难好难好难好难好难
    • 做完后:就这?能不能再难点?
  • 完成感受

    • 心理:如释重负,身心愉悦
    • 身体:不堪重负,面色憔悴
    • 我终于不用天天背那笔记本去教室打代码了,太重了
  • 代码模块

    • 遇到问题,百度一下,百度不行,问问同学,同学不会,问问佛祖,然后Debug一整天,所幸最后还是顺利解决
  • 学习启发

    • 一开始的学习都是在模仿,知识其实并没有太多的吸收,真正吸收知识的时候,其实是模仿着模仿着,

      模仿出bug的时候,为了debug,必须将代码的逻辑捋清楚,才可以改好bug

    • 之后想学点动画,倒也不用特别深入,够用就行,看别人的作业的骰子会动,很是羡慕,我也想写。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值