简单的魔鬼计算

魔鬼计算是《脑科学专家 川岛隆太博士监修 突破极限 脑的五分钟 魔鬼锻炼》里代表性的小游戏,也是我的最爱。可惜的是,系列最新作《脑科学专家 川岛隆太博士监修 大人的Nintendo Switch脑部锻炼》没有收录这个锻炼我的3DS不在手边,却时不时想玩魔鬼计算,所以写了下面的简化版。

看完规则后,点击开始试试吧(开始后再点开始可以重来


溯答

? ? ? =
正确率:??%

规则

用一句话说就是:一边计算当前题目,一边填写前N题的答案。

比如在2溯答模式中,假设游戏先显示了“1 + 12 + 2,此时正在显示“3 + 3。你应该做的是计算“3 + 3,同时填入“1 + 1”的答案。无论正确与否,游戏都会显示下一题,那时你需要记住新出现的题目,再填写“2 + 2”的答案。

在原版游戏中,每24题后会根据正确率调整N直到游玩时间超过五分钟——川岛隆太博士认为一口气玩五分钟才能真正锻炼工作记忆。

代码

规则所描述的就是队列,所以代码需要做的就是循环对队列进行操作:

  1. 生成新的题目,压入队列后面
  2. 弹出队列前面,判断输入正误

原版中的题目只有加法减法,操作数与答案也都是10以下自然数。我生成题目的方法是扔色子,不合条件就重扔。应该有更巧妙的方法——但是这个已经够用了。

完整代码
<div>
    <div>
        <div>
            <textarea rows='1' cols='2' id='N'>1</textarea>
            溯答
            <button id='start'>开始</button>
        </div>
        <div id='question'><br></div>
        <div>
            ? <small>?</small> ? = <textarea rows='1' cols='2' id='input' style='visibility: hidden'></textarea>
        </div>
        <div>正确率:<span id='accuracy'>??</span>%</div>
        <div id='log'></div>
    </div>
    <script>
        const textarea = document.getElementById('input'),
            log = document.getElementById('log'),
            pane = document.getElementById('question'),
            accuracy = document.getElementById('accuracy'),
            button = document.getElementById('start'),
            nBack = document.getElementById('N')

        function getRandomInt(max) {
            return Math.floor(Math.random() * max)
        }

        let queue
        function updateQuestion() {
            const op = getRandomInt(2)
            let question, c
            for (; ;) {
                // 原版的abc都是[0, 9]
                const [a, b] = [getRandomInt(10), getRandomInt(10)];
                [question, c] = [[`${a} + ${b}`, a + b], [`${a} - ${b}`, a - b]][op]
                if (0 <= c && c < 10)
                    break
            }
            pane.innerHTML = question
            textarea.value = ''
            queue.push([question, c])
        }

        function sleep(seconds) {
            return new Promise(resolve => setTimeout(resolve, seconds * 1000))
        }

        async function main(n) {
            queue = []
            textarea.style.visibility = 'hidden'
            accuracy.innerHTML = '??'
            log.innerHTML = ''
            for (let i = 0; i < n; ++i) {
                updateQuestion()
                await sleep(1)
            }
            // 最后一题不需要等
            updateQuestion()
            // 开始
            textarea.style.visibility = 'visible'
            textarea.focus()
        }

        button.addEventListener('click', (e) => main(parseInt(nBack.value)))

        textarea.addEventListener('keydown', (e) => {
            if (e.repeat) {
                const curr = textarea.value
                textarea.value = curr.substring(0, curr.length - 1)
                return
            }
        })

        let answered = 0, correct = 0
        textarea.addEventListener('keyup', (e) => {
            const answer = parseInt(textarea.value)
            const [question, result] = queue[0]
            // 我就不验证了
            ++answered
            queue.shift()
            if (result == answer) {
                ++correct
                log.innerHTML += '对<br>'
            } else
                log.innerHTML = `错: ${question} = ${result} ≠ ${answer}<br>` + log.innerHTML
            updateQuestion()
            accuracy.innerHTML = Math.round(correct / answered * 100)
        })
    </script>
</div>

关于3DS版的汉化

神游曾发行过DSi版的《一下下脑年龄 DSi锻炼 算数篇》,却没发行3DS版。Switch版的制作人员中可以看到神游和港任员工。3DS版可能也是他们一起汉化的,但只有港任发行出去了——这让人想起那12个由神游翻译好却从未被发行的GBA游戏——有趣的是3DS锁区,但港区的《魔鬼锻炼》插到神游的机器里也可以玩

3DS版的汉化真的是特别好,全程普通话配音先按下不表。单说3DS版和Switch版都有的朗读小游戏:前者使用了大量中文作品来本地化后者直接把这个模式给砍了(英文版还在。这是Switch版另一点让我感到可惜的地方。

到了Switch版哪个语言都没配音,任天堂有够敷衍。