结对编程作业
我和队友的博客与Github链接
原型设计
我们本次设计采用了墨刀来设计
- 游戏开始界面
- 游戏运行界面
- 游戏random后的界面
- 成功完成游戏后的界面
原型设计时的困难及解决方法
在设计原型设计时我们比较苦恼的还是按钮的设计和布局吧,对于要做成什么风格的界面我们也是一时没法确定,后来经过讨论,一致同意了采用简约一些的界面,然后在界面下方还加入了random打乱功能和score计分功能,最后才有了最终版本的出现。
讨论图片
以下这张图片是我们两个人在教室奋战时候拍的
AI及原型设计实现
代码实现思路
- 网络接口
网络接口部分的解决方法是将题目给的json文件分析后分别将其中的信息保存到json_get.txt中,并将对应的图片的base64编码解码为pit.jpg图片
ef get_json():
swap=[]
response = urlopen("http://47.102.118.1:8089/api/problem?stuid=031802120").read().decode('utf-8')
data = json.loads(response)
photo = data["img"]
imag = base64.b64decode(photo)
fh = open("pit.jpg","wb")
fh.write(imag)
fh.close()
js = open("json_get.txt","w")
step = str(data["step"])
swap=data["swap"]
#print(swap)
js.write(step+"\n")
js.write("\n".join(str(i) for i in swap))
js.close()
-
算法流程
- 首先就是将获取到的图片base64解码,并切割成9块进行比对
- 将九宫格图片转化为矩阵
- 判断有无解,并进行AI处理
- 得出结论
-
代码组织与内部实现设计(类图)
-
AI部分代码(一部分)
def generate_child(cur_node, end_node, hash_set, open_table, dis_fn):
'''
生成子节点函数
:param cur_node: 当前节点
:param end_node: 最终状态节点
:param hash_set: 哈希表,用于判重
:param open_table: OPEN表
:param dis_fn: 距离函数
:return: None
'''
if cur_node == end_node:
heapq.heappush(open_table, end_node)
return
num = len(cur_node.state)
# print("num is {}".format(num))
for i in range(0, num):
for j in range(0, num):
if cur_node.state[i][j] != 9:
continue
for d in direction: # 四个偏移方向
x = i + d[0]
y = j + d[1]
if x < 0 or x >= num or y < 0 or y >= num: # 越界了
continue
# 记录扩展节点的个数
global SUM_NODE_NUM
SUM_NODE_NUM += 1
state = copy.deepcopy(cur_node.state) # 复制父节点的状态
state[i][j], state[x][y] = state[x][y], state[i][j] # 交换位置
# print("state[i][j] is {}".format(state[i][j]))
# print("state[x][y] is {}".format(state[x][y]))
h = hash(str(state)) # 哈希时要先转换成字符串
if h in hash_set: # 重复了
continue
hash_set.add(h) # 加入哈希表
gn = cur_node.gn + 1 # 已经走的距离函数
hn = dis_fn(cur_node, end_node) # 启发的距离函数
node = State(gn, hn, state, h, cur_node) # 新建节点
cur_node.child.append(node) # 加入到孩子队列
heapq.heappush(open_table, node) # 加入到堆中
def print_path(node):
'''
输出路径
:param node: 最终的节点
:return: None
'''
num = node.gn
def show_block(block):
for b in block:
print(b)
'''
try:
print(b.index(9))
except ValueError:
pass
'''
stack = [] # 模拟栈
while node.par is not None:
stack.append(node.state)
node = node.par
stack.append(node.state)
count=0
old_line = 0
old_row = 0
while len(stack) != 0:
t = stack.pop()
show_block(t)
print(t)
new_line = 0
new_row = 0
flag = 0
for i in t:
for j in i:
if j == 9:
flag = 1
break
else:
new_row += 1
if flag == 0:
new_row = 0
new_line += 1
else:
break
if count != 0:
if new_line - old_line == -1:
answer.append('w')
if new_line - old_line == 1:
answer.append('s')
if new_row - old_row == -1:
answer.append('a')
if new_row - old_row == 1:
answer.append('d')
old_line = new_line
old_row = new_row
count += 1
# print("9的坐标为[{}][{}]".format(new_line,new_row))
return num
- 游戏部分代码(一部分)
# 初始化
pygame.init()
mainClock = pygame.time.Clock()
# 加载图片
gameImage = pygame.image.load(r'./e_2.jpg')
gameRect = gameImage.get_rect()
# 设置窗口
windowSurface = pygame.display.set_mode((1530, 785))
pygame.display.set_caption('拼图')
clock = pygame.time.Clock()
pygame.font.SysFont('arial',32)
cellWidth = int(gameRect.width / VHNUMS)
cellHeight = int(gameRect.height / VHNUMS)
game_intro()
game_loop()
pygame.quit()
quit()
- 性能分析
- 测试
我们测试时利用了接口的图片来进行测试,测试代码如下:(部分)
if __name__ == '__main__':
NUMBER = 3
win, temp = pictureCompare("./letter1") # 与分割好的图片进行对比,得到目标矩阵和当前状态矩阵
GOAL =[ [win[0], win[1], win[2]], [win[3], win[4], win[5]],[ win[6], win[7], win[8]] ] # 得到目标矩阵
OPEN = []
BLOCK = [[temp[0], temp[1], temp[2]], [temp[3], temp[4], temp[5]],[ temp[6], temp[7], temp[8]]] # 原始状态
SUM_NODE_NUM = 0
start_t = datetime.datetime.now()
length = A_start(BLOCK, GOAL, manhattan_dis, generate_child, time_limit=10)
end_t = datetime.datetime.now()
if length != -1:
print("length =", length)
print("time = ", (end_t - start_t).total_seconds(), "s")
print("Nodes =", SUM_NODE_NUM)
print("answer is :",answer)
跑出来的测试结果
代码签入记录
困难及解决方法
- 因为是第一次和别人组队一起开发,在最开始的时候我们各自的文件的读取路径都是各写各的,后来才汇总时出现了路径问题,然后双方都采用了绝对路径后就解决了这一问题,也算是让我了解到代码规范性的重要性吧,包括注释之类的东西,没有写的话别人真的很难看懂自己的代码。
- 在最开始的时候就遇到了问题,包括怎么从接口里面读取信息(因为确实没有做过),后面查百度才明白实现途径和爬虫差不多,就解决了问题
- 后面在如何确认获取的图片是什么字母这一问题卡住,经过讨论,最后打算将图片分割成9块,每一块和我们的图片库进行比对,有两张及以上一样的图片碎片的话就可以确认图片的字母了,然后就可以进行后面的一系列操作
评价队友
我的队友非常优秀,其实一开始我对于代码规范性不大讲究,而且也不知道该怎么下手,后面也是在他的帮助下一步步完善了自己的代码,同时我队友的性格也和我十分合得来,总而言之,这是一次十分满意的合作
PSP和学习进度条
第N周 | 新增代码(行) | 累计代码(行) | 本周学习耗时(小时) | 累计学习耗时(小时) | 重要成长 |
---|---|---|---|---|---|
1 | 300 | 300 | 20 | 20 | 学习了A*算法,并加以应用 |
2 | 200 | 500 | 24 | 44 | 通过完成游戏部分,对pygame及原型设计有了了解 |