2015年12月28日月曜日

graphvizを使ってわかりやすいプログラミングを

はろはろ、セルディアです。

やだ…私のコード、汚すぎ…?


しばらく触っていないソースコードを見るときとかに、よく思います。

「この変数、色んな所に散らばってるけど、何のための変数なんだ…?」
「この関数、中身を変更したいけど、どこで呼ばれているんだ…?」
「ぎゃあ! 勘違いして処理を書き換えて、とんでもない動きをした!」

頭を抱えたくなります、そして昔の自分を小一時間問い詰めたくなります。

そんなことにならないように、少しでも理解を助ける資料があってもいいものです。

今回の便利グッズ


今回は「graphviz」を紹介します。

こいつは、テキストで書いたグラフ構造を、自動的に画像出力してくれるツールです。
様々な意味の点を定義して、点と点の繋がりを決めると、あとはえんやこらさして適切な配置で線を引いてくれるのです。

いったい何の役に立つのか、シューティングで一つ例を挙げてみます。




シューティングというゲームがどんな流れで実装すべきか、ちょっとした図でまとめてみました。
タイトル画面でボタンを押すと、メニューが出てきます。
一番左の流れは、ゲームスタートを押すと、機体選択画面へ、選択するとステージプレイ画面へ行きます。(実際の、十字キーで動いて、弾を撃って、弾を避けてっていう画面ですね)
その他、ステージセレクトやオプションにも行けます。

恐らく、プログラミングではこの流れを、関数やif文条件分岐で実装しますが、プログラムが大きくなってくると、パッと見ただけではこの流れがわかりづらくなります。逆に、パッと見ただけでわかる、という資料は、思っている以上にとても強い味方になります。
関数や変数の役割は、あるとき、ふっ…と忘れてしまうものなので、大まかな流れだけでも図に残しておきましょう。きっとミスや勘違いを減らしてくれます。

これは単なる使い方の一例ですが、想像力を膨らませていろんな使い方ができるようになると、もっとプログラミングが楽になるかもしれません。

簡単な使い方


実は上の図は以下のようにDOT言語で書かれています。

----------------sample.dot----------------------
digraph graph_name {
graph [
   charset = "UTF-8";
fontname="MS ゴシック";
]
node [
   charset = "UTF-8";
fontname="MS ゴシック";
fontsize = 14;
]
edge [
   charset = "UTF-8";
fontname="MS ゴシック";
fontsize = 10;
]
  TITLE [label = "タイトル画面"]
  MENU [label = "メニュー画面"]
  SELECT_PLAYER [label = "機体選択画面"]
  PLAY_STAGE [label = "ステージプレイ画面"]
  RESULT [label = "リザルト画面"]
  GAMEOVER [label = "ゲームオーバー画面"]
  ENDING [label = "エンディング画面"]
  SELECT_STAGE [label = "ステージセレクト画面"]
  PLAY_SELECT [label = "ステセレ用プレイ画面"]
  OPTION [label = "オプション画面"]
  
  {rank = same; SELECT_PLAYER; SELECT_STAGE; OPTION;}
  
  TITLE -> MENU [taillabel = "決定ボタン押下"];
  MENU -> SELECT_PLAYER;
  SELECT_PLAYER -> PLAY_STAGE;
  PLAY_STAGE -> RESULT [taillabel = "ステージクリア"];
  PLAY_STAGE -> GAMEOVER[taillabel = "残機0"];
  GAMEOVER -> TITLE;
  RESULT -> PLAY_STAGE [taillabel = "最終面以外"];
  RESULT -> ENDING [taillabel = "最終面クリア"];
  ENDING -> TITLE;
  MENU -> SELECT_STAGE;
  SELECT_STAGE -> PLAY_SELECT;
  PLAY_SELECT -> SELECT_STAGE;
  MENU -> OPTION;
  OPTION -> MENU;
}
----------------sample.dot----------------------

このdotファイルをコマンドプロンプト上で次のように指定します。

dot -Tgif sample.dot -o sample.png

これでグラフ構造を書いたテキストファイルから、画像出力できます。

(コマンドプロンプトを使わないGUI版もあるようですが、詳しく調べていないのであしからず)

参考サイト


Graphvizとdot言語でグラフを描く方法のまとめ
http://qiita.com/rubytomato@github/items/51779135bc4b77c8c20d
Graphvizでできることがわかりやすくまとめられています。
上から読むだけでGraphvizマスター。

Graphviz チュートリアル
http://homepage3.nifty.com/kaku-chan/graphviz/
もう少し詳しい、グラフとノードとエッジの仕様が書かれています。
思い通りの配置にしたいときに。

Graphvizで日本語を使う
http://d.hatena.ne.jp/simply-k/20100705/1278326617
日本語文字を使うときに嵌らないためのメモです。

