ZAKKIです。 >ていうのはありです。でも、Cのソースとしては無駄が多いので、ZAKKI >さんに「普通はこういう風に書くのか」と知っておいてもらいたいと思 >っただけなんです。おせっかいですみません。 C言語自体まだまだ勉強中なので、いろいろ教えてくださって とてもありがたいです。 > ついでに次回予告としては、start:やgoto start;をなくしたりgameo >ver:やgoto gameover;をなくしたりします(今回作ったrestartもなく >なります)。gotoをなくしたいとのことでしたので、これは楽しみにな >るんじゃないでしょうか? とりあえず自分で考えてみました。4.0に組み込んでいます。 ---------------------------- ZAKKI http://www3.to/zslash/ mailto:zakki !Atmark! yacht.ocn.ne.jp ---------------------------- >-----Original Message----- >From: Hidemi KAWAI [mailto:kawai !Atmark! imasy.org] >Sent: Wednesday, July 17, 2002 9:20 PM >To: OSASK-ML >Subject: [OSASK 4081] Re: 絶対音感ゲーム3.0 > > > こんばんは、川合です。 > > >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/ >