一、结对探索
1.1 队伍基本信息(1分)
结对编号:39;队伍名称:三星小白
学号 | 姓名 | 作业博客链接 | 具体分工 |
---|---|---|---|
032001305 | 兰鸿昊 | 博客链接 | 小程序设计、前后端编程实现、UI设计 |
032002620 | 廖诚杰 | 待填入 | 原型设计、算法设计 |
1.2 描述结对的过程
LCJ:大哥靠你带了
LHH:我也是菜狗
1.3 非摆拍的两人在讨论设计或结对编程过程的照片
二、原型设计
2.1 原型工具的选择
原型设计工具我们选择的是墨刀,主要原因是这款工具比起Axure容易上手(之前没什么经验)。
2.2 遇到的困难与解决办法
遇到的困难主要是动态组件的切换、不同页面间的交互还有背景的选择,前两者都在b站上找到了解决方法,背景
由大哥提供。
2.3 原型作品链接
2.4 原型界面图片展示
原型主要分为引导页、主页、规则页、游戏界面和退出界面
我们一共设计了三个模式以供选择(还有个pve模式由于时间问题未能实现)
如图为游戏界面
三、编程实现
3.1 网络接口的使用
此次微信小程序的编程实现,后端选择了python,利用了flask框架,作为轻量化的框架,flask入手可以十分快速的入手,对于之前没有学习过框架的我们来说,可以很轻松的将前后端交互起来。对于网络接口,这次我们通过flask来传送数据,没有在后端中存储游戏的数据,这样的做法对于联网中的网络编程有利有弊,优是后端的代码量较少,弊是同一时间只能接受两人来进行联网对战,属于是假性联网,但是也实现了在线双人匹配。
3.2 代码组织与内部实现设计(类图)
3.3 说明算法的关键与关键实现部分流程图
算法关键主要是遍历每一条线计算出能得分最多的那一条
3.4 贴出重要的/有价值的代码片段并解释
后端重要代码块
@app.route('/data_send',methods=['POST'])
def data_send():
global position, size, player_mark
position = str(json.loads(request.values.get("position")))
if operator.contains(position, "player1"):
player_mark = 1
elif operator.contains(position, "player2"):
player_mark = 2
print("接收到了玩家" + str(player_mark) + "的数据")
size = int(json.loads(request.values.get("size")))
print("位置为:" + position)
print("点数为:" + str(size))
string = "成功发送数据到服务端"
return json.dumps(string.encode('utf8').decode('utf8'))
作用:flask通过路由就可以接收前端的内容,data_send路由,是匹配成功后,用来接收双方发送来的数据,通过position记录是哪一个位置,size记录骰子大小,再通过另一路由data_get发送数据,就完成了数据交换。
前端重要代码块
match: function(){
var that = this
console.log('开始匹配')
wx.request({
url: 'http://47.113.179.4:5000/match',
method: "POST",
header: {
'content-type': 'application/x-www-form-urlencoded',
'chartset': 'utf-8'
},
success: function (res) {
console.log(res.data);
},
})
timer = setInterval(this.Confirm_number, 1000);
}
作用:match()的目的就是通过wx.request()函数来连接后端,告诉后端此时有玩家开始匹配,后端记录人数。
player1: function() {
var that = this;
wx.request({
url: 'http://47.113.179.4:5000/data_get_player1',
method: "POST",
header: {
'content-type': 'application/x-www-form-urlencoded',
'chartset': 'utf-8'
},
success: function (res) {
console.log(res.data);
var position = Object.values(res.data)[0]
var size = Object.values(res.data)[1]
if(size!=0){
that.setData({
position: position,
size: size,
})
if(that.data.player2_counts==9){
that.gameover()
}
that.setData({
player1_mark: 1,
})
}
}
作用:player1()即是玩家1接收玩家2数据的接口,通过不断的轮询来接收后端的positio和size数据,再通过判断position是哪一个位置,如何改变前端的数据。
3.5 性能分析与改进
3.6 单元测试
后端全部代码
每一个函数都是独立的,不进行单元测试
# coding=utf8
from flask import Flask, request
from flask import json
import operator
app = Flask(__name__)
player_counts = 0
player_mark = 0
position = ""
size = 0
@app.route('/')
def hello_world():
return "Hello"
@app.route('/match',methods=['POST'])
def match():
if request.method == 'POST':
print("一位玩家成功进入在线匹配")
global player_counts
player_counts = player_counts+1
if player_counts == 2:
string = "人数已达2人,成功匹配"
print(string)
return json.dumps(string.encode('utf8').decode('utf8'))
else:
string = f"人数已达{player_counts}人,继续等待"
print(string)
return json.dumps(string.encode('utf8').decode('utf8'))
else:
string = '一位玩家进入在线匹配失败'
print(string)
return json.dumps(string.encode('utf8').decode('utf8'))
@app.route('/match_counts',methods=['POST'])
def match_counts():
global player_counts
if request.method == 'POST':
if player_counts == 2:
string = "人数已达2人,成功匹配"
print(string)
return json.dumps(player_counts)
else:
string = f"人数已达{player_counts}人,继续等待"
print(string)
return json.dumps(player_counts)
else:
string = '一位玩家进入在线匹配失败'
print(string)
return json.dumps(player_counts)
@app.route('/data_send',methods=['POST'])
def data_send():
global position, size, player_mark
position = str(json.loads(request.values.get("position")))
if operator.contains(position, "player1"):
player_mark = 1
elif operator.contains(position, "player2"):
player_mark = 2
print("接收到了玩家" + str(player_mark) + "的数据")
size = int(json.loads(request.values.get("size")))
print("位置为:" + position)
print("点数为:" + str(size))
string = "成功发送数据到服务端"
return json.dumps(string.encode('utf8').decode('utf8'))
@app.route('/data_get_player1',methods=['POST'])
def data_get_player1():
global position, size, player_mark
if player_mark == 2:
key_value = {"position": position, "size": size}
player_mark = 0
return key_value
else:
key_value = {"position": "等待数据", "size": 0}
return key_value
@app.route('/data_get_player2',methods=['POST'])
def data_get_player2():
global position, size, player_mark
if player_mark == 1:
key_value = {"position": position, "size": size}
player_mark = 0
return key_value
else:
key_value = {"position": "等待数据", "size": 0}
return key_value
@app.route('/game_over',methods=['POST'])
def game_over():
global position, size, player_mark, player_counts
player_mark = 0
player_counts = 0
position = ""
size = 0
string = "游戏参数已重置"
print(string)
return json.dumps(string.encode('utf8').decode('utf8'))
if __name__ == '__main__':
app.run(host='10.133.52.191', port=5000)
3.7 贴出GitHub的代码签入记录,合理记录commit信息
利用了微信小程序开发工具的上传工具来进行签入。
四、总结反思
4.1 本次任务的PSP表格
PSP2.1 | 预估耗时 | 实际耗时 |
---|---|---|
计划 | 1h | 0.4h |
· 估计这个任务需要多少时间 | 1h | 0.4h |
开发 | 36.8h | 44.6h |
· 需求分析 (包括学习新技术) | 10h | 16h |
· 生成设计文档 | 1h | 1h |
· 设计复审 | 0.4h | 0.2h |
· 代码规范 (为目前的开发制定合适的规范) | 0.4h | 0.4h |
· 具体设计 | 1h | 2h |
· 具体编码 | 20h | 22h |
· 代码复审 | 1h | 1h |
· 测试(自我测试,修改代码,提交修改) | 2h | 2h |
报告 | 4h | 2h |
· 测试报告 | 1h | 1h |
· 计算工作量 | 1h | 0.6h |
· 事后总结, 并提出过程改进计划 | 2h | 0.4h |
· 合计 | 30.8h | 37h |
4.2 学习进度条(每周追加)
第N周 | 新增代码(行) | 累计代码(行) | 本周学习耗时(小时) | 累计学习耗时(小时) | 重要成长 |
---|---|---|---|---|---|
1 | 100 | 100 | 5 | 5 | 完成微信小程序页面初始化 |
2 | 1000 | 1100 | 15 | 20 | 学习了墨刀的使用,完成了本地双人对战模式 |
3 | 2400 | 3500 | 10 | 30 | 完成了原型设计、人机对战模式 |
4 | 2500 | 6000 | 10 | 40 | 完成联网对战前后端、小程序页面美化 |
4.3最初想象中的产品形态、原型设计作品、软件开发成果三者的差距如何?
我们此前都没有接触过甚至怎么听说过原型设计,当然我们想要将想象中的产品形态全部做到原型设计作品当中,但是真正实现原型设计时,就需要思考这个功能我们能不能完成,能不能在后续的软件开发中实现,所以在这个过程中阉割了许多内容,然而到了后续真正软件开发的时候,才能知道自己的技术栈够不够用,原型设计的功能怎么去实现,这是三者之间的关联和差距。
4.4 评价你的队友
兰鸿昊:
交流的很顺利,分工明确,在完成作品的过程中,没有急急忙忙,各司其职,在三周里合理的安排了时间,分配的任务也能顺利的完成。
廖诚杰:
大哥很厉害,肝了很久的代码(还熬夜到两三点),在微信上写好了小程序,平时问他一些问题也回复得很细心。然后就是他心态超好的,做联机部分的时候搞服务器搞了好久也没有摆烂(最后在大哥的努力下做出来了),懂的东西也很多,蛮让人羡慕的,总之就是大哥牛逼。
4.5 结对编程作业心得体会
兰鸿昊:
此前没有接触过小程序甚至是前端代码,简单学习了前端知识就开始写代码的难度还是很大的,在实现各种功能的过程中,遇到不会的需要我多查多问,有时候自己死磕并不能很好的解决问题,也第一次接触了前后端交互接口,初步了解了前后端是怎么来交互数据的,对于我也是一次很新奇很有收获的体验。
廖诚杰:
这次作业对我个人而言难度还是比较大的,所幸有大哥带我,帮助我解决很多问题,在完成项目和解决问题的过程中,我看见了和大哥明显的差距,也跟着大哥学了很多东西,比如原型设计工具墨刀、还有一些小程序开发方面的知识,尤其是跟着心态超好的大哥我感觉我的心态也比之前好了很多,很多方面都有不小的提升。最后就是,在这次作业里面我觉得我需要学的东西还是很多的(努力向大哥看齐)。