是否可以删除函数的一部分? (即满足条件时的特定变量)

Is it possible to remove a part of a function? (i.e. a specific variable when a condition is met)

我正在尝试使用 JavaScript 创建一个简单的骰子游戏。我想用 5 个骰子模拟 Yahtzee 游戏,每次掷骰子后,每个显示 6 的骰子都应该放在一边,代码应该滚动剩余的骰子,直到所有骰子都放在一边。

这是我目前所做的:

<html>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<head>

<style>
div.dice{
float:left;
width:32px;
background:#F5F5F5;
border:#999 1px solid;
padding:10px;
font-size:24px;
text-align:center;
margin:5px;
}
</style>

<script>

function rollDice1(){
 var die1 = document.getElementById("die1");
 var d1 = Math.floor(Math.random() * 6) + 1;
 die1.innerHTML = d1;
}

function rollDice2(){
 var die2 = document.getElementById("die2");
 var d2 = Math.floor(Math.random() * 6) + 1;
 die2.innerHTML = d2;
}

function rollDice3(){
 var die3 = document.getElementById("die3");
 var d3 = Math.floor(Math.random() * 6) + 1;
 die3.innerHTML = d3;
 var status3 = d3;
}

function rollDice4(){
 var die4 = document.getElementById("die4");
 var d4 = Math.floor(Math.random() * 6) + 1;
 die4.innerHTML = d4;
}

function rollDice5(){
 var die5 = document.getElementById("die5");
 var d5 = Math.floor(Math.random() * 6) + 1;
 die5.innerHTML = d5;
}

function allDice() {
 rollDice1(); rollDice2(); rollDice3(); rollDice4(); rollDice5();
}

</script>

</head>

<body>

<div id="die1" class="dice">0</div>
<div id="die2" class="dice">0</div>
<div id="die3" class="dice">0</div>
<div id="die4" class="dice">0</div>
<div id="die5" class="dice">0</div>
<button onclick="allDice()">Roll Dice</button>

</body>

</html>

我已经成功创建了我的 5 个骰子,而且每次掷骰子都会为它们分配一个新值。但是,我还没有设法找到一种方法来停止滚动显示值 6 的特定骰子。

理想情况下,我可以一直按下标记为 "Roll Dice" 的按钮,直到所有五个骰子都显示值 6。

我尝试了很多方法,包括将所有 5 掷函数放入一个数组,然后删除负责特定骰子的函数,这些骰子在每次掷骰后最终显示 6。但是,创建数组似乎以某种方式影响了我以前的代码。我收到错误消息,例如 'die1' is 'null' 或函数 'allDice' 未定义。

如果需要,我可以添加一些我尝试过的其他版本的程序;我最初选择不添加它们,因为 post 感觉太长了。

所以,我已经达到了这样一个地步,我试图创建一个函数,每次按下按钮都会掷出所有 5 个骰子,然后我正在寻找一种方法来删除这些函数中的每一个相应的骰子显示 6,或从每个滚动函数中删除覆盖骰子上显示的数字的变量。如果这不可能或其他解决方案更合适,请将它们写在下面。

您可以将变量 d1, d2, d3, d4, d5 转换为全局变量并在执行每个 rollDice 函数之前检查它们的值:

var d1, d2, d3, d4, d5;

function rollDice1(){
 var die1 = document.getElementById("die1");
 d1 = Math.floor(Math.random() * 6) + 1; // NO 'var'
 die1.innerHTML = d1;
}

...

function allDice() {
 if (d1 !== 6)
  rollDice1(); 

  ...

}

var diceTab = [0, 0, 0, 0, 0, 0], i;
var dieTab = [die1, die2, die3, die4, die5]
function allDice() {
  for (i=0; i < diceTab.length; i++) {
    diceTab[i] =  Math.floor(Math.random() * 6) + 1;
    dieTab[i].innerHTML = diceTab[i];

    if (diceTab[i] === 6) {
      diceTab.splice(i, 1);
      dieTab.splice(i, 1);
    }
  }
}

