1

私はコーディングが初めてで、最初の Javascript プロジェクトに取り組んでいます。設定をランダムに選択する小さなランダム キャラクター ジェネレーターと、2 つの配列からキャラクター アーキタイプを作成しようとしています。私の問題は、おそらくリストのサイズが小さいために、繰り返しが発生し続けることです。

<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));

ランダム操作で同じ値が 2 回返されないようにするにはどうすればよいですか?

4

3 に答える 3

5

配列をシャッフルして (たとえば、Fisher-Yates shuffleを使用して)、シャッフルされた配列を 1 つずつ反復するだけです。1 つ最後まで来たら、もう一度シャッフルします。

于 2012-09-15T07:27:15.137 に答える
1

シャッフルには次の方法を使用できます。

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);

参照

于 2012-09-15T08:39:44.373 に答える
1

参照を取得するためにループできる配列の追加のインデックスを作成します。これにより、配列内のすべての要素の一定のランダムな順序が作成され、すべての要素をトラバースすると、最初の要素にリセットされ、同じ順序で再度トラバースします。

この方法は、他の回答で説明されているように、シャッフルされたコピーとも互換性があります。そして、より良いシャッフル アルゴリズムを使用できますが、これは単純です。ただし、アレイが非常に小さいため、パフォーマンスの向上は最小限になります。シャッフル コピーを作成する場合は、インデックスをマップする必要はありません。オブジェクトの作成時にコピーを作成するだけで済みます。

このコードはテストされていません。の間隔についてはわかりませんが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' ...]

ところで、'Archetype' は不適切な変数名である可能性があります。関数のように見えます。ここでは「アーキタイプ」を使用します。

于 2012-09-15T09:48:28.447 に答える