• 结对编程作业


    PART 1 链接以及分工

    一、链接

    二、分工

    队伍成员 姓名 负责部分
    组长 杨文龙 AI算法的实现,原型图的绘制
    组员 蔡沿江 可玩华容道的实现,优化游戏界面

    PART 2 原型设计

    一、设计过程

    • 本次原型设计采用了Axure Rp

    • 首先我们先从网上找到了一个数字华容道的代码,将其的数字改造成图片华容道,而该数字华容道的话,是固定每次将第九个格子变成空格,为了符合题目要求,应该设计成空白图片随机生成,所以我们设计了以下这个缺失了第三块图片的华容道,并将其打乱。

    • 接着我们认为如果只有游戏的话未免显得太过单调,于是我们就设计了一个游戏开始之前的开始页面,在这个页面中有三个按钮,一个是开始游戏,一个是显示历史成绩,一个是结束选择退出程序。

    • 点击开始游戏就可以进入到最开始我们设计的游戏界面,并关闭开始界面;点击历史成绩就会打开历史成绩页面,并关闭开始界面;点击退出按钮则会结束程序。

    • 在历史得分界面我们会将最近十五次的游戏成绩呈现,但并不按照步数的长短来进行排序,因为华容道的生成是随机的,那么完成的步数并没有对比的公平性。同时我们也添加了返回开始页面的按钮和再来一局的按钮,用来进行页面的跳转。
    • 最后考虑到游戏界面的美观问题,决定将开始界面的背景图片融入到游戏界面当中,并且稍微加大图片块之间的间隔。

    二、结队

    (1)结队过程

    • 两个人在上课时候一拍即合组队成功十分顺利没有意外

    (2)困难及解决方法

    • 刚开始并不会使用Axure Rp,然后及时去B站上学了一下才发现并不困难。之后就是感觉自己设计的原型图太过丑陋,希望图没事 就一直改图,而且背景图总感觉和开始界面格格不入,一直找好看的图片,后面去参考了一下网上的一写界面设计才有了一些思路,虽然设计出来的原型还是很丑陋,但至少能看一些了(这大概就是理工直男吧)。

    PART 3 AI与原型设计实现

    一、代码实现思路

    • 网络接口的使用
    
    #获取文本
    def gethtml(url):
        try:
    
            headers = {
                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3941.4 Safari/537.36'
            }
    
            r = requests.get(url, headers=headers)
            r.raise_for_status()
            r.encoding = r.apparent_encoding
            return r.text
        except:
            return ""
    #获取赛题列表
    def getchallengelist():
        url = "http://47.102.118.1:8089//api/challenge/list"
        # 每次请求的结果都不一样,动态变化
        datalist = json.loads(gethtml(url))
        for t in datalist:
            print(t)
    #获取具体赛题
    def getchallenge(uuid):
        url = "http://47.102.118.1:8089/api/challenge/start/" + uuid
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3941.4 Safari/537.36',
            'Content-Type': 'application/json'
        }
        data_json = json.dumps({
        "teamid": 21,
        "token": "a8aee99c-f29b-42c6-abd0-72216d8d851c"
        })
        r = requests.post(url, headers=headers, data=data_json)
        text = json.loads(r.text)
        chanceleftleft = text["chanceleft"]
        data = text["data"]
        img_base64 = data["img"]
        step = data["step"]
        swap = data["swap"]
        success = text["success"]
        img = base64.b64decode(img_base64)
        uuid = text["uuid"]
        expire = text["expire"]
        with open("photo.jpg", "wb") as fp:
            fp.write(img)  # 900*900
        return step, swap, uuid
    #提交答案
    def postAnswer(uuid,operations,swap):
            url ="http://47.102.118.1:8089/api/challenge/submit"
            headers = {
                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3941.4 Safari/537.36',
                'Content-Type': 'application/json'
            }
            data_json = json.dumps({
                "uuid": uuid,
                "teamid": 24,
                "token": "a8aee99c-f29b-42c6-abd0-72216d8d851c",
                "answer": {
                    "operations": operations,
                    "swap": swap}}
            )
            r=requests.post(url,headers = headers,data = data_json)
            print(r.text)
    

    --> getchallengelist():获取今日赛题后打印列表
    --> getchallenge(uuid):传入getchallengelist()中获取的的uuid获取具体的赛题数据和答题所用的uuid
    --> postAnswer(uuid,operations,swap):输入getchallenge(uuid)获取的uuid和答题数据来上传答案,返回排名等数据

    • 代码组织与内部实现设计(类图)
    • 说明算法的关键与关键实现部分流程图

    --> 算法关键是如何将原始图片转换成对应矩阵进行求解,这部分求解了大佬才知道该怎么做

    • 贴出你认为重要的/有价值的代码片段,并解释
    
    def cutimage():
        # 切割图片
        img = Image.open('photo.jpg')
        size = img.size
        # 准备将图片切割成9张小图片
        weight = int(size[0] // 3)
        height = int(size[1] // 3)
        # 切割后的小图的宽度和高度
    
        for j in range(3):
            for i in range(3):
                box = (weight * i, height * j, weight * (i + 1), height * (j + 1))
                region = img.crop(box)
                region.save('{}{}.jpg'.format(j, i))
    

    -->切割图片用的函数,调用了PIL库的crop函数,给定边界将图片切割成9块保存

    
    def compare(pic1,pic2):
        image1 = Image.open(pic1)
        image2 = Image.open(pic2)
    
        histogram1 = image1.histogram()
        histogram2 = image2.histogram()
    
        differ = math.sqrt(reduce(operator.add, list(map(lambda a,b: (a-b)**2,histogram1, histogram2)))/len(histogram1))
    
        if differ == 0:
            return True
        else:
            return False
    

    --> 对比两张图片是否相同的函数,调用PIL库中histogram函数比较,但是发现只能用同一切割函数切出来的块图片才能准确识别

    
    #获得图片所对应的图是哪一区域
    def getnum(path11):
        path = 'E://PyCharm 2020.2.1//python//确定序列//'
        for i in range(0, 36):
            path2 = path + str(i) + '_'
            for j in range(1, 10):
                path22 = path2 + str(j) + '.jpg'
                if compare(path11, path22):
                    return i
    
    def bulitlist(num):
        list1 = []
        for i in range(3):
            for j in range(3):
                path1 = 'E://PyCharm 2020.2.1//python//' + str(i) + str(j) + '.jpg'
                if compare(path1, 'E://PyCharm 2020.2.1//python//确定序列//white.jpg'):
                    list1.append(0)
                else:
                    for k in range(1, 10):
                        path2 = 'E://PyCharm 2020.2.1//python//确定序列//' + str(num) + '_' + str(k) + '.jpg'
                        if compare(path1, path2):
                            list1.append(k)
        sum = 0
        for i in list1:
            sum += i
        whitenum = 45-sum
        list2 = [[], [], []]
        list2[0] = list1[0:3]
        list2[1] = list1[3:6]
        list2[2] = list1[6:9]
        return list2,whitenum
    

    -->获取到初始矩阵的函数,getnum函数负责对比找到题目所给图片位于36张中对应的那一组,builitlist函数负责将9张切割过的图片和对应字母组的预先切割好的图片进行匹配,然后得到初始矩阵

    • 性能分析与改进

    --> 原本采用的A算法,效率太低就想着采用A*算法来改进了

    • 展示性能分析图和程序中消耗最大的函数
    • 展示出项目部分单元测试代码,并说明测试的函数,构造测试数据的思路
    
    #获取文本
    def gethtml(url):
        try:
    
            headers = {
                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3941.4 Safari/537.36'
            }
    
            r = requests.get(url, headers=headers)
            r.raise_for_status()
            r.encoding = r.apparent_encoding
            return r.text
        except:
            return ""
    #获取问题
    def getproblem():
        url = "http://47.102.118.1:8089/api/problem?stuid=031802435"
        # 每次请求的结果都不一样,动态变化
        text = json.loads(gethtml(url))
        # print(text.keys())#dict_keys(['img', 'step', 'swap', 'uuid'])
        # text["img"] = "none" #{'img': 'none', 'step': 0, 'swap': [7, 7], 'uuid': '3bc827e5008d460b893e5cb28769e6bf'}
        img_base64 = text["img"]
        step = text["step"]
        swap = text["swap"]
        uuid = text["uuid"]
        img = base64.b64decode(img_base64)
        # 获取接口的图片并写入本地
        with open("photo.jpg", "wb") as fp:
            fp.write(img)  # 900*900
        return step, swap, uuid
    #提交答案
    def postAnswer(uuid, opertions, swap):
        url = "http://47.102.118.1:8089/api/answer"
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3941.4 Safari/537.36',
            'Content-Type': 'application/json'
        }
        data_json = json.dumps({
            "uuid": uuid,
            "answer": {
                "operations": opertions,
                "swap": swap}
        })
        r = requests.post(url, headers=headers, data=data_json)
        print(r.text)
    

    --> 测试代码我采用的是结对编程要求的接口,经过测试没有问题

    二、贴出Github的代码签入记录,合理记录commit信息

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

    • 一开始对算法不了解,采用A算法经常跑不出结果,效率过低,然后换用A*算法。
    • 在测试前一天发现自己的代码有时对有时错,询问测试组大佬才知道自己理解错题,然后一顿倒腾才解决强制交换的问题。

    四、评价你的队友

    • 是个很勤奋的人,半夜发他的进度交流总是能及时反馈给我。学习能力很强(羡慕555),是个很稳的队友。

    五、PSP和学习进度条

    PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
    Planning 计划 540 600
    · Estimate · 估计这个任务需要多少时间 540 600
    Development 开发 950 1080
    · Analysis · 需求分析 (包括学习新技术) 500 500
    · Design Spec · 生成设计文档 30 40
    · Design Review · 设计复审 40 50
    · Coding Standard · 代码规范 (为目前的开发制定合适的规范) 20 30
    · Design · 具体设计 60 60
    · Coding · 具体编码 180 240
    · Code Review · 代码复审 30 40
    · Test · 测试(自我测试,修改代码,提交修改) 90 120
    Reporting 报告 130 130
    · Test Repor · 测试报告 60 60
    · Size Measurement · 计算工作量 30 30
    · Postmortem & Process Improvement Plan · 事后总结, 并提出过程改进计划 40 40
    · 合计 1620 1810
    第N周 新增代码(行) 累计代码(行) 本周学习耗时(小时) 累计学习耗时(小时) 重要成长
    1 0 0 0 0
    2 150 150 8 8 熟悉了python的pyqt5的基础使用方法
    3 100 250 10 18 通过对原型实现的过程,掌握了pyqt5页面设计和切换
    4 100 350 13 31 通过对原型实现的过程,掌握了pyqt5通过按钮来执行不同的任务
  • 相关阅读:
    PHP多进程模拟多客户端并发访问远程mysql数据库进行网络压力测试
    不安装证书如何通过模拟器+Fiddler抓包APP的HTTPS请求?
    Fiddler+模拟器+APP抓包HTTPS 为什么有时候抓不到?
    什么是宽表?什么是窄表?宽表和窄表的区别、优点、缺点以及各自的用处
    php-fpm的配置详解
    网站千万级访问量优化服务器负载方案
    理解正向代理&反向代理
    字符串数组中查找固定字符串
    paddingBottom和layout_marginBottom的区别
    android线性布局
  • 原文地址:https://www.cnblogs.com/cyj-12138/p/13811189.html
Copyright © 2020-2023  润新知