ES6 非常短的版本(丑陋):

let dice = [1,2,3,4,5,6].map(r => document.getElementById(`die${r}`));
const [btn, roll] = [document.getElementById('btn'), function roll() {dice.forEach((die, i) => (result = die.innerHTML = Math.floor(Math.random() * 6) + 1) === 6 ? dice.splice(i, 1) : null)}];
btn.addEventListener('click', roll);

这不是一个好的解决方案,但要通过对代码进行最少的更改来做到这一点,只需在每个函数中添加一个条件来检查值是否不等于 6:

函数 rollDice1(){ var die1 = document.getElementById("die1"); 如果(die1.innerHTML !== '6'){ var d1 = Math.floor(Math.random() * 6) + 1; die1.innerHTML = d1; } }

     function rollDice2(){
      var die2 = document.getElementById("die2");
      if(die2.innerHTML !== '6'){     
        var d2 = Math.floor(Math.random() * 6) + 1;
        die2.innerHTML = d2;
      }
     }

     function rollDice3(){
      var die3 = document.getElementById("die3");
      if(die3.innerHTML !== '6'){         
        var d3 = Math.floor(Math.random() * 6) + 1;
        die3.innerHTML = d3;
      }
      var status3 = d3;
     }

     function rollDice4(){
      var die4 = document.getElementById("die4");
      if(die4.innerHTML !== '6'){             
        var d4 = Math.floor(Math.random() * 6) + 1;
          die4.innerHTML = d4;
      }
     }

     function rollDice5(){
      var die5 = document.getElementById("die5");
      if(die5.innerHTML !== '6'){  
        var d5 = Math.floor(Math.random() * 6) + 1;
        die5.innerHTML = d5;
      }
     }

function allDice() {

  var dices = [
    document.getElementById("die1"),
    document.getElementById("die2"),
    ...
  ]

  for each(var dice in dices) {
    if (dice.innerHTML != 6) //does not equal
    {
      dice.innerHTML=rollDice();
    } else {
      //put aside
    }
  }

}

有很多方法可以完成您在 javascript 中尝试做的事情,但我假设您想要一个您理解/不太复杂的答案,所以我'我将使用一个对您的代码稍作修改的代码,我将重构它以使其更短/更少重复。将您的 javascript 替换为以下内容:

var die1, die2, die3, die4, die5;
//Create one global variable per die

//We use one rollDice function that accepts the die number
function rollDice(whichDie){
  var die = document.getElementById("die"+whichDie);
  var dNum = Math.floor(Math.random() * 6) + 1;
  die.innerHTML = dNum;
}

//In allDice, we check each global die value and only roll the ones that 
//are not yet equal to 6
function allDice() {
  if (die1!==6) {rollDice(1)}
  if (die2!==6) {rollDice(2)}
  if (die3!==6) {rollDice(3)}
  if (die4!==6) {rollDice(4)}
  if (die5!==6) {rollDice(5)}
}

或者,对于更时尚、更短的版本:

var diceCount = 5,
    diceEls;

while (diceCount--){
  diceEls[diceCount] = document.getElementById("die"+diceCount);
}

function allDice() {
  diceEls.forEach(function(el, index){
    var curVal = parseInt(el.innerHTML, 10);
    el.innerHTML = curVal===6 ? curVal : Math.floor(Math.random() * 6) + 1;
  })
}

这是我能想到的最紧凑的方式(ES6代码):

let range = [1,2,3,4,5,6];
let dice = range.map(r => document.getElementById('die' + r))
const btn = document.getElementById('btn');

btn.addEventListener('click', roll);

function roll(){
    dice.forEach((die, index) => {
      result = Math.floor(Math.random() * 6) + 1;
      die.innerHTML = result;
      if(result === 6){
        dice.splice(index, 1);
    }
  })
}

https://jsfiddle.net/wbnhgr5a/

如果我们查看您当前的掷骰子算法,我们会发现它们除了元素 ID 外都是相同的

