h.nkgwのメモ書き

自分のためのメモです

久しぶりにrogueのソースを見てみた話

この記事は Roguelike advent calendar 2019 8日目の記事です

今からrogueのソースを読んでみようという人が、全国に1人か2人はいるかもしれないので、その人向けの文章です。

今の時代に独学でC言語を独学で学ぶのに適したソースかといえば、分量もまあまあだし、趣味で休日にコンソールベースゲームを作りたいという事であれば参考にはなると思うが、今ならもっと目的に適した言語もあるし、また仕事でC言語が必要なのでという事なら、もっと参考にするには適したソースがあるでしょうから、単なる自分の記憶の間違い探しをしたいだけというのが真相です。

自分がrogueのソースを読んだきっかけ

学生の頃、C言語の勉強を始めたときに、最初に眺めたのがrogueのソースでした。そもそも最初に見たソースがrogueというのは不幸の始まりだったと思うのですが当時は趣味でゲームが作りたかったというだけだったので、まあ仕方がないかな。

当時はインターネットとかなかったし、別の所でプログラミングを学んでいたら、おそらく違う所から初めていたと思う。

ソースを取得する

ネットを調べてみると、rogueのソースもいろいろある感じでした。自分が学生の頃は「ローグのソースは残っていない」という事で、rogue cloneなるものが出回っており、自分はrogue clone 2 のソースを見てでいました。とりあえず、前に近い物ということで、いくつか見てみたのですが、ubuntuのリポジトリに含まれるものが近かったのでそれをベースに振り返りたいと思います。ちなみにbsdgames-nonfreeはrogueしか含まれておらず、それ以外は無印のbssdgamesに入っています。

全体構成

ソースファイルは約20ファイル、ヘッダはrogue.hに大体定義されている模様。古いC言語のために char を unsigned charに読み替えるようにマクロかdefineが切られていたのがなくなっており、昔のようなトリッキーさは消えている模様。あと、cursesライブラリが無い場合のため、最低限の機能を代替え的に実装していたソースもなくなっていた。昔みたいに様々なコンパイラを相手にする必要がなく、C言語の規格も定まってきたという事なのでしょう。clone版は古い関数の定義方法で書かれているので、そこさえ気にしなければ比較的見やすく書かれていると思います。(少なくともオリジナルと思われる方のソースは、中カッコが不要な所はすべて省かれている感じなので、初心者が真似をすると思わぬところではまる可能性が高い)

読み進め方

ヘッダがrogue.hのみでグローバルに使用する定数、構造体、関数の宣言が書かれているので比較的全貌は把握しやすいです。ただ、objectという構造体で敵とすべての種類のアイテムを表現しているので、ソースの中のobjectが何かを意識する必要があるが、逆に敵とアイテムで共通の処理を書くためには(C++のような継承もないので)便利だったからだと思います。

mainはシンプルで、引数処理を行ったあとは、無限ループがあるだけだ。ただ注意しなければいけないのはinitで初期設定を読んだ後はいきなりフロアの設定を行わずプレイ状態に入ることだが、これは中断したデータを読み込んだ時の処理だったと記憶していますが、ちがったらごめんなさい

次に見るべきは、play.cで、ここには実際のキー入力したときのイベント処理が記されている。イベント処理といっても、getcharでとってきた文字をひたすら大きなswitch文で分岐するものなので、キーバインドを書き換えたいのならば、ここを書き換えればよい、ただし方向キーはここ以外にmove.cのis_directionを書き換えないとおかしなことになるので注意が必要です。

参考にできる点

自分はリスト構造という言葉を知る前にrogueのソースを読んだので、細かくポインタの操作を追っていたのですが、単方向リストの実装としては普通だと思うのでいつもはC++のlist等を使用していて、templateは解析がめんどくさいというならば、簡単な実装例としてみるのはよいかもしれない。また、mallocしたobject構造体は不要になっても捨てずに、free listにとっておいて、free listが空でないときはmallocせずにそこから使うという工夫は、昔のメモリが少ない(そしてmalloc/freeを繰り返すのに躊躇される環境)では参考になるのではないかと思います。

終わりに

プログラム的には今でも初心者がC言語を学ぶときに読むソースとしてはよい教材だと思います。簡単な改造をして遊ぶのも、リアルタイムゲームに比べて動きが想像しやすく、市販ゲームの罠とか攻撃とかを参考にしていろいろ組み込めると思います。(ただしモンスターを増やすのは少し面倒ですが…)