2015年12月12日土曜日

HSPからCへのコード変換について

やはー、セルディアです。

ある日突然訪れる恐怖


HSPには、AndroidやiPhoneアプリを開発できるHSP3dishという環境があります。(何度目かの説明)
そして、HSP3dish Helperを使えば、さらに簡単にアプリを作れます。

しかし…それは突然やってくる…。

Helperのビルドを押すとエラーが出る日々が…!!

その原因は


Androidの場合は、ビルドしたときに、HSPからCへコード変換されたコードがプロジェクトフォルダにできます。
<プロジェクトフォルダ>\jni\hsp3embed
hspsource.cpp

このファイルを見ると、Cコードがぶつ切りのような終わり方になっています。
下手をすると、関数を閉じていないのにEOFが来ていたり…。まともなソースじゃない。

実際にコード変換しているのは、HSP3インストールフォルダにある「hsp3cnv.exe」です。
Dishからビルドするときにも呼び出されています。
果たしてこれが打つ手なしの詰み、あきらめてくださいになるのかと言えば、意外とそうではないです。HSPは開発にかかわる様々なソースを公開しています。

OpenHSP

今回のhsp3cnv.exeもソースが公開されていたので、うまく変換できるように改造できるか挑戦してみました。

具体的な手順


まずソースをビルドして実行ファイルを作れる環境を入手します。

あっさり言っていますが、一からやるとかなりめんどうです。
今回私はVisual Studio 2012 Expressを使いました。無料で使えますが、たぶんダウンロードしてインストールするまで、けっこう手順を踏みます。

実行ファイルを作れるようになったら、OpenHSPからhsp3cnvディレクトリのファイルをダウンロードします。そして、これをビルドするためにはhsp3ディレクトリのファイルも必要なので、こちらもダウンロードします。

これは、おそらく、になりますが、HSPからCへソース変換する過程のテキストデータはCHsp3クラスの中に抱え込んでいて、main.hspファイルの129行目のhsp3.SaveOutBuf( oname );で吐き出されている…と思います。

その変換過程のテキストデータを蓄えるバッファはCMemBufクラスで実装されているのですが、どうもこいつは文字列が長くなると、自動的にバッファを拡張する機能を持っているみたいです。こいつ自体に問題はなさそう。

いろいろソースを覗いたのですが、さすがに機能を全部解析するわけにもいかず、らちが明かず。

結局手あたり次第改造することにしました。

その結果、キャラ型配列変数が、バッファ用に適当に長さ4096で作られているのがどうも怪しいと感じ、これまた適当に伸ばしてみました。(4096->65536)
すると、ビルドしてできたhsp3cnv.exeを使って、無事にコード変換することができました。

改造箇所から考えると、ソースコードが一定の長さ以上になるか、コード変換時のなんらかのスタック処理が、変換処理の想定を超えてしまうとファイルがぶつ切りになってしまうようです。

最終的に力技になったけど気にしない!

ファイル配布


せっかく問題を解決できたので、できあがったhsp3cnv.exeを配布します。
BSDライセンスなので問題ない…ハズ。ライセンスは明記しときます。


ファイルを「hsp3cnv.exe」にリネームして、HSP3インストールフォルダのファイルを上書きしてください。(もちろん前のファイルは取っておいた方がいいですよ)

脅しのようにお決まりの言葉を載せますが、このファイルを使って起きた、いかなる問題にも私は責任を負いません。
あくまで自己責任で使ってください。

2015年12月1日火曜日

シューティング「空飛ぶ赤いワイン樽」

はろはろー、セルディアです。

今回のシューティングは


今回は「橙汁」様から出ている「空飛ぶ赤いワイン樽」を勧めます。

空飛ぶ赤いワイン樽(以下ワイン樽)は、トゥーン調のかわいらしい見た目でありながら、ゲーム性はかなり硬派な熱いシューティングです。

無制限弾数の「バルカン」と、弾数は限られながらも高威力で弾も消せる「ミサイル」の二つの武器を使って戦います。

難易度が三種類から選べるので、初心者でも上級者でも楽しめる内容となっています。


敵を倒すとコインが出てきて、たくさん回収するとミサイルが補充されていきます。
ミサイルは敵に当たると爆風が生まれ、敵にダメージを与えるとともに、敵弾も消してくれます。
バルカンだけでは心許ない火力なので、ミサイルをいかに使っていくかがカギになります。

ミサイルを敵に当てると倍率が上がり、スコアも上がってコインも多くなるため、ミサイルを撃ちまくって稼げば稼ぐほど、より攻略が楽になっていきます。高難易度では重要なテクニックです。



リプレイ


せっかく撮ったので、私のリプレイを添付します。


難易度:hard
スコア:8162219

各ステージ内訳



それなりにスコアを稼いでいます。それなり…