野狐消暇録

所感を記す

平行処理の勉強を始めた。

最近時間が出来たので、平行処理の勉強を始めた。

まずは、結城浩氏の『増補改訂版 Java言語で学ぶデザインパターン入門 マルチスレッド編』を読んでる。

www.amazon.co.jp

昔読みかけて、途中で読まなくなった本だ。

他にもいくつか昔買ったマルチスレッド関連の本が自宅にあるので、順番に読んでいこうと思う。例えば、以下である。

www.amazon.co.jp

これはJavaに慣れているので、まだ読めそうだけど、次の本は、プログラミング言語Haskellなので、その辺りがハードルにならないといいなと思う。

www.amazon.co.jp

次の本は持っていないけど、買うかもしれない。

www.amazon.co.jp

 

市販されている本に載っている事は、マルチスレッドに関して基本的な話題だろうから、まずはそこを押さえたい。

それから先は、やるかどうか、またその時に考えようと思う。

平行処理は、自分にとって、レベルの高い話題である。レベルが高い話題だから、僕の仕事で使わないかというと、それが結構出てくる。案外仕事でぱっと要求される知識なのである。そういう点で、純粋に知識を学ぶという事でなく、すぐに実践が待っている話題である。

他にも、仕事で必要であるにも関わらず、ちゃんと理解していない話として、DB,Web,ネットワークの知識などがある。この辺りをこれから重点的に取り組む予定である。

少し仕事が安定してくれそうなので、この機会にできるだけ勉強を進めておきたいと思う。次にいつ時間ができるか、分からない。

『新・世界樹の迷宮2 ファフニールの騎士』に挫折しました。

3DSで発売された、ダンジョンRPG新・世界樹の迷宮2 ファフニールの騎士』を70時間ぐらいプレイしたのですが、途中で投げてしまいました。

理由はボスが強過ぎるためです。

空の城にいるボス敵「オーバーロード」の第二形態を倒すのが面倒になりました。

挫折したとはいえ、折角買ったソフトなので、難易度を「スタンダード」から「ピクニック」に下げてエンディングまで見ました。難易度「ピクニック」で進めると、敵がとても弱いのです。

最初、自分は難易度「スタンダード」でクリアするつもりで、途中のボス敵「炎の魔人」が強かった辺りから、Webサイトの攻略情報を見始めました。

新・世界樹の迷宮2 ファフニールの騎士 Wiki - トップページ

新・世界樹の迷宮1 ミレニアムの少女」をプレイした時は、攻略を見れば勝てたのですが、攻略情報を見ても『新・世界樹の迷宮2 ファフニールの騎士』は難しい。

それで、ついにゲームを投げる時、いつも感じるあの気持ちがやってきました。

「なぜ、俺はゲームで苦労せねばならないのか。ゲームは楽しみでやるものではないのか」

それで、自分は『新・世界樹の迷宮2』をプレイする事を止め、別のゲームを買って遊びました。

しかし、しばらく経つと、途中で止めた事が残念に思えてきました。どうも勝ちたい。最後までやってみたい。

それで再度挑戦する事にしました。

その時、難易度を下げれば勝てるという事に気が付いたのですな。

それでいいのか、という気もしたのですが、ともかくエンディングまでいければそれでいいと思って、そうしました。

そうやってエンディングを見た後、ぼんやりとネットの海を彷徨っていると、『新・世界樹の迷宮2』を猛烈に罵っているサイトに出くわしたのです。

新世界樹の迷宮シリーズ 葬式 Wiki*

ここに書かれている事を熟読するうち、少しづつ分かってきました。

コンピュータゲームはプログラムです。

僕はプログラマです。

プログラムについては、素人より詳しい。少なくとも、僕の母よりは詳しいのです。

それで、専門家である僕の考えを述べると、プログラムというのは、複雑になりやすいのです。

パラメータが増えると、それだけ可能な状態の数が増えるため、扱いにくくなる。

どうも読んでいくうち、自分が途中で嫌になった理由が分かりました。

このゲームはパラメータの調整に失敗したようです。

「FORCE」というゲーム中に出てくる必殺技ゲージを溜めて放つ技を使用する事を前提としてゲームバランスを組んでいる。グリモアというこれもまたゲームに出てくるアイテムを使って、スキルレベルを上げる事を前提にしている。

つまり、この2点の重要性に気付かなかったプレイヤーは、そもそも勝てないのです。だから僕は勝てなかったわけです。必殺技はあまり使わなかったし、スキルレベルをグリモアで上げる作戦も、おまけ程度にしか活用していなかった。

また、この「葬式スレ」により、ボスに勝つための戦略に持久戦というものがなく、攻撃力で押し切る戦法しか通用しない事も知りました。

戦法がひとつしか取れない。多様性が売りのダンジョンRPGで。

これは駄目でしょう。

一度そうやって気が付くと、あれこれとそれらしい兆候が其処此処に見い出されてきます。

簡単にゲーム中のお金「エン」が溜まるダウンロードコンテンツが配信される。こういう目に見える救済策というのは、ゲームバランスが取れなかった時、ゲームプログラマが取るありきたりの作戦ではないか?

アクションゲームでも、難しい箇所には、やたらと回復アイテムが落ちているではないか?

つらつら考える内、プログラマなら聴いた事があるであろう、巨象の話を思い出したのです。

「便利な機能」を足し算していった挙句、何がしたいのか分からなくなってしまった巨大なプログラムの事を。

これは推測ですが、ダンジョンRPGにストーリー要素を足す、という事が、そもそも、「余計な機能」だった可能性があるように思います。そして、グリモアというのも、「余計な機能」に結局はなってしまったのではないか、とも思います。

これはコンセプトの問題だという感じがしました。

ダンジョンRPGのコンセプトの延長をやるのか、それとも、(ダンジョンRPG+ストーリー)で、『ドラクエ』以外の何かを本当にやれるのか。

後者をやって、ファンが付いてきたら、「新・世界樹~」シリーズは成功なんでしょう。しかし、それが難しい。普通のRPGになってしまう。それならそれで、既に世の中にいっぱいある。何かそういう、微妙なラインで、どうしたいんだというのがあるのかもしれない。

また、これも作成者の配慮が裏目に出てしまった例ですが、雑魚敵が無暗に弱いのです。フィールド上に最初から見えている敵であるFOEは結構強い。とてもじゃないが勝てない。しかし、フィールド上に見えていなくて、パッと戦闘に入る雑魚敵が全然強くない。作成者の考えとしては「ボス戦とのメリハリをつけた」との事ですが、普段の戦闘が、ボス戦の練習にならない。雑魚敵は普通に攻撃すれば大体勝てる。ボス戦は、色々考えないと絶対に勝てない。つまり、普通の戦闘とボス戦で採るべき作戦とが違い過ぎて、その辺も、「ボスが強過ぎて面白くない」感じを増してしまっていたように思います。

ただ僕はこのシリーズが嫌いかというと、妙に好きなのです。

なんかこう、素朴味があり、民芸品のような良さがある。

僕はそれを好んでいる。

こう書いてみると、僕こそ、真の信者だ、という気が致します。

他の人が嫌っている、出来損ないのストーリーを正にその出来損ないの故に好いているのだから。

 ありきたりのキャラ、登場人物のどこかで見たような記憶喪失、その全てが、無名性を持って迫ってくる。作家性がどこにも見えない事、まさにその事が、望郷の念のように僕の胸に迫ってきます。どこにでもある田舎であるからこそ、人は故郷を懐かしく感じるのではないか。

僕としては、この物語の甘ったるさが良くて、それでプレイしている所は大いにある。僕は永井荷風のファンであって、ああいう、甘ったるい詩情が好きなのです。

そういう味が『新・世界樹の迷宮』シリーズにはある。人はこれを嗤うであろう。

しかし、ダンジョンRPGファンが見ていない良さを、僕は『新・世界樹の迷宮』に見い出しているのであって、これはこれで、正しいファンだなと思います。『新・世界樹の迷宮』のストーリーモードを楽しんでいるのだから。

それで、ストーリーに関して言うと、僕はクロエが面白いなと思いました。台詞が笑っちゃうんですよ。あれは声優がうまいんでしょうな。

「楽勝、うん、らーくしょ」とか、あとちょっと忘れましたが、とぼけた面白さがある。かなり昔の白黒映画で出てきそうな古典的なギャグって感じでいいですね。森繁久彌的というか。森繁久彌、そんなに知らないですけど。

あと、これはネタバレなので、読みたくない人は読まないで欲しいんですが、エンディングで、主人公がどこかに去っていき、残された仲間が落ち込んでいるという筋があったでしょ。あったんですよ。

これは、ディレクターとスタッフの関係なんじゃないかと思ってしまったんですよ。

最後、主人公がカッコよく変身してボスを倒す。この主人公の姿が、『新・世界樹2』をちょっと強引に完成まで持って行ったディレクターの投影で、後に残された仲間は、変なものを作ってしまったスタッフじゃないかと思います。

なんか、そういう憶測をしてしまいました。最後に変身して、敵の大将を簡単にやっつける、あれはゲーム中のお金がガンガン入るダウンロードコンテンツを出したりといった、「パラメータ調整諦めた」後に無理やりゲームをまとめる、そういう姿の比喩なのではないか。そういう、メタ的な、自己言及的な部分があるんじゃないかとか、考えました。

僕は鴎外の小説でもここまで考えません。

エライ、ここまで人に考えさせるストーリー、ふぁふにーるの騎士、エライ。

それは冗談ですが、ゲームの出来不出来、単に面白かった、詰まらなかったじゃなくて、なぜつまらないのか、それには理由があるらしい事、そういう事が分かったり、プログラムとしてゲームを考えたり、僕にとっては、とても面白い事を経験する事になった作品である。

まぁそんな事で、このゲームを人には勧めませんし、自分ももう一度やるかと聞かれると、やらない気もしますが、まぁいいじゃないか、一度でも楽しめたんだから、それでいいのだ。夏休みみたいなものだ。二度と戻ってこなくて、ちょうどいいのだよ、きっと。

外部プログラムの呼び出しの話

Javaから外部プログラムを呼び出すための手順をまとめた記事をQiitaに書いて残す事にした。

qiita.com

この記事を書いたのには理由がある。

あるプログラムから、別の言語や環境のプログラムを呼び出すのは難しい事が多く、いつも苦労してきた。しかし、先日Javaから外部のプログラムを呼び出す処理を書いた所、思いの外容易に書く事ができた。そこで、この経験を纏めて書き残そうと思い、上述のQiitaの記事を書いたのである。

 

外部プログラムの呼び出しには、苦労した経験がある。

例えば、昔、Windowsのバッチファイルを使った事があった。

バッチファイルから別のバッチファイルを呼び出したのだが、ブロッキングしてくれず、平行して実行されてしまった。何かのコマンドだと、逐次実行されると聞いて試したのだが、なぜか駄目だったのだ。

他にも、外部プログラムの実行結果を呼び出し元で取得できなかったり、色々と難しい事が起こりがちである。

元々、ひとつのプログラムで実行したいと思っていて、呼び出し元の言語でうまくいかないから、外部プログラムを使う。そうすると、呼び出し元の言語内での単なるプロシジャ呼び出しで済んだ場合の簡便さが頭にあるから、余計大変な気がするのだと思う。

外部プログラムの呼び出しが面倒な理由をつらつら考えてみると、下記が挙げられるように思う。

  • 別のプロセスが起動され、プログラムが並列で実行されてしまう。

シングルスレッドで実行したい場合が多い。何もなければ、シングルスレッドで書きたい。しかし、外部のプログラムを呼び出すと、そこで新しいプロセスが開始されるので、意識して同期を取る必要が出てくる。先に挙げたバッチファイルが並列して実行されてしまったというのは、ここの絡みである。

  • エラー処理が難しい。

外部プログラムの実行結果が容易に分からない。

外部プログラムの終了コードを取れる場合があるが、それ以上の内容となると、外部プログラムが出力する標準出力や標準エラー出力をどこかのファイルに書き出し、そのファイルを読み込むとか、何か方法を考えねばならない。

 

そんな訳で、色々面倒だった記憶があり、自分はつい最近まで、外部プログラムの呼び出しをあまりしたくないと思っていた。しかし、この間、Javaコードで圧縮ファイルの解凍処理を書いたらうまくいかず、止むを得ずJavaから圧縮解凍ソフト「7-zip」を呼び出した所、案外その処理がスムーズにいったので、感動したのである。

Qiitaに記事を書いていて思ったのは、外部プログラムの標準出力、標準エラー出力の出力先をリダイレクトするAPIがあり、ProcessBuilderクラスのredirectOutputメソッド辺りがそうなのだが、これがJava1.7で追加との事で、有難く思った。Javaの標準ライブラリのサポートが、外部プロセスの呼び出しに関して厚くなってきているとしたら、とても嬉しい事である。

  • まとめ

外部プログラムの呼び出しの難しさというのは、結局は平行処理の難しさなのではないか。

異なるプロセス間で適切に連携を取る事の難しさが、外部プログラムの呼び出しにはあると思う。

『Effective Java』がめっちゃ勉強になる。

 

  • 概要

『Effective Java』を久しぶりに開いてみたら、心に響いた。

  • 詳細

『Effective Java』を購入したのは、何年も前の事で、その時の事はもう覚えていない。確か評判がいいと聞き、試しに買ってみたのだと思う。しかし、内容をあまり覚えていないから、おそらく難し過ぎて、そのまま読まなかったのだろう。

久方ぶりに開いた『Effective Java』は、Javaを2年位書きまくった僕の脳天に痛棒を食らわした。

「君、この位は分かっていたまえ。Javaは手続き型じゃないんだから」

『Effective Java』は、ちょっと上から目線でそう言った。

「この前君が書いていたコードだが、最初はHashMapで実装した。その理由は確か、KeyとValueを辞書のように使えれば良く、特に順序を考慮する必要はないから、だったね。だから君は、TreeMapを使わなかった。しかし、途中で、事情が変わり、Keyの昇順に並び替える必要が生じた。その時君はどうした? 一度全ての値をHashMapから取得し、ArrayListに格納した。そして、そのリストを並び替えた。つまり、TreeMapを使わなかった。なぜならもしその時からTreeMapに書き換えるとなると、修正箇所が多く、コードを書き変えるのが面倒だったからだ。しかしだ、それはなんでだと思う。修正箇所が多かったのは、止むを得ない事情でも何でもない。君の書き方が悪いからだ。君はHashMapを生成した後、そのインスタンスをHashMap型の変数に格納していた。しかし、Javaにはインターフェースという機能がある。Mapインターフェースにインスタンスを格納しておけば、インスタンスを生成する箇所で、生成するインスタンスのクラスをHashMapからTreeMapに修正するだけで良かった筈だ。そうすれば、Mapから取得したコレクションは、TreeMapクラスの力により、順序が保証されたのである。分かるか? 君が愚かだからだ。結論はそういう事だ」

 「Enumの書き方もそうだ。なぜそうやすやすとEnumでswitchしてしまうんだ。Enumにはもっと効果的な使い方がいくらでもある。switch文で分岐させる代わりに、Enum型の内部で抽象メソッドを宣言し、列挙定数ごとに抽象メソッドを実装したっていい。そうすれば、列挙定数を追加した時に、switch文にひとつ列挙定数を追加し忘れる事もない。またswitch文の最後に、定型的なエラーをスローする処理も書かないで済む」

「他にも言いたい事は山ほどあるが、今日はこの辺にしておこう。あまり一度に話しても混乱するだろうから」

JavaFXを使ってみたのだった。

会社で、技術勉強会を催す事になった。何と責任者は僕である。
...
やりましょう。

最初、AOJとか、そういうプログラミング・コンテストを通した勉強をイメージしていたのだが、参加者の提案で、月ごとの持ち回りの、発表形式になった。1月に一度、誰かが勉強した事をみんなの前で発表する。
僕は技術関連の発表をした経験がなく、どういう事をすればいいのか、はっきりとしたイメージはなかったが、ともかく勉強会を始める事が先決だと思った。最初の発表者は自分にした。また、発表時期は月末にした。そうすると、発表まで、時間がない。2週間ちょっとしかない。
考えた末、JavaFXをやってみる事にした。

JavaFX テクノロジーの概要

Oracleの技術である。ここで出てくるJavaはそう、あのプログラミング言語Java」である。JavaFXとは、一言で言うと、Javaで作るUIである。
まずは下記のサイトで勉強だ。

初心者のためのJavaFXプログラミング入門

チュートリアルって感じのサイトである。JavaFXはSwingに変わって新しく登場した、JavaのUI作成技術なのだ。
このサイトで学んでて感心したのが、JavaFXXMLでUIを作るという事。そういう点では、Androidに近いのかしら。でも、Androidで使っているJavaは公式じゃない?んだってね。GoogleOracleが争っているってどこかで読んだよ。このXMLはFXMLと名付けられていて、名前の由来はJava"FX"と"XML"を掛けているんだと思うな。

ここでちょっとFXMLの例を挙げたいのだが、会社の勉強会向けに作った物をここで挙げていいのか、分からないので止めよう。

あと、JavaFX向けのCSSというのもある。これはWebサイトを書くときにHTMLと一緒に使うあのCSSとはやや違うらしいのだが、目的は一緒だ。

これも例を挙げたいんだけど、会社向けのやつだから止そう。というか、上記に挙げたチュートリアルサイトに全部載っているから、そっちでいいよ。

なんか情報量ゼロになってきた。これだけ書いたのに、情報量ゼロ。なるほど、これがゴミブログだな!

あとですね、FXML内で、スクリプト言語が使えるのだよ。JavaScriptClojureやGroovyとか。使えるはずだよ、エラーになっちゃって自分は使えなかったけど。

なぜコンパイルエラーごときで諦めたかと言えば、あまり僕の作ったサンプルで、スクリプト言語を使う必然性がなかったからなんだよ。

だって、Javaで書けるんだよ。JavaFXは入力ボックスとか、プルダウンメニュー、ラジオボタン、日付選択用のピッカー、ボタンなど、色々なコントロールを配置できる。それを押したり、選んだりしたとき、ちゃんとそのアクションをJavaで受けて、イベント駆動できるのだ。とすると、ちょっとスクリプトの使いどころが分からなかった。スタンドアローンでアプリを書いて、そのUIをJavaFXで作ったとしたら、要らないと思う。多分、リッチクライアントという事なので、別の使い方があるのではないかと思っている。Webサイトで、このXML+CSS+軽量言語を閲覧できるようになる? ちょっと分かってない。Adobe Flashみたいな使い方ができるそうなんだけど。

僕がJavaFXを使ってみて思ったのは、企業で自社向けツールを書いた時、開発した本人以外の人が実行する時に使うUIをJavaFXで書くのが良いのではないかという事。Javaツールを作ったら、UIもJavaで作れると一貫して開発できていい。ちょっとしたUIなら、まず問題ないだけのコントロールやCSS機能が入っていそうだ。

そういう点で、MicrosoftVisual Studioで作るフォームアプリケーションのフォーム部分みたいなのが、Javaでもできる、という事なんじゃないかね?

あと、書き忘れていたが、JavaFX Scene Builderという、GUIベースでFXMLが記述できるツールOracleが配布している。

JavaFX Scene Builder Information

上記サイトのサブタイトルに「A Visual Layout Tool for JavaFX Applications」とあるが、まさにその通りだ。以下の画像は起動した所。

f:id:nogitsune413:20150505035523j:plain

こんな技術があるんだな。Javaの世界は広い。

 

会社で作ったJavaツール

  • 発端

スクリプトを書いてくれ」

最初はそう言われたのだった。

しかし、話を聞くうちに分かってきた。

これはスクリプトでは済まない。

そこで、使用する言語をPowerShellから急遽Javaに変更した。近頃、Javaで書くシステムはWebシステムが多かったが、仕事でコンソールプログラムを書く事になった。

  • ライブラリ

HTMLをパースする。XMLをパースする。パースというのは解析という事で、プログラムがHTMLを解釈してデータを取得するのである。XMLも同じである。

これはJavaの標準機能ではできない。ライブラリを使う事になった。

[Jsoup]

jsoup.org

これでHTMLをパースした。出力も出来る。お世話様だ。

[dom4j]

sourceforge.net

これはね、最初はJava標準のXMLパーサでいけると思ってたんだ。ところがどっこい、読み取りはまぁいいんだけど、書き込みができない。

全然できない訳じゃないんだけど、ちょっと難しそうだったんだ。

因みに標準は、javax.xml.parsersというのらしいんだけど、うまく使えなかった。時間がかかりそうだったので、ネットで評判の良さそうなdom4jにした。

[jaxen]

http://jaxen.codehaus.org/

これはdom4jに必要なライブラリだったんだけど、XPathというものを使えるようにするライブラリだ。このXPathというのが、今回自分には大きな発見だったんだな。

詳しくはググって欲しいんだけど、以下のMicrosoftのページが分かりやすいな。

XPath の例

要は、SQLのように、XMLから指定した集合を抽出できる言語が、XPathだ。これは誰かが勝手に考えたという訳ではなくて、 標準化団体W3Cで開発されたという事で、それなりに権威があるというか、公式な感じの言語だと思う。

これがまぁ面白いね。

先のMicrosoftのサイトにある例で、

x[1]/y[2] → 最初の <x> の 2 番目の子要素 <y>

とある。SQLっぽいと言いつつ、順序も扱える所、なかなか。

  • plist

iOS系の開発をする人は知っていると思うんだけど、plistというのは、XML形式のファイルで、iOSで使っている設定ファイルだ。これを今回生成する事になった。

iOSで使うファイルをWindows上で動くJavaで生成する。

俺は何をやっているんだ。plistを生成しているんだ。

そんな事を開発中に考えてしまったよ。

  • 環境

個人的というか、要件は「ちゃんと出力しろよ」というだけだから、使うツールや環境に殆ど制約のない開発だった。それでJava8を使ったんだけど、使い慣れていないものだから、あまり新機能、ラムダ式とか使えなくて、残念だった。でも、Java7から入った、ファイル操作系のクラス、「Files」「Paths」なんかはガンガン使わせてもらった。初めてtry resourcesも使って便利だったよ。やっぱりバージョンアップは大事だな。自慢にならないけど、ついこの間まで、Java1.4だったんだ。Java6に上がって嬉しかったんだけど、もう8の時代だ。ようやく時代に俺が追い付いたって感じかな。

 

--  追記  2015/04/19  --

このツールに機能を追加する事になった。

具体的には、Androidで使うpreferences.iniファイルを生成する。

このpreferences.iniというのは、設定ファイルだ。key=valueという形式で値が書いてある、簡易なデータベースといった所。テキストで扱える。

ええと、こいつを読み込んで編集するのか。どうしようかな。ライブラリ、だな。これは確か標準ライブラリにクラスがあったな。あったあった、これだ。Propertiesクラス。

。。。ちょっと違うな。

セクションが扱えないのではないか?

セクションというのは「[」と「]」で囲んだセクション名を見出しのように置くと、設定項目の組を作れるというものである。例えば、以下である。

ーーーーーーーーーーーーーーーーーーーーーーーーーーー

[Animal]

fox=3

rabbit=1

cat=7

[bird]

pigeon=2

peacock=3

ーーーーーーーーーーーーーーーーーーーーーーーーーーー

preferences.iniではセクションを使っているから、セクションが扱えないと駄目だ。

また外部ライブラリかよ。別にいいけど。

ini4j.sourceforge.net

標準ライブラリのPropertiesクラスを諦めて、これを使いました。ini4j。ちっちゃいライブラリで可愛い。

それで、まぁつまらないこだわりなのですが、INIファイルを生成した時、自分の意図した通りの順番で上からセクションを並べたい。Androidのpreferences.iniは手で編集する事も充分あり得るから、綺麗に出力したいのです。しかし、このライブラリはMapというデータ構造で、INIファイルを読み込むのですな。Mapというのは、KeyとValueを紐付けて一組とし、これをたくさん保持するのですが、基本的に順序性はないのですよ。Javaの場合、TreeMapというクラスがあって、これなら、順序も扱えるのですがね。まぁそれで無駄に悩みました。

...

そうだ、一から値を格納していけば、きっと格納した順序で出力されるに違いない。設定ファイルからini4jに読み込んだ状態で編集して、そのまま書き出そうとするのではなく、一旦値を全部ini4jからアプリに取り出して編集し、ゼロクリアした状態のini4jに編集後の値を入れ、書き出してみよう。

そうやって書いちゃいました。

今は動いています。今後は知りませぬ。いざとなれば、ライブラリを使わずにアプリで書き出すしかないが、今の所うまく動いているので、そのままである。