2013年1月 - fairy.ouchi.to


2013-01-17 一時閉鎖の理由と今後の方針みたいなもの

2006-06-01に正式公開して以降、2012-11-30まで、ゲームや時事ニュース等、その時思ったさまざまなことを記事にしつつ、 サイトの構成やjavascriptのお遊びプログラムの改良も並行して続けていましたが、 いーかげんうんざりするくらいに記事が溜まった上、自分でもメンテが面倒なくらいにサイトのフレームが複雑化したので、 記事は丸ごと削除してサイトのフレームも綺麗さっぱり取っ払って、自分が見通しよくなるように再構成しました。

今後は、雑記についてはゲームとjavascriptと日々の私生活のどうでもいい話にのみ絞り、 サイトのフレームの手入れも最小限にして、お遊びプログラムをいじり倒すことがメインになる予定です。


2013-01-17 サイト再公開

枝葉を大雑把に切り落として1か月半振りの再開。
何もないというのも意外といいもんだ。

昔作ったプログラムは、見ても大雑把にしか分からん。切り貼りなんてとてもできないので丸ごと捨て。
それでもまあ、不要な依存を切って独立コンテンツにしていたものは、一応ちゃんと動いてるっぽい。

面倒だったのはCSSと連携していた部分。
いっそ依存CSSはjavascriptの中に取り込むべきかなぁ…。


2013-01-17 各ブラウザのjavascriptエンジン

Firefox v18で「javascriptが最大25%高速化」らしいので、このサイトの万年カレンダーで千年表示。

速いな!
DOM関係をかなり最適化したなぁ。

「ひょっとして万年カレンダーいけるんじゃ?」とか思って1万年表示したところ、 3回やって、8千年ちょい前で必ず落ちるという結果に。
オーバーフローすると問答無用で落ちる仕様は問題だと思うぞ。


2013-01-18 星芒祭ジョブ当て屋の攻略参考

来年はあるのだろうか。

難しいと思ってる人も多いようですが、効率よくヒントを引き出す手順さえ覚えてしまえば、別にさして難しいものでもなく。
まあ、わたしなりの解法以外でやれと言われると困りますが。初手戦モ白黒赤とか全く意味が分からないw

Q.1~Q.13 は、わたしが実際にプレイした時の結果。
Q.14 は、わたしの解法を適用した場合に、思いつく限り最も面倒になるパターン。

