第二次结对编程作业

1、在文章开头给出结对同学的博客链接、本作业博客的链接、你所Fork的同名仓库的Github项目地址(2分)

2、给出具体分工(2分)

  • 陈碧芬:负责UI界面设计以及UI接口连接
  • 黄森敏:负责后端代码的编写以及单元测试环节
  • 朱丽辰:负责后端服务器接口链接以及代码的完善

3、给出PSP表格(2分)

UI部分

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 100 120
· Estimate · 估计这个任务需要多少时间 100 120
Development 开发 2700 3300
· Analysis · 需求分析 (包括学习新技术) 1200 1500
· Design Spec · 生成设计文档 120 120
· Design Review · 设计复审 60 60
· Coding Standard · 代码规范 (为目前的开发制定合适的规范) 180 180
· Design · 具体设计 180 180
· Coding · 具体编码 600 900
· Code Review · 代码复审 90 90
· Test · 测试(自我测试,修改代码,提交修改) 60 60
Reporting 报告 60 90
· Test Repor · 测试报告 0 0
· Size Measurement · 计算工作量 60 60
· Postmortem & Process Improvement Plan · 事后总结, 并提出过程改进计划 90 60
· 合计 2800 3420

AI部分

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 60 90
· Estimate · 估计这个任务需要多少时间 60 90
Development 开发 1020 1290
· Analysis · 需求分析 (包括学习新技术) 120 180
· Design Spec · 生成设计文档 60 30
· Design Review · 设计复审 30 60
· Coding Standard · 代码规范 (为目前的开发制定合适的规范) 30 30
· Design · 具体设计 240 360
· Coding · 具体编码 360 420
· Code Review · 代码复审 60 30
· Test · 测试(自我测试,修改代码,提交修改) 120 180
Reporting 报告 120 120
· Test Repor · 测试报告 30 30
· Size Measurement · 计算工作量 30 30
· Postmortem & Process Improvement Plan · 事后总结, 并提出过程改进计划 60 60
· 合计 1200 1500

4、解题思路描述与设计实现说明(15分)

  • 网络接口的使用(3分)
    登陆接口(UI部分)
    function my() {
        if(document.getElementById("username").value=="" || document.getElementById("password").value=="")
        {alert("账号和密码不能为空");return ;}
        else{
            var data = JSON.stringify({
                "username": document.getElementById("username").value,
                "password": document.getElementById("password").value
            });
            var xhr = new XMLHttpRequest();
            xhr.onreadystatechange=function(){
                if(xhr.readyState==4&&xhr.status==200){
                    var json=JSON.parse(xhr.responseText);
                    alert("登陆成功");
                    localStorage.removeItem("token");
                    localStorage.removeItem("user_id");
                    localStorage.setItem("token",json.data.token);
                    localStorage.setItem("user_id",json.data.user_id);
                    window.location.href='start(1).html';
                    console.log(xhr.responseText);
                }
            }
            xhr.open("POST", "https://api.shisanshui.rtxux.xyz/auth/login",true);
            xhr.setRequestHeader("content-type", "application/json");
            xhr.send(data);
        }
    }

注销登录接口(UI部分)

function my() {
        var xhr=new XMLHttpRequest();
        xhr.onreadystatechange=function () {
            if(xhr.readyState==4&&xhr.status==200){
                alert(xhr.responseText);
                window.location.href="index.html";
            }
        }
        xhr.open("POST", "https://api.shisanshui.rtxux.xyz/auth/logout");
        xhr.setRequestHeader("x-auth-token", localStorage.getItem("token"));
        xhr.send();
    }

历史详情接口(UI部分)

function my(){
        dec();
        var obj;
        var xhr = new XMLHttpRequest();
        var num=document.getElementById("number").value;
        xhr.onreadystatechange=function(){
            if(xhr.readyState==4){
                obj=JSON.parse(xhr.responseText);
                if(xhr.status==200){
                    function getJson(json){
                        var l=0;
                        for(var j in json.data.detail){
                            document.getElementById("demo").innerHTML+='<tr><td style="width: 13%">'+json.data.detail [l].player_id+'</td><td style="width: 17%;text-align: center">'+json.data.detail [l].name+'</td><td style="width: 10%">'+json.data.detail [l].score+'</td><td style="width: 60%">'+json.data.detail [l].card+'</td></tr>';
                            l++;
                        }
                    }
                    getJson(obj);
                }
                else if(obj.status==2004){alert("战局不存在或已结束");}
                else if(obj.status==3001){alert("战局不存在或未结束");}

            }

        }
        xhr.open("GET", "https://api.shisanshui.rtxux.xyz/history/"+num,true);
        xhr.setRequestHeader("x-auth-token", localStorage.getItem("token"));
        xhr.send();
    }

