こんばんは、川合です。 ZAKKI さんは 2002/07/17 18:34:11 の「[OSASK 4077] 絶対音感ゲーム 3.0」で書きました: >絶対音感ゲームをバージョンアップしました。 >http://zslash.s5.xrea.com/onkan.zip > >[OSASK 4073]での川合さんのアドバイスを取り込んでいます。 >結果、サイズがかなり縮みました。 >3.19KB(1.1)->2.32KB(2.0)->1.90KB(3.0) >1.1と比べるとかなりの差です。 喜んでもらえて嬉しいです。でもまだまだです。 >今度こそ最終版になりそうです。 ごめんなさい、先はまだ長いのです。ということで、テクニック紹介 第3弾です。 まず、プログラムを見ると、 lib_putstring_ASCII(0x0000, 0, 0, ****, 0, 0, ****); というパターンが非常に多く出ていることに気が付きます。ということ で、こんな関数を作りましょう。 void putstr(struct LIB_TEXTBOX *tbox, const char *str) { lib_putstring_ASCII(0x0000, 0, 0, tbox, 0, 0, str); return; } そしてこいつを代わりに使うことにしましょう。・・・これで少し縮む と思います。しかも読みやすくなるでしょう。そんでもって、start:前 後の > /*メッセージを表示(初回のみ)*/ > putstr(textbox, "ONKAN 3.0"); > putstr(textbox2, "SCORE:"); > putstr(scorebox, "00000000"); > /*判定の後ここに戻る*/ > start: > putstr(helpbox, "Hit Space "); の7行を以下のように書き換えます。 putstr(textbox2, "SCORE:"); restart: miss = score = 0; /* メッセージを表示 */ putstr(textbox, "ONKAN 3.0 "); putstr(scorebox, "00000000"); start: putstr(helpbox, "Hit Space "); ここで、missとscoreの0の代入をやっているので、/*変数*/のところで の代入はやめます。宣言だけにします。 で、こうすると、gameover:のところで表示やmissなどの再代入を記 述することなく、goto restart;でOKになります。 修正個所はあと少しです。プログラムを見ると、getsignal()を使う ときはいつでも0以外のシグナルが来るまで待機していることが分かり ます。それなら、getsignalを書き換えて、以下のような関数にしてし まいましょう。 const int getsignalw() /* 0が返されたら、シグナルなし */ { int signal; /* シグナルがなければ来るまでスリープ。シグナルがあればスリープしない */ lib_waitsignal(0x0001, 0, 0); if (*sig_ptr == REWIND_CODE) { /* REWINDシグナルを受け取った */ /* 直後の値の分だけシグナルを処理したことにして、ポインタを先頭に戻す */ lib_waitsignal(0x0000, *(sig_ptr + 1), 0); sig_ptr = signalbox0; } signal = *sig_ptr; if (signal != 0) { sig_ptr++; /* 1シグナル受け取ったことをライブラリに通知 */ lib_waitsignal(0x0000, 1, 0); } return signal; } これを使えば、プログラムがすっきり書けます。たとえば、スペース キーの入力を待つループは(start:とgameover:のところにありますね )、 while (getsignalw() != 9); と書けます。だからgameover:のところは、こうなります。 while (getsignalw() != 9); goto restart; 関数beep()のところでは、 while (getsignalw() != 10); になります。 /*キー操作受付*/のところは、 do { num2 = getsignalw(); } while (num2 > 8); /* num2が0や1になる事はないから */ num2--; それと、ラベル「judge:」はもう不要なので、消しちゃいましょう。 これだけ直すと、まあまあ変わるでしょう。ところで、直せるところ はまだあります。だからまだ「最終版」って書かないでおいてください (笑)。 ええと、もしうんざりしちゃったらごめんなさい。今のレベルでもバ イナリサイズとしては十分なので、面倒だからもう改良したくない、っ ていうのはありです。でも、Cのソースとしては無駄が多いので、ZAKKI さんに「普通はこういう風に書くのか」と知っておいてもらいたいと思 っただけなんです。おせっかいですみません。 ちなみに僕がこういうレクチャーをするのは負担ではないか、とは思 わないでください。僕にとっては、こんなのは暇つぶしレベルです。休 憩です。だから負担になるどころかリフレッシュしています。楽しんで やっていますので、心配なさらないでください。 ついでに次回予告としては、start:やgoto start;をなくしたりgameo ver:やgoto gameover;をなくしたりします(今回作ったrestartもなく なります)。gotoをなくしたいとのことでしたので、これは楽しみにな るんじゃないでしょうか? ちなみに最終的には、1.0KBくらいになると思われます。ゲームの内 容からすると、そんな感じです。もちろん、読みにくくなるような過激 な最適化はしません(そんなのはC言語の勉強にはなりませんから)の で、ご安心ください。 それでは。 -- 川合 秀実(KAWAI Hidemi) OSASK計画代表 / システム設計開発担当 E-mail:kawai !Atmark! imasy.org Homepage http://www.imasy.org/~kawai/