Q.1
1.戦戦戦モモ 1 0
2.モモモ白白 0 0
3.黒黒黒赤赤 0 2
4.赤赤赤シシ 0 0
5.ナナナ暗暗 1 1
----------------
6.戦ナ暗黒黒 2 3
7.暗戦ナ黒黒 5 0
Q.2
1.戦戦戦モモ 1 0
2.モモモ白白 0 1
3.白白白黒黒 0 0
4.赤赤赤シシ 1 0
5.シシシナナ 0 1
6.ナナナ暗暗 1 1
----------------
7.赤ナ暗モ獣 2 3
8.暗赤ナモ獣 5 0
Q.3
1.戦戦戦モモ 0 2
2.モモモ白白 3 0
3.白白白黒黒 0 1
4.黒黒黒赤赤 0 1
5.シシシナナ 0 1
----------------
6.モモ赤白シ 3 2
7.モ赤モ白シ 5 0
Q.4
1.戦戦戦モモ 1 0
2.モモモ白白 0 0
3.黒黒黒赤赤 0 1
4.赤赤赤シシ 0 1
5.ナナナ暗暗 1 1
----------------
6.戦シナ黒ナ 3 2
7.シ戦ナ黒ナ 2 3
8.戦ナシ黒ナ 5 0
Q.5
1.戦戦戦モモ 0 0
2.白白白黒黒 1 1
3.黒黒黒赤赤 1 0
4.赤赤赤シシ 1 0
5.ナナナ暗暗 1 1
----------------
6.白黒ナシナ 3 2
7.黒白ナシナ 5 0
Q.6
1.戦戦戦モモ 0 0
2.白白白黒黒 0 0
3.赤赤赤シシ 2 0
4.シシシナナ 0 2
5.ナナナ暗暗 0 2
----------------
6.暗暗獣シシ 5 0
Q.7
1.戦戦戦モモ 0 2
2.モモモ白白 1 0
3.黒黒黒赤赤 0 2
4.赤赤赤シシ 1 0
5.ナナナ暗暗 1 0
----------------
6.モ赤ナ戦黒 2 3
7.ナモ赤戦黒 2 3
8.赤ナモ戦黒 5 0
Q.8
1.戦戦戦モモ 0 0
2.白白白黒黒 0 0
3.赤赤赤シシ 2 0
4.シシシナナ 0 3
5.ナナナ暗暗 2 0
6.暗暗暗獣獣 1 0
----------------
7.赤ナナシ獣 3 2
8.ナ赤ナシ獣 1 4
9.赤ナナ獣シ 5 0
Q.9
1.戦戦戦モモ 2 0
2.モモモ白白 0 1
3.白白白黒黒 0 1
4.赤赤赤シシ 0 0
5.ナナナ暗暗 1 1
----------------
6.戦黒ナモナ 2 3
7.ナ戦黒モナ 5 0
Q.10
1.戦戦戦モモ 2 0
2.モモモ白白 0 2
3.白白白黒黒 0 2
4.赤赤赤シシ 0 0
5.ナナナ暗暗 1 0
----------------
6.黒黒ナモモ 3 2
7.黒ナ黒モモ 5 0
Q.11
1.戦戦戦モモ 0 1
2.モモモ白白 0 0
3.黒黒黒赤赤 0 0
4.シシシナナ 0 1
5.ナナナ暗暗 2 0
----------------
6.ナ獣獣戦暗 3 2
7.獣ナ獣戦暗 5 0
Q.12
1.戦戦戦モモ 0 0
2.白白白黒黒 1 0
3.黒黒黒赤赤 0 0
4.シシシナナ 0 2
5.ナナナ暗暗 2 1
----------------
6.白ナ暗シ暗 1 4
7.ナ白暗暗シ 2 3
8.暗ナ白暗シ 5 0
Q.13
1.戦戦戦モモ 0 0
2.白白白黒黒 0 1
3.黒黒黒赤赤 2 0
4.シシシナナ 1 0
5.ナナナ暗暗 0 2
----------------
6.黒暗獣赤ナ 3 2
7.暗黒獣赤ナ 5 0
Q.14
1.戦戦戦モモ 0 1
2.モモモ白白 1 0
3.白白白黒黒 0 0
4.赤赤赤シシ 0 1
5.シシシナナ 1 1
6.ナナナ暗暗 1 1
----------------
7.モナ獣赤ナ 3 2
8.ナモ獣赤ナ 2 3
9.獣ナモ赤ナ 2 3
10.モ獣ナ赤ナ 5 0

わたしの解法は大きく2段階。
上記の回答で、--- で区切った部分が第一段階と第二段階の中間線です。

最初に左3人と右2人で分けて、全員のジョブを割り出すのが第一段階。
上記の回答の第一段階は、全て理詰めで解いています。パターンによっては手間ですが、慣れれば難しくはありません。

第一段階で左3人右2人のジョブが判明した(CH + H = 5になった)あと、並べ替えるのが第二段階。
第二段階の最初が 3 2 になった時は、次に左3人のうちの左側2人を入れ替えて、1 4 になったら右2人が間違い。それ以外なら右2人は正解。 第二段階の最初が 2 3 になった時は、右2人は正解なので左3人を順に右に1つずつずらしてみます。

大抵のパターンで、第一段階は6回以内、第二段階は4回以内で判明します。
それぞれ7回/5回以上必要なパターンがあるかは不明。

10回以内で解けないパターンが実際にあるのか、プログラム組んで確かめてみりゃいいわけですが…。
FF11の星芒祭ミニゲームでもこのサイトのjavascript版でも、どっちにしてもそれをわたしがプレイするのである限り、 自力で解けばそれで十分なわけで、わざわざ解法プログラムなんぞ作る必要性を感じておりませぬw


2013-01-18 階層構造の隠蔽に伴うサイト構成の可能性とその利点をボンヤリと考えたフリをする

URLを検索クエリと混同するとどうなるか。

再公開でサイトのフレームを一掃したついでに、このサイトの各ページは、全て /?p= になるように変更。
ブラウザでURLのフル表示をしていない場合には、パッと見、意味がわからんことになってますw

