Skip to content

恶龙与公主

作者:江月迟迟
发表于: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 图片)。

具体需求如下:

  1. 补全 js/index.js 中的 mazePath 函数,将起点到终点顺时针经过的每个元素(即 class 包含 boxdata-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 函数检测时使用的输入数据与题目中给出的示例数据可能是不同的。考生的程序必须是通用的,不能只对需求中给定的数据有效。

  1. 补全 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

effect-2

effect-1

题解

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);
    }