イースマイル株式会社 : Human is designed. デザイン[design]するイースマイルです。
E-Smileってどんなとこ?
ホーム サイトマップ

まず初めに・・・

私のプログラミングのコツを伝えられれば・・・という思い。

    新人教育でいつも感じることは、プログラムを書く能力はあっても、最後まで完成しないことです。
    あと少しのところまで出来るのですが、そこから先になかなか進めず、時間がかかってしまいます。
    その原因の多くは、設計が曖昧だったり、逆にプログラムが複雑過ぎてしまったりなど様々ですが。
    何はともあれ、ある程度までは完成しなければ、ゲームの製品にはなりません。
    いつも途中で行き詰ってしまう。そんな人の役に立てればと思い、私のプログラム作成方法を紹介してみたいと思います。
    

アセンブラから始めた経験が重要・・・かも??

    自分がプログラムを始めたのは、18年前です。当時のゲーム開発の言語は、アセンブラでした。
    ファミコンやPCエンジンでは、6502、メガドラは68000、ゲームボーイやゲームギアは、Z80系です。
    C/C++、JAVAなどの高級言語とは全くことなり、アセンブラは、まさしく低級言語です。
    そんな言語から始めた理由からなのか、私の書くプログラムの処理単位は、とても単純です。
    アセンブラでプログラムを書いた経験がある方なら、想像できると思いますが、
    汎用レジスターという変数を格納する場所が、数個あるだけですから、
    極端に言うとメモリーから読み出して、アキュームレーターで計算をしたら、また直ぐにメモリーに保存するしかないのです。
    当時のゲームボーイなどは、A80系といって、同じZ80系ですが、命令体系にIXとIYレジスターがありません。
    となると、汎用レジスタは、A、B、C、D、E、H、Lレジスターのみ。裏レジは、あったかも?
    例えば、10バイトのメモリーコピーのプログラムは、下記のような感じになります。
    
    	ORG	8000H
    _INIT:	LD	HL,8100H	;アドレス8100番地
    	LD	DE,8200H	;アドレス8200番地
    	LD	C,10	;ループカウンターに10を代入
    _LOOP:	LD	A,(HL)	;HLのアドレスから、Aレジスターに1バイト読み込む
    	LD	(DE),A	;Aレジスターの値を、DEのアドレスに格納
    	INC	HL	;HLレジスターをインクリメント 8100番地から次は、8101番地
    	INC	DE	;DEレジスターをインクリメント 8200番地から次は、8201番地
    	DEC	C	;カウンターを、デクリメント
    	JP	NZ,_LOOP	;0フラグのビットが立っていない場合は、_LOOP 処理
    	END
    
    ※ Z80 シミレーターは、こちらから、ダウンロード可能です。
    
    極端な例ですが、こんな単純なプログラムのみで、当時はゲームを作成したものでした。
    従って複雑な処理を行なうときは、一度保存したデーターから再度読み込んで、計算しては、また保存するという。
    その繰り返しによって、複雑な処理を実装していたのです。
    
    そんな環境でアセンブラのプログラムを10年も作成してきた結果、
    私のプログラムスタイルは、データーテーブルや、データー保存用メモリーを多く確保しています。
    C言語いうところの配列や構造体のポインターなどを多用しております。
    またローカル変数も、少ないレジスターでの経験からか、とても少なめです。
    そしてプログラム自体は短く、ひとつの関数処理は、殆ど10行以下です。長くても20行ぐらいでしょうか。
    そんな訳で、私のプログラムは、とてもシンプルです。ループも、for しか使いませんし、3重ループなんて滅多に書きません。
    

高級言語は、容易に変数定義が書ける為、逆に多くの処理を書きすぎて、複雑化してしまう。

    この後で紹介する予定のトランプの婆抜きゲームのプログラミンについてで言えば、
    揃ったペアーのカードを捨てる処理があるとします。
    普通に考えると、揃ったカードを捨てるのには、カードペアーの判定を行い、
    次に揃ったカードを捨てて、最後に、カードソートするという処理を考える訳です。
    
    勿論、処理全体としては合っていますが、これを一気に処理するプログラムは、かなり複雑なものになってしまいます。
    そこでこれらの処理を、なるべく分けて、プログラムを作成したいと思います。
    
    ,泙此▲ードと同じ要素の配列を用意して、揃ったカードにフラグを立てること。
    int card_buff[10] = { A,A,2,3,4,4,6,8,9,9 };
    int pare_flag[10] = { 1,1,0,0,1,1,0,0,1,1 };
    
    ⊆,法揃ったフラグから、カードを捨てること。0で上書きする。
    int card_buff[10] = { 0,0,2,3,0,0,6,8,0,0 };
    int pare_flag[10] = { 1,1,0,0,1,1,0,0,1,1 };
    
    最後に、カードバッファーをソートすること。但し、別途ソート用のバッファーを持って、まずはコピーすること。
    int card_buff[10] = { 0,0,2,3,0,0,6,8,0,0 };
    int card_sort[10] = { 2,3,6,8,0,0,0,0,0,0 };
    
    い△箸蓮card_sort から、card_buff にコピーして終了です。
    結果、pare_flag 配列と、card_sort の2つのテンポラリー用のバッファーを消費しますが、
    ひとつひとつの処理は、とても単純な処理になります。
    
    ※,離廛蹈哀薀
    void pare_check()
    {
    int i;
    	for( i = 0; i < sizeof(card_buff)/sizeof(int) ; i++)
    	{
    		pare_flag[i] = 0;	// バッファークリアー
    	}
    
    	for( i = 0; i < sizeof(card_buff)/sizeof(int) ; i++)
    	{
    		if( card_buff[i] == card_buff[i+1] ) {
    			pare_flag[i] = pare_flag[i+1] = 1;
    			i++;	//	揃っていたら、ひとつ飛ばす。
    		}
    	}
    }
    
    	pare_check();	//	.撻◆爾鬟船Д奪、1を立てる
    	pare_fill();	//	▲撻◆爾鬘阿脳綵颪
    	pare_sort();	//	フラグを参照しながら、別バッファーへコピー
    	card_copy();	//	い發箸離丱奪侫 爾北瓩后
    
    

別のバッファーを複数設けて、処理を単純化する。

    さて、^奮亜↓↓い蓮△澆覆気鷦力で作成してみましょう。
    そして最後に、´↓い鯱続して呼び出せば完成します。
    さてみなさんは、どんなプログラムを最初に考えましたか。
     銑い泙任劼箸弔隆愎瑤悩鄒してしまっている方も多いかも知れません。
    完成していれば、それでもいいのですが、もしバグ取りに時間がかかっているなら、
    私のように単純な処理に分解してみては、如何でしょうか?
    別バッファーを設けることによって、途中経過も分かりますから、デバッグも容易になります。
    是非、思い当たる節があるなら、私の方法をお試し下さい。
    
Human is designed.
基本概念
まず、初めに
データー構造を考える
婆抜きゲーム
ポーカーゲーム
Android Program
Web Program
3D Program
Linux Server

イースマイル株式会社
〒103-0016 東京都
中央区日本橋小舟町8-6
新江戸橋ビル4F
TEL.03-5652-5566(代)
FAX.03-5652-5358
[地図] [お問い合わせ]


(C)2005 E-Smile., Co, Ltd. All rights reserved.