【问题标题】:for loop, Math.random() not acting as intendedfor 循环,Math.random() 未按预期运行
【发布时间】:2015-03-31 15:17:51
【问题描述】:

我正在尝试用 javascript 编写一个骰子游戏,使用 Math.random() 生成骰子的值,并使用一个数组来保存每个骰子的当前值。

我遇到的问题是 1),数组最终包含六个数字,循环只运行五次,2) 我不知道如何让 Math.random() 返回不同的数字每次掷骰子。

这是有问题的函数:

var array = []

function rollDice() {
    for (var i = 0; i <= 4; i++) {

        var roll = Math.floor(Math.random() * 6) + 1;

        array[i] = roll;
        //array.splice(i, 1, roll);
    }
}

你可以看到'i'在循环中从零迭代到四(相当于五个循环),并且在每个循环中生成另一个随机数并插入到数组中的等效位置。

关于数组中的项目数:如果我按照上面写的方式运行代码,我会得到这样的结果:[1, 2, 3, 4, 5, undefined]。 如果我使用带有'splice'函数的注释行运行它(它应该删除存储在'i'位置的值并将其替换为新值),我将得到 [1, 2, 3, 4, 5, 6]。如果循环只运行了五次,这是怎么回事?

至于我让随机数更可靠地变化的困难:我在循环中尝试了以下...

var roll;
while (roll === hand[i] || roll === null) {
    roll = Math.floor(Math.random() * 6) + 1;
}

...希望'roll' 会继续旋转随机数,直到它产生一个不同的数字,但没有骰子。有人有什么建议吗?

编辑:我添加了一个显式数组声明,因为我没有足够清楚地表明我的数组实际上之前是显式声明的。

【问题讨论】:

  • 试试array[array.length]=roll;。此外,您在循环之前缺少var array=[]; 行。或者改用for (var roll = i = 0, array = []; i &lt;= 4; i++),这是更可取的方式。并删除var roll = [...]; 上的var
  • 您的代码看起来不错,请查看fiddle
  • 你需要确保你声明了你的数组;你没有发布你的代码的那部分。 while 循环不起作用可能是因为roll 将以undefined 开始,而不是null,所以循环根本不会运行。
  • 我的阵列似乎有些混乱。它被明确且正确地声明,我只是将声明从我的代码 sn-p 中删除,因为我认为我的读者会认为这是给定的。我现在什么都不做,并相应地编辑了我的帖子。
  • 不清楚你的目标是什么。你想要5个没有重复的随机数吗?那是你想要做的吗?如果不是,请解释一下,因为您的第一个代码块成功生成了 5 个随机数。

标签: javascript arrays loops


【解决方案1】:

我让它按你的意愿工作了。

代码中的错误:

  1. array 未定义 它被声明为 outside
  2. 您正在定义 undefined 变量的属性。
  3. 您错误地使用了while 循环。
  4. 你的函数没有返回任何东西。(由于数组是在循环外声明的,这是不必要的。)

这里是修改后的代码,使用for:

function rollDice() {
    for (var i = 0, array = []; i <= 4; i++)
    {
        array[array.length] = Math.floor(Math.random() * 6) + 1;
    }
    return array;
}

变化:

  1. 删除了无用的roll 变量。
  2. 使用属性length 设置下一个位置(类似于array.push(value),但更快)。
  3. 声明了array
  4. 返回要在函数外赋值的值

使用do ... while 循环:

function rollDice() {
    var array = [];
    do
    {
        array[array.length] = Math.floor(Math.random() * 6) + 1;
    }
    while ( array.length < 5 );
    return array;
}

区别:

  1. 变量i 不再需要了。
  2. array.length 的直接声明和递增
  3. 您只检查最后的长度,这是一项少用的检查
  4. 更快!!!

关于(以前的)编辑:

不要那样做!!!

不要访问在函数声明的变量。

这是最容易出错的方法!

【讨论】:

  • 反对票不是我做的。或者,如果是,它是错误的。我什至还没有在我的项目中测试过你的代码。一分钟。
  • @bmurrell30 慢慢来。请用您在 cmets 中所说的内容编辑您的问题。
  • @bmurrell30 - 现在你已经接受了这个答案,它没有按照你所说的在 cmets 中做你想要的(在同一个插槽中没有重复)。我和你放弃。您的问题不清楚,您的投票与您的要求不符。当你变得如此不清楚时,显然不值得尝试帮助你。
  • @jfriend00 根据问题中写的,这与描述相符。我仍在等待问题的更新,以便更改我的问题。但是我能做什么...?
  • 我的评论是写给 bmurrell30,而不是你。请参阅我评论开头的@bmurrell30。这就是它的收件人。到目前为止,当天最不清楚的问题。如果 OP 只想用 5 个随机数填充数组,那么它们的原始代码已经可以正常工作,如以下 jsFiddle 所示:jsfiddle.net/jfriend00/frh3dyvd。目前还不清楚他们实际上在问什么。
【解决方案2】:

随机返回 1 到 5 之间的 5 个唯一数字:

var array = [1,2,3,4,5]

function rollDice() {
    array.sort(function(){
        return Math.random() - 0.5;
    });
}

小提琴:http://jsfiddle.net/1wrgrr0v/1/

【讨论】:

    【解决方案3】:

    现在您已经澄清您想要的是连续调用roll() 不会在数组中的特定槽中重复值,您可以这样做:

    function rollDice() {
        var roll;
        for (var i = 0; i <= 4; i++) {
            // keep generate a new random value until it is different
            // than what was in this slot of the array before
            while ((roll = Math.floor(Math.random() * 6) + 1) === array[i]) {}
            array[i] = roll;
        }
    }
    

    工作演示:http://jsfiddle.net/jfriend00/frh3dyvd/

    【讨论】:

      猜你喜欢
      • 2021-04-04
      • 2022-12-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-13
      • 1970-01-01
      • 2014-10-21
      • 1970-01-01
      相关资源
      最近更新 更多