[Prev] [Home] [Next]
2002/04
29日
随分と間が開いてしまった。
そして、作ってた内容を忘れてしまった(爆)
一度整理しよう。
・これは実験プログラム(単なる趣味)。
・作るのは倉庫番。
(とっつきやすく奥が深そうだから)
・環境はDOS版でC言語。
(個人的に一番手軽な環境である為)
・オブジェクト指向(というかクラス指向)で作成。
・5階層(フロー、ロジック、デザイン、部品、環境依存部)
(クラス指向に階層化という構造化指向を組みあわせられるのだろうか)
・1日1コンパイル(単に実況中継的にできるかなぁ、と)
で、C言語でのコーディング規約を以下の通りとする。
・1クラス1ソースファイル
・関数名の先頭はクラス名イニシャルの1文字を大文字で、それ以降は小文字で。
(将来的には、その前に階層のイニシャルの1文字を大文字でつける予定)
・1からカウントする関数、変数は名称の最後に大文字のN。
・ポインタ/配列となる変数は名称の最初にアンダーバー。
・定数は#defineで大文字の文字列にて定義。
(将来的に変更の可能性あり)
・他関数と受け渡す定数はヘッダにて定義し呼び出し先/元それぞれでinclude。
(将来的に変更の可能性あり)
こう書いて見ると規約をあまり満たしてない・・・。
現在のクラスの階層関係は次の通り。
フロー :SOKOBAN.C / MENU.C −プログラム制御
ロジック:PLAY.C / LEVELSET −データ処理部
デザイン:OUTPUT.C / (INPUT.C) −入出力デザイン
部品 :(OUTPUT.C) / INPUT.C −汎用関数
環境依存:ENV.C −キーボード/画面/ファイルの制御
・・・こっちもあまり整理されていない。
ここまで書いて思ったが、将来的にというところは先にやってしまった方が楽だ。
という事で、規約を次の通り1部変更。
・定数はグローバル変数としてクラスの先頭で初期化。大文字の文字列にて定義。
・他関数と受け渡す定数は、呼び出し先のクラスの定数をヘッダにてextern宣言し、呼び出し元にてinclude。
これはjavaへの移植(するかどうかは未定だが)時に、次の様にする為。
C言語---
file:aa1.c(呼び出し先class:aa1)
struct aa1_{
int RET_OK;
int RET_NG;
} aa1;
void aa1init(){
/* この関数はどこかから初期化の為に始めに呼び出される */
aa1.RET_OK = 1;
aa1.RET_NG = 0;
}
int AAcalc(foo)
int foo;
{
if(foo < 100){
return aa1.RET_OK;
}else{
return aa1_RET_NG;
}
}
file:aa1.h
extern struct aa1_ aa1;
file:bb1.c(呼び出し元class:bb1)
#include "aa1.h"
void BBcalc()
{
int foo = 5;
int aa;
aa = AAcalc(foo);
if(aa == aa1.RET_OK){
XXcalc();
}else if(aa == aa1.RET_NG){
YYcalc();
}else{
ZZcalc();
}
}
java---
public class aa1{
final int RET_OK = 1;
final int RET_NG = 0;
int AAcalc( int foo){
{
if(foo < 100){
return RET_OK;
}else{
return RET_NG;
}
}
}
public class bb1{
void BBcalc()
{
int foo = 5;
int aa;
aa = AAcalc(foo);
if(aa == aa1.RET_OK){
XXcalc();
}else if(aa == aa1.RET_NG){
YYcalc();
}else{
ZZcalc();
}
}
}
---
なお、最終目標点であるバージョン1.0までの道のりは以下の通り。
-0.1
1levelだけプレイできる(済み)
-0.2
2levelプレイできsteplimitオーバーでエンド。2レベルクリアでオールクリア。
-0.3
プレイ中Aボタンでメニュー呼び出し。
メニューから、アンドゥ(1回だけ)、リトライ、タイトル画面へ戻る、が可能。
-0.4
無限回のアンドゥ可能(アンドゥはBボタン)
-0.5
プレイ中メニューからアンドゥ後のリドゥ可能。
複数レベル対応の仕組み。
-0.6
ファイルからのレベルデータ読み込み。
プレイ中メニューからレベルセレクト可能。
-0.7
トレースモード。
アバウト画面表示。
-0.8
プレイの手順を記録してファイルへ書き出し/読み込み。
-0.9
目標地点への自動移動を可能。
ヘルプ画面表示。
-1.0
設定ファイル対応。
グラフィック対応。
・・・道のりは長そうだ。
という事で本日の対応。
まずはlevelset.cのコンパイルエラーを直す為、Lcopytempのセミコロンを削除。
それから良く見るとy,x,ystart,xstartが定義されてないのでローカル変数として定義。
---ソース1(ファイル名:levelset.c)(一部)
/*-------------- 20020429-Berse */
Lcopytemp(templdata,ymax,xmax,_retldata)
int ymax,xmax;
struct leveldata templdata, *_retldata;
{
int y, x, ystart, xstart;
(*_retldata).steplimit = templdata.steplimit;
ystart = (BOTTOM_LIMIT-ymax)/2+2;
xstart = (RIGHT_LIMIT -xmax)/2+2;
for(y=0;y < ymax;y++){
for(x=0;x < xmax;x++){
(*_retldata).block[(ystart +y)][(xstart +x)]
= templdata.block[y][x];
}
}
}
---
本日のメインはsokoban.c。
Splaygame()を別のフロークラス(Fgame)として分割し、関数名もFGplaygameに変更。
新ファイルfgame.cができるが、内容については別途検討。
---ソース2(ファイル名:fgame.c)
/*******************************
SOKOBAN for DOS
fgame.c
Build:0001
Berse
(C)ThinkingRabbit
*******************************/
#include"level.h"
#define P_CLEAR 0
#define P_EXIT 1
#define P_RETRY 2
#define P_CHANGE_LEVEL 3
/*-------------- 20011214-Berse */
int FGplaygame()
{
int play,level, maxlevel;
struct leveldata ldata;
level = 1;
maxlevel = Lgetmaxlevel();
for(;;){
Lgetleveldata(level,&ldata);
Odispstatus(level, maxlevel, ldata.steplimit);
play = Pplaylevel(ldata);
if(play==P_CLEAR){
level++;
Oputstr(13,12,"+--------+");
Oputstr(13,13,"+ CLEAR! +");
Oputstr(13,14,"+--------+");
if(level > maxlevel){
Oputstr(13,10,"+--------+");
Oputstr(13,11,"+ ALL +");
Igetkey();
break;
}
Igetkey();
}else if(play==P_EXIT) break;
}
}
---
続いてsokoban.c本体をfsokoban.cに改名。main()関数を初期処理、メインループの呼び出しのみとし、Lsetlevelset()の呼び出しを初期処理にて行う様に変更。
その他、規約に従い変更する。
但し、menu.cで規定している定数については暫定的にこの中で定義する(アバウト画面、ヘルプ画面用の戻り値も)。
---ソース3(ファイル名fsokoban.c)
/*******************************
SOKOBAN for DOS
fsokoban.c
Ver. 0.2 Build:0016
Berse
(C)ThinkingRabbit
*******************************/
int M_TITLE_START = 0;
int M_TITLE_EXIT = 1;
int M_TITLE_ABOUT = 2;
int M_TITLE_HELP = 3;
struct ~fsokoban {
char *_VERSION;
int BUILD;
} fsokoban;
/*-------------- 20020429-Berse */
FSinit()
{
fsokoban._VERSION = "0.2";
fsokoban.BUILD = 16;
Lsetlevelset();
}
/*-------------- 20020429-Berse */
FSmainloop()
{
int menu;
for(;;){
menu = Mtitle(
fsokoban._VERSION,
fsokoban.BUILD);
if(menu == M_TITLE_START){
FGplaygame();
}else{
break;
}
}
}
/*-------------- 20020429-Berse */
main()
{
FSinit();
FSmainloop();
}
---
という事で久々のコンパイル!
実行ファイルの名前がfsokoban.exeになってしまったがオッケー。
実行! オッケー。バージョン0.2完成。
本日でのクラスの階層関係は次の通り。
フロー :Fsokoban.c / Fgame.c / MENU.C −プログラム制御
ロジック:PLAY.C / LEVELSET −データ処理部
デザイン:OUTPUT.C / (INPUT.C) −入出力デザイン
部品 :(OUTPUT.C) / INPUT.C −汎用関数
環境依存:ENV.C −キーボード/画面/ファイルの制御
・・・見直しの必要があるな。
[Prev] [Home] [Next]