137
社区成员
结对编号:20;队伍名称:饿鬼;
学号 | 姓名 | 作业博客链接 | 分工 |
---|---|---|---|
032002231 | 谢以盛 | https://github.com/Yummy-y/Kex-Bonesdice.git | 后端 |
032002235 | 杨明 | https://github.com/Yummy-y/Kex-Bonesdice.git | 前端 |
Yummy:搞?
Eson:搞!
选择的原型工具是墨刀,墨刀是一款打通产设研团队,实现原型,设计,流程,思维导图一体化的在线协同工具。它方便使用,利于协同开发,故选择其为原型工具。
解决尝试:通过文档和视频学习,逐步上手实现原型设计。通过各个软件和搜索引擎的搜索查找,找到美观且风格接近的设计素材。
是否解决:是。
收获:世上无难事,只怕有心人。
https://modao.cc/app/IrTCOyU9rjod98yMagrDLb
(共两页)
创新点:左上角三个小功能,打开bgm、切换主页背景、查看游戏规则(音效音乐功能展示还请移步github项目或bilibili视频查看)
创新点:
左上角增加三个小功能分别是打开bgm、切换背景和返回主页
轮到某一方的回合时,该玩家的头像呼吸灯闪烁。
九宫格两旁统计每行得分,并以大写中文展示。
点数重复以及消除对方点数会有字母特效(共五种)并伴有音效。
前端部分:
main.js文件:
//导入 axios 使我们可以发起axios请求
import axios from 'axios'
Vue.prototype.$axios = axios
axios.withCredentials = true
// 配置请求的跟路径 由后端提供 这样我们只要输入根路径后面的地址就OK (例如/login /home
axios.defaults.baseURL = 'http://127.0.0.1:5000'
调用接口页面文件Pve.vue(定义接口函数,发起post请求,通过this.getBChangeRow()即可调用):
//api
async getBChangeRow() {
const result = await this.$axios({
method: "post",
url: "/pve",
data: {
dataA: this.playerBData,
dataB: this.playerAData,
point: this.randb,
},
});
this.AIRow = res.data;
return res.data;
},
后端部分:
import re
from flask import Flask,request
from flask import jsonify
from flask_cors import CORS
import AIcontrol
app = Flask(__name__)
CORS(app,resources=r'/*',supports_credentials=True)
@app.route('/pve',methods=['POST'])
def aAI():
data=request.get_json()
print(data)
next_step=AIcontrol.AI_decide(data['dataA'], data['dataB'], data['point'])
print(next_step)
next_step={
'next_step': next_step
}
return jsonify(next_step)
前端部分:
游戏对局流程控制流程图如下:
后端部分:
后端的模块主要是提供交互接口和ai决策;
后端部分简单的交互接口使用flask库建立本地接口;
ai决策过程则是以贪心算法为主的简单策略:我们希望每一列都能得到最大分数,所以做决策时尽可能贴近最大的分数,同时对对手进行一定简单干扰,即消除决策。
前端部分:
data部分:
//用对象包数组方式表示九宫格,对象的KEX三元素表示数组的三行
data() {
return {
playerAData: {
K: [],
E: [],
X: [],
},
playerBData: {
K: [],
E: [],
X: [],
},
}
用数组方法push()实现放置骰子的点数:
//this.randa为我们掷得的点数
pushAE() {
this.playerAData.E.push(this.randa);
this.changeRow = "E";
this.removeB();//remove方法即消除方法
},
用数组方法splice()实现点数的消除:
removeA() {
var row = this.changeRow;
for (let i = 0; i < this.playerAData[row].length; i++) {
if (this.playerAData[row][i] == this.randb) {
var removed = this.playerAData[row].splice(i, 1);
console.log("remove the " + removed + "!");
}
}
for (let i = 0; i < this.playerAData[row].length; i++) {
if (this.playerAData[row][i] == this.randb) {
var removed = this.playerAData[row].splice(i, 1);
console.log("remove the " + removed + "!");
}
}
至此,实现游戏的基本也是核心功能,点数的放置和消除,其他功能(流程控制、消除特效、得分统计、图形界面转化等)在此基础上通过增加判断条件变量,监听和获取九宫格数据,即可逐一实现(实现逻辑思路大于算法设计),具体各个判断变量的设置和使用以及九宫格监听思路,本博客篇幅有限还请移步github项目查看。
ps:为便于后端开发,九宫格数据重构为以下格式(数组本质是特殊的对象,重构后不影响已实现的任何功能)
playerAData: [[], [], []],
playerBData: [[], [], []],
后端部分:
后端的AI由简单策略组成:
获取每列未来预期最大能够获取的分数:比如列状态为[1],那么它未来填满时最大得分的状态为[1,6,6],分数为25,而状态[1,5]的未来最大得分为[1,5,5],分数为21。这些状态我们枚举保存。
def exp_score1(board,list):
maxn = 0
k = 1
for i in range(1, 7):
list.append(i)
score = exp_score2(board, list)
list.pop()
if (score > maxn):
maxn = score
k = i
board[str(list)] = score
return score
def exp_score2(board,list):
maxn=0
k=1
for i in range(1, 7):
list.append(i)
score = exp_score3(board, list)
list.pop()
if(score>maxn):
maxn=score
k=i
board[str(list)] = maxn
return maxn
def exp_score3(board,list):
score=0
num=[0,0,0,0,0,0]
for i in range(0,3):
num[list[i]-1]+=1
for i in range(0,6):
score+=num[i]*num[i]*(i+1)
board[str(list)]=score
return score
def exp_socre():
dict={}
list=[]
dict['[]']=-54
for x1 in range(1,7):
list.append(x1)
exp_score1(dict,list)
for x2 in range(1, 7):
list.append(x2)
exp_score2(dict, list)
for x3 in range(1, 7):
list.append(x3)
exp_score3(dict,list)
list.pop()
list.pop()
list.pop()
return dict
#嵌套获取每一种情况下的未来最大得分
将点数填入每列中并获取它未来的最大得分,将其与现在的未来最大得分相减,得到权重以比较,抉择接下来放在哪一列。这里我们希望它们的差值越小越好。
得分模块外,消除对手的干扰行为同样重要,但是消除对手的骰子有可能会减少分数收入,所以我们设定一定限制,不难发现,1,2这样的点数一般来说是不值得消除的。综合观察的情况,对程序予以一定阈值以操控消除决策。
以下是简单决策的环节:
for i in range(0,3):
if(list_count(my_data[i])==3):
print(i,":max!")
else:
my_max=exp_dict[str(my_data[i])]
his_max=exp_dict[str(his_data[i])]
my_data[i].append(point)
my_exp = exp_dict[str(my_data[i])]
my_data[i].pop()
ans=0
while point in his_data[i]:
his_data[i].remove(point)
ans+=1
his_exp = exp_dict[str(his_data[i])]
while ans:
ans-=1
his_data[i].append(point)
pd=my_exp-his_exp
pd2=my_max-his_exp
pd3=pd-pd2
score=Exp_add(my_data[i],point)+Exp_lost(his_data[i],point)#当前步收益
print(i,":",my_max - my_exp)
nt[i]=my_max
if score>=12:
set=i
situ=0
if situ==2:
if my_max - my_exp < change:
change = my_max - my_exp
set = i
elif my_max - my_exp == change:
if my_max>nt[set]:
set = i
因为是简单的贪心策略,后端的AI算法基本上只是 O(1)级别的时间复杂度,所以没什么需要优化的。
(描述你改进的思路,展示性能分析图和程序中消耗最大的函数)
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | ||
Estimate | ·估计这个任务需要多少时间 | 20 | 20 |
Development | 开发 | ||
Analysis | ·需求分析 (包括学习新技术) | 300 | 250 |
Design Spec | ·生成设计文档 | 60 | 60 |
Design Review | ·设计复审 | 15 | 20 |
Coding Standard | ·代码规范 (为目前的开发制定合适的规范) | 30 | 15 |
Design | ·具体设计 | 60 | 60 |
Coding | ·具体编码 | 1000 | 800 |
Code Review | ·代码复审 | 120 | 120 |
Test | ·测试(自我测试,修改代码,提交修改) | 50 | 150 |
Reporting | 报告 | ||
Test Repor | ·测试报告 | 20 | 15 |
Size Measurement | ·计算工作量 | 20 | 15 |
Postmortem & Process Improvement Plan | ·事后总结, 并提出过程改进计划 | 30 | 30 |
合计 | 1725 | 1605 |
第N周 | 新增代码(行) | 累计代码(行)) | 本周学习耗时(小时) | 累计学习耗时(小时) | 重要成长 |
---|---|---|---|---|---|
1 | 700 | 700 | 8 | 8 | 熟练用vue框架搭建项目 |
2 | · 800 | 1500 | 10 | 18 | 学会动态修改vue背景图,熟练使用vue动画,掌握后端接口书写的基本流程 |
3 | 700 | 2200 | 10 | 28 | 熟练使用flask库实现后端接口开发 |
产品形态和预期的有些差别,最初本来想做个很酷的小游戏。有丰富的音效和动画效果,交互感强,功能丰富,页面信息清晰明了又面面俱到,最好是小程序。但是实际开发过程中考虑到技术栈(前端动画效果的实现,页面各类高质量素材获取,后端数据库调用,对跨域的处理等等。)以及完成度(学习成本大,可分配时间有限。)很多想法都被pass掉了。原型设计上我们根据自身能力对预期实现功能进行了考量,原型设计作品和软件开发成果很接近,基本还原了原型设计,还额外补充了一些功能。这点还算是比较满意。
心得体会:
是一款带有中国风特色的游戏,每一点都做的很精致,可以点击按钮实现打开或关闭背景音乐,背景音乐也选得很好,让人在对战中真的有一种与人切磋的感觉。以及背景图片也可以切换,这点很值得学习。
在开始游戏时,会有“拔剑”字样提醒,中途会有“接招、来也”等字样提醒数字已被消解,还设置了结束游戏的按钮,让人的游戏体验更上一层楼。并且鼠标放在哪里,棋盘就会有相应着重提示。每一行都会显示当前该行分数,也是很不错的。
每一个按钮(如龙争虎斗)、字体、音效(如剑相碰撞的声音)都有着一种侠士的感觉,让人身临其境,值得一玩。
1.我觉得背景和对战的时候一些效果很有意思,给人一种古代棋手在万军中对弈的的感觉,游戏细节做得也很棒。
2.你们的一些对战效果以及音效给用户的视觉与听觉的冲击很强,这一点很值得我们去学习与借鉴。
3.视频有些地方可以稍微加速,然后可以再多录制一点其他的东西。原型界面设计这一块稍微过于简单,就只有两页,可以多学习一下UI设计工具。
真的好帅啊!这些背景我都想求原图了!
每一处都做的好细节,包括鼠标悬停的动态效果(最细节的是悬停在棋盘的落子处,会在己方和对方的同行落子处给出加深和凸出效果)、点击落子之后给出的反馈(刀光剑影锵锵锵,音效和金戈铁马帅帅帅)、旁边每一行的大写数字(看得太有感觉了!!)、各处词语的运用(“龙争虎斗”、“投石拔距”看得我起鸡皮疙瘩)。很多地方都别具匠心,真的一个大写的服。
对于这个作品,我愿称之为神中神,建议直接给一伯分。
国风yyds!!!
这原型爱了。。。很棒
开始界面一开始就让人耳目一新,背景是吸引人的古风风格,文案也是别出心裁,进入游戏的呼吸头像和五种消除声效都是很好的反馈
好看!!!
音乐很好,有种新潮的复古的感觉~
对战中,有消除特效就很棒!!!有种“决战紫禁之巅”感觉(大侠梦又出来了)
很有文化气息音乐选的很好,有种现代又古风的感觉很有意思,有种“决战紫禁之巅”的感觉~(大侠梦又出来了)
在对战中,消除的时候有特效
1.一打开原型设计就能感受到古风的气息,完成度很高,细节把控也很好,对玩家的引导作用很强;
2.bgm很带感
中国风特色的UI设计给人一种震撼的感觉,很精致的界面。bgm搭配合理,紧张刺激的风格很适合这个UI和游戏。
web端的实现使得游玩变得方便,作品整体的完成度也很高。有很多值得我学习的地方啦,尤其是界面的设计方面太强了
总体来说相当优秀的作品!感觉这么菜的自己提不出什么建设性的建议啦。真的很厉害,令人眼前一亮的作品,加油~
作品充满中国元素,UI和音乐完美融合,让人眼前一亮,作品完成度很高,commit记录能看出整个开发过程的进度,值得自己学习。
原型设计很有中国武侠风的味道,很酷,bgm也非常传神,令人有身临其境的感觉。
AI算法设计的思路很有意思,值得学习。
对战的体验很好,堪称一绝。
原型设计非常好!走了古风的路线,画面非常美观,有种真的在对局的感觉,好看好看!
还可以显示每一列的分数这一点很新奇。
很精美的中国风,配合bgm有很强的对战的氛围
背景图片精美特效棒,设计风格充满中国风,用户交互出色体验好,功能完善完成度很高,代码规范好简明易懂
首先UI风格带有中国风特色,棋盘上印着中国“龙”的传统,有种霸气的感觉。
在游戏开始时,动画效果多样且都有肃杀的氛围,让人身临其境,增添玩家乐趣。
轮到某玩家时,头像有闪烁功能提醒。
建议可以加上实时分数更新功能。
很精美的中国风,配合bgm有很强的对战的氛围。
原型设计非常的完善,画面风格独树一帜,特别是对空白格做了填充;流程图清晰,版本迭代详细,很多优点都值得学习。
1.原型设计做得十分炫酷,很吸引人,让人有很想玩的冲动
2.程序整体的完成度很不错,值得学习
3.AI算法的思路很新奇,值得学习
背景精致,不仅有各种特效,还有多个背景特效,这十分的漂亮;作品完成度比较高,实现了大部分功能;点击特效很帅,有一股浓烈的中国风。在用户交互体验做的好。整个作品完成的很棒!
原型设计图也十分精美,不过图片较少。
演示视频也很不错。
我觉得这个组的创新点非常的吸引人,就是在开始的时候出现拔剑的字样,以及游戏过程中出现接招的字样,我作为用户是会被吸引到的,是比较酷炫的,还有我觉得鼠标移到棋盘对应格子悬浮的动态看着也很舒服,而且给pvp模式取名龙争虎斗,以及其他模式的取名也都很有心意,是一个完成度很高的作品。
相较于我们组,我觉得这个组的创新点可以借鉴,因为同样是web开发,没有想到可以从模式名上做文章,细节做的很好值得学东西。
建议是可以加上实时的分数显示,便于玩家游玩。
1.原型走了古风的路线,画面非常美观,有种真的在对局的感觉,好看好看!
2.还有bgm选的也很棒
3.还有就是可以显示每一列的分数这一点很新奇,是我没有想到的,值得我学习。