• 结对编程作业


    结对成员

    • 031802501 蔡震泽 博文地址 GitHub地址

    • 031802531 王昱 博文地址 GitHub地址

      成员 分工
      蔡震泽 原型设计、AI
      王昱 原型设计实现、AI

      2.1-原型设计

      2.1.1-流程图

      2.1.1-原型图

      我们整体以水墨风格设计了图片华容道,其界面如下:

      1.开始界面

      在开始界面,玩家可以进行继续下一步游戏进行登入,或者注册,或者更改游戏设置,或者退出游戏

      2.登入界面及注册

      玩家输入账号密码即可登入游戏


      3.系统设置界面

      玩家可以对音乐,音效进行设置

      4.游戏菜单

      在此界面,玩家可以查看自己的排行榜和进入游戏

      5.游戏界面

      玩家在此进行游戏,有记录时间与步数

      6.暂停界面

      在对战界面时,可以选择暂停功能

      7.胜利

      如若玩家成功完成华容道,则会出现胜利界面,有着耗费的步数和时间

      8.排行榜

      玩家可在此查看排行前列的玩家

      2.1.2-开发工具

      Axure Rp 9、 photoshop

      2.1.3-结对图

      2.1.4-遇到的困难及解决方法

      问题一:

      困难描述:由于之前的作业都是编程作业,第一次接触原型模型设计的题目,一开始有点不知所措。

      解决尝试:通过百度,查阅资料,以及观看视频来通过对原型模型的了解,经过几天的摸索,对这方面也有了一点的了解。

      是否解决:

      问题二:

      困难描述:第一次使用Axure,对于很多功能都还不熟悉
      解决尝试:依然还是通过百度,上B站看教程来自学
      是否解决:暂时解决

      问题三:

      困难描述:原型设计需要有很多的图片素材
      解决尝试:查阅了大量的素材,才找到几张觉得还不错的素材,有时候甚至自己都想用PS弄素材,但无奈自己不会PS
      是否解决:

      收获:

      这次是结对作业,所以经过这一段时间的学习,和队友的合作更加紧密,关系更加密切,交流得更多。初次体会到了一个软件的设计过程,以及团队合作的重要性。

      2.2 - AI与原型设计实现

      2.2.1-代码实现思路

      网络接口的使用

      网络接口是使用python的requests模块实现的,requests在python内置模块的基础上进行了高度的封装,所以使用方法十分简单。

      GET请求

      import requests
      
      json_url = 'http://47.102.118.1:8089/api/teamdetail/48'
      
      req = requests.get(json_url)
      
      file_requests = req.json()
      

      POST请求

      import requests
      
      import json
      
      json_url = 'http://47.102.118.1:8089/api/challenge/start/321a5671-8bfa-4664-8986-fc7a413fa540'
      
      data = json.dumps({
      
        "teamid": 48,
      
        "token": "396e1989-984d-4777-98fa-1907fd2072bf"
      
      })
      
      r=requests.post(json_url, data=data, headers={'Content-Type': 'application/json'})
      
      file_requests = r.json()
      
      代码组织与内部实现设计(类图)

      说明算法的关键与关键实现部分流程图

      算法的关键是如何应对强制交换的问题,以及无解状态的处理。实现流程图如下:

      重要代码片段展示及解析

      由于BFS实现比较简单自己太菜,没有特别复杂的代码片段。这里我展示一下BFS里面比较核心的一段代码,就是move操作的实现

        def move(self,qi,blank,dire,level, path): 
        
        	 '''将空图blank进行移动,
        	 	qi是当前状态(用字符串存储),
        	 	blank是空图所在位置,
        	 	dire是移动方向,
        	 	level是当前步数
        	 	path是从原状态到当前状态的移动序列'''
      
      ​    add = 0
      ​    if dire == 'a':
      ​    	add = -1
      ​    elif dire == 'w':
      ​       add = -(self.n)
      ​    elif dire == 's':
      ​       add = self.n
      ​    elif dire == 'd':
      ​       add = 1
      ​ 	 x = blank + add	#x为blank经过移动后的位置
      	 #越界判断
      ​    if x<0 or x>=self.N or blank==x:	
      ​       return False
      ​    if abs(blank%self.n-x%self.n)>1:
      ​       return False
      	 #生成移动后的状态
      ​    if blank<x:
      ​       temp=qi[:blank]+qi[x]+qi[blank+1:x]+qi[blank]+qi[x+1:]
      ​    else:
      ​       temp=qi[:x]+qi[blank]+qi[x+1:blank]+qi[x]+qi[blank+1:]
      	 #该状态之前已经走到过,舍弃
      ​    if temp in self.dict:
      ​       return False
      	 #更新队列
      ​    self.dict[temp]=level+1
      ​    self.dict_path[temp] = path + dire
      ​    self.que_qi=[temp]+self.que_qi
      ​    self.que_bk=[x]+self.que_bk
      ​    self.que_lv=[level+1]+self.que_lv
      ​    self.que_path=['{0}{1}'.format(path, dire)]+self.que_path	#注意要记录下移动序列
      	 #如果已经完成,则结束寻路
      ​    if temp == self.fin_map:	
      ​       self.end = 1
      ​       self.ans = '{0}{1}'.format(path, dire)
      ​    return True
      
      性能分析与改进

      ​ 相比于A*和DFS,BFS能够保证最终答案是最优解,所以比较符合题目的要求。但是BFS的时间复杂度是比较高的,所以当完成拼图所需要的路径较大时,耗时也会急剧增加。BFS里面耗时占比最大的两个分别是判重和移动,这里判重是通过记录走过的状态再加上"in"操作实现的。移动操作已经通过将状态转换为字符串进行了优化,未来的改进可能会集中在判重这一块上。

      改进的思路

      ​ 在洛谷OJ上面看到了八数码难题这道题,有些大佬使用了双向BFS来解决,时间复杂度得到了极大的降低,但是实现的思路还没有完全理解,再加上由于强制调换带来的一些困难,暂时没有往这个方向上做改进。但是在判重的问题上却给了我很大的启示,如果能够将每个状态对应一个hash值,就能够直接将判重的时间复杂度将为O(1)。这里我参考了关于“康托展开”的相关知识,通过康托展开值映射到不同的状态上,而且无需占用很大的地址空间。

      性能分析图

      ​ 可以看到耗时最大的就是move函数了,之前也在前面分析了对应代码以及相应的改进方案。还有一个耗时占比较大的是将原始图片转换为对应矩阵,主要是图像的对比识别比较花时间,但这个用了别人的库,就没办法改进啦。

      2.2.2-代码签入记录

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

      问题一:

      困难描述:不知道如何传数据到api,传什么类型的数据,收到什么类型的数据
      解决尝试:通过网上查资料,问同学,一步步尝试,最终还是将接口连上了
      收获:学会了如何使用python的requests模块

      问题二:

      困难描述:异常是移动序列的顺序被打乱。本来是不知道顺序乱了,只是手工检查后发现移动序列不正确,在后面调试中把限制深度缩小到2,这才意识到是顺序乱了。
      解决尝试:经过检查发现是字符串拼接的时候出错,查阅资料后了解到,如果使用“+”运算来连接字符串可能会出现顺序错误,于是使用了格式化的方式来进行字符串拼接,解决了这一问题。
      收获:从这个错误中学习到了python的格式化输出方式,这在处理多个不同类型的数据输出时能起到很大的便利。

      问题三:

      困难描述:异常是出现在自由交换的时候,一旦需要用到自由调换时,答案一定都是错误的。我将实现自由交换的代码封装成一个函数,输入初始状态和目标状态,用两层循环遍历所有可能的交换,将有解的交换输出。但是我误以为在python中,列表作为函数参数是值传递的方式,实际上进行遍历的时候,列表已经发生了变化,而我却在函数返回交换序列后再次对列表进行了交换。
      解决尝试:至于我是怎么发现这个问题的嘛......可能人在疲倦的时候更容易灵光一现?由于前一天晚上改算法改到两点都没出结果,上课时昏昏欲睡的我脑子里还是一直装着这个问题,结果突然就想到了这个点......于是之后我又去详细了解了python关于函数的知识,看来基础还是不够牢固呀。
      收获:顺带学习了python的函数参数的各种用法

      2.2.4-评价你的队友

      值得学习的地方:

      震泽哥真的全能,Axure、PS、Java、Python全都会,原型设计直接带飞。

      需要改进的地方:

      感觉震泽哥可能细节上考虑得不太周全,设计算法时有些情况没有注意到,不过不是常说成大事者不拘小节嘛O(∩_∩)O。

      2.2.5-PSP表和学习进度条

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

    第N周 新增代码(行) 累计代码(行) 本周学习耗时(小时) 累计学习耗时(小时) 重要成长
    1 0 0 10 10 熟悉了pyame的基本开发框架,学习了如何以面向对象的思想组织游戏代码
    2 357 357 28 38 在实际操作中掌握了如何监听游戏事件的发生以及响应处理
    3 520 877 10 48 学习了使用python的PIL库进行图像处理
    4 395 1272 35 83 掌握了如何利用python的requests模块设计网络接口

  • 相关阅读:
    每日总结50
    每日总结49
    每日总结48
    每日总结47
    每日总结46
    每日总结45
    每日总结44
    每日总结42
    每日总结41
    每日总结39
  • 原文地址:https://www.cnblogs.com/my-orange/p/13812376.html
Copyright © 2020-2023  润新知