2011/3/11 - 2011/3/15
Pen Jr.D言語なんてやってみそWelcome BeginnerHow old最終
<<・・How old最終
・・>>
日付・時間( Phobos
printf のサンプルコードでは、ディレイ に foreach 文 を使っています、この場合は問題ないと思いますが ディレイ が CPU の処理能力に依存しますから、環境によって表示スピードが変わってしまします。

OS は ナノ秒レベル の計測が出来る Tick Count という カウンター を持っていて、Tick Count を使えば、その環境に依存しない正確な時間計測などが出来ます。

精度を保証する規格などは多分ないでしょうから、どの程度正確なのかはその環境によりけりでしょうし、Windows は マルチスレッド ですから、正確さはその スレッド の優先度にも依存しますが、少なくとも手巻きの ROLEX なんかよりは正確でしょう。

core.time
struct TickDuration;
  long length;
Duration dur( string units )( long length );
dur

Duration

core.thread
class Thread;
  static void sleep( Duration val );
  static void sleep( long period );
sleep

class

呼び出した スレッド を 指定された時間(以上)停止します。

この 関数 は class Thread の メンバー関数 になりますが、関数 が static 属性 の場合、class 名 は 関数パッケージ名 という解釈で良いでしょう。

period100 ナノ秒単位( 10_000 で 1ミリ秒 )。

Thread.sleep( 100_000_000 );   // 10秒停止

Durationdur で、

Thread.sleep( dur!( "seconds" )( 10 ) );   // 10秒停止
import  std.stdio, core.thread, std.conv,
        my.std;

immutable{
  int cntAnime = 5, defAges = 30,
      sleep1st = 1_000_000, sleepAges = 1_000_000;
  char*[ 3 ] dispS = [ "*", "!", "@" ];
}

  /*----------------------------
  *
  */
void main( in string[] args ){
  int age = defAges;
  
  // コマンドライン引数があれば age に
  if( args.length > 1 ){
    if( isInteger( args[ 1 ] ) ){
      age = to!int( args[ 1 ] );
    }
  }
  writeln(
    toMBS(
      "ほんじゃ歳の数だけ星のプレゼントじゃ"
      "\nうけとれや!"
    )
  );
  // アニメーションもどきを追加
  foreach( i; 0 .. cntAnime ){
    foreach( j; 0 .. dispS.length ){
      Thread.sleep( sleep1st );
      printf( dispS[ j ] );
      printf( "\r" );
    }
  }
  
  foreach( i; 0 .. age ){
    Thread.sleep( sleepAges );
    printf( "*" );
  }
  
  writeln( toMBS( "\n\nほじゃ!" ) );
}

make test で ビルド して、

D:\Pen-Jr\My Programs\How old3>make test
dmd test my\std -w


D:\Pen-Jr\My Programs\How old3>test
ほんじゃ歳の数だけ星のプレゼントじゃ
うけとれや!
******************************

ほじゃ!

実行結果じゃわかりませんが、

std.datetime
class Clock;
  static TickDuration currSystemTick();
Clock
乱数
こんぴゅーたー は規則正しく動作するように、規則正しい クロック で制御していますから、
基本的に 乱数 は苦手です。

一般的なゲームやスロットにパターンにあるのはほとんどが 意図的 でしょうが、予測不可能な良い 乱数 を作るのは簡単ではありません。

std.random
alias Random;
Random rndGen();
void popFront();    // 乱数を1つ進める
UIntType front();   // 現在の乱数値
uint unpredictableSeed();
Random( unpredictableSeed );
import  std.stdio, std.random;

  /*----------------------------
  *
  */
void main( in string[] args ){
  auto rnd = Random();  // 最適乱数器
  
  foreach( i; 0 .. 10 ){
    if( i ){
      if( i % 5 ){
        write( ", " );
      }
      else{
        writeln();
      }
    }
    writef( "%d : %10d", i, rnd.front );
    rnd.popFront;
  }
  writeln();
}

「毎回同じ乱数」というのも変な感じですが、

D:\Pen-Jr\My Programs\How old3>dmd test

D:\Pen-Jr\My Programs\How old3>test
0 : 3499211612, 1 :  581869302, 2 : 3890346734, 3 : 3586334585, 4 :  545404204
5 : 4161255391, 6 : 3922919429, 7 :  949333985, 8 : 2715962298, 9 : 1323567403

D:\Pen-Jr\My Programs\How old3>test
0 : 3499211612, 1 :  581869302, 2 : 3890346734, 3 : 3586334585, 4 :  545404204
5 : 4161255391, 6 : 3922919429, 7 :  949333985, 8 : 2715962298, 9 : 1323567403

D:\Pen-Jr\My Programs\How old3>test
0 : 3499211612, 1 :  581869302, 2 : 3890346734, 3 : 3586334585, 4 :  545404204
5 : 4161255391, 6 : 3922919429, 7 :  949333985, 8 : 2715962298, 9 : 1323567403

unpredictableSeed で初期化すると、

import  std.stdio, std.random;

  /*----------------------------
  *
  */
void main( in string[] args ){
  // 最適乱数器 & 良い初期化シード
  auto rnd = Random( unpredictableSeed );
  
  foreach( i; 0 .. 10 ){
    if( i ){
      if( i % 5 ){
        write( ", " );
      }
      else{
        writeln();
      }
    }
    writef( "%d : %10d", i, rnd.front );
    rnd.popFront;
  }
  writeln();
}

unpredictableSeed 以外同じですが、

D:\Pen-Jr\My Programs\How old3>dmd test

D:\Pen-Jr\My Programs\How old3>test
0 : 2700217497, 1 : 2706738900, 2 : 3458166020, 3 : 2247057448, 4 :  638163583
5 : 3750497478, 6 :  485812859, 7 : 2749733874, 8 : 3818362195, 9 :  849749404

D:\Pen-Jr\My Programs\How old3>test
0 : 3781894208, 1 : 1017296890, 2 : 3329858770, 3 : 1290740351, 4 :  596666863
5 : 3712217078, 6 : 3951494457, 7 :  727944970, 8 : 2740456454, 9 :  301037400

D:\Pen-Jr\My Programs\How old3>test
0 : 1459536659, 1 : 3709226789, 2 :  702624146, 3 : 3312937133, 4 : 3438828821
5 : 1993613550, 6 : 3006039367, 7 : 1286358637, 8 : 3274245039, 9 :  210920736

乱数ですわ

また、

auto rnd = rndGen();

でも、同じ・・・じゃありませんが同様です。

uniform
CommonType!( T1, T2 ) uniform(
    string boundaries = "[)", T1, T2
  )( T1 a, T2 b );

なんだかややこしいことになってますが、

auto n = uniform( 0, 128 );   // 0 .. 128 の整数を生成

ということみたいです。

import  std.stdio, std.random, core.thread;

immutable{
  int defAges = 30,
      sleepAges = 1_000_000;
  char*[ 3 ] dispS = [ "*", "!", "@" ];
}
  /*----------------------------
  *
  */
void main(){
  foreach( i; 0 .. defAges ){
    Thread.sleep( sleepAges );
    // 0 .. 3 の乱数を使って * ! @ をランダム表示する
    printf( dispS[ uniform( 0, 3 ) ] );
  }
  writeln();
}
D:\Pen-Jr\My Programs\How old3>dmd test

D:\Pen-Jr\My Programs\How old3>test
@@***!@@@!*!!!!@*!@@*!*!@*!@*@

D:\Pen-Jr\My Programs\How old3>test
!!!@*!@*@@**@!@!**!!**!!!@***!

D:\Pen-Jr\My Programs\How old3>test
@*@*@!**!@*@!@@!@!*@!@@@@*@@!*
dice
size_t dice( R, Num )( ref R rnd, Num[] proportions... );
import  std.stdio, std.random, core.thread;

immutable{
  int defAges = 30,
      sleepAges = 1_000_000;
  char*[ 3 ] dispS = [ "*", "!", "@" ];
}
  /*----------------------------
  *
  */
void main(){
  // デフォルトのグローバル乱数ジェネレータ
  auto rnd = rndGen();
  
  foreach( i; 0 .. defAges ){
    Thread.sleep( sleepAges );
    // * : 60%, ! : 20%, @ : 20% で表示
    printf( dispS[ dice( rnd, 60, 20, 20 ) ] );
  }
  writeln();
}
D:\Pen-Jr\My Programs\How old3>dmd test

D:\Pen-Jr\My Programs\How old3>test
**!***@****@**@@!!**@******@@*

D:\Pen-Jr\My Programs\How old3>test
@*!!**@!****@*@***!@**!*@@**@*

D:\Pen-Jr\My Programs\How old3>test
**@!*@**@@*@****!@@***@*!@@*!!
コマンドライン・オプション
Const と Immutable( Const and Immutable
E-Mail : open@pen-jr.org

ご意見やご指摘は大歓迎ですが、質問など返信は期待しないでください

pen jr.
D言語研究
わかったつもりになるD言語
D言語友の会
News&Days
はじめてのブログ選び