#pragma twice

KAB-studio > プログラミング > #pragma twice > 139 Version 7.19 ランダマイズとのべ秒

#pragma twice 139 Version 7.19 ランダマイズとのべ秒

前のページへ 表紙・目次へ 次のページへ

 Version 7.19
ランダマイズとのべ秒

今回はちょっと横道にそれて、〈ランダマイズ〉ってものを紹介します
らんだまいず?
〈ランダム〉は知ってるでしょ
テキトーってゆーかバラバラってゆーか、そういうののことだよね
そうそう。日本語だと〈乱数〉、英語で random 。このランダムを作るこ
とを〈ランダマイズ〉って言います。ゲームなんかだとランダムはとても大
切だからね
そりゃそーよね、敵がいっつも同じふうに攻撃してきたらゲームになんな
いもんね
今回はちょっとランダムなアニメーションをするつもりだから、その前に
ランダムをってことで。色々勉強になるしね
……なーんか嫌な予感するけど……
まーねー、ちょっとこつこつした話になってくるからね。ま、とりあえず
使ってみましょう

void CAnimeDlg::OnBDraw() 
{
    int iRandData;
    for( int iF1 = 0; iF1 < 5; iF1++ )
    {
        // ランダムな値を作成!
        iRandData = rand();
        TRACE( "%d\n", iRandData );
    }

    // 下のは前の。
    ::KillTimer( GetSafeHwnd(), 100 );
}

あ、前の KillTimer() が残ってる
これは一応取っといて。タイマーのをまた後でやるかもしれないから
かも、って……まーいーや。この rand() っていうのがランダムなの?
そう、これはランタイムのひとつで、適当な整数値を戻り値として返しま
す。それを5回呼んでみました

41
18467
6334
26500
19169

おおっ、見事にバラバラ!
こういうふうに、ランダムな値を取り出すのにこのランタイムを使いま
す。あ、もう一度やってみて
ほいっ

41
18467
6334
26500
19169

おおっ見事にバラバラ、ってさっきと同じじゃない!!
そう、実は rand() をそのまま使うと〈決まってるバラバラ〉な値が返っ
てくるんです
決まってるバラバラ……って、それじゃ全然ランダムじゃないじゃな
い!
そう。なぜかっていうと、コンピューターは実はランダムが苦手だから
苦手? コンピューターが?
コンピューターは決まったことを決まったようにするのは得意なんだけ
ど、テキトーにするのは苦手なんだよね
どうして?
たとえば歯車。コンピューターの中身は機械仕掛けの時計みたいに、きっ
ちり歯車が噛み合ってる状態
それだとランダムなことが起きないわけね
いきなり1時が7時になったりはしないからね。この歯車の歯がいきなり
ひとつずれる、ってことはあまりないから
落としたりしたらずれるんじゃない?
そこがポイント
へ?
外からショックを与えれば、ちゃんと噛み合ってた歯車もずれるでしょ。
そのショックっていつ起きる?
いつって、いつかわからないいつか……あ! それってランダム?
そういうこと。つまり外からランダムな要因を取り込めば、ランダムのな
いコンピューターの世界にランダムを入れられるわけです
……なんか、変……ランダムがないから外からもらうなんて
コンピューターの変な部分のひとつかもね。ちなみにこの、ランダムを作
るために外から加えるもののことを【乱数の種】って言います
乱数の種を蒔くとランダムな値が出てくる?
そゆこと。そのあたりをやってみましょう

void CAnimeDlg::OnBDraw() 
{
    // 乱数の種を蒔きます。
    srand( 100 );

    int iRandData;
    for( int iF1 = 0; iF1 < 5; iF1++ )
    {
        iRandData = rand();
        TRACE( "%d\n", iRandData );
    }

    // 下のは前の。
    ::KillTimer( GetSafeHwnd(), 100 );
}

 srand() っていうのが、乱数の種を蒔くためのものだね
このランタイムを呼ぶと、 rand() の値がさっきと変わります

365
1216
5415
16704
24504

さっきと値が違う!
もう一度やってみて

365
1216
5415
16704
24504

おおっ、今度は、って今度も同じー!!
これは、 srand() の引数が同じだから
 100 を渡してるね
この値が乱数の種。この値が同じだと、 rand() の値も毎回同じになりま

毎日同じ時刻に時計落っことすようなもんね
だから、この乱数の種は、ランダムな値を入れなきゃいけないわけです
ってことはここに……何入れればいいの!?  rand() は決まってるから
ランダムじゃないし、他にランダムがなかったらランダムにならないじゃな
い!! あ、水希ちゃんが毎回違う値入れれば
それは面倒かも……まぁ、乱数の種はホントにランダムじゃなくてもいい
んです。ただ、値を取り出すたびに、ランダムの種の数字をまったく違うも
のにすればいいだけ
違えると?
 rand() で同じような値が出てくることがなくなるから、その時は
ホントのランダムになるわけね。でも、毎回違う値も難しくない?
うん、結局はこれも〈外〉から取り込まないといけないんだよね。で、こ
れには〈時計〉を使います
そっか! 時間はいつも違うもんね
そこで time() ってランタイムを使います

void CAnimeDlg::OnBDraw() 
{
    time_t lTime_t;
    time( &lTime_t );
    TRACE( "%d\n", lTime_t );
    // 1008433967

    // 下のは前の。
    ::KillTimer( GetSafeHwnd(), 100 );
}

 time_t って謎の引数を渡してるね
実際には long 型。ランタイムはこういうふうに普通の型を違う名前で
使ってること多いから、ちゃんと調べてね
ファイルから検索でっと、 typedef されてるね
そのポインタを渡すと、そこに現在時刻が返ってきます
でも変な値しか返ってきてないよ?
 time() は秒しか返ってこないからね
びょ、秒だけ!?
1970年1月1日0時0分0秒からののべ秒
使えなさそう……
普通の時刻は、こののべ秒を他のランタイムに渡せば分かるから
あ、そーゆー仕組みねー
ま、それはまた今度。で、この秒を乱数の種に使えば
毎回違う値になる!
ではやってみましょう

void CAnimeDlg::OnBDraw() 
{
    time_t lTime_t;
    time( &lTime_t );

    srand( lTime_t );

    int iRandData;
    for( int iF1 = 0; iF1 < 5; iF1++ )
    {
        iRandData = rand();
        TRACE( "%d\n", iRandData );
    }

    // 下のは前の。
    ::KillTimer( GetSafeHwnd(), 100 );
}

4802
2789
13024
15284
18714

ほいもう一度!

4894
8833
21701
929
12610

うん、今度はちゃんと違う!
こういうふうに、秒ならある程度乱数の種として機能するわけ
ある程度?
たとえばネットワークゲームでいろんな人が同時に乱数を使ったら?
同じ秒の可能性大……
そういう場合には乱数の種を工夫する必要があるかな

/*
    Preview Next Story!
*/
でも時間以外の種って?
専用のハードウェアを使うとか、ネットワーク上から出力するとか
なんか複雑〜
プログラミングよりも、そういうのの仕組みの方が難しいかもね
なんかめんどそう
というわけで次回
< Version 7.20 時間あれこれ >
につづく!
時間もまた複雑な話なんだ
ポピュラーそうなのに
そういうのが結構、ってことなのかもね
 
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
RSSに登録
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
 
このページは、Visual C++ 6.0を用いた C++ 言語プログラミングの解説を行う#pragma twiceの一コンテンツです。
詳しい説明は#pragma twiceのトップページをご覧ください。