function rollDice5() {
  var die5 = document.getElementById("die5");
  var d5 = Math.floor(Math.random() * 6) + 1;
  die5.innerHTML = d5;
}

什么时候可以通过传入一个正在改变的东西(元素 id)作为参数来使你的代码枯竭

function rollDie(dieElementID){
    var die = document.getElementById(dieElementID);
    var newDieValue = Math.floor(Math.random() * 6) + 1;
    die.innerHTML = newDieValue;     
}

Element.innerHTML 适用于设置和读取元素的 HTML 值。我们可以读取当前骰子显示的内容并确定是否需要再次掷骰子。

function rollDie(dieElementID){
    var die = document.getElementById(dieElementID);
    if(die.innerHTML != 6){
        var newDieValue = Math.floor(Math.random() * 6) + 1;
        die.innerHTML = newDieValue;
    }
}

为了掷出所有的骰子,我们只需调用我们的新通用 rollDie 并传入 id。

function allDice() {
  rollDie("die1");
  rollDie("die2");
  rollDie("die3");
  rollDie("die4");
  rollDie("die5");
}

每次我们看到重复的代码只有一件事发生变化时,我们都可以尝试将其干掉。我们可以通过存储骰子元素 ID

的列表来使用 allDice 来做到这一点
function allDice() {
  var diceToRoll = ["die1","die2","die3","die4","die5"];
  for(var i = 0; i < diceToRoll.length; i++){
     rollDie(diceToRoll[i]);
  }
}

这是让它正常工作所需的最低限度。我们还应该重新检查我们的 rollDie 功能。请注意,我们已经引入了当骰子值为 6 时不滚动的副作用。我们应该打破滚动并检查它是否为 6 以在我们的代码中创建灵活性。为此,我们可以创建两个单独的函数并传入 die 元素而不是 die id。

function rollDie(dieElement) {
  var newDieValue = Math.floor(Math.random() * 6) + 1;
  dieElement.innerHTML = newDieValue;   
}

function dieHasValue(dieElement, value) {
  return dieElement.innerHTML == value;
}

那么我们的 allDice 看起来像这样

function allDice() {
  var diceToRoll = ["die1", "die2", "die3", "die4", "die5"];
  for (var i = 0; i < diceToRoll.length; i++) {
    var dieElement = document.getElementById(diceToRoll[i]);
    if (!dieHasValue(dieElement, 6)) {
      rollDie(dieElement);
    }
  }
}

function rollDie(dieElement) {
  var newDieValue = Math.floor(Math.random() * 6) + 1;
  dieElement.innerHTML = newDieValue;
}

function dieHasValue(dieElement, value) {
  return dieElement.innerHTML == value;
}

function allDice() {
  var diceToRoll = ["die1", "die2", "die3", "die4", "die5"];
  for (var i = 0; i < diceToRoll.length; i++) {
    var dieElement = document.getElementById(diceToRoll[i]);
    if (!dieHasValue(dieElement, 6)) {
      rollDie(dieElement);
    }
  }
}
div.dice {
  float: left;
  width: 32px;
  background: #F5F5F5;
  border: #999 1px solid;
  padding: 10px;
  font-size: 24px;
  text-align: center;
  margin: 5px;
}
<html>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<head>
</head>

<body>
  <div id="die1" class="dice">0</div>
  <div id="die2" class="dice">0</div>
  <div id="die3" class="dice">0</div>
  <div id="die4" class="dice">0</div>
  <div id="die5" class="dice">0</div>
  <button onclick="allDice()">Roll Dice</button>

</body>

</html>

如果您愿意,可以使用 Array 操作函数使所有骰子看起来更干净。

function getDie(elementId){
   return document.getElementById(elementId);
}
function dieNotShowingSix(dieElement){
   return !dieHasValue(dieElement,6);
}
function allDice() {
  ["die1", "die2", "die3", "die4", "die5"].
  map(getDie).
  filter(dieNotShowingSix).
  forEach(rollDie);
}