🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

Windows

Windowsは、マイクロソフト社が開発したオペレーティングシステムです。当初は、MS-DOSに変わるOSとして開発されました。 GUIを採用し、主にインテル系のCPUを搭載したコンピューターで動作します。Windows系OSのシェアは、90%を超えるといわれています。 パソコン用以外に、POSシステムやスマートフォンなどの携帯端末用、サーバ用のOSもあります。

Windows Forms

Windows Forms(WinForms)はMicrosoft .NET フレームワークに含まれる視覚的なアプリケーションのプログラミングインターフェイス(API)です。WinFormsは管理されているコードの既存のWindowsのAPIをラップすることで元のMicrosoft Windowsのインターフェイスのエレメントにアクセスすることができます。

Q&A

解決済

3回答

1759閲覧

初心者 C# での乱数からenumの値取得が偏る

SUGAKI

総合スコア16

Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

Windows

Windowsは、マイクロソフト社が開発したオペレーティングシステムです。当初は、MS-DOSに変わるOSとして開発されました。 GUIを採用し、主にインテル系のCPUを搭載したコンピューターで動作します。Windows系OSのシェアは、90%を超えるといわれています。 パソコン用以外に、POSシステムやスマートフォンなどの携帯端末用、サーバ用のOSもあります。

Windows Forms

Windows Forms(WinForms)はMicrosoft .NET フレームワークに含まれる視覚的なアプリケーションのプログラミングインターフェイス(API)です。WinFormsは管理されているコードの既存のWindowsのAPIをラップすることで元のMicrosoft Windowsのインターフェイスのエレメントにアクセスすることができます。

0グッド

1クリップ

投稿2019/10/10 05:57

前提・実現したいこと

乱数の偏りをなくしたい

