2

私は次元(8 x 8)のc#でマインスイーパゲームを開発しています。難易度レベルはグリッド上の地雷の数を増減します。

ランダムクラス(min、maxが設定されている;)を使用して乱数セル番号を生成します。私が直面している問題は、ランダムオブジェクトが同じ番号を繰り返し続けることです。この問題を解決するには、格納するローカルリストを維持します。生成された一意の乱数。次にNext()を呼び出すときは、ローカルリストと照合して、その番号がすでに存在するかどうかを確認します。番号がすでに存在する場合は、新しい番号を取得するまでNext()を呼び出し続けます。これは一意であり、リストには含まれていませんが、新しいリストを生成するのに時間がかかることがあるため、これ自体は良い解決策には見えません。

これに関する提案をお願いします

4

7 に答える 7

2

同じ乱数ジェネレーターを使用しても、値が繰り返される可能性があります。

これを回避する 1 つの方法は、可能な値のリストを生成し、生成された乱数を使用してこのリスト内の値にアクセスし (インデックスとして使用)、地雷を配置する場所を見つけるときにこのリストを減らすことです。

8 X 8 の例では、64 の可能な場所があります

 List<int> possibleValues = new List<int>();
 for (int i = 0; i < 64; i++)
 {
     possibleValues[i] = i;
 }

List<int> result = new List<int>();

Random r = new Random();
int numberOfMines = 50; //say you want to put 50 mines there

for (int i = 0; i < numberOfMines; i++)
{
    int indice = r.Next(possibleValues.Count);

    int value = possibleValues[indice];

    possibleValues.Remove(value);
    result.Add(value);
}
于 2012-04-20T13:01:00.650 に答える
1

Fisher-Yates shuffleなど、固定数のセル (8,8) に基づくシャッフルが必要なようです。これにより、任意の座標が 1 回だけ表示され (同じ数を何度も描画できる Random.Next() を繰り返し使用するのとは対照的に)、座標の表示順序がランダム化されることが保証されます。

セルのすべての座標を含む配列を初期化し、配列をシャッフルして次の「ランダム」セルのインデックスを維持し、インデックスのオフセットでセルを返し、インデックスを増やします。

于 2012-04-20T12:54:06.083 に答える
1

地雷があるはずのスロットを選ぶ代わりに、スロットをループして、そこに地雷があるはずの確率を計算します。必要なループは 1 つだけなので、この実装は非常にシンプルになります。

bool[] mines = new bool[64];

int cnt = 12;
Random rnd = new Random();
for (int i = 0; i < mines.Length; i++) {
  if (rnd.Next(mines.Length - i) < cnt) {
    mines[i] = true;
    cnt--;
  }
}

cnt(改善の余地:すべてのスロットを初期化する必要がない場合は、ゼロに達したときにループを終了できます。)

于 2012-04-20T12:55:05.180 に答える
1

最初に地雷の数を計算し、フィールドを空にします。

Random rand=new Random();
int mines=GetMinesFromDifficulty(...);
int empty=TotalFields-mines;

次に、各フィールドについて:

for(int y=0;y<height;y++)
  for(int x=0;y<height;y++)
  {

    if(random.Next(mines+empty) < mines))
    {
      field[x,y]=Mine;
      mines--;
    }
    else
    {
      field[x,y]=Empty;
      empty--;
    }
  }
于 2012-04-20T12:56:40.690 に答える
0

グリッドが 8x8 で、未使用のセルに到達するまで乱数を引き出すのではなく、未使用のセルをランダムに選択する場合は、未使用のセルの数を追跡します。8 個が使用済みで、55 個が未使用のままであるとします。次に、0 から 54 までの乱数を生成します。次に、数えて n 番目の空のセルを見つける必要があります。

于 2012-04-20T12:54:01.607 に答える
0

問題をより直線的な方法で考える方がおそらく簡単でしょう。2D 配列と言う代わりに... Squares[8][8] 1 次元配列 Squares[64] と考えてください。

この時点で、ランダムな地雷の配置のために 0 ~ 63 の数字を生成します。値が 10 の場合、後で保存して後続の数値を相殺することができます。ここで範囲を 0 ~ 62 に減らすことができます。値 16 を取り出した場合は、その下で既に取り出した値ごとに +1 を追加します (この場合、実際には 17 を使用しますが、10 の正方形はセットから除外されます)。

于 2012-04-20T12:54:12.047 に答える
-1

コードを見ないと物事の要点をつかむのは難しいですが、私が言えることは次のとおりです。

ゲームのグリッド レイアウト用の多次元配列 [8][8]。地雷をランダムに配置しようとしていますか?

数値を生成するために Random の 1 つのインスタンスを保持する必要があります。そうしないと、同じ数値が何度も取得されます。このようなもの

private readonly Random randomNumber = new Random();

for(int i = 0; i < 10; i++)
{
    Console.WriteLine(this.randomNumber.Next(1, 10));
}

これにより、それぞれ異なる 10 個の乱数が生成されます。

于 2012-04-20T12:54:09.690 に答える