
C#で複重しない乱数
とにかく自分の書いたプログラムの一部分を見てください
Bitmap my1 = new Bitmap(GetType(), rand.Next(1,52) + ".png");
Bitmap my2 = new Bitmap(GetType(), rand.Next(1,52) + ".png");
Bitmap my3 = new Bitmap(GetType(), rand.Next(1,52) + ".png");
Bitmap my4 = new Bitmap(GetType(), rand.Next(1,52) + ".png");
Bitmap my5 = new Bitmap(GetType(), rand.Next(1,52) + ".png");
Bitmap my6 = new Bitmap(GetType(), rand.Next(1,52) + ".png");
Bitmap my7 = new Bitmap(GetType(), rand.Next(1,52) + ".png");
Bitmap my8 = new Bitmap(GetType(), rand.Next(1,52) + ".png");
Bitmap my9 = new Bitmap(GetType(), rand.Next(1,52) + ".png");
Bitmap my10 = new Bitmap(GetType(), rand.Next(1,52) + ".png");
Bitmap my11 = new Bitmap(GetType(), rand.Next(1,52) + ".png");
Bitmap my12 = new Bitmap(GetType(), rand.Next(1,52) + ".png");
Bitmap my13 = new Bitmap(GetType(), rand.Next(1,52) + ".png");
Bitmap my14 = new Bitmap(GetType(), rand.Next(1,52) + ".png");
こんなかんじで、なんかプログラムが回りくどかったり下手くそだったりするのは触れないでくださいww
1~52の乱数を発生させてるのですが、コレが同じ数字が出て欲しくないんですけど
やり方が分かりません^^;
どなたか教えてくれませんか
No.6ベストアンサー
- 回答日時:
動かしてみて動作確認をとってみました。
これで動くと思います。
class UniqueRandom
{
private int rand_max;
private int rand_min;
private int rand_range;
bool[] check;
System.Random rand;
private int last_num;
public UniqueRandom(int imin, int imax)
{
rand_max = imax;
rand_min = imin;
rand_range = imax - imin + 1;
check = new bool[rand_range];
for (int i = 0; i < rand_range; i++) {
check[i] = false;
}
rand = new System.Random();
last_num = 0;
}
#if false
public int urand()
{
int num;
do {
num = rand.Next(rand_min, rand_max);
} while (check[num - rand_min]);
check[num - rand_min] = true;
return(num);
}
#else
public int urand()
{
int i, j;
int num = rand.Next(rand_min, rand_max);
for (i = last_num + 1, j = rand_min; j <= rand_max; i++)
{
if (i >= rand_range) {
i = 0;
}
if (!check[i]) {
if (j == num) break;
j++;
}
}
check[i] = true;
last_num = i;
return(i + rand_min);
}
#endif
}
乱数の取り方は
// 乱数生成用のオブジェクト
UniqueRandom u_rand = new UniqueRandom(1, 52);
// num に 1~52のどれかをユニークに取り込み
int num = u_rand.urand();
当然ながら、52回を超えると空きの数値が無いので帰ってこなくなります。
つまり、それ以上はランダムは出来ないってことですか?
プログラム試しました
すごいです。重複しませんでした
難しいですね
とりあえずこれを使ってプログラムを作っていきたいと思います
ありがとうございました
No.5
- 回答日時:
52という数字で重複禁止というところからするとトランプの山でも作りたいのでしょうか。
発想の方向を変えて、「1~52の数値を持つ配列をシャッフルし、頭から順次抜き出す」という手法を紹介しておきます。
#たぶんこのままクラスに突っ込んでも動作するんじゃないかな?
#シャッフル部分は実装してませんので注意
配列と現在位置:
int numbers[52];
int current;
シャッフルするルーチン:
// num = シャッフル回数
void shuffle(int num)
{
int i;
for(i = 0; i < 52; i ++)
{
// 配列の初期化
numbers[i] = i + 1;
}
// 配列をシャッフル
for(i = 0; i < num; i ++)
{
// 適当なシャッフルルーチン
// rand二回の実施結果で一枚ずつ入れ替える、というのがとりあえずは楽か
}
// 参照位置を頭にする
current = 0;
}
// 配列を先頭から順次取っていく
// 取れなくなった(=モノがなくなった)ら0を返す
int get()
{
if(current < 52) return numbers[current++];
return 0;
}
この回答への補足
そうですねトランプです
大富豪を作ろうと思っているのですが全然進まないので
基本的なことから作っていこうと思いまして
手札にとりあえず14枚カードが配られるようなプログラムを作っています
考え方はわかるのですが・・・
なるほど・・・少しづつ解読していきます
No.4
- 回答日時:
> public int rand()
> の部分でrandにエラーが出てきてしまいます
> randの定義をすでに含んでいますって感じです
System.Randomのオブジェクトとクラスの関数(メソッド)名がダブってましたね。
どちらを変えても同じですけど、関数名の方を適当に変えてください。
public int urand()
とか……(関数を呼び出してるところも)
だいぶ理解してきました
でも結局うまくいきませんでした・・・
すいませんこんなに詳しく描いてもらったのに
今後この技術も活用させてもらいたいと思います
ありがとうございました
No.3
- 回答日時:
> voidがダメみたいです無効なパラメーター型です。
っていわれますC#だと引数のない場合は何も書かないみたいですね。
(CとかC++の方が慣れてるから、ついvoidを書いてしまいましたが)
public int rand()
で良いと思います。
No.2
- 回答日時:
#1 の補足です。
check[num]とあるのはcheck[num - rand_min]に置き換えてください。
下記の例ではテーブルに出た乱数毎にフラグを立てて、その値にフラグが立ってるかどうかの判断を行っていますが、この場合、値の範囲に対して乱を使う回数が少ない場合は良いのですが、テーブルがフラグで埋まってくると新しい値を取り出すのに時間がかかってきます。
したがって、範囲内の値をある程度多く使う場合は、乱数を取り出した値を直接テーブルのインデックスにして判断するのではなく、取り出した乱数でテーブルのフラグの立ってない部分を順次探していくような形にした方が効率的になります。
例えば、下記のUniqueRandomクラスを変更するなら
// クラス変数の追加
private int last_num;
// コンストラクタの追加
last_num = 0;
// 関数本体(置き換え)
public int rand()
{
int i, j;
int num = rand.Next(rand_min, rand_max);
for (i = last_num + 1, j = rand_min; j <= rand_max; i++)
{
if (i >= rand_range) {
i = 0;
}
if (!check[i]) {
if (j == num) break;
j++;
}
}
check[i] = true;
last_num = i;
return(j);
}
この回答への補足
こんなに早く、詳しく返答ありがとうございます
少しづつですが部分的に理解ができてきました
public int rand()
の部分でrandにエラーが出てきてしまいます
randの定義をすでに含んでいますって感じです
お手数かけてすいません
No.1
- 回答日時:
乱数はランダムに値を生成しますが、同じ値を生成しないという機能はありません。
特に上下限値を指定した場合は値の取りうる範囲が狭いので、重複した値が出る確率は高くなります。重複した値を排除したいのであれば、自分で管理するしないでしょう。
例えば
class UniqueRandom
{
private int rand_max;
private int rand_min;
private int rand_range;
bool[] check;
System.Random rand;
UniqueRandom(int min, int max)
{
rand_max = max;
rand_min = min;
rand_range = max - min + 1;
check = new bool[rand_range];
for (i = 0; i < rand_range; i++) check[i] = false;
rand = new System.Random();
}
public int rand(void)
{
int num;
do {
num = rand.Next(rand_min, rand_max);
} while (check[num]);
check[num] = true;
return(num);
}
}
というようなユニーク値を返す乱数クラスを作って
UniqueRandom u_rand = new UniqueRandom(1,52);
Bitmap my1 = new Bitmap(GetType(), u_rand.rand() + ".png");
というのもひとつの方法です。
この回答への補足
public int rand(void)
すいません、この部分でエラーが出てしまいます
いろいろ試してみたのですが、分からないです・・・^^;
voidがダメみたいです無効なパラメーター型です。っていわれます
教えてもらってるのにすいません・・・
すごいです・・・
えーっとクラスを作ってこのプログラムを入力すればいいのでしょうか・・・
ごめんなさい、C#はまだ勉強中でいまいち理解できてなくて
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C言語の質問です。バイナリ形式で保存されたWindows Bitmap形式の画像ファイルを読み込み、 3 2023/07/19 14:58
- PHP imageフォルダに、画像をリサイズして保存する時のファイル名を変更したい 1 2023/05/30 11:39
- 英語 高校英語の問題 1 2023/05/23 15:29
- 英語 【英語】 新しい職場の人と仲良くできるか心配です。 ①I'm worried I won't get 4 2022/06/26 21:19
- 英語 the fee is a bit too large considering our interne 3 2022/06/18 14:02
- Visual Basic(VBA) FileSearch2007に変わる構文について 1 2022/12/16 16:57
- JavaScript 1日1回引けるJavaScriptおみくじについて 1 2022/12/12 22:28
- その他(クラウドサービス・オンラインストレージ) Google ColabでGoogleドライブのサブフォルダにファイルを生成する方法 1 2022/10/31 17:37
- Visual Basic(VBA) 複数シートの複数列に入力されているデータを重複なしで抽出するVBAを作りたいです。 9 2022/06/17 10:33
- Visual Basic(VBA) 実行時エラー´5854´ 文字列型パラメーターが長すぎます。 3 2023/06/08 21:17
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・「それ、メッセージ花火でわざわざ伝えること?」
- ・ゆるやかでぃべーと すべての高校生はアルバイトをするべきだ。
- ・【お題】甲子園での思い出の残し方
- ・【お題】動物のキャッチフレーズ
- ・人生で一番思い出に残ってる靴
- ・これ何て呼びますか Part2
- ・スタッフと宿泊客が全員斜め上を行くホテルのレビュー
- ・あなたが好きな本屋さんを教えてください
- ・かっこよく答えてください!!
- ・一回も披露したことのない豆知識
- ・ショボ短歌会
- ・いちばん失敗した人決定戦
- ・性格悪い人が優勝
- ・最速怪談選手権
- ・限定しりとり
- ・性格いい人が優勝
- ・これ何て呼びますか
- ・チョコミントアイス
- ・単二電池
- ・初めて自分の家と他人の家が違う、と意識した時
- ・「これはヤバかったな」という遅刻エピソード
- ・ゴリラ向け動画サイト「ウホウホ動画」にありがちなこと
- ・泣きながら食べたご飯の思い出
- ・一番好きなみそ汁の具材は?
- ・人生で一番お金がなかったとき
- ・カラオケの鉄板ソング
- ・自分用のお土産
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
2の補数を計算するプログラム
-
ハフマン符号化の問題を解くプ...
-
intとlongは同じ?
-
c++ TCHARで文字化け
-
C言語 サイコロ 2つの値を返せない
-
| (or) を使った関数の引数の作...
-
C++で表を作成したいのです ...
-
再起呼び出しの回数をカウント...
-
C言語プログラミング 漸化式に...
-
Aの値からBの値を除するとは??
-
「Aに対するBの割合」と「Aに対...
-
信頼区間の1.96や1.65ってどこ...
-
2進数、16進数、10進数のことを...
-
複数桁10進数の*桁目だけを抽出...
-
エクセルで可視セルにのみ値貼...
-
20'(角度)の計算がわかりま...
-
C言語での引数の省略方法
-
DWORDの実際の型は何でしょうか
-
ある商品のロス率を5%見込み、...
-
「指定されたキャストは有効で...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
2の補数を計算するプログラム
-
intとlongは同じ?
-
コマンドプロンプトのウィンド...
-
再帰処理をループ処理に変換
-
C++で表を作成したいのです ...
-
再起呼び出しの回数をカウント...
-
【C#】SQL文の中に変数を埋め込...
-
C言語で%を使わない余りの出し方
-
カードシャッフルのブログラム...
-
条件が多い場合
-
C++ bmp 透過処理
-
C言語のプログラムについて(...
-
C言語で簡単なパックマンゲーム...
-
C++ Debug Errorについて教えて
-
argvのNULLチェック
-
C言語の問題
-
関数とビット列
-
C言語
-
16bitで乱数を生成する方法
-
迷路を脱出する経路探索プログ...
おすすめ情報