C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[3]: 直前の数値と違う乱数の出し方は?


(過去ログ 139 を表示中)

[トピック内 6 記事 (1 - 6 表示)]  << 0 >>

■81559 / inTopicNo.1)  直前の数値と違う乱数の出し方は?
  
□投稿者/ よっしー (11回)-(2016/10/10(Mon) 07:56:05)

分類:[.NET 全般] 

1〜50までの数が格子状に並んでいて、その中からいくつかの数字を選び、
スタートボタンを押すとランダムにマスが点滅し、最後に止まったマス(数字)
と選んだ数字が同じ場合に当たりというプログラムを作っています。

ほぼ希望通りにできたのですが、ランダムにマスを点滅させるときに続けて同じマスが
点滅することがあります。

同じマスが何回か点滅しても構わないのですが、続けての点滅は無しにしたいのです。

点滅の方法としては1〜50までのラベルを貼り付け、タイマーにより乱数1〜50まで
の乱数を発生させ、その数値のラベルの背景色を変えています。

しかしその時に同じ数値が続けて発生することがあります。

重複なしの乱数の発生のさせ方はWEBに載っているのですが、同じ数値を連続させない方法が
見つかりませんでした。

直前の数値と違う乱数の出し方をご存知の方がいらっしゃいましたら教えていただけないでしょうか?

自分が書いた乱数を発生させラベルを点滅させる部分のプログラムを以下の通りです。


    Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick

        If i < 30 Then

            i += 1

            If selected = True Then
                Me.Controls(ControlName).BackColor = Color.Aquamarine
            Else
                Me.Controls(ControlName).BackColor = Color.Empty
            End If

            Randomize()
            ControlName = "label" & Rand.Next(1, 50)


            If Me.Controls(ControlName).BackColor = Color.Aquamarine Then
                selected = True
                Me.Controls(ControlName).BackColor = Color.Yellow
            Else
                selected = False
                Me.Controls(ControlName).BackColor = Color.Aqua
            End If

            System.Console.Beep(1000, 50)
        End If

    End Sub


よろしくお願いします。

引用返信 編集キー/
■81560 / inTopicNo.2)  Re[1]: 直前の数値と違う乱数の出し方は?
□投稿者/ Azulean (723回)-(2016/10/10(Mon) 08:29:16)
No81559 (よっしー さん) に返信
> 直前の数値と違う乱数の出し方をご存知の方がいらっしゃいましたら教えていただけないでしょうか?

そういう風に自分で作れば良いというのが、プログラムの世界です。
考え方としては、「前回の数値を覚えておく(変数を作る)」と「前回と同じだったら数値を変える」です。

前回の数値を覚えておく方法としては「メンバー変数を作ること」です。

Private previousValue As Integer = -1


    Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
'略
            Dim currentValue As Integer = Rand.Next(1, 50)
            ControlName = "label" & currentValue
            previousValue = currentValue

こうすれば、previousValue に今回出した数値が入り、次の Timer1_Tick の時に見ることができるようになります。


次に数値を変える方法ですが、いくつかアプローチがあります。

1.前回と同じ数値が出たらまた Rand.Next を呼び出す(While ループなど)
2.前回の数値があれば、1 〜 49 を求めるようにしておき、同じ数値になったら 1 を足す


1の方法は While という条件が同じ場合に繰り返すというループとなると思います。

currentValue = Rand.Next(1, 50)
While (currentValue = previousValue)
    currentValue = Rand.Next(1, 50)
End While


2の方法はこんな感じですかね。

Dim randomMax = 50
If (0 <= previousValue) Then
    randomMax = 49
End If

currentValue = Rand.Next(1, randomMax)

If (currentValue = previousValue) Then
    currentValue = currentValue + 1
End If

引用返信 編集キー/
■81566 / inTopicNo.3)  Re[1]: 直前の数値と違う乱数の出し方は?
□投稿者/ shu (919回)-(2016/10/10(Mon) 18:17:45)
No81559 (よっしー さん) に返信

Azuleanさんの提示されている方法でだいたいよいと思います。

ただ
前回値をa
としたときに
a+1の出る確率が2倍になってしまうので
aのときは最大値にするとよいと思います。
例) 1から50までの整数からの乱数として
 前回値が50以外
  => 前回値と同じ値を50にすることで前回値を除く各値の出る確率に偏りが増えなくてすみます。
 前回値が50の場合
  => 前回値と同じ値になることはないので同様に確率の偏りが増えなくてすみます。


また前回値に発生した乱数を足して50を超えたら50を引くという出し方でもよいかもしれません。
このときmodを使うとif文を使わなくてすみます。

引用返信 編集キー/
■81567 / inTopicNo.4)  Re[1]: 直前の数値と違う乱数の出し方は?
□投稿者/ もりお (24回)-(2016/10/10(Mon) 21:08:33)
2016/10/10(Mon) 21:12:36 編集(投稿者)

間違えました、ごめんなさい
引用返信 編集キー/
■81573 / inTopicNo.5)  Re[2]: 直前の数値と違う乱数の出し方は?
□投稿者/ よっしー (13回)-(2016/10/12(Wed) 19:42:17)
Azulean様、アドバイスありがとうございます。

1の方法で上手く出来ました。


2の方法は何となく理解できるような、出来ないようなとういう状態ですので、
今回はパスさせていただきました。


shu様、アドバイスありがとうございます。

今回はAzulean様の1の方法を利用させていただきました。

2の方法は私には少々理解するのが難しいです。
出現確立が2倍になってしまうなんて、私には全くわかりませんでした。


今回の質問はこれで解決とさせていただきます。

ありがとうございました。


解決済み
引用返信 編集キー/
■81574 / inTopicNo.6)  Re[3]: 直前の数値と違う乱数の出し方は?
□投稿者/ Azulean (726回)-(2016/10/12(Wed) 21:56:14)
No81573 (よっしー さん) に返信
> 2の方法は私には少々理解するのが難しいです。
> 出現確立が2倍になってしまうなんて、私には全くわかりませんでした。

私の書いたコードのバグです。

> If (currentValue = previousValue) Then
> currentValue = currentValue + 1
> End If

この部分は本来 = ではなく、 >= とすべきでした。

たとえば、前回が 30 だった場合、currentValue が 30 の時には 31 になりますし、currentValue が 31 の時も 31 になってしまいます。
よって、1 〜 50 の内、50 が出現せず、31 がほかの数字に比べて、30 と 31 の時に 31 になるので 2 倍の確率(振り分け)になるということです。
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -