D言語でSQLite触ってみる。

あけましておめでとうございます。
今年も何卒、よろしくお願いいたします。


新年初書きです。
あまりにもスローペース^^




さて本題。
D言語でちまちまpixiv用ツールを作りまして。
指定したユーザー(複数指定可)が投稿した画像を全てDLするという
なんとサーバーに負担の掛かるプログラム…


一度だけ公開したんだけど、とんでもミスを見つけて即消去。
(ソースにIDとパスを直書きしてたから、リクエストが全部僕のIDで付いてしまう。)


その部分を修正(ユーザー側へ入力を求める仕様へ)して、
とりあえず自己満足は出来たので、次のステップに向かうためにSQLiteを触ってみる。


皆さんお馴染みのdsource.org、この中に幾つか
SQLiteのポーティングがあるようなのですが、なんだかどれも微妙に更新されてない。
(最新SQLite3.6.9に対して3.5.1までしか対応していないとか・・・)


なんだかそれも微妙なので、自分で最新版対応を作ってみるテスト。




1、まずSQLite公式から、
  『sqlitedll-3_6_9.zip』『sqlite-source-3_6_9.zip』
  を落として解凍。


2、"sqlite3.dll"、"sqlite3.def"、"swlite3.h"以外は破棄。
  ↑3つを[sqlite3-d]というフォルダを作ってその中に入れる。


3、dsource.orgの
  http://www.dsource.org/projects/bindings/browser/trunk/sqlite3-d
  から、『sqlite3.d』を落とし、[sqlite3-d]フォルダに入れる。


4、"sqlite3.h"を見ながら、"sqlite3.d"を書き換える。
  (ここがミソ?自分でも上手く出来てるか分からない。)


5、implibを使って、"sqlite3.dll"から"sqlite3.lib"を作る。
  ( C:\~~~\sqlite3-d>implib /system sqlite3.lib sqlite3.dll )


6、↓のようなソースを準備。

 //main.d
 import std.stdio;
 import sqlite3;

 int main( string[] args ) {
   sqlite3* db;
   int check = sqlite3_open( "hoge.db", &db);

   if( SQLITE_OK==check)
     writefln("Success!");
   else
     writefln("Faild!");

  sqlite3_close(db);

  return 0;
 }

7、"sqlite3.dll"を"main.d"と同じフォルダにコピーして、
  それからコンパイル
  ( ex. C:\~~~\>dmd main.d -I../../sqlite3-d ../../sqlite3-d/sqlite3.lib )


8、出来たexeを実行して、"Success!"の文字と共に
  同フォルダ内に"hoge.db"が出来てれば成功!



こんな感じでした。
忘れない内にメモしておくだけなので、間違っている可能性大。
これから使ってみて検証しようと思う。

あ、もし 欲しい方 or 修正してくれる方 、いらっしゃいましたら連絡ください。
コメント全削除したsqlite3.dとその他一式プレゼントします


2009/01/15 10:17 若干修正


2012/05/07 06:41 追記修正
もう3年も前の記事なのに某所に URLとか貼られてるの見かけてしまったので…。
この記事書いた時のソースは紛失してしまったので
どんな書き方したか覚えてないのですが、
http://www.kmonos.net/alang/d/2.0/interfaceToC.html
に書いてある事に気をつけながら sqlite3.d編集していけばどうにか使える筈。
もしくは
http://www.dprogramming.com/sqlite.php
に zip落ちてるからそれ使ってみるとか…
(これに関しては触ってないので何とも言えませんが


特に気をつけなければならない事と言ったら、
D言語の文字列は NULL終端付いてないから
SQLite側に渡す時には加工してやらないといけない事。
後はいつの更新だったか、 Dの stringは immutable(char)[]になってるので
http://www.kmonos.net/alang/d/2.0/arrays.html
の一番下、文字列の所読んでおくと Cとの連携で詰まる所減らせるかも。

wxDを使う

とりあえずwxDのSamplesが動くまでの覚書。



まずwxWidgets公式(http://www.wxwidgets.org/downloads/)からzipを拾ってくる。

C:\Installed_Programs\dmd 以下に解凍。

dmd関係のパスを通す。
> set PATH=C:\Installed_Programs\dmd\dm\bin;C:\Installed_Programs\dmd\dmd2\bin;%PATH%

解凍フォルダに移動、make。
> cd C:\Installed_Programs\dmd\wxMSW-2.8.9\build\msw
> make -f makefile.dmc


次にwxD公式(http://wxd.sourceforge.net/)からzipを拾ってくる。

C:\Installed_Programs\dmd 以下に解凍。

wxWidgetsのパスを設定し、make。
> set WXDIR=C:\Installed_Programs\dmd\wxMSW-2.8.9
> cd C:\Installed_Programs\dmd\wxd
> make




ここまででwxDの使用環境は整うはず。
で、次はwxDのサンプルを動かす。


C:\Installed_Programs\dmd\wxd\Samples\Hello を開く


build.bat を作る。
 -SET PATH=C:\Installed_Programs\dmd\dmd2\bin\;C:\Installed_Programs\dmd\dm\bin\;%PATH%
 -SET WXDIR=C:\Installed_Programs\dmd\wxMSW-2.8.9
 -make
 -del *.obj
 -del *.map
 -pause


makefile を少し書き換える。
 -NAME=Hello
 -OBJECTS=$(NAME).obj
 -TARGET=.\$(NAME).exe
 -TOPDIR=C:\Installed_Programs\dmd\wxd
 -WXDIR=C:\Installed_Programs\dmd\wxMSW-2.8.9
 -
 -include $(TOPDIR)\Configs\config.mak

で、build.batを実行すると.exeがカレントフォルダに出来上がる。

2008/11/03 *修正*
makefile書き直すのはやっぱり面倒だったので、
build.batの中に"WXDIR"を書き足して、それを実行するだけに変更。
出来た.exeは ~\wxd\bin の中に出来ますので、それを実行しよう。



とりあえず、これで.dファイルが1つだけのサンプルはコンパイルできる。
しかし.dファイルが複数に分かれてる場合の対処がまだ出来ていない(というか分からない)。


そして、わなDさん所には
必要な.libと.dだけを作業環境にコピっちゃえばOKみたいな事が書いてあるが
同じ事やろうとすると"Symbol Undefined"なエラーをがっつり吐かれてしまう。
やり方が不味いのだろうか。


今のままだと、wxWidgetsもwxDも中身無闇に動かせないし
コンパイルに必要なファイルがはっきりしてないから
とても気持ちが悪い。


もう本当に"とりあえず"な応急処置。
wxWidgetsの組み方も覚えないと、先に進めないし・・・頑張ろう。





ちなみに今回初めてSocket使ったプログラムを組んだのだけれど、
今まではDelphiスタンドアロンなモノしか作った事がなかったので
簡単な事でも実現できるまで物凄い時間がかかった。


Cookieの扱いを如何すれば良いのか全然分からなかった・・・。
それが只の文字列なだけだったなんて・・・。


こういう時に相談できる知人友人が居れば全然違うのだろうけど、
その中でプログラミングな話題が通用する人が残念ながらいないし、
そもそも私には友達が片手で数えられる程しかいない。


交友関係的な事を考えて、やっぱり大学に行きたいと思うようになった。
若しくは、ネット上でプログラマなコミュニティに顔突っ込んだりするべきなのか。


ただ単純に知人友人を増やすだけを考えて、MMO始めようかとも考えたりしたが、
MMOは気が付かない内に時間をごっそり持っていかれるから怖ろしい。
何で俺高校青春の半分以上をROなんぞに注ぎ込んでしまったのだろうか・・・。
本当に勿体無い事をしたと、今でも思う。


季節も相まって、孤独が身に刺さります。
さて寝よう。

D2.0とSDL/OpenGLでライフゲーム作った。

のっけから余談ですが、先日発売になった"EeePC901"を買ってしまった。
6万であの性能なら、まぁ文句は無いでしょう。
Dの開発環境も乗っけたし、これで何処でもDと一緒(^q^)



スキルアップも兼ねてOpenGLも使ってみる事にした。


前回はD1.0を使っていたが、今回からはD2.0で行きます。
でも何故またD2.0に戻したか、といいますと。
少し前まではOpenGLのportingがデフォのままでは使えなかったのが
今回試してみたらバッチリ修正されていた為です。


(ちなみに問題だった部分は、D2.0から予約語登録された"ref"が
 portingの中で仮引数に使われていた所だったはず。)


では今回もビクビクしながら晒します。
前回と比べると、マウスによる生死の操作ができなくなっています。
だって面倒なんだもの。
後は、OpenGLで"頂点配列"というものを使ってみたつもりです。
全然美しくないけど・・・。

/* 頂点配列を使ったバージョン */
import std.stdio;
import std.conv;
import std.random;
import std.date;
import std.string;
import SDL;
import opengl;
import openglu;

invariant int g_Magnification = 2;

class fpsCounter {
private:
  Uint32 m_StartTick;
  Uint32 m_EndTick;
  int    m_Result;
  int    m_Counter;
public:
  this() {
    m_StartTick = SDL_GetTicks();
    m_EndTick   = 0;
    m_Result    = 0;
    m_Counter   = 0;
  }
	
  void calc() {
	
    m_EndTick = SDL_GetTicks();
    if( m_EndTick - m_StartTick > 1000 ) {			
      m_Result    = m_Counter;
      m_Counter   = 0;
      m_StartTick = m_EndTick;
    } else {
      m_Counter++;
    }
		
  }
	
  int Result() { return m_Result; }
};

class island {
private:
  typedef int[2]    vertex;
  typedef vertex[4] inhabitant;
	
  const uint m_Width;
  const uint m_Height;

  inhabitant[] m_Inhabits;
  bool[][]     m_Fields;
  bool         m_Freezing   = false;
  uint         m_Generation = 1;
public:

  this( int p_Width, int p_Height ) {
    m_Width  = p_Width;
    m_Height = p_Height;
		
    m_Fields.length     = m_Height;
    for( int y=0; y < m_Height; y++ ) {
      m_Fields[y].length     = m_Width;
      for( int x=0; x < m_Width; x++ ) {
        m_Fields[y][x]     = false;
      }
    }	
  }
	
  //Setter
  void Freezing( bool p_Freezing ) { m_Freezing = p_Freezing; }
  //Getter
  bool Freezing()                  { return m_Freezing; }
	
  //Setter
  void Generation( uint p_Generation ) { m_Generation = p_Generation; }
  //Getter
  uint Generation()                    { return m_Generation; }
	
  bool opIndex( int p_x, int p_y ) {
    return m_Fields[p_y][p_x];
  }

  void opIndexAssign( bool p_living, int p_x, int p_y ) {
    m_Fields[p_y][p_x] = p_living;
  }

  void randomize( int p_Probability ) {

    inhabitant l_Inhabit;
    bool       l_living;
	
    for( int y=0; y < m_Height; y++ ) {
      for( int x=0; x < m_Width; x++ ) {

        if( rand()%100 <= p_Probability ) {
          m_Inhabits ~= cast(inhabitant)([ [x,y],[x+1,y],[x+1,y+1],[x,y+1] ]);
          this[x,y] = true;					
        }

      }
    }

    m_Generation = 1;

  }
	
  void print() {

    clear();	

    glEnableClientState(GL_VERTEX_ARRAY);
    glVertexPointer(2 , GL_INT, 0 , cast(int*)m_Inhabits);
    glDrawArrays(GL_QUADS , 0 , m_Inhabits.length*4);
			
    flip();	
  }
	
  void next() {
	
    int l=0,r=0,u=0,d=0,i=0;
    bool[][] l_NextFields;
		
    l_NextFields.length = m_Height;
    for( i=0; i < m_Height; i++ )
      l_NextFields[i].length = m_Width;

    if( ++m_Generation > 100000000 )
      m_Generation = 1;

    m_Inhabits.length = 0;

    for( int y=0; y < m_Height; y++ ) {
      for( int x=0; x < m_Width; x++ ) {

        i = 0;

        l = (x + m_Width - 1) % m_Width;
        r = (x + 1) % m_Width;
        u = (y + m_Height - 1) % m_Height;
        d = (y + 1) % m_Height;

        if(this[l,u]) i++; if(this[x,u]) i++; if(this[r,u]) i++;
        if(this[l,y]) i++;                    if(this[r,y]) i++;				
        if(this[l,d]) i++; if(this[x,d]) i++; if(this[r,d]) i++;

        if( ( (this[x,y]) && (i==2) ) ||(i==3) ) {				
          m_Inhabits ~= cast(inhabitant)([ [x,y], [x+1,y], [x+1,y+1], [x,y+1] ]);
          l_NextFields[y][x] = true;
        }
      }
    }
		
    m_Fields = l_NextFields;
		
  }

};

void clear() {
  glClear(GL_COLOR_BUFFER_BIT);
  return;
}

void flip() {
  SDL_GL_SwapBuffers();
  return;
}

bool PropertysCheck( string[] p_args, out int p_Width, out int p_Height, out int p_Probability, out int p_StopCount ) {

  if( p_args.length <> 5 ) {
    writefln("Parameters Disposition Failed.\n1:Width, 2:Height, 3:Probability, 4:StopCount.");
    return false;		
  }

  p_Width         = toInt(p_args[1]);
  p_Height        = toInt(p_args[2]);
  p_Probability   = toInt(p_args[3]);
  p_StopCount     = toInt(p_args[4]);

  if( (p_Width < 100) || (p_Width > 500) ) {
    writefln("Please Wedth length between 100 and 300.");
    return false;
  }

  if( (p_Height < 100) || (p_Height > 500) ) {
    writefln("Please Height length between 100 and 300.");
    return false;
  }

  if( (p_Probability <= 0) || (p_Probability >= 100) ) {
    writefln("Please Probability Value between 1 and 99.");
    return false;
  }

  if( p_StopCount < 0 ) {
    writefln("Please StopCount value over 0.");
    return false;
  }

  return true;

}

bool Init( int p_Width, int p_Height ) {

  SDL_VideoInfo* l_Info = null;

  writefln("SDL Initialize.");

  if( SDL_Init( SDL_INIT_VIDEO ) < 0 ) {
    writefln("SDL Initialize Failed. : %s.", SDL_GetError());
    return false;
  }

  l_Info = SDL_GetVideoInfo();

  SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 5 );
  SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 5 );
  SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 5 );
  SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 );
  SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
  //SDL_GL_SetAttribute( SDL_GL_SWAP_CONTROL, 0);


  if( SDL_SetVideoMode( p_Width * g_Magnification,
                        p_Height * g_Magnification,
                        l_Info.vfmt.BitsPerPixel,
                        SDL_OPENGL                  ) == null ) {
    writefln("Set Video Mode Failed. :%s", SDL_GetError() );
    return false;
  }
	
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glOrtho(0, p_Width , 0, p_Height, 0, 10);

  glViewport(0, 0, p_Width * g_Magnification, p_Height * g_Magnification);
  glClearColor( 0, 0, 0, 0 );
	
  //SDL_ShowCursor( SDL_DISABLE );

  return true;

}

void End() {

  writefln("SDL Finalise.");

  SDL_Quit();

}

bool PollEvent( ref island p_Island ) {

  SDL_Event l_Event;
  SDLKey*   l_Key;

  while( SDL_PollEvent(&l_Event) ) {

    switch( l_Event.type ) {

      case SDL_QUIT:{
        return false;
      }break;

      case SDL_KEYDOWN:{
        l_Key = &(l_Event.key.keysym.sym);				
        switch (*l_Key) {

          case SDLK_SPACE:{
            p_Island.Freezing = !p_Island.Freezing;
          }break;

          case SDLK_ESCAPE:{
            return false;
          }break;

          default:{
          }break;				
        }				
      }break;

      default:{
      }break;

    }
  }
  return true;
}

int main( string[] args ) {

  int l_Width = 0, l_Height = 0, l_Probability = 0, l_StopCount = 0;
  rand_seed( getUTCtime(), 0 );	

  //引数チェック
  if( !PropertysCheck( args, l_Width, l_Height, l_Probability, l_StopCount ) ) return -1;

  if( !Init( l_Width, l_Height ) ) return 0;

  fpsCounter l_FPS = new fpsCounter();

  island l_Island = new island( l_Width, l_Height );
  l_Island.randomize( l_Probability );

  while( true ) {

    l_FPS.calc();		
    SDL_WM_SetCaption( cast(char*)toStringz(format("lifegame Generation:%d FPS:%6d",
                                                   l_Island.Generation,
                                                   l_FPS.Result)), null);

    l_Island.print();

    if( !l_Island.Freezing)
      l_Island.next();

    if( l_Island.Generation == l_StopCount )
      l_Island.Freezing = true;

    if( !PollEvent( l_Island ) ) break;
		
  }

  End();

  return 0;

}


一応こんな感じになりました。
SDL版とFPS比較しても、そんな差は出ませんでした。
俺のコーディングが悪いんだ・・・。


とりあえずこれからも、ぼちぼちOpenGLを触って行こうかと思います。

D1.0とSDLでライフゲーム作った。

久方ぶりの投稿。
更新速度こんなんでいいのかと自問中。


週末を使ってD1.0とSDLライフゲーム書いてみた。
ゲームを作るのに、どの "言語+ライブラリ" がいいのかを悩みまくった。


候補としては 「C++/Irrlicht」「C++/SDL」「D/SDL」があって、
最初に「C++/Irrlicht」を触ってた。がしかし。
サンプルコードがコンパイルできず、原因も解決できないという
へたれっぷりを全開にしてしまい、挫折。
それと"ノード"を管理するっていうスタンスがイマイチしっくり来ない。
しかも目指すは2Dゲームなのに・・・って事で、
3D技術的なのはやっぱり全部後回しにすることに。


で、残った2つの選択肢があって
実際どっちでも良かった気はするけど、何となくで「D/SDL」を選択。
(ちなみにD1.0とD2.0のどっちを使うかも迷ったが、安定性を考えてD1.0を選択。)


そっからはDとSDLのリファレンス&サンプルを読みながらゴリゴリと。


以下成果物。
変数名とかエラーメッセージとかが恥ずかしい事になってるのは、
目を瞑ってくださいお願いします><
もし、バイナリ欲しいとかいう変態さんがいらっしゃいましたら言ってください。

//lifegame2.d
import std.stdio;
import std.conv;
import std.random;
import std.date;
import std.string;
import SDL;

SDL_Surface* g_Surface;
Uint32       g_White;
Uint32       g_Black;

struct inhabitant {
  SDL_Rect field;
  bool     living;
}

class island {
private:
  inhabitant[][] m_Fields;
  const int m_Width;
  const int m_Height;
public:

  this( int p_Width, int p_Height ) {

    m_Width       = p_Width;
    m_Height      = p_Height;	
		
    //全フィールドの初期化
    m_Fields.length = m_Height;
    for( int y = 0; y < m_Height; y++ ) {		
      m_Fields[y].length = m_Width;
      for( int x = 0; x < m_Width; x++ ) {			
        m_Fields[y][x].field.x = x;
        m_Fields[y][x].field.y = y;
        m_Fields[y][x].field.w = 1;
        m_Fields[y][x].field.h = 1;
        m_Fields[y][x].living  = false;				
      }
    }
  }
	
  bool opIndex( int p_x, int p_y ) {
    return m_Fields[p_y][p_x].living;
  }
	
  void opIndexAssign( bool p_Value, int p_x, int p_y ) {
    return m_Fields[p_y][p_x].living = p_Value;
  }
	
  void randomize( int p_Probability ) {
    //引数の誕生確率を使ってフィールドのランダム設定
    for( int y = 0; y < m_Height; y++ ) {
      for( int x = 0; x < m_Width; x++ ) {			
        this[x,y] = ( rand()%100 <= p_Probability );				
      }
    }		
  }
	
  void print() {

    for( int y = 0; y < m_Height; y++ ) {
      for( int x = 0;  x < m_Width; x++ ) {			
        if( m_Fields[y][x].living ) {
          SDL_FillRect( g_Surface, &(m_Fields[y][x].field), g_White );
        } else {
          SDL_FillRect( g_Surface, &(m_Fields[y][x].field), g_Black );
        }				
      }
    }		
  }
	
  island next() {
	
    int l = 0, r = 0, u = 0, d = 0, i = 0;
		
    island l_Island = new island( m_Width, m_Height );
		
    for( int y = 0; y < m_Height; y++ ) {
      for( int x = 0; x < m_Width; x++ ) {
			
        i = 0;
				
        l = (x + m_Width - 1) % m_Width;
        r = (x + 1) % m_Width;
        u = (y + m_Height - 1) % m_Height;
        d = (y + 1) % m_Height;
				
        if(this[l,u]) i++; if(this[x,u]) i++; if(this[r,u]) i++;
        if(this[l,y]) i++;                    if(this[r,y]) i++;				
        if(this[l,d]) i++; if(this[x,d]) i++; if(this[r,d]) i++;
				
        if( ( (this[x,y]) && (i==2) ) ||(i==3) ) {
          l_Island[x,y] = true;
        } else {
          l_Island[x,y] = false;
        }
				
      }		
    }		
    return l_Island;		
  }
	
};



int main(string[] args) {

  int l_Width = 0, l_Height = 0, l_Probability = 0;
  rand_seed( getUTCtime(), 0 );
	
	
  //引数チェック
  if( !PropertysCheck( args, l_Width, l_Height, l_Probability ) ) return -1;
	
  //SDL初期化
  if( !Init( l_Width, l_Height )) return -1;
	
  //ライフゲーム第一世代作成	
  island l_Island = new island( l_Width, l_Height );	
  l_Island.randomize( l_Probability );
	
  while( true ) {
	
    l_Island.print();
    l_Island = l_Island.next();

    if( !PollEvent( l_Island ) ) break;

    SDL_Flip( g_Surface );
  }

  End();

  return 0;

}

bool PropertysCheck( string[] p_args, out int p_Width, out int p_Height, out int p_Probability ) {

  if( p_args.length <> 4 ) {
    writefln("Parameters Disposition Failed.\n1:Width, 2:Height, 3:Probability.");
    return false;		
  }
	
  p_Width         = toInt(p_args[1]);
  p_Height        = toInt(p_args[2]);
  p_Probability   = toInt(p_args[3]);
	
  if( (p_Width < 100) || (p_Width > 500) ) {
    writefln("Please Width length between 150 and 1000.");
    return false;
  }
	
  if( (p_Height < 100) || (p_Height > 500) ) {
    writefln("Please Height length between 150 and 1000.");
    return false;
  }
	
  if( (p_Probability <= 0) || (p_Probability >= 100) ) {
    writefln("Please Probability Value between 1 and 99.");
    return false;
  }
	
  return true;

}

bool Init( int p_Width, int p_Height ) {

  writefln("SDL Initialize.");

  if( SDL_Init( SDL_INIT_VIDEO|SDL_INIT_JOYSTICK ) < 0 ) {
    writefln("SDL Initialize Failed. : %s.", SDL_GetError());
    return false;
  }

  SDL_WM_SetCaption( "lifegame", null);

  g_Surface = SDL_SetVideoMode( p_Width, p_Height, 32, 
                                SDL_SWSURFACE //|SDL_FULLSCREEN );

  //SDL_ShowCursor( SDL_DISABLE );

  g_White = SDL_MapRGB( g_Surface.format, 255,255,255);
  g_Black = SDL_MapRGB( g_Surface.format,   0,  0,  0);
	
  return true;

}

void End() {

  writefln("SDL Finalize.");

  SDL_Quit();

}

bool PollEvent( ref island p_Island ) {

  SDL_Event l_Event;
  SDLKey*   l_Key;

  while( SDL_PollEvent(&l_Event) ) {

    switch( l_Event.type ) {
		
      case SDL_MOUSEBUTTONDOWN: {
			
        switch (l_Event.button.button) {
				
          case SDL_BUTTON_LEFT: {
            writefln("push Left x:%d y:%d", l_Event.button.x, l_Event.button.y );
            p_Island[l_Event.button.x, l_Event.button.y] = true;
          }break;
					
          case SDL_BUTTON_RIGHT: {
            writefln("push Right x:%d y:%d", l_Event.button.x, l_Event.button.y );
            p_Island[l_Event.button.x, l_Event.button.y] = false;
          }break;
					
          default: {
          }break;
        }				
      }break;

      case SDL_QUIT:{
        return false;
      }break;

      case SDL_KEYDOWN:{
        l_Key = &(l_Event.key.keysym.sym);
        if(*l_Key == 27) return false;
      }break;
			
      default:{
      }break;

    }

  }
  SDL_Delay(1000/30);

  return true;
}

久しぶりに目で動きが分かるプログラムを組んだ。
ライフゲームも初めて実装したから、なかなか楽しめてよかったー。


本当はもっとDっぽいテクニックが使えればよいのだけど、とりあえずって形で落ち着いた。
これで少しは道が広がったかしら。



何かありましたらご指摘お願いします><

気になったからD言語のGUI構築環境を作ってみる。(2008/05/18 修正版)

やり直したら色々と不安な所が出てきたので、加筆修正させて頂きました。



まず材料集め。

DMD(Ver 2.013)を取ってくる
http://www.digitalmars.com/d/2.0/changelog.html

DMC を取ってくる。
http://www.digitalmars.com/d/2.0/dcompiler.html#Win32

Entice Designer(Ver 0.8.5.02)を取ってくる。
http://www.dprogramming.com/entice.php

DFL(dfl-20080427.zip archive)を取ってくる。
http://wiki.dprogramming.com/Dfl/Snapshots



次にインストール。
(以下僕の環境で書くけれど、各々任意の場所で設定してください。)

  1. DMDを解凍する。("\dmd.2.013")
  2. DMCも解凍して、できた"\dm"フォルダを丸々"\dmd.2.013\dm"に上書き。
  3. 出来上がった"\dmd.2.013"を"\dmd"にリネームし、"C:\Installed_Programs\"以下に移動。
  4. 環境変数PATHに"C:\Installed_Programs\dmd\dmd\bin"と"C:\Installed_Programs\dmd\dm\bin"を加える。
  5. PCの再起動。
  6. DFLを解凍して、できた"\bin","\import","\lib","\packages"フォルダを"C:\Installed_Programs\dmd\dmd"以下に上書きする。
  7. コマンドプロンプトで【>cd C:\Installed_Programs\dmd\dmd\bin】と入力してディレクトリ移動。
  8. 【>dfl -i】と入力してDFLのパスを設定する。
  9. 【>dfl -dfl-build】と入力してDFLをビルド。(←ここか難所)
  10. Entice Designer を解凍して、できた"\Entice"を"C:\Installed_Programs\dmd"(注、"\dm","\dmd"があるフォルダと同じ階層)に移動。
  11. Entice Designer で適当なフォーム(myform.d)を作って保存。
  12. Menu->Project->Compile Command... に "dfl myform.d -gui" と入力。
  13. Compileする。(F7)

これでmyform.dと同じフォルダに.exeが出来て、実行してウィンドウが出れば完璧!



このインストール作業は、それぞれの材料のバージョンが上記の場合にしか動作確認をしていません。

現時点のDMD最新版である"Ver 2.014"でセットアップしようとしても、DFLのビルドでこける。
(僕はそれで環境の入れ直しをする羽目になりました・・・)

さぁ、Let's D Programming!