You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

技术咨询:用for循环创建动态DOM元素及实现Fallout终端猜词游戏

Hey there! 很高兴看到你在复刻Fallout经典的终端破解小游戏——这个Mastermind类的机制用原生JS实现其实挺顺手的,我来一步步给你拆解怎么用for循环搞定动态DOM生成和交互逻辑~

核心实现步骤

1. 先搭好基础HTML架子

先给页面准备一个容器放单词按钮和反馈信息,结构越简单越好,剩下的交给JS动态生成:

<div id="terminal-container">
  <div id="feedback"></div>
  <div id="word-buttons"></div>
</div>

2. 定义游戏核心数据

先把游戏的基础配置和状态变量写好,比如单词库、随机选中的正确密码、剩余尝试次数:

// 自定义单词库(建议统一长度,更贴合Fallout原版体验)
const wordList = ["VAULT", "PIPBOY", "RAIDER", "SANCTUARY", "MODULAR"];
// 随机选一个正确密码
const correctPassword = wordList[Math.floor(Math.random() * wordList.length)];
// 剩余尝试次数(Fallout原版一般是4-5次,可自行调整)
let attemptsLeft = 4;

3. 用for循环动态生成单词按钮

这是实现动态界面的核心:通过遍历单词列表,逐个创建按钮元素,绑定点击事件后插入到DOM中。这里用for...of遍历更简洁,如果你需要索引也可以用传统的for (let i = 0; i < wordList.length; i++):

const wordButtonsContainer = document.getElementById('word-buttons');
const feedbackElement = document.getElementById('feedback');

// 遍历单词列表,生成每个单词按钮
for (const word of wordList) {
  // 创建按钮元素
  const button = document.createElement('button');
  // 设置按钮文本
  button.textContent = word;
  // 添加类名方便样式控制
  button.classList.add('terminal-button');
  // 把单词存在data属性里,后续点击时直接取用
  button.dataset.word = word;

  // 给按钮绑定点击事件,触发猜测逻辑
  button.addEventListener('click', handleGuess);

  // 把按钮插入到容器中
  wordButtonsContainer.appendChild(button);
}

4. 实现猜测处理的核心逻辑

点击按钮后要做这些事:禁用按钮防止重复点击、计算匹配数、更新反馈、判断游戏胜负。重点是x/y correct的计算——x是位置和字符完全匹配的数量,y是字符出现在密码中的总数量(含精确匹配),这里要注意处理重复字符的情况,避免重复计数:

function handleGuess(e) {
  const guessedWord = e.target.dataset.word;
  const clickedButton = e.target;

  // 禁用当前按钮,防止重复点击
  clickedButton.disabled = true;
  clickedButton.classList.add('guessed'); // 标记已猜过的单词

  // 初始化匹配数
  let exactMatches = 0; // 位置+字符都对的数量
  let partialMatches = 0; // 字符存在但位置不对的数量

  // 第一步:计算精确匹配
  for (let i = 0; i < guessedWord.length; i++) {
    if (guessedWord[i] === correctPassword[i]) {
      exactMatches++;
    }
  }

  // 第二步:计算部分匹配(需要排除已精确匹配的字符,避免重复计数)
  const correctChars = correctPassword.split('');
  const guessedChars = guessedWord.split('');

  // 先标记已精确匹配的字符,后续不再参与计算
  for (let i = 0; i < guessedChars.length; i++) {
    if (guessedChars[i] === correctChars[i]) {
      correctChars[i] = null;
      guessedChars[i] = null;
    }
  }

  // 遍历剩余字符,统计部分匹配
  for (const char of guessedChars) {
    if (char && correctChars.includes(char)) {
      partialMatches++;
      // 移除已匹配的字符,避免重复计数(比如密码有两个P的情况)
      correctChars[correctChars.indexOf(char)] = null;
    }
  }

  // 总匹配数 = 精确匹配 + 部分匹配
  const totalMatches = exactMatches + partialMatches;

  // 更新反馈信息
  feedbackElement.textContent = `${exactMatches}/${totalMatches} correct`;

  // 判断游戏胜负
  if (guessedWord === correctPassword) {
    feedbackElement.textContent += " —— 恭喜!终端已破解!";
    // 禁用所有按钮,结束游戏
    document.querySelectorAll('.terminal-button').forEach(btn => btn.disabled = true);
    return;
  }

  // 减少尝试次数,判断是否耗尽
  attemptsLeft--;
  if (attemptsLeft === 0) {
    feedbackElement.textContent += ` —— 尝试次数耗尽!正确密码是:${correctPassword}`;
    document.querySelectorAll('.terminal-button').forEach(btn => btn.disabled = true);
  }
}

5. 加个Fallout风格的样式(可选但很有那味儿)

给终端加个绿字黑底的复古样式,还原游戏内的感觉:

#terminal-container {
  background-color: #000;
  color: #0f0;
  font-family: 'Courier New', monospace;
  padding: 2rem;
  max-width: 600px;
  margin: 2rem auto;
  border-radius: 4px;
}

.terminal-button {
  background-color: #111;
  color: #0f0;
  border: 1px solid #0f0;
  padding: 0.5rem 1rem;
  margin: 0.3rem;
  font-family: inherit;
  cursor: pointer;
  transition: all 0.2s;
}

.terminal-button:hover:not(:disabled) {
  background-color: #222;
}

.terminal-button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.terminal-button.guessed {
  color: #ff0; /* 已猜过的单词变黄 */
}

#feedback {
  margin-bottom: 1.5rem;
  font-size: 1.2rem;
}
一些小提示
  • 如果需要兼容更老的浏览器,可以把for...of换成传统的for循环,逻辑是一样的
  • 可以扩展的功能:添加终端打字机效果、错误次数过多触发“锁定”动画、自定义单词库长度等
  • 处理重复字符的逻辑很重要,比如密码是“PIPBOY”时,猜“PAPBOY”应该正确计算匹配数,避免重复统计P

内容的提问来源于stack exchange,提问作者Tsardines

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 07:07:56