Short Program (モグラたたき)
ゲームを作ったことのある人なら、おそらく誰もが一度は作ったことがあると思いますが、
往年の由緒あるゲーム「もぐらたたき」を作制してみます。今回のソースはLSIC用です。
1 ゲームの内容
まずは、シンプルなゲームにするために、アルファベットをモグラに見立てることにします。
'A' が表示されたら、A のキーを押すことによりモグラをたたいたことにします。
モグラたたきというよりは、キー打ちの練習のようなものですが、まあ、勘弁してください。
少しゲームらしくするために、制限時間を設け、たたいたモグラの数をカウントすることにします。
モグラは、ランダムに出現しますが、最大同時に出現する数は20とします。
モグラの出現は乱数により決定します。
モグラの出現から消えるまではターン制とし出現時間は20ターンとします。(20ターン後に消える)
また、それだけではつまらないので、11ターン以降は無敵モグラに変身(文字色を変化させる)する
こととし、無敵モグラになると、たたいてもやられないということにします。
たたかれたモグラは * 表示し、ターンを17ターン目にします(すなわち3ターン
* 表示されている)
まとめると以下の様です。
モグラ出現−−−−−>11ターン−−−−−−−−−−−−−−−−>20ターン
| 無敵モグラ モグラ消える
|
たたく−−−−−−−−−−−−−−−−>17ターン−−>20ターン
*
表示 消える
実行画面は下のような感じです。赤で表示されているのが無敵モグラです。
(LSICでコンパイルしたDOS/V用のバージョンは無敵モグラは反転表示で表示されます。
TurboC でコンパイルした PC98用、DOS/V 用は無敵モグラは赤色で表示されます)
****アルファベットもぐらたたき ver 0.01***** coded by Tsuyoshi Kasai for LSIC-86 らんだむに表示するアルファベットのもぐら(A−Z)と同じキーを押して下さい 時間がたつともぐらは反転文字になります。この反転文字もぐらは無敵になります キーは大文字にして下さい 制限時間 40 マシンウェイト(1000−3000が標準) 2000 残り時間 : 0 COUNT : 31 * * M X K THE END!! C:\C> |
2 プログラム
プログラムはLSIC用です。LSICでコンパイルされた実行ファイルは DOS/V,
PC-98両方で動きます。
(1) 初期化
まずは、初期化の関数です。
void init() /*初期化*/ {long nowt; long t; /* window(1,1,80,24); */ printf("\x01b[2J"); /*画面クリア*/ printf("\x01b[>5h"); t= time(&nowt); srand(nowt%3600); } |
Window関数はTurboC用なのでLSIC用ではコメント 画面クリアのエスケープシーケンス カーソル消去のエスケープシーケンス t に現在時刻取得 乱数発生系列の初期化 |
LSICには画面制御関連の関数がない(おじさんが知らないだけ?)ので、画面クリア、カーソル消去は
エスケープシーケンスで行っています。
srand で乱数のシードはもとめた現在時刻(システムクロック)を3600で割った余りをあてています。
(2) 画面上の表示位置
TurboC では文字の画面表示位置の指定には、 gotoxy という便利な関数がありますが、LSICには
見当たらないので、これもエスケープシーケンスで実現しています。
(BASICでいうところの Locate)
locate 関数にx,y 座標を引数として渡します。
void locate (tx,ty) int tx,ty; { printf("\x1b[%d;%dH" ,ty,tx); } |
(3) 文字色の設定
テキスト文字色の設定には、TurboCでは textcolor という関数がありますが、LSICにはこれも見当たらない
ので、エスケープシーケンスで実現しています。
color 関数に 表示文字の属性を引数として渡します。7をわたすと反転表示になります。
void color(col) int col; {printf("\x01b[%dm",col);} |
(4) モグラの出現
void appear(n) int n; {int r,d; d=32767/26; if (rand()<2000) { r=rand()/d; m[n][0]=r+65; st[n]=1; locate(n*2,10);putch(m[n][0]);}} |
rand()<2000 ならモグラ出現 確率 2000/32767 = 約6% rは0〜25まで。アルファベットのアスキーコード(大文字)の決定 モグラの状態 st=1 出現 |
LSICでは 乱数発生の関数' rand() は32767までの整数を発生します。
必要な乱数を得るため、適宜加工します。
変数 st はモグラの状態を現わす変数です。実際は各モグラのターンを入れます。
0は消えている状態
1で出現
10以降無敵モグラ状態
20で再び消える
というわけです。
(5) メインルーチン
まずは初期化の部分です
main(){ int i,j,k,t,wait; time_t start,interval; for (i=1; i<=num; i++){ /*変数初期化*/ st[i]=0;m[i][1]='\n';} init(); printf("\n****アルファベットもぐらたたき ver 0.01*****\n coded by Tsuyoshi Kasai for LSIC-86"); printf("\nらんだむに表示するアルファベットのもぐら(A−Z)と同じキーを押して下さい\n"); printf("時間がたつともぐらは反転文字になります。この反転文字もぐらは無敵になります\n"); printf("キーは大文字にして下さい 制限時間 %d",timelimit); printf("\nマシンウェイト(1000−3000が標準) ");scanf("%d",&wait); |
以下はゲームの骨格部分です
time(&start); for (;;){ for (i=1; i<=num; i++){ if (st[i]==0) {appear(i);continue;} st[i]++; if (st[i]==10) {color(7); locate(i*2,10);putch(m[i][0]); color(0); continue;} if (st[i]==20) {locate(i*2,10);putch(' '); st[i]=0;} } /*キー入力(モグラをたたく)の処理*/ while(kbhit()) {int c; int n; c=getch(); for (n=1;n<=num;n++){ if (c==m[n][0] && st[n]<10 && st[n]>0) { count++; locate(1,9);printf("COUNT : %d",count); locate(n*2,10);putch('*'); putch('\x07'); st[n]=17;} }} /*終了判定 */ for (j=0;j<8000;j++){for (k=0;k<wait;k++);} time(&interval); t=(unsigned int)difftime(interval,start); locate(1,8);printf("残り時間 : %3d",timelimit-t); if (t>=timelimit) break;} locate(1,12);printf("THE END!!\n"); printf("\x01b[>5l"); } |
&start にゲームスタート時間を入れる この for (;;) は ・・・(a) までが範囲 各モグラ(num=20まで)の処理 出現関数をコールし、continueで次のモグラの処理に移る ターンを一つ増加 ターン10になったら 表示反転(−−>無敵モグラ) 表示 表示属性を元にもどしておく ターン20ならモグラ消える キー入力チェック キーコードの取得 各モグラに対して処理 キーが一致しており、普通の状態のモグラなら−−>たたいた countを増加 * たたいた印の表示 Beep音 ターンを17に ウェイトをかけている 関数difftimeで経過時間とスタート時間の差をとる 残り時間の表示 タイムリミットなら終了 ・・・・(a) main 終わり |
短いプログラムなので全リストつけておきます
/*アルファベット(A−Z)モグラたたき ver 0.01−−coded by Tsuyoshi Kasai for LSIC*/ #include <stdio.h> #include <stdlib.h> #include <time.h> #define timelimit 40 #define num 20 void locate (int,int); void init(); void appear(int); void color(int); char m[num][2]; int st[num],count; main(){ int i,j,k,t,wait; time_t start,interval; for (i=1; i<=num; i++){ /*変数初期化*/ st[i]=0;m[i][1]='\n';} init(); printf("\n****アルファベットもぐらたたき ver 0.01*****\n coded by Tsuyoshi Kasai for LSIC-86"); printf("\nらんだむに表示するアルファベットのもぐら(A−Z)と同じキーを押して下さい\n"); printf("時間がたつともぐらは反転文字になります。この反転文字もぐらは無敵になります\n"); printf("キーは大文字にして下さい 制限時間 %d",timelimit); printf("\nマシンウェイト(1000−3000が標準) ");scanf("%d",&wait); time(&start); for (;;){ for (i=1; i<=num; i++){ if (st[i]==0) {appear(i);continue;} st[i]++; if (st[i]==10) {color(7); locate(i*2,10);putch(m[i][0]); color(0); continue;} if (st[i]==20) {locate(i*2,10);putch(' '); st[i]=0;} } while(kbhit()) {int c; int n; c=getch(); for (n=1;n<=num;n++){ if (c==m[n][0] && st[n]<10 && st[n]>0) { count++; locate(1,9);printf("COUNT : %d",count); locate(n*2,10);putch('*'); putch('\x07'); st[n]=17;} }} for (j=0;j<8000;j++){for (k=0;k<wait;k++);} time(&interval); t=(unsigned int)difftime(interval,start); locate(1,8);printf("残り時間 : %3d",timelimit-t); if (t>=timelimit) break;} locate(1,12);printf("THE END!!\n"); printf("\x01b[>5l"); } void init() /*初期化*/ {long nowt; long t; /* window(1,1,80,24); */ printf("\x01b[2J"); /*画面クリア*/ printf("\x01b[>5h"); t= time(&nowt); srand(nowt%3600); } void locate (tx,ty) int tx,ty; { printf("\x1b[%d;%dH" ,ty,tx); } void color(col) int col; {printf("\x01b[%dm",col);} void appear(n) int n; {int r,d; d=32767/26; if (rand()<2000) { r=rand()/d; m[n][0]=r+65; st[n]=1; locate(n*2,10);putch(m[n][0]);}} |
ソースファイルと実行ファイルは、ショートプログラム集に置いて有ります。
また、エスケープシーケンスについては、関連サイト(!)ラピュタへの道/エスケープシケンスを参照して下さい