恶龙与公主
发表于:2024-12-10
字数统计:1451 字
预计阅读5分钟
介绍
恶龙与公主是一个很经典的故事,恶龙抓住公主关在自己的洞府内,骑士激斗并战胜恶龙最后解救公主。下面我们通过编码模拟出这个场景:
- 公主被关在地图中央,骑士最开始在二维地图
[0,0]的位置,恶龙位置和数量随机生成,左下角固定位置有天使,骑士初始血量为 3。 - 点击“马上营救”按钮,系统随机生成 1-3 步,骑士按照随机生成的步数进行移动(蓝色边框位置变换)。
- 若骑士停留位置(红色边框
class包含active)有恶龙,则进行战斗并扣除 2 点血量。 - 若骑士停留位置(蓝色边框
class包含active)有天使,则增加 3 点血量。 - 如果血量小于等于 0,则弹出红色背景提示框,提示重伤不治。
- 如果骑士(蓝色边框
class包含active)顺利到达公主的位置,则弹出绿色背景提示框,提示营救成功。
准备
开始答题前,需要先打开本题的项目代码文件夹,目录结构如下:
txt
├── effect-1.gif
├── effect-2.gif
├── css
├── index.html
├── images
└── js
└── index.js其中:
index.html是主页面。js/index.js是待完善的 js 文件。css/index.css是 css 样式文件。images是存放图片的文件夹。effect-1.gif是营救成功效果图。effect-2.gif是营救失败效果图。
注意:打开环境后发现缺少项目代码,请手动键入下述命令进行下载:
bash
cd /home/project
wget https://labfile.oss.aliyuncs.com/courses/18421/test3.zip && unzip test3.zip && rm test3.zip在浏览器中预览 index.html 页面,显示如下所示:

目标
请在 js/index.js 文件中补全代码。
最终效果可参考文件夹下面的 gif 图,营救成功图片名称为 effect-1.gif ,营救失败图片名称为 effect-2.gif (提示:可以通过 VS Code 或者浏览器预览 gif 图片)。
具体需求如下:
- 补全
js/index.js中的mazePath函数,将起点到终点顺时针经过的每个元素(即 class 包含box)data-index属性值依次保存在数组中并返回。
js
// 本题中输入的二维数组 dyadicArray 值为
dyadicArray = [
["start", 1, 2, 3, 4],
[5, 6, 7, 8, 9],
[10, 11, "end", 13, 14],
[15, 16, 17, 18, 19],
[20, 21, 22, 23, 24],
];
// 执行 mazePath 函数
pathArr = mazePath(dyadicArray);
// 得到的数据为
pathArr = ["start", 1, 2, 3, 4, 9, 14, 19, 24, 23, 22, 21, 20,
15, 10, 5, 6, 7, 8, 13, 18, 17, 16, 11, "end"];注意:
mazePath函数检测时使用的输入数据与题目中给出的示例数据可能是不同的。考生的程序必须是通用的,不能只对需求中给定的数据有效。
- 补全
js/index.js中的moveHandler函数,需求如下:
- 根据点击“马上营救”按钮后获得的随机步数,由外向内顺时针到达指定位置。
- 根据骑士到达位置(
class包含active)是否存在恶龙(该元素节点class包含dragon)或者天使(该元素节点class包含angel)执行函数bloodCalculator(boxEle)计算出目前目前骑士剩余的血量。 - 根据血量和位置显示正确的提示框:血量为
0时,执行函数tipRender("warning");到达公主所在位置,执行函数tipRender("success")。
规定
- 请勿修改
js/index.js文件外的任何内容。 - 请严格按照考试步骤操作,切勿修改考试默认提供项目中的文件名称、文件夹路径、class 名、id 名、图片名等,以免造成判题无法通过。
mazePath函数检测时使用的输入数据与题目中给出的示例数据可能是不同的。考生的程序必须是通用的,不能只对需求中给定的数据有效。
判分标准
- 完成目标 1,得 15 分。
- 完成目标 2,得 10 分。
总通过次数: 6 | 总提交次数: 9 | 通过率: 66.7%
难度: 中等 标签: 蓝桥杯, 2023, 国赛, Web 前端, JavaScript


题解
js
/**
* @description 根据传入的二维数组,得到一维数组
* @param {Array} arr: getDyadicArray 得到的二维数组,存储地图上每个box的 data-index 值
* @return {Array} 一维数组,保存经过的路径
*/
mazePath(arr) {
// TODO:得到起点到终点经过的每个 box 元素的 data-index 的值并依次保存在数组中
let l = 0
let r = arr[0].length - 1
let t = 0
let b = arr.length - 1
let result = []
while(l <= r && t <= b) {
for(let i = l; i <= r; i++) {
result.push(arr[t][i])
}
t++
for(let i = t; i <= b; i++) {
result.push(arr[i][r])
}
r--
if (l > r || t > b) {
break
}
for(let i = r; i >= l; i--) {
result.push(arr[b][i])
}
b--
for(let i = b; i >= t; i--) {
result.push(arr[i][l])
}
l++
}
return result
},
moveHandler() {
let step = this.element.gameStep.value = this.getStep(this.gameData.step);
// TODO:根据点击营救后获得的点数,正确到达指定位置调用bloodCalculator函数计算当前血量,到达公主处调用 tipRender 函数,每步的时间间隔在 200ms内(大于此时间会导致判题失败)。
let timer = setInterval(() => {
// 清除
document.querySelector('.container>.active').classList.remove('active')
this.gameData.curPos++
const node = document.querySelector(`[data-index='${this.gameData.pathArr[this.gameData.curPos]}']`)
node.classList.add('active')
this.bloodCalculator(node)
if (this.gameData.curBlood === 0) {
this.tipRender('warning')
}
if (this.gameData.pathArr[this.gameData.curPos] === 'end') {
this.tipRender('success')
clearInterval(timer)
}
step--
if (!step) clearInterval(timer)
}, 200);
}