从在Javascript两次返回相同的值,防止随机操作(Preventing random oper

2019-09-28 17:09发布

我很新的编码,并且在我的第一个JavaScript项目。 我试图创建一个小随机字符发生器随机选择的设置,并从两个数组人物原型。 我的问题是,我不断收到重复的,可能是由于表的规模较小。

<html>
<head>
<script type="text/javascript">

  var setting=new Array('Steampunk',
                        'Fuedal Japanese',
                        'Post Apocalyptic',
                        'Horror',
                        'Fantasy',
                        'Cyberpunk',
                        'Western',
                        'Pulp',
                        'Military',
                        'Space Opera',
                        'Medieval',
                        'Ancient',
                        'Mythological',
                        'Urban',
                        'Trans-Humanist',
                        'Renaissance',
                        'Dystopian',
                        'Retro Futuristic',
                        'Nordic',
                        'Colonial');  

  var Archetype=new Array('Ninja',
                          'Samurai',
                          'Viking',
                          'Cowboy',
                          'Rogue',
                          'Wizard',
                          'Wrestler / Luchador',
                          'Knight',
                          'Scientist',
                          'Gadgeteer',
                          'Druid',
                          'Performer',
                          'Pirate',
                          'Alien',
                          'Superhero / Villain',
                          'Robot',
                          'Soldier',
                          'Vampire',
                          'Werewolf',
                          'Bounty Hunter');

  function resetSettingAndArchetype()
  {
    var whichsetting = Math.floor(Math.random()*(setting.length));
    var whicharchetype = Math.floor(Math.random()*(Archetype.length));

我怎样才能获得随机操作永远不会返回相同值的两倍?

Answer 1:

您可以洗牌阵列(例如,使用费雪耶茨洗牌 ),那么就遍历一个接一个的洗牌阵列上。 当你到一个结束,只需再次将它洗。



Answer 2:

您可以使用下面的互换方法:

function shuffle(o){ //v1.0
    for(var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
    return o;
};
shuffle(setting);
 shuffle(Archetype);

参考



Answer 3:

我想创建数组,我可以遍历得到引用的一个附加的索引。 这将在阵列中创建的所有元素的恒定随机顺序,即在穿过当所有元件将复位到第一和一个以相同的顺序再次遍历。

此方法是用混洗拷贝兼容,以及,如在任何其他的答案进行说明。 您还可以使用更好的洗牌算法,这个人是天真的。 由于您的数组是如此之小,但业绩增长将是最小的。 如果你想洗好的副本,你将不再需要地图索引,你只需要创建对象时创建的副本。

这段代码没有进行测试。 我不知道有关的区间Math.random ,但我假设0 < x < 1浏览:

var RandomWalk = function(items) {
  var self = this;
  if (!items.length) {
    // throw some error
  }

  this.index = 0;
  this.index_map = (function(items) {
    var map = [], i = 0;
    while(map.length < items.length) {
      i = Math.floor(Math.random() * items.length);
      if (map.indexOf(i) === -1) {
        map.push(i);
      }
    }
    return map;
  })(items); // Note that this function is evaluated, index_map is not a function
  this.index_max = this.index_map.length - 1;
  this.next = function() {
    var r = self.index_map[self.index];
    if (self.index == self.index_max) {
      self.index = 0;
    } else {
      self.index += 1;
    }
    return r;
  }
  return this;
}

然后,你会做这样的事情:

// define settings and archetype
var archetype_walk = new RandomWalk(archetype);
function resetSettingAndArchetype()
{
  ...
  var arch_index = archetype_walk.next(),
      arch = archetypes[arch_index]
  // arch is in ['Ninja', 'Samurai', 'Druid' ...]

顺便说一句,“原型”可能是一个糟糕的变量名。 它看起来像一个函数。 我用“原型”在这里。



文章来源: Preventing random operation from returning same value twice in Javascript