初めて質問します。
初心者用の本を見ながら(作って覚えるVisual C# 2017)
間違い漢字探しのwindowsフォームアプリを作っています。
本には正しい漢字が1か所だけに、他の箇所には間違いの漢字(一種類)を表記させるように載っていますが、
自分で応用的に間違いとして出現する漢字をランダムに出現させようと思い
間違いの漢字リストを別クラスに置き、
enumで番号を振った後、その番号をランダムに発生させるコードを書きました。
が、出現する漢字がものすごく偏ります(間違いの漢字が1~2種類ぐらいしか出現しない)
何故なのでしょうか?

発生している問題・エラーメッセージ

エラーメッセージ

エラーメッセージはなし

該当のソースコード

C#

1~メインフォーム~ 2using System; 3using System.Collections.Generic; 4using System.ComponentModel; 5using System.Data; 6using System.Drawing; 7using System.Linq; 8using System.Text; 9using System.Threading.Tasks; 10using System.Windows.Forms; 11 12namespace FukushimaDifferenceHunt 13{ 14 public partial class FormGame : Form 15 { 16 17 string correctText = "福嶋"; 18 double nowtime;//経過時間 19 public FormGame() 20 { 21 InitializeComponent(); 22 } 23 24 private void bunttons_Click(object sender, EventArgs e) 25 { 26 if (((Button)sender).Text == correctText) 27 { 28 //when 25buntton click 29 timer1.Stop();//計測終了 30 } 31 else 32 { 33 nowtime = nowtime + 10;//ペナルティ 34 } 35 } 36 37 private void timer_Tick(object sender, EventArgs e) 38 { 39 //0.02秒おきに呼ばれるタイマーのいべんとはんどる 40 nowtime = nowtime + 0.5; 41 textTimer.Text = nowtime.ToString("0.00"); 42 43 } 44 45 private void bunttonStart_Click(object sender, EventArgs e) 46 { 47 textHunt.Text = correctText; 48 Random rnd = new Random(); 49 int randomResult= rnd.Next(25); 50 51 //splitcontainerの下のパネル2に載っているボタンのテキストを全て間違いの文字にする 52 for (int i =0;i < splitContainer1.Panel2.Controls.Count;i++) 53 { 54 var random = new Random(); 55 var mistakesvalue = random.Next(Enum.GetNames(typeof(mistakes)).Length); 56 var mistakesnumber = (mistakes)mistakesvalue; 57 switch(mistakesnumber) 58 { 59 case mistakes.伏島: 60 splitContainer1.Panel2.Controls[i].Text = "伏島"; 61 break; 62 case mistakes.副嶋: 63 splitContainer1.Panel2.Controls[i].Text = "副嶋"; 64 break; 65 case mistakes.副隝: 66 splitContainer1.Panel2.Controls[i].Text = "副隝"; 67 break; 68 case mistakes.幅嶋: 69 splitContainer1.Panel2.Controls[i].Text = "幅嶋"; 70 break; 71 case mistakes.幅隝: 72 splitContainer1.Panel2.Controls[i].Text = "幅隝"; 73 break; 74 case mistakes.愊隝: 75 splitContainer1.Panel2.Controls[i].Text = "愊隝"; 76 break; 77 case mistakes.服隝: 78 splitContainer1.Panel2.Controls[i].Text = "服隝"; 79 break; 80 case mistakes.楅嶋: 81 splitContainer1.Panel2.Controls[i].Text = "楅嶋"; 82 break; 83 case mistakes.福島: 84 splitContainer1.Panel2.Controls[i].Text = "福島"; 85 break; 86 case mistakes.福嶌: 87 splitContainer1.Panel2.Controls[i].Text = "福嶌"; 88 break; 89 case mistakes.福縞: 90 splitContainer1.Panel2.Controls[i].Text = "福縞"; 91 break; 92 case mistakes.福隝: 93 splitContainer1.Panel2.Controls[i].Text = "福隝"; 94 break; 95 } 96 97 } 98 //ランダムで一つだけ正解の文字にする 99 splitContainer1.Panel2.Controls[randomResult].Text = correctText; 100 101 //タイマースタート 102 nowtime = 0; //タイマーの初期化 103 timer1.Start(); 104 } 105 106 private void FormGame_Load(object sender, EventArgs e) 107 { 108 for (int i = 0; i < splitContainer1.Panel2.Controls.Count; i++) 109 { 110 splitContainer1.Panel2.Controls[i].Text = null; 111 } 112 } 113 } 114} 115 116 117~ここから別クラス~ 118namespace FukushimaDifferenceHunt 119{ 120 enum mistakes 121 { 122 福隝, 123 福嶌, 124 幅嶋, 125 幅隝, 126 副隝, 127 副嶋, 128 福島, 129 愊隝, 130 楅嶋, 131 服隝, 132 伏島, 133 福縞 134 135 } 136 137}

試したこと

最初はswith文ではなく(漢字ごとにわざわざ分岐させるのは面倒なので)、random.Next(Enum.GetNames(typeof(mistakes))を文に使ってループ処理させ
文章を短くしてましたが、出現漢字が偏るので
swith文にしましたが、出現漢字が偏ったままでした。
デバックモードでF10を一行1行押しつつ実行すると
均等な率で間違えの漢字が出現するのですが、
どこにもブレークポイントを付けずに実行をすると偏ってしまいます。
何故なのでしょうか???

補足情報(FW/ツールのバージョンなど)

VS2019
ここにより詳細な情報を記載してください

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

こんにちは。

bunttonStart_Click メソッドの for 文の中で Random を new しているのが原因です。
Random は時刻をベースに乱数を初期化するので、for 文などで極めて短い時間内に複数回作成すると同じ乱数列を持ってしまいます。
for 文の外で Random を一つのみ作り、その Next を繰り返し呼ぶことで正しく乱数を発行できます。

randomrnd の2つの乱数を作っているようですが、一つあれば足りるので rnd を使い回せば良いと思います。

投稿2019/10/10 06:08

tamoto

総合スコア4237

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

SUGAKI

2019/10/10 06:24

なるほど!時刻でランダムに発生させているのですね、謎が解けました。 まだまだ応用が利かないので無駄なコードが多くてすいません、 素早い回答ありがとうございます
guest

0

お二人の意見を参考に作り直したらできました!ありがとうございます
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace FukushimaDifferenceHunt
{
public partial class FormGame : Form
{

string correctText = "福嶋"; double nowtime;//経過時間 public FormGame() { InitializeComponent(); } private void bunttons_Click(object sender, EventArgs e) { if (((Button)sender).Text == correctText) { //when 25buntton click timer1.Stop();//計測終了 } else { nowtime = nowtime + 10;//ペナルティ } } private void timer_Tick(object sender, EventArgs e) { //0.02秒おきに呼ばれるタイマーのいべんとはんだおら nowtime = nowtime + 0.5; textTimer.Text = nowtime.ToString("0.00"); } private void bunttonStart_Click(object sender, EventArgs e) { textHunt.Text = correctText; Random rnd = new Random(); int randomResult= rnd.Next(25); //splitcontainerの下のパネル2に載っているボタンのテキストを全て間違いの文字にする for (int i =0;i < splitContainer1.Panel2.Controls.Count;i++) { string[] ary = { "福隝", "福嶌", "幅嶋", "幅隝", "副隝", "副嶋", "福島", "愊隝", "楅嶋", "服隝", "伏島", "福縞"}; var mistakesvalue = rnd.Next(ary.Length); splitContainer1.Panel2.Controls[i].Text = ary[mistakesvalue]; } //ランダムで一つだけ正解の文字にする splitContainer1.Panel2.Controls[randomResult].Text = correctText; //タイマースタート nowtime = 0; //タイマーの初期化 timer1.Start(); } private void FormGame_Load(object sender, EventArgs e) { for (int i = 0; i < splitContainer1.Panel2.Controls.Count; i++) { splitContainer1.Panel2.Controls[i].Text = null; } } }

}

投稿2019/10/10 06:48

SUGAKI

総合スコア16

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

var random = new Random();

これがループの中にあるからです。出してください。
というより rnd があるので、それを使ってください。

投稿2019/10/10 06:06

Zuishin

総合スコア28669

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Zuishin

2019/10/10 06:07

あと私なら enum ではなく配列を使います。
Zuishin

2019/10/10 06:25 編集

https://referencesource.microsoft.com/#mscorlib/system/random.cs,bb77e610694e64ca Random のソースです。 乱数発生とは言いますが、実は乱数のように見える値を計算で求めているだけです。これを疑似乱数と言います。 new Random(1) のように、シードと呼ばれる最初の値を与えると、そのシードに従って全く同じパターンの乱数を発生します。 new Random() のようにシードを与えなかった場合は実行された時間(ミリ秒)をシードとして使いますから、シードは 1ms ごとにしかかわらないことになり、その間は同じパターンの乱数になります。 途中で止めた時にパターンが変わったのは、そこで時間が経ったからです。
Zuishin

2019/10/10 06:22

これを応用して、シードを保存しておくことで全く同じ乱数を発生させることができ、ゲームのリプレイなどに利用できます。
SUGAKI

2019/10/10 06:25

配列という発想がありませんでした。 使ったことありませんでしたがこれから使ってみます。 ありがとうございます!
SUGAKI

2019/10/10 06:29

凄いサイトですね初めて見ました。ランダム関数の元ということでしょうか シード・・・なかなか難しいです。 読み解く力がまだまだついていないですが 独学で勉強しているのでこういうサイトを参考に出していただけるととても勉強になります。 ありがとうございます。
Zuishin

2019/10/10 06:33

.NET Framework はソースが公開されているので内部実装を見ることができます。ライブラリに含まれているクラスの挙動を疑問に思ったらここで検索してください。
SUGAKI

2019/10/10 06:55

分かりました!ブックマーク登録しました、ありがとうございます
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問