AI:api请求使用的是python里的request库
以下贴出net_api.py文件中的主要函数

import requests

import cards_division

url='https://api.shisanshui.rtxux.xyz'
cards_list = []
max_list = []
def sign_in(username,password):

def register(username,password):

def logout():

def new_game_and_play():

def get_rank():

def get_history_list(limit,page):

def get_history_details(game_id):

if __name__=='__main__':
  • 代码组织与内部实现设计(类图)(6分)

    我们使用的是纯贪心算法,先出后墩和中墩代码,之后再根据后中墩牌型的类型在避免倒水的情况下出头墩,在后中墩代码实现过程中尽量使牌面平衡,三墩牌面尽量都大

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

算法关键:

# 获取牌型桶
def getBucket(arr_card):

# 统计同数值花色的多少并统计同花色数值的多少
def CardVal(cards_):

# 判断同花顺 判断同花个数 在判断有无联顺much个
def CardsTHS(cards_, much):

# 后墩,中墩出牌函数
def judge5(_post, _pai, card):

# 进行头墩出牌函数
def judge3(_post1, _post2, _pai, card, ty1, ty2): 

# 将自己处理好的代码进行转换发送至服务端
def zhuanCards(chu, much):    

# 出牌主函数
def divide_cards(cards_list):

5、关键代码解释(3分)

  • 贴出你认为重要的/有价值的代码片段,并解释(3分)
    UI:
    UI接口部分的使用
            var xhr = new XMLHttpRequest();
            xhr.onreadystatechange=function(){
                if(xhr.readyState==4&&xhr.status==200){
                    var json=JSON.parse(xhr.responseText);
                    alert(xhr.responseText);
                    localStorage.removeItem("token");
                    localStorage.removeItem("user_id");
                    localStorage.setItem("token",json.data.token);
                    localStorage.setItem("user_id",json.data.user_id);
                    window.location.href='start(1).html';
                    console.log(xhr.responseText);
                }
            }
            xhr.open("POST", "https://api.shisanshui.rtxux.xyz/auth/login",true);
            xhr.setRequestHeader("content-type", "application/json");
            xhr.send(data);

AI:
这里贴出比较有特色的片段,为方便阅读先解释如下:
在这个片段前,我们先表达一下处理从服务器接收来的字符串我们是如何处理的:1.我们将字符串中的花色符号全部转换为数字1-4;2.将数值部分提取出来;3.计算公式:牌=值*4+花色。存储方面:建立二维数组,不同行代表花色(四行),不同列代表数值(13列)。
至于讲到普通出牌的判断,咳咳咳我们用的是鸵鸟算法。哈哈哈接下来po出一些片段:
idea:是将同种花色的牌数量存储在每一行的最后一位;将同大小数值的牌数存储在每一列的最后一位。

# 统计同数值花色的多少并统计同花色数值的多少

def CardVal(cards_):

    for i in range(2, 15):

        sum = 0

        for j in range(1, 5):

            if cards_[j][i] == 1:

                sum = sum + 1

        cards_[5][i] = sum

    for i in range(1, 5):

        sum = 0

        for j in range(2, 15):

            if cards_[i][j] == 1:

                sum = sum + 1

        cards_[i][15] = sum

    return cards_

这里po出判断同花顺的函数,
idea:much代表的是想要判断3同花还是5同花,直接判断每行最后一位是否足够much,若足够就往回推。

# 判断同花顺 判断同花个数 在判断有无联顺much个

def CardsTHS(cards_, much):

    for i in range(1, 5):

        if cards_[i][15] >= much:

            for j in range(14, much, -1):

                count = 0

                for k in range(much):

                    if cards_a[i][j - k] == 1:

                        count = count + 1

                if count == much:

                    return i, j

    return 0, 0

