实现 CYOA 游戏而不是使用 switch 的更有效方法

问题描述 投票:0回答:1

我正在尝试实现一个函数,该函数将根据此树形图的选择组合返回结果(蓝色文本):

我目前有三个功能:

  • optionA
    点击 - 使用 switch 处理左选项点击
  • optionB
    点击 - 使用 switch 处理正确的选项点击
  • reset
    点击 - 将一切重置为初始状态

这种方法效果很好,但我想知道是否有更有效的方法来达到相同的结果。我当前的代码并不是真正可扩展的。它是重复的,我认为它可能会被缩短,但我不确定如何处理它。

let optA = document.querySelector(".optionA");
let optB = document.querySelector(".optionB");
let result = document.querySelector(".result");
let reset = document.querySelector(".reset")

function handleOptAClick() {
  if (result.innerHTML === '') {
    switch (optA.innerHTML) {
      case 'Hot':
        optA.innerHTML = "Leaf";
        optB.innerHTML = "Flower";
        break;
      case 'Leaf':
        optA.innerHTML = "Pure";
        optB.innerHTML = "Blend";
        break;
      case 'Alcohol':
        optA.innerHTML = "Plum";
        optB.innerHTML = "Rice";
        break;
      case 'Pure':
        optA.innerHTML = "Sunlight";
        optB.innerHTML = "Shade";
        break;
      case 'Plum':
        result.innerHTML = "Umeshu";
        break;
      case 'Bacteria':
        optA.innerHTML = "Yeast";
        optB.innerHTML = "Milk";
        break;
      case 'Sunlight':
        result.innerHTML = "Sencha";
        break;
      case 'Yeast':
        result.innerHTML = "Kombucha"
        break;
      default: 
        console.log("Something went wrong");
    }
  }
}

function handleOptBClick() {
  if (result.innerHTML === '') {
     switch (optB.innerHTML) {
    case 'Cold':
      optA.innerHTML = "Alcohol";
      optB.innerHTML = "Soft";
      break;
    case 'Flower':
      result.innerHTML = "Sakura"
      break;
    case 'Soft':
      optA.innerHTML = "Bacteria";
      optB.innerHTML = "Soy";
      break;
    case 'Blend':
      result.innerHTML = "Genmaicha"
      break;
    case 'Rice':
      result.innerHTML = "Sake"
      break;
    case 'Soy':
      result.innerHTML = "Soymilk"
      break;
    case 'Plum':
      result.innerHTML = "Umeshu";
      break;
    case 'Shade':
      result.innerHTML = "Matcha";
      break;
    case 'Milk':
      result.innerHTML = "Yakuruto";
      break;
    default: 
      console.log("Something went wrong");
     }
  }
}

function handleResetClick() {
  optA.innerHTML = "Hot";
  optB.innerHTML = "Cold";
  result.innerHTML = '';
}
<div>
  <button class="optionA" onClick=handleOptAClick()>Hot</button>
  <button class="optionB" onClick=handleOptBClick()>Cold</button>
  <button class="reset" onClick=handleResetClick()>Reset</button>
  <p class="result"></p>
</div>

感谢您的任何建议。

javascript tree switch-statement
1个回答
0
投票

您的代码中有很多重复。您可以通过制作一个数据结构来表示树来改进它,而不是在代码中对每个父子关系进行硬编码。

例如,树节点可以是一个包含三个元素的数组:选项(要显示)、左选项的(嵌套)树节点和右选项的(嵌套)树节点。树中的叶子将是一个只有两个条目的数组:选择(要显示)和要显示的相应结果。

然后代码可以专注于维护对树中当前节点的引用,即与到目前为止所做的选择相对应的节点。

我还建议不要使用 HTML 属性定义点击处理程序,而是使用代码(使用

addEventListener
)。

这是它的样子:

const tree = 
["Root",
    ["Hot",
        ["Leaf",
            ["Pure",
                ["Sunlight", "Sencha"],
                ["Shade", "Matcha"]
            ],
            ["Blend", "Genmaicha"]
        ],
        ["Flower", "Sakura"]
    ],
    ["Cold",
        ["Alcohol",
            ["Plum", "Umeshu"],
            ["Rice", "Sake"]
        ],
        ["Soft",
            ["Bacteria",
                ["Yeast", "Kombucha"],
                ["Milk", "Yakuruto"]
            ],
            ["Soy", "Soymilk"]
        ]
    ]
];

let current = tree;

const [left, right] = document.querySelectorAll(".option");
const result = document.querySelector(".result");
const reset = document.querySelector(".reset")

left.addEventListener("click", () => choose(1));
right.addEventListener("click", () => choose(2));
reset.addEventListener("click", () => display(tree));

function display(choice) {
    current = choice;
    left.textContent = current[1][0];
    right.textContent = current[2][0];
    result.textContent = "";
}

function choose(side) {
    const choice = current[side];
    if (choice.length == 2) { // We're at a leaf
        result.textContent = choice[1];
    } else {
        display(choice);
    }
}
<div>
  <button class="option">Hot</button>
  <button class="option">Cold</button>
  <button class="reset">Reset</button>
  <p class="result"></p>
</div>

© www.soinside.com 2019 - 2024. All rights reserved.