ただやはり、趣味でやるなら別の言語の方が楽ちんだし、仕事ならもっと良いソースがあるということで、素人にはおすすめしません

 

結論 - rogueにはまった廃人以外は読まなくてもよいよ

 

Roguelike Advent Calendar 2019に参加します

仕事も少し暇になってきたので、以前からやってみたいと思っていたアドベントカレンダーに参加してみました。

(息子は毎日チョコ食ってますが)

 

あまり人がいなかったローグ関係のアドベントカレンダーを見つけたので初心に帰ってローグのソースを久しぶりに読んで、思った事をつらつらと書いてみる事にします

 

ttps://adventar.org/calendars/4601

Terminal.app (gnustep)の日本語設定

日本ではほとんど利用者がいないと思われるGnustep純正ターミナルアプリTerminal.appの日本語設定方法です。

いつの間にか日本語使えるようになっているのですが、デフォルト設定だと日本語使えなかったり、メニューが英語なので気づかない人が多いと思います。 

  • 設定ダイアログを開く (Info-Preferenceの順に選択)
  • linux perserの項目から言語指定をUTF-8にする(残念ながらEUC等の設定は無い)
  • displayの項目からHandle wide (multi-cell) glyphsにチェックを入れる。
  • フォントを日本語フォントに変更(IPAゴシックやTakaoゴシック等)
  • 一旦 Alt+Qでプログラムを終了してから再起動

これで動くはずです。

 

あと、日本語リソースを作ったので、下記のURLからJapanese.lprojを取ってきてTerminal.app/Preferences/にコピーするとメニューが日本語になります。

 

github.com

 

古いマシンの活用のためLinuxを入れるという古い話

工人舎のSRというDVD搭載の10年ぐらいのマシンをなんとか動かそうとした記録です。

最近、32ビットの場合はPAE対応でないと動かないものが増えてきたので、色々試したところ、LMDEがインストールできたのですが、使われているパッケージが古いので、source.listをいじってdebianのバージョンを上げる。

/etc/apt/source.listの中身を見たところ、

 

#/etc/apt/source.list

と1行書かれていただけだったので、そこは諦めてフォルダ無いを探したところ、/etc/apt/source.list.d/offical-package-repositories.listがあったので、debianのソースをsidに変更して、linuxmintのソースをコメントアウト

 

apt update ; apt-get dist-upgradeしたあとに、testingにしたほうがよかったのではないかと後悔。

 

後悔しても仕方がないので、重くて使えなかったcinnamon関連を削除して、lxdeとかtwmなど、軽そうなウィンドウマネージャを入れて使ってみる。

今日はこれまで

 

 

 

タイマーを追加する

せっかくのなので、C++11っぽくchronoとthreadを使ってタイマーを追加してみました。

時間は最初にクリックした時から秒表示を999秒まで行うというWindowsマインスイーパーをまねした感じの仕様にしました。説明を読む限り、sready_clockの方がよいと思うのですが、使い方がわからなかったので、system_clockを使い、開始の時刻と現在時刻を引いたあとに秒に直すという事を行っています。

実際にプレイしてみると、画面が広くてまどろっこしいででサイズ指定ができるようにしたいのと、あと、キーバインドを何も考えずにローグ互換にしてしまったので、ほとんどの人がロクにプレイできないという代物なので、キー設定をなんとかしたいと思います。

 

github.com

cygwinでビルドができなかったので直す

先日のマインスイーパーだが、どうやらCygwinではビルドが出来ないようで、とりあえず修正。time()とtolower()が見つからないのはヘッダファイルを追加して、gcc -> g++に変更、その後ライブラリをcurses -> ncursesにして、リンクは最後に持ってくる感じでビルドがとおるようになった。

更に初回起動時に爆弾の残りが表示されていなかったので、少し手直しをした。

 

今日は遅いのでこれぐらいにして続きはまた明日

githubに登録してみた

先日のマインスイーパーのプログラムをgithubの使い方の勉強がてら、登録してみた。

 

以前アカウントだけ作ったgithubにログインして、start a projectを選択。非公開プロジェクトにしたかったのだが、有料コースでないと非公開では作れないので公開を選択してリポジトリを作成。

ここからはローカルのMacで git clone のパラメータにページに現れたURLを指定してローカルにクローン、先日作ったファイルをコピーしてgit add してコミット、さらにpushという事でなんとか公開はできる感じ。

 

最初の更新は、前回は作らなかったタイマーをつけるのかな?

github.com