结对编程作业
结对成员
-
成员 分工 蔡震泽 原型设计、AI 王昱 原型设计实现、AI 原型设计
流程图
原型图
-
我们整体以水墨风格设计了图片华容道,其界面如下:
1.开始界面
在开始界面,玩家可以进行继续下一步游戏进行登入,或者注册,或者更改游戏设置,或者退出游戏
2.登入界面及注册
玩家输入账号密码即可登入游戏
3.系统设置界面
玩家可以对音乐,音效进行设置
4.游戏菜单
在此界面,玩家可以查看自己的排行榜和进入游戏
5.游戏界面
玩家在此进行游戏,有记录时间与步数
6.暂停界面
在对战界面时,可以选择暂停功能
7.胜利
如若玩家成功完成华容道,则会出现胜利界面,有着耗费的步数和时间
8.排行榜
玩家可在此查看排行前列的玩家
开发工具
Axure Rp 9、 photoshop
结对图
遇到的困难及解决方法
问题一
-
困难描述:由于之前的作业都是编程作业,第一次接触原型模型设计的题目,一开始有点不知所措。
-
解决尝试:通过百度,查阅资料,以及观看视频来通过对原型模型的了解,经过几天的摸索,对这方面也有了一点的了解。
-
是否解决:是
问题二
- 困难描述:第一次使用Axure,对于很多功能都还不熟悉
- 解决尝试:依然还是通过百度,上B站看教程来自学
- 是否解决:暂时解决
问题三
- 困难描述:原型设计需要有很多的图片素材
- 解决尝试:查阅了大量的素材,才找到几张觉得还不错的素材,有时候甚至自己都想用PS弄素材,但无奈自己不会PS
- 是否解决:是
收获
- 这次是结对作业,所以经过这一段时间的学习,和队友的合作更加紧密,关系更加密切,交流得更多。初次体会到了一个软件的设计过程,以及团队合作的重要性。
AI与原型设计实现
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函数了,之前也在前面分析了对应代码以及相应的改进方案。还有一个耗时占比较大的是将原始图片转换为对应矩阵,主要是图像的对比识别比较花时间,但这个用了别人的库,就没办法改进啦。
Github的代码签入记录
遇到的代码模块异常或结对困难及解决方法
问题一:
困难描述:不知道如何传数据到api,传什么类型的数据,收到什么类型的数据
解决尝试:通过网上查资料,问同学,一步步尝试,最终还是将接口连上了
是否解决:是
问题二:
困难描述:异常是移动序列的顺序被打乱。本来是不知道顺序乱了,只是手工检查后发现移动序列不正确,在后面调试中把限制深度缩小到2,这才意识到是顺序乱了。
解决尝试:经过检查发现是字符串拼接的时候出错,查阅资料后了解到,如果使用“+”运算来连接字符串可能会出现顺序错误,于是使用了格式化的方式来进行字符串拼接,解决了这一问题。从这个错误中学习到了python的格式化输出方式,这在处理多个不同类型的数据输出时能起到很大的便利。
是否解决:是
问题三:
困难描述:异常是出现在自由交换的时候,一旦需要用到自由调换时,答案一定都是错误的。我将实现自由交换的代码封装成一个函数,输入初始状态和目标状
态,用两层循环遍历所有可能的交换,将有解的交换输出。但是我误以为在python中,列表作为函数参数是值传递的方式,实际上进行遍历的时候,列表已经
发生了变化,而我却在函数返回交换序列后再次对列表进行了交换。
解决尝试:至于我是怎么发现这个问题的嘛......可能人在疲倦的时候更容易灵光一现?由于前一天晚上改算法改到两点都没出结果,上课时昏昏欲睡的我脑子里还是一直装着这个问题,结果突然就想到了这个点......于是之后我又去详细了解了python关于函数的知识,看来基础还是不够牢固呀。
是否解决:是
评价队友
评价人:蔡震泽
队友值得学习的地方:队友的腿非常粗,我抱得很舒服。队友代码能力非常强。坚持不懈,百折不饶。
队友需要改进的地方:做事情有点着急了,总是感觉这个来不及,那个来不及,心态需要平稳一点。
评价人:王昱
队友值得学习的地方:震泽哥真的全能,Axure、PS、Java、Python全都会,原型设计直接带飞。
队友需要改进的地方:感觉震泽哥可能细节上考虑得不太周全,设计算法时有些情况没有注意到,不过不是常说成大事者不拘小节嘛O(∩_∩)O。
学习进度条:
第N周 | 新增代码(行) | 累计代码(行) | 本周学习耗时(小时) | 累计学习耗时(小时) | 重要成长 |
---|---|---|---|---|---|
1 | 0 | 0 | 50 | 50 | 学会了使用Axure软件、ps软件,初步做出几个原型界面(简陋) |
2 | 357 | 357 | 65 | 115 | 完成所有原型设计,开始原型设计实现 |
3 | 520 | 877 | 80 | 195 | 初步实现AI算法 |
4 | 395 | 1272 | 100 | 295 | 完善AI算法,将接口完成 |
psp表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 60 | 60 |
Estimate | 估计这个任务需要多少时间 | 60 | 60 |
Development | 开发 | 300 | 350 |
Analysis | 需求分析 (包括学习新技术) | 1000 | 800 |
Design Spec | 生成设计文档 | 30 | 30 |
Design Review | 设计复审 | 20 | 20 |
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 60 | 50 |
Design | 具体设计 | 500 | 600 |
Coding | 具体编码 | 1000 | 1500 |
Code Review | 代码复审 | 30 | 60 |
Test | 测试(自我测试,修改代码,提交修改) | 60 | 60 |
Reporting | 报告 | 60 | 40 |
Test Repor | 测试报告 | 20 | 20 |
100Size Measurement | 计算工作量 | 10 | 10 |
Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 20 | 15 |
Total | 合计 | 3230 | 3665 |