6、性能分析与改进(6分)

  • 描述你改进的思路(5分)
    我们通过修改算法来试图改进它的性能,举几个小板栗:
    一开始我们设想的存牌的方式特别简单粗暴,想说直接转换成一对一对的数值,在对它们的头尾做操作。在后来边打边想到新方法边激烈讨论的过程中,有一种方法被三木想了出来,就是做一个矩阵,因为扑克牌一种花色一个值只能找出一张牌,所以用1来代表有牌,0代表没有。
    在这个事件之后,我们又在存储花色桶和数值桶的时候,经过各种尝试,最后又修改成将需要的值存在矩阵中,减轻了不少负担。也提高了速度。
  • 展示性能分析图和程序中消耗最大的函数(1分)

    消耗最大的是input????input你怎么了,我只是为了单元测试...有没有人曾giao诉我,你怎么了有没有人曾在你input里哭泣啦啦啦

7、单元测试(5分)

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


这五个单元测试是在实现算法的时候,通过本地输入输出来测试我们代码的可行性,测试了判断五张牌的函数Judge5和Judge3,def CardsTHS上文有展示一部分。这样构造的思路是为了测试,五张中的炸弹、同花、葫芦等这种我们在编写函数的时候比较担心的点,以及还有三张中的同花,且通过测试来查看是否会产生倒水。

8、贴出Github的代码签入记录(1分)

  • 请合理记录commit信息

9、遇到的代码模块异常或结对困难及解决方法(8分)

  • 问题描述(2分)
    1.对出牌的技巧不够熟练,多种牌型不同组合虽然不保证每一墩都最大,但是尽可能让多的墩赢,这方面思路比较匮乏
    2.半路上车python,有些地方只是初步了解,对接口的使用等等完全没有接触过,一头雾水不知道如何去做
  • 做过哪些尝试(2分)
    1.刚开始考虑使用组合算法,利用C(13,5),C(8,5)对后墩中墩的牌进行遍历,得到一个评分表,最后统一计算全值,选出最优牌,奈何评分系统想不出合理的方案,故放弃,转用纯贪心算法。
    2.利用搜索引擎得到python中requests库的使用方法,使接口问题得到解决参考资料
  • 是否解决(2分)
    1.最后勉强完成了算法,算是写出来了
    2.感谢教程,问题解决
  • 有何收获(2分)
    1.同一种问题可能有多种解决的方法,有些方法更优但是不会使用,求真务实,学会放弃,只求顺利完成出牌
    2.搜索引擎妙啊,很多python不会使用的问题都可以靠它速成

10、评价你的队友(4分)

  • 值得学习的地方(2分)
    1.黄森敏:代码灌溉机,在作业过程中能把代码中一些不够好、或者比较繁琐的地方修改得更好。在思路方面总能有新的想法。
    2.朱丽辰:比较沉稳,在代码方面总是一步一步来,每个细节都能注意到。
  • 需要改进的地方(2分)
    1.黄森敏:有的函数循环的量或者判断语句会比较多,可以以后优化
    2.朱丽辰:写代码的速度稍微慢一些,但是写的代码错误率极少。

11、学习进度条(2分)

UI部分

第N周 新增代码(行) 累计代码(行) 本周学习耗时(小时) 累计学习耗时(小时) 重要成长
1 0 0 5 5 熟悉使用axure,并利用axure设计了产品原型
2 0 0 10 15 简单了解了html,css,和js
3 500 500 15 30 学习了html,css,js语言及其使用,开始做网页页面设计,做出了网页雏形
4 300 800 27 57 主要学习了接口的使用,以及规范代码,确定最后的布局

AI部分

第N周 新增代码(行) 累计代码(行) 本周学习耗时(小时) 累计学习耗时(小时) 重要成长
1 0 0 5 5 学了一点js,学习使用axure,尝试做了第一个原型模型
1 0 0 5 5 学习一些JavaScript知识
2 200 200 5 10 学习一些接口知识,理清楚出牌思路
3 400 600 10 25 实现出牌算法,并对一些问题进行修复,学到了很多python算法
posted @ 2019-10-15 21:34  一只胖柠檬  阅读(288)  评论(4编辑  收藏  举报