この変更によって、各ページは /?p=time のような短いパスか、/?p=時間相互変換 といったページ名そのものでアクセスできるようになり、 URLに長ったらしい /prog/exec/js-tool-time のような階層構造を含むことはなくなりました。
「特定のページを表示するためにURLを入力する」ことと、「そのページが内部でどのように階層分類されているか」というのは、 本来完全に別のことであって、URLが階層構造を含むことで、内部の階層構造の変化によってURLを変えなければならないということがおかしいし、 "http://サイトアドレス/?p=ページタイトル" で、そのサイトの特定ページが表示されるなら、 その方がより直感的なはずです。

これをさらに突き詰めると、たとえばサイト内の全ての要素を適切に分割分類タグ付けしておいて、 /?p= に対する複雑なページ指定の仕様を用意し、仕様通りに動的なページを生成する機能を実装しておけば、 もはやそのサイトには一切の関連構造が存在せず、あたかもGoogleのトップページのようなシンプルな状態から、 訪問者がサイト内のコンテンツを自由に組み立て表示することができるようにもなるわけですれども。

……はて、ではそこまでやったサイトがあったとして、それを誰が便利だと思うのかと考えてみれば、 仕組みに興味を持つ人はいたとしても、それそのものがいいと思う人はまずいないはずなんですよね。
他サイトに行くことが前提のGoogleと違って、普通はそのサイトを見たいからこそ、そのサイトに行くわけで、 行ったサイトのトップページに、そこに何があるのかというメニューが全く提示されていなければ、 訪問者は中身を知る前に帰ってしまうし、中身がメニューという形で最初から一覧表示されているなら、 各ページが静的か動的かは重要視されず、目的のコンテンツを素早く表示できさえすればそれでいい。

わたしのように内部の階層構造を適宜変更したいと思うタイプにとっては、ファイル管理のための階層構造を訪問者に見せない、 URLが階層構造を含まないというのは大きなメリットとなる。
けれども、それはURLが階層構造を含まなくなるだけで十分に得られるメリットで、 それをさらに押し進めて複雑なクエリを受け付けられるようにしても、 訪問者の立場からすれば「メニューがあればそんなものはどうでもいい」で終わり。
フラットな同種情報が大量に蓄積されていてこそ、柔軟なページ組み立てに価値ができるわけで、 メニューで用意できる程度の量であれば、組み立てに価値を見出せってのが無茶な話。

らーめん屋のメニューに、醤油らーめん650円・大盛り750円・チャーシューメン850円・大盛りチャーシュー950円とあって、 それとは別に大盛り100円、チャーシュー200円のトッピングメニューがあるのは、 個々のメニューを無駄と感じるのではなく、客の利便を考えればむしろ個々のメニューの方こそ大切なわけで。

やり過ぎないのが大切。
客観的な評価は難しいけれど。


2013-01-20 そうだ、トイレ、行こう

考えて考えて考えて考えて、煮詰まってイヤになってソースを最初に戻して、ふとトイレに行くと何をやればいいのかあっさり理解できたりするというあるある話。

ただし
「気付かなかった解決策はトイレに行くと思いつくが、トイレに行って解決策を見つけることはできない」
マーフィーの法則的な意味で。

つかそもそも、イベントハンドラの中で他の要素を focus() すると、直後のイベントがそっちで発生するとゆー仕様そのものがおかしいと思うんだが。


2013-01-20 ジョブ当て屋改良完了

キーボード操作楽だ。
前のままでもマウスで不満は無かったのに、ここまでくるとゲームパッドでやりたくなるから不思議w

Firefoxウザいです^^
selectが左右で選択できるのはいいとして、だったらそれを止める方法も用意しておけと。
Operaには同じ機能があってもonkeydownで簡単に止められたし、そもそもそんな機能のないIEは問題にならないのに、変な所で足を引っ張るのな。


2013-01-23 FFXI戦闘スキル表を再公開

サイト構成変更に伴うファイルパスの書き換えと、 一時閉鎖前からずっと放置してたバグを修正。
変数名を整理して、整理ついでに階層構造に組み直して、さらに重複してた処理の一元化と、不要にデカい下請け関数を分割整理。
やっつけ仕事でデッチ上げた部分が、今見ると実にやっつけ仕事ですw

プログラムをメンテする場合、最大の敵は以前のプログラマ。
この場合は、つまり自分自身。

・変数名を練りきらずに実装すると、後のメンテにメチャメチャ跳ね返ってきます。
・重複処理はバグの温床です。片付けるとバグが減ります。
・デカい関数には、それが大きな一塊の処理である場合と、複数の処理が混ざっている場合があります。適宜切り分けると見通しが良くなります。

「メンテは終わらぬ、何度でも繰り返すさ。メンテの存在こそ趣味プログラムの価値だからだ!」
趣味でない方だと話は変わるんですが。


2013-01-26 MH3G金冠付け

正月にサイズ系3つ以外の勲章を埋めて、最近はドスフロ面接中。
2台ありゃ速攻終わるわけですが、まあ、片手剣でドス鳥竜種をのんびりやるのも悪くないなと。 状態異常耐性さえあればストレスないし。

手持ちの素材見て、だいたい揃ってそうな装備を適当に作ったりしてますが、それを「せっかく作ったんだから」と担いでみても、 結局、片手剣/大剣/スラアクが一番馴染むなあという確認になっただけで、武器種の幅を広げるまでには至らず。
他の武器は、どうやら攻撃のモーション時間や打点が自分の感覚と合わないみたいです。 振りが遅い上、攻撃によって打点が左右どちらにもなるハンマーとか超苦手。

で、使うアテもないラギア希スラアクなんぞのために天の山菜使ったら、レイア天麟が欲しくなったりするわけで。
まあ、そっちも使うアテのない繚乱の対弩だったりして、どうでもいいという点では変わりませんがw
アテと言えば、錆び武器5種/風化武器8種で大地の結晶約2600、炭鉱夫で溜まったストックを使い切りました。

使い所のある装備で言えば、匠5が限界のT9在住の身としては、アルバ武器が欲しいところだけれども。
とはいえ、アレをソロで行く気になるとすれば、金冠終わって勲章完成してからだろうなぁ。


2013-01-27 そんな気分だった

普段なら車で行くのをたまたま別の道から歩いたら、車道の方は太い枯れ枝が落ちて片付けていたらしい。

第六感なしで回避ってことは、GMが3Dでピンゾロ振ったんだな。
自分で振る判定はまあまあだけど、GM側の判定はも少し良さそうだw


2013-01-29 配列の添え字は0からだけど

「1じゃダメなんですか?」とか考えてしまった。
いや、全世界のプログラマ同様、わたしも0始点で慣れきってしまってるから、今さら1始点にされても困るけど。

PHPに array_search という関数がある。
$arr = array("a" => "AAA", "b" => "BBB", "c" => "CCC"); $key = array_search("BBB", $arr);
これで "BBB" の添え字である "b" が返る。該当する値がない場合は、ブール値 false が返る。

んで、この関数は、値がない場合にブール値 false を返すけど、条件によっては真偽値が偽になる添え字を返すこともある。
$arr = array("AAA", "BBB", "CCC"); $key = array_search("AAA", $arr); if ($key){ echo $key; }
これは期待通りの動作をしない。$key に入るのが数値 0 だから、if文の条件を満たさない。
$arr = array("AAA", "BBB", "CCC"); $key = array_search("AAA", $arr); if ($key !== false){ echo $key; }
こうする必要がある。PHPには、こういう「成功したら値、失敗したら false を返す。true を返すことはない」関数が山ほどある。

関数が山ほどあるということは、PHPのリファレンスにはこういうバカバカしい関数がずらっと並んでいるわけで、 見てると「なんだあの処理の関数あるのかよ」というのがよくある。
実際のところ、他言語では該当する関数がないから自分で組み立てるしかなく、 そうして定型化してしまっている処理をPHPに限って標準関数に置き換えたところで、別に見通しが良くなるってこともないわけで。
むしろ、PHP独特の関数の仕様をしっかり把握しておかなければならない手間や、 本来重要であるべき最も単純な関数が、無駄に肥大化したリファレンスの中に埋もれてしまっているなどの弊害の方が、 少々のコード削減なんかよりよほどマイナスになってると確信している次第。

わたしは個人的に、PHPやjavascriptにある厳密比較演算子(=== と !==)が大っ嫌いなので、 たとえば array_search を使う場合、引数に渡す配列の添え字に偽と評価されるものを含まないようにすることで、 戻り値をそのままif文に渡してしまっている。つまり、array_search は単純配列には使わず、ハッシュでのみ使う。
単純配列でこの処理が必要になったなら、$n = -1; for($i = 0; $i < arr.length; $i++){} で素直に定型処理するか、 先頭要素に無効な値でも突っ込んでおくかすると思う。
どうしても避けられない処理として、strpos が -1 ではなく false を返すのは、イラっとくるレベルを超えて仕様決定者に猛省を促したい。 Perl の index が -1 を返すのは、元言語の慣習を引き継ぐことによって処理が定型化され、 プログラムの可読性が上がるという点で非常に重要だったのに、なぜ PHP は仕様を改悪したのか。 戻り値を検査せずに適用して最終文字を取ってくる可能性でも考えたか? 仕様をよく読まない初心者の失敗の可能性を減らすために、 言語間の仕様の違いを意識しなければならなくなるプログラマの総コスト増過を容認するというなら、わたしはそれが正しい判断だとは到底思えない。
プログラムはあくまでツールであるべきはず、高級言語はより扱い易いツールであるべきはず、 スクリプト言語は実行速度を犠牲にしてでもお手軽簡単に扱える事を目的としていたはずだ。

ここから本題。

ところで、そもそも「見つからなかったら-1」というのは、配列の添え字が 0始点であるという、 C系言語、ひいては機械語からずっと続く慣習から必然的に決まったことなのだけれども。
配列が1始点なら、見つからなければ 0、つまり偽になって、世のプログラムはもっと単純になっていたのではなかろうか?

この辺、「電流はプラスからマイナスに流れる」のと同じぐらいやっかいな話なんだろうけど。
プログラムの原点が Perl なために、「型はコンテキストで明示的に与えるもの。 処理に型指定がない場合は最も自然な動作が為されるもの」という考え方が根底にあるわたしからすると、 成功失敗の情報が戻り値に含まれているなら、戻り値をそのまま真偽判定することで成否が分かるというのは、 この上なく当然のことだと思うわけで、わざわざ -1 と比較しなければならないのは非常に鬱陶しい。

乱数なんかは、6つの値からランダムに1つ取り出す時に、値が 0..5 であることは理に適っている。 一般的な六面体ダイスを複数使うようなゲームを設計しようとすると、 「ダイスが 0..5 だったら3Dでも4Dでも分布が単純になって楽なのに」と思い当たる部分がたくさん出てくる。
プログラムにおいては、たとえばHTMLページでのselectボックスの設計で、「最初のoptionは独立要素にして、 連番になる要素は2番目以降にする」といった設計になる(できる)場合には、プログラムが単純になる。
常に 1始点がいいというわけではなく、その値そのものに意味があって何らかの計算をする場合や、 配列の先頭に「その他」が入る場合には、0始点にはメリットがある。 全てのものを 1始点にするのは、今現在 +1 している部分が減る代わりにどこかで -1 する部分が増えることになるし、 そもそも、既に 0始点に慣れ切ってしまっているから、現状に特に不満を抱いているわけではないけれども。
もしも、1始点がスタンダードだったなら、プログラムは今とどう違っていたのか、興味はあるな、と。

あ、ちなみに、わたしのCポインタの知識はこの本を最低限読み通した程度なので、 慣習ではなく理由としての「配列はなぜ 0始点なのか」ということぐらいは理解しています。


2013-01-30 ちょこちょこといじり倒し

GIFグラデーションやっつけ仕事版。HSVで値変更する所まで実装の予定。
IEだと生成したGIFが正常にドラッグできません。 たぶん、イベント発生順回りなんだろうとは思うけど、この辺が実にIEで腹立つので対応しません。

時間相互変換。リージョン選択の multiple 対応。
optgroup.style.display = "none"; に対応してるのは Firefox だけという残念な事実のために、 わざわざ毎回 removeChild するというふざけた実装になってしまった次第。

選択変更による追加・削除の効率的な実装を考えてみたけど、gdgdになったので力押しでいいやと。
どうせ、optgroup.style.display = "none"; に対応すりゃそれで済むんだから、わざわざ効率化してもなぁ。


2013年1月 | 2013年2月→