yamicha.com's Blog - Presented by yamicha.com
Blog yamicha.com's Blog - 2018/09 の記事
[1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30]

yamicha.com's Blog
 諸事情により、現在更新休止中。ご了承ください。もし今後ブログを再開することがあるとすれば、その際にはこのブログスクリプトではなく、新しく開発したものによるかもしれません。
 当ブログ管理者についてはこちらをご参照。
開発魔法(737)
社会問題(733)
お知らせ(11)
質問・バトン回答(15)
ゲスト出演(8)
経済・知的財産(150)
ゲーム開発(182)
[Ada] 勝手に補足
- Note
- 金配りの次の一手


- Endless Ultimate Diary
- 銃世界

漢字バトン
- うるる雑記帳
- 漢字接力棒

ツキアイゲノムバトン
- ブログ@うにうに画像倉庫
- あぶ内閣

縺イ縺セ縺、縺カ縺励ヰ繝医Φ
- 月夜のボヤキ
- 騎士サーラバトン
パスワードを使う
名無し (2012/02/27)


開発者解放裁判
yamicha.com (2010/03/14)
Winnyに関しては、私も「純白」とまでは考えておりませんし、使用し..

開発者解放裁判
通りすがり (2010/03/08)
winnyに関しては「ダウンロードソフト板」なんてところを拠点に開発..

新型インフルエンザの恐怖
いげ太 (2009/11/03)
> C#などの「int Some(int , int)」は、F#では「(int * int) ->..

時効に関する思考
yamicha.com (2009/08/31)
>いげ太さんコメントありがとうございます。手元にドキュメントが少..
Homepage
Blog Top
Normal View
List View
Search
Calendar
Comment List
Trackback List
Blog RSS
Send Trackback
Phone Mode
Administrator
yamicha.com
Blog
るううるる。
Source
法令データ提供システム
FindLaw
Development
Java2 Platform SE 6
Java EE 6 API
MySQL Developer Zone
PHP Reference
MSDN Library
Ada Reference Manual
Objective Caml
Python Documentation
Erlang
Prolog Documents
カテゴリ表示
 カテゴリ ゲーム開発 に当てはまるもののみを表示します。

 存在する記事 182 件の中から 11-15 件を表示しています。
雪うサギ
2006/01/20(Fri)18:48:18
 いきなり先頭にこの話題をぶつけるのもなんですが、Tactical Revolutionの新ステージ(騎士の魂)にハマりました
 何が面白いって、あのゲームにターン制限があれほどピッタリとは。具体的には、Tactical Revolutionには「CON」のステータスがあり、毎ターンその数値だけMRが回復することになりますが、ターン制限があるというのはあらかじめ使えるMRの枠が決まっていると言い表すことが可能です。
 例えばあのステージの場合、魔道士イリアスのCONが22、ターンが16であるため、ディスパッチできるのは最大でも5回だけです。どこでどう魔法を使うのかが非常に重要です。「誰を」「どの時点で」「どのように」ディスパッチするか、これが問題です。
 魔道士イリアスを最初にディスパッチする場合を考えると、1度南側に移動しておいてからまた北側に戻り、さらにそこから3人をディスパッチすれば、それで16ターン分のMRを使い果たします。パワークリースの1つすらまともに使えません。これでは、最初に向こう岸に渡る意味が全くありません。向こう岸に渡ったら、そこで支援を徹底した方が有利です。
 逆に、北の全員をディスパッチするのであれば、少なくともある程度片付いてから1人をディスパッチし、完全に終わってからもう1人をディスパッチする必要が出てきます。今回の魔道士イリアスは攻撃手段を持たないため、敵を片付けないままで騎士を2人とも南に送ってしまうと、到底倒しきれません。送るタイミングが非常に重要です。
 または、北の1人と自分をディスパッチして補助で攻める、といった手もありますし、2人ともディスパッチするなら順番も重要です。自分だけディスパッチするなら、ウィークやパワークリースをその分多く使えることになりますが、その分戦力は明らかに不足します。
 このような具合に、MRシステムは自由度が極めて高いのが面白いところです。その他、LAシステムが重要なのが南側で、パラディン10人を一般騎兵3人を含む4人で食い止めようとするムチャです。しかし、そこはさすがにティラーの名指揮官、その程度の戦力でも敵を食い止めるばかりか、1人か2人は撃破することができます。「REG」による自然回復を生かせば、延々と食い止めておくことも可能です。逆にREGを考えずに戦うと、あっという間に崩れます。
 それにしても一般騎兵3人の弱さといったら。剣聖はパラディンより明らかに強いのですが、数が数だけに。こういう場合は「ウィーク」が有効です。

 新しいPHPには例外処理があります。ただ、標準の関数で例外を投げるものというのは聞いたことがありません(当たり前ですが)。特にSQL関連関数で例外を投げてくれないのは困ります。うっかり命令を間違えたりするのですから。
 というわけで、例外を作ってみます。構文はJavaとそれほど変わりません。ただ、「throws Exception」はいらないようです。
class SQLSyntaxException extends Exception{
	function __construct($text){
		parent::__construct();
		$this->message = "SQL Syntax Error : $text";
	}
	function __toString(){
		return $this->message;
	}
}
function execute_query($sql , $db){
	$result = 0;
	if(!($result = mysql_query($sql , $db))){
		throw new SQLSyntaxException($sql);
	}
	return $result;
}

$db = mysql_connect("localhost" , "yamicha" , "password");
mysql_select_db("yamicha" , $db);

$result = execute_query("SELECT * FROM invalid_table" , $db);
mysql_close($db);

// Result
Fatal error:  Uncaught SQL Syntax Error : SELECT * FROM invalid_table
  thrown in c:\Apache\htdocs\exception.php on line 25
 例外をキャッチしていないので、致命的なエラーが出ます。例外をキャッチするのは、CやJavaでもおなじみのtry-catchです。
try{
	execute_query("SELECT * FROM invalid_table" , $db);
	print "Success!";
}catch(Exception $e){
	print $e->getMessage();
}

// Result(失敗の場合)
SQL Syntax Error : SELECT * FROM invalid_table

// 成功すると
Success!
 なるほど、これは便利です。私はJavaではTactical Revolutionですら例外クラスを作りませんでしたが(例外を投げるような処理がないため)、PHPではそこそこ使えるかもしれません。サーバーがPHP5に対応してくれれば
 ただ、PHPの例外は他の例外と異なる部分が1つあります。キャッチしなくてもパースエラーは出ないのですが、致命的なエラーになってしまいますので、それを回避する方法として「デフォルト処理」なるものが用意されているとのこと。
function exception_default(Exception $e){
	print "Exception Default Handler\n";
	print $e->getMessage();
}

set_exception_handler("exception_default");
 これでtry-catchされていない部分ではデフォルトの例外処理(exception_default)が呼び出され、プログラムはその時点でストップします。exception_default関数の引数には例外オブジェクトが渡されるため、クラスタイプヒントでそれを明示しています。

 さらにPHPには「declare」なる複雑怪奇なものがあるようです。今さら見るまでもないや、と考えつつ「制御構造」の項を見て、見慣れない記述にビックリ。MySQLのストアドで使わなかったら絶対スペルも覚えきれていません。逆にMySQLが絡むと「SET TRANSACTION ISOLATION LEVEL REPEATABLE READ」でも「CREATE TABLE tbl(pri INT , PRIMARY KEY(pri) , FOREIGN KEY(pri) REFERENCES other(column))」でも覚えられてしまうのですから。これがSQLの魔力です。
 さて、このdeclareですが、「低レベル命令の数をカウントする」とか。何のことやら。とにかく実験あるのみです。
$value = 0;
function declare_call(){
	$GLOBALS["value"] ++;
}
register_tick_function("declare_call");
declare(ticks = 2){
	$loop = 0;
	while($loop < 50)
		$loop ++;
}
print $value;
 が、動かないばかりかApacheが落ちてしまいました。何度繰り返しても同じです。どうなっているのでしょうか。PHPマニュアルのコメント欄を調べてみると、「Using ticks on Windows, running Apache as a php-module, crashes Apache and will not work」なる書き込みが。で、http://bugs.php.net/bug.php?id=26771を参照とのこと。そういうことらしいです。
 動かないのでは仕方ありませんが、混乱させてくれます。

 さて、少しばかり気になるニュース、「ライブドア・堀江氏が米国などで擁護されていたりする」点について。実際にあちらの新聞紙面などでは擁護や同情の声があるようです。言うまでもなく「問題の深刻さが伝わっていない」のも原因なのでしょうが(株式分割不正でのし上がった会社であるなど)、理由は他にもあります。
 言ってみれば、堀江氏の行動と米国の利害が一致しているのです。例えば米国は自由・競争主義で回っている国ですが、その分個々のつながりが強く、「車中に置き去りの子どもがいたらウィンドウを割ってでも助ける」「車椅子やお年寄りの人がいれば助けるのが常識」「子ども連れには気を使う」などが徹底しているといいます。
 ところが、恥ずかしいことに我が国は「子どもが炎天下の車中で死んでも知らぬ存ぜぬ、ガラス割って助けようものなら弁償モノ」「車椅子は邪魔者、お年寄りは厄介者」「子ども連れはうるさい」といった状況です。ここに米国流の主義だけ持ってきても上手くいくはずがありません。言ってみれば、細い竹に巨木を接木するようなもので、まず不可能なのです。
 事実、他国の人はイラク人質などをバッシングすることはなく、無事に帰還した人は歓喜ムードで迎えられています。ところが、日本がまた情けない。外国人は首をかしげています。バッシングは国際的ハレンチです。そういう国が他国の一部のみを切り取ったところで、手詰まりしないと考える方が不自然です。
 しかし、他国にとってそんなのは関係ありません。米国などは、要は日本の市場が米国流市場に近くなって、自分らがモノにできる市場が増えれば万々歳なのです。ですから、堀江氏のようにとんでもない人間であっても、日本市場を米国がモノにしやすいような形に変えてくれるのは「正義」、それを阻むのは「悪」なのです。
 分かりやすく言えば、日本は昨年末に米国産牛を輸入するという反国益愚行を犯しました。しかしながら、これを歓迎しない米国人はほとんどいません。この場合、堀江氏は米国産牛に当たります。
 自分の配下に投資組合を作り、あらかじめそこに会社を買わせておいて、その組合から会社を受け取るのを「買収」と称して株価をつり上げて売り抜ける。その利益を自社に回して決算を粉飾する。1株を3万株にして一時的株価上昇を利用して売り抜ける。東証は監理送りを検討しているそうですが、当然です。
 ただ、民放連が何だかんだ言っているようですが、あなた方は黙っていてください。「ライブドアが悪で自分らは正義」のような顔をするとは。私はライブドアは大嫌いですが、被害者保護などにインネンをつける民放連も大嫌いです。

 ここで少しばかり重要なニュースを。おそらくこのブログの読者の中で雪国の人は半数以下でしょうし、雪下ろしを業者に頼む人はほとんどいないでしょうが、こういう情報はできるだけ多くのソースで取り上げるべきですし、それが「A級メディア」たるインターネットの責務と考えています。
 ということで、これはぜひとも知っておいて欲しいのですが、過疎地などには「雪下ろし代行業」と称して20万円などをぼったくる悪人どもが出没しています。お年寄りなど自分で雪下ろしするのが難しい人をターゲットにしているようです。しかし、政府サイドが雪下ろしの不正請求にはクーリングオフを適用できるとの見解を示しました。
 この場合、形のある商品と違って雪下ろしは返却できないわけですから、単に代金支払いを拒否することができる形になります。これで悪人どもは「タダ働き」になり(ついでに「タダ働き残業」も不正契約として致命的なほどの厳罰に処しては?)、自然消滅していくのではと考えられています。
 しかし、この情報が老人など被害者に伝わらない限り、せっかくの政府の動きも意味を成しません。マスコミが頼れない以上、インターネットでちまちまと訴え、そこから口コミなり何なりで広げることを期待するしかありません。読者のあなた自身、もしくはその友人・知人・親族・縁者・知人の知人などにそういう人がいたら、この情報を回してあげましょう。クーリングオフは原則8日間のみ有効ですから、早い方が有利です。
 オレオレから始まり、それが「ワタシ」やら何やらの亜種に変わり、公務員・会社員名簿などを使った巧妙な詐欺、勝手にツボやら電波を送りつけてきて督促状を送ってくる詐欺、果ては弱者を打ちのめす今回の雪下ろし詐欺など、詐欺の火種は尽きません。この場合に最も有効なのは、インターネットを置いて他にはありません。
 悪いことをすると必ず報いを受けるのは、ライブドアの堀江を見ての通りです。だから「墓穴ホリエモン」であり「ホラエモン」なのです。私は国民の命を売り渡した伊藤、安倍、武部の悪人トリオ・悪人3兄弟にも天罰が下ることを強く望みますが、詐欺が栄えるためしはありません。雪下ろし詐欺も電波送りつけ詐欺も絶対に衰退しなければなりませんし、実際に衰退することになるでしょう。
 私のブログなど微小以下の微小な影響力しか持ちえませんが、それでも「A級メディア」の端くれとして、どれほど微力であっても「悪いこと・悪いもの・悪い権力」への反発は捨てたくないものです。
カテゴリ [開発魔法][社会問題][経済・知的財産][ゲーム開発] [トラックバック 0][コメント 0]

安倍・次期死傷候補
2006/01/18(Wed)18:58:24
 不正会社ライブドア、宮崎被告の死刑確定にまぎれている偽装建築ヒューザー社長証人喚問。脱法か合法スレスレかの違いはあるとはいえ、ライブドアが不正をしていることは以前から分かっていましたし、宮崎被告への死刑判決確定も前々から予想されていたことですから、実際にはこれが最も重要です。
 あれだけ証言拒否が多くては、まだ何とも言えません。しかし、これだけは言い切ることができます。「安倍を首相にしようなどというバカな考えは捨てましょう」。地震大国たる日本にとって、建造物の耐震偽装は未必の故意による殺人とさえ定義できます。それを献金で許すような政治家も同罪です。そんな人殺しまがいを首相にするなどとんでもない話です。
 阪神大震災から11年、まさに「阪神大震災を忘れるな」です。少なくとも、建物が最悪でも耐震基準さえ満たしていれば、大地震が来ても被害はそれなりに抑制できます(「経費節減のため耐震基準はギリギリで満たせ」と言われている現状ではどれだけ効果があるかは分かりませんが、耐震基準50%以下などという建造物よりよっぽど安全です)。逆に、建物がスカスカなら、被害は大幅に拡大することでしょう。
 つまり、こういういい加減な建造物を献金1つで許す政治家など本来なら存在すらしてはいけないのです。「国民の命を売り渡している」と言い換えることもできます。そして、私は以前から何となく安倍氏にそういう雰囲気を感じていたのですが、やはりそうでした。彼は献金と引き換えに国民の命を平気で売り渡すことができるような人間です。
 これは安倍氏に限らず、オイシイ武部にしてもそうです。だからああして必死で偽装建築者をかばおうとするのです。安倍氏にせよ、武部氏にせよ、やましいことが全くないのなら、知らぬ存ぜぬで通す必要などありません。しかも、伊藤氏まで一枚かんでいるというではありませんか。自民党を舞台にした壮大な偽装建築の可能性が高いです。
 事実、自民党はヒューザー社長の証人喚問を拒み続け、このままではまずいと気づいてからようやく応じたという経緯があります。以前の証人喚問では、ひたすら自分の演説を繰り返し、時間を潰していました。自民党、特に「伊藤・安倍・武部」の3悪が絡んだ組織的な建築偽装と考えない方が不自然です。
 当然ですが、この問題はまだ終わっていません。終わらせてはいけません。ヒューザー社長が「刑事訴追の恐れがある」と証言拒否している以上、「訴追されるようなことをしている」と考えなければなりません。また、政治家と絡んでいるのもほぼ確実であり、その点をうやむやに終わらせるいつものパターンを繰り返してはいけません。地震大国たる日本にとって、真相を究明できないのでは命にかかわります。
 おそらく安倍などの政治家連中は、すでに根回しを開始しているでしょう。マスコミを操って核心に触れるような情報を潰したり、事件の追求や伊藤氏証人喚問要求の動きを妨害したり、警察の捜査に圧力をかけたりしているものと考えられます。しかし、ここで政治家連中の意図にハマっていては、阪神大震災の悲劇を繰り返すことになります。
 安倍氏曰く「行動に一点の曇りもない」そうですが、当たり前です。全部曇っているのですから。犯罪者が全員「私がやりました」と素直に認めるようなら、未解決事件など出ませんし、警察も必要ありません。安倍氏にかかわりがないわけがないのです。
 真相究明がなされるまで、この事件を風化させてはいけません。

 ところで、私は昨日「ライブドア問題について、あんなのを候補に立てたことを謝罪するなら私は自民党を見直す」と書きましたが、期待はずれ。小泉曰く「会社でも採用した方が不祥事を起こしたから採用が間違っていると言えるのか」。政治家の次に無責任なマスコミ連中ですら、毎日新聞は女児殺害した時に謝罪しました。確かに、大量破壊兵器でニセ情報を垂れ流しておいて謝罪しないマスコミを私は知っていますが、別問題です。
 この問題に関しては、また新しい情報が続々出ているのですが、中には何と「買収自体が資金調達のために作られた物語」という情報まで。不正も不正、何とも狡猾です。安倍も堀江も「私は関与していない。知らない」を繰り返しますが、知らないわけがないでしょう。下っ端だけの判断でできることではありません。
 実際、こんな奴が議員にならなくて本当に良かったです。仮に政治家になっていたら、自分の権力を利用して、もしくは自民党が「事実上公認の当選者が不祥事を起こしたのでは立場が悪い」ということで、警察に圧力をかけて問題をもみ消していた可能性すらあるのですから。
 私は広島6区の皆さんの良識に感謝します。ここまで来たからには、まさか「次の選挙にも出たい」などと厚顔無恥なことは今さら言い出さないでしょうが、仮にそういうフザけたことをほざき始めたら、再び良識を見せてくださいますよう本気でお願いいたします。

 書き忘れていましたが、Servlet Chatの携帯電話対応化の際の小話を。PerlではIPなどの情報取得の際、環境変数ハッシュ(ENV)を用いるのですが、Servletにも一応これを取得するメソッドは用意されています。ただし、PHPのように「getenv("REMOTE_ADDR")」とは記述せず、request.getRemoteAddr()のようにメソッドを呼び出して取得します。
 ところが、どういうわけかユーザーエージェント情報を得るメソッドが見当たらないのです。これがなければ、使われているブラウザがIEなのか、NNなのか、その他のブラウザなのか、携帯電話なのか、といった区別すら行えません。これでは携帯電話対応のコードを書くなど夢のまた夢です。
 そこで用いるのがこの記述。
Pattern p = Pattern.compile("(?:DoCoMo|UP\\.Browser)" ,
	Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher(request.getHeader("User-Agent"));
boolean phone = m.find();
 これで携帯電話かそうでないかを識別することができます(ちなみに「UP\\.Browser」の部分ですが、「.」は正規表現で定められた命令文字ですから、普通に文字としてマッチさせるにはエスケープしなければなりません。ところが、単なる「\」はJavaの規則によって文字列のエスケープシーケンスとみなされてしまいます。つまり「\\」とすることで、Javaはこれを「\」と解釈し、それが正規表現に渡されます。ボーダフォンのエージェントは失念)。
 そしてRegexはここでも偉大でした。
 ついでに、昨日扱った「ダーティー読み込み」について。あまり良い言葉ではない気がしますが、スペルが違うのでしょうか。しかし、原文を確かめてみても、やはり「Dirty Reads」でした。どういう意味で名づけられたのでしょう。
 「Phantom Reads」なら「トランザクション中はデータの独立性が保たれる仮想(ファントム/幻影)テーブルが作られ、それを読み取る」という意味であることが何となく分かりますが、「Dirty Reads」とは。「データに汚れが混入する恐れがあります」というのでは、いくらなんでも。トランザクションの意味がなくなるため、普段使わないことは確かなのですが。
 それにしても、Java側で使えているということは、MySQLをプロンプトなりPerlなりで使う際にもトランザクションレベルを設定できるのでしょうか。というわけで調べてみたところ、しっかり用意されていました。
// 次のトランザクションでファントム読み込みを抑制
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;

// 今後あらゆるトランザクションでダーティ読み込み
SET GLOBAL TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

// 今後この接続のトランザクションでファントム読み込み
SET SESSION TRANSACTION ISOLATION LEVEL READ REPEATABLE READ;
 また、これらのトランザクションの設定によって「LOCK IN SHARE MODE」(書き込みロック)及び「FOR UPDATE」(読み取りロック)の動作も変わるとのことです。
 Tactical Revolutionに久々に新ステージを実装。完全にハマってしまった人からの要望です。目玉としては、とりあえず新クラス「アークパラディン」の聖騎士シェインが出ます。
 性能は軒並み高く、パラディンと違って固有クラスですから、その強さはかなりのものです。移動タイプは水中、移動力は6、装備アビリティ種別は「小剣・剣・大剣・剣技・弓矢・槍・斧・盾・回復1-3・支援1-3」となっています。装備からしてパラディンより幅広いです。しかもCONが12もあるため、リカバリーが連発できるのも強みです。
 ステージの概要としては、せっかくの騎士サーラと聖騎士シェインを操作できません。ただ、味方ユニットとして戦闘には加わってくれます。ステージが2つに分割されているのですが、片方が明らかに戦力不足になりますから、ディスパッチウィンドを使って飛び回らなければなりません。
 プレイしてみると、パラディンが意外に強いことが分かります。汎用クラスのくせに、やたら強力なのですから。さすがは年に1人しか出ない聖騎士だけあります。これ全部を制限ターン以内に撃破しなければなりません。私がプレイした際には13ターンでクリアでき、制限ターンは16ターンですから、そこまで厳しいターンではありません。ただ、マゴついているほど余裕があるわけでもありません。
 ディスパッチウィンドを効率的に使い、サクサク進めていくことが重要です。念のために書いておきますが、ディスパッチウィンドは敵に用いることはできませんが、他軍の仲間に用いることは可能です。これで敵軍に一気に突っ込む場面など、将棋の「持ち駒」を髣髴とさせます。将棋の場合は飛車も歩兵に一撃でやられますから、活用場面は限られるのですが、サーラさんの力は一般騎兵2000人分。ひたすら攻めましょう。
カテゴリ [開発魔法][社会問題][ゲーム開発] [トラックバック 0][コメント 0]

節度あるふりを申し合わせ
2006/01/10(Tue)17:12:36
 あなたがJavaを選んだのは。Tactical RevolutionもTyping WindもJavaアプレットで、ServletもJavaで動作するサーバーですが、それではどうしてJavaなのでしょう。
 とりあえず1つ目に「ダウンロードなしでも高度なものが動かせる」点があります。Tactical Revolutionなどは、ダウンロードゲームとして提供することもできたわけですし。それがアプレットとしてブラウザで動いてしまいます。この手軽さは、他にはせいぜいShockWaveでしか出せませんが、あいにく私はツールを所持していません。
 2つ目は、やはりOS関係なく動くことでしょう。世間のほとんどのPCはWindowsとはいっても、未だ95で動いているものも一部にあるようですし、20人に1人程度はMacintoshを使っているのでは。プラットフォームをまたいで動作するソフトウェアといえば、何といってもJava、しかも1.1ベースのVMしかありません。
 ですから、当サイトのゲームは(余程古くない限り)どのようなPCでも、自宅のPCでも、知人のPCでも、ネットカフェのPCでも、会社のPCでも動きます。ダウンロードゲームではないので証拠も残りません。実際にそういう遊び方をしている人もいるとかいないとか。そもそもJavaの理念が「どのPCでも同じように見えて同じように使える」ですから。
 Javaを使えば、携帯電話向けのゲームを作ることもできます。以前に携帯電話でのJavaゲームを他人数名に見せてもらったことがあるのですが、もちろん私もこうしたゲームを作ろうとすれば、作ることは一応可能なはずです。操作インターフェイスが違うのと、SEではなくMEを使わなければならない点を除けば、言語形態も同じです。
 ところが、私がこれをしない理由は何といっても「互換性」です。Javaの理念に反し、携帯電話自体は似たようなものなのに、動作の面で各社に互換性がないのです。携帯電話は容量制限が厳しいですから、Tactical Revolutionのようにクラスファイルだけ圧縮しても何百KBもあるような大作を作ることは到底不可能ですが、それなりのものを苦労して作った挙句、特定の端末でしか動かないというのでは。
 先日の「HDML」もau独自の言語でしたが、結局はXHTMLに取って代わられました。あの時も散々苦労したのですが、たった1社の携帯電話のために仕様を習得するなどといったことを繰り返していては、日が暮れてしまいます
 それにしても気になるのが、携帯電話のJavaは組み込みであり、ユーザーが削除したりアップグレードしたりすることはできません。SEでは例えばEvent/EventListenerクラスなど、アップグレードで挙動がガラッと変わってしまったクラスも存在しますが(しかもそれが「推奨されていません」の一言で片付けられる)、携帯電話ではこういうことはないのでしょうか。

 というわけでTactical Revolution。小さなところを手直ししてみました。これで敵が少しばかり強くなっていることでしょう。
 具体的には、ファイアーボールとコンフラグレイションの2つのアビリティを持っているキャラが隣接した敵を攻撃するような場合、以前まではMR消費を判定に加えていなかったため、後者を使用することがありましたが、今回からはどちらを使っても同じなら、MR消費がより少ない方を使ってきます
 無論、これは「どちらを使っても同じ」場合のみです。サンダーボルトで3、4人巻き込んでくるような状況で、ファイアーボールやコンフラグレイションを使ってくれるほど生易しくはありません。しかも、サーラさんは鎧でガチガチなだけに雷耐性が少しばかり低いため、ファイアーボールが使える状況でも敵はわざわざサンダーボルトを使ってきます。あくまで「条件が全く同じならMR消費量を検討」するだけの話です。
 もう1つ、どちらかといえばこちらの変更の方が重要な気もしますが、アンデッドでLAがゼロ以下のキャラと、LAが1を上回っているキャラがいれば、敵は動ける方のキャラを攻撃してきます。これは非常にいやらしい仕様ではありますが、欠点として「生存者を攻撃できる場合は何が何でもそちらを攻める」ようになっており、ディメンジョンを使ったり、防御に有利な地形に立たせることで、生存者に対して絶対に攻撃が通用しない状態にしても、そちらを攻撃するようになっていました。人間ならまずやりません。
 そこで、今回からは「攻撃が全く通用しない場合は死者を追撃」する実装に変更しました。ひどいのなんの。言うまでもなく、全条件が同じならよりLAのマイナスが少ないキャラを攻撃する実装は健在です。これだから敵が強くてたまらないのです。
 このように複雑な敵思考ですが、次にコマンダーバトルのようなものを実装する際には、もう少し簡単にまとめようかと考えています。例えば「こちらから攻める」「射程に入ったら攻める」「その場を守る」「逃走」といった程度の命令でも、それなりに細かい指示を出すことは可能ですし。ただ、プリースト系がかなり突拍子もない行動を取りそうではあります。
 具体的には、今のところ思考パターンとして「接近」「攻撃」「回復」「逃走」の4つの処理が存在するのですが、例えば「戦乙女」は攻撃と接近の組み合わせです。また、「接近」思考では攻撃が通用しない相手に対しても見境なく攻撃を仕掛ける(しかも攻撃アビリティを持っていなくても敵に突進)のに比べ、「攻撃」では辛口のCPUになりますから、例えば「射程に入ったら」思考を「回復 + 攻撃」にしておけば、これをプリーストに指示したとしても、通常はプリーストの攻撃など敵には通用しませんから、回復に徹してくれます。剣聖やパラディンであっても、回復魔法だけ持たせておけば、回復に徹してくれます。
 このような具合に、マップ作成時は敵に持たせるアビリティにもなかなか気を使います。「空中庭園摩天楼」のステージでは、当初ヴァリアスナイト全員にコンフラグレイションを持たせていたのですが、2ターン目にサーラさんの受難。コンフラグレイション10連発で戦線離脱。これではゲームにならないため、アビリティを変更した裏話があります。

 ついでに当サイトの逆引きアクセスCGIについて。このサーバーがMySQLの4.0しか使えないというので、ローカル版ではサブクエリを使って「○時間は同IPからのカウントを行わない」仕様を実装したのですが、こちらでは妥協して「前回と同一IPはカウントしない」ことにしています。
 しかし、そうするとやたら「Favorites」が水増しされてしまいます。例えば私がブログのページを開き、投稿が終わってトップページに戻って来るまでの間に、他の誰かがサイトにアクセスしていれば、それだけでFavoritesが1つ水増しされることになります。時間制カウント防止機構をサブクエリなしで、しかもSQLだけで実装する方法はないものでしょうか。と考えてみるも、あるならとっくの昔に実装しています
 やむを得ません。どうせ全く難しくない作業なのですから、横着せずにコードを書くことにします。SQL関連の記述はwhileが多く、うっかり文字1つ間違うだけで無限ループになってしまうため、書くのはかなり消耗するのですが、仕方ありません。
 といっても、要は今回の場合「8時間以内のアクセスに同じIPがあればカウントしない」というだけの話ですから、単純に
table raccess
url	VARCHAR(255)
dates	DATETIME
ip	VARCHAR(15)
host	VARCHAR(255)

SELECT ip FROM raccess 
WHERE ADDDATE(dates , INTERVAL 8 HOUR) > NOW()
 で手に入れたデータをループさせて読み取った上で、1つでも同じIPが見つかったら更新しなければ良いだけの話です。スクリプト側で書いても簡単ではありますが、サブクエリさえあればこれが一発でできてしまうのですから、どちらにしても早く4.1か5.0にして欲しいところです。
 と、ここでふとひらめきました。どうせスクリプト側で判定するなら、これでも構わないのでは。
SELECT 1 FROM raccess 
WHERE ADDDATE(dates , INTERVAL 8 HOUR) > NOW() 
AND ip = ?

? : IP アドレスのプレースホルダ
 当てはまるものがあれば、当てはまった数だけ「1」が返ってくるわけです。後はデータが1つでも読めれば同じIPがあったとみなせます。別に「LIMIT 1」を加えたり、「COUNT(*)」として出てきた個数を確かめたりしても構いませんが、とりあえず最もシンプルな方法です。これならわざわざループする必要もありません。簡単ではありませんか。
 サブクエリと違って、このデータをbooleanとみなしてさらに条件を重ねたりといったことはできませんが、サブクエリが使えないなら使えないでそれなりに何とかなってしまうものです。

 さて、またしても「過剰な反フェミニズム思想」が社会に害悪をもたらしました。
 何でも、東京の方で行われることになっていた人権学習講座に招かれるはずの東京大学院教授が、「女性学の権威だ」という理由で「ジェンダーフリー」といった用語を使用するなどと勝手に決め付けられて東京都の教育庁が講師を拒否、結局講座計画自体が破綻したとか。バカげていますが、本当の話です。
 この教授が「女性学」の権威だからと拒否したのなら、とんでもない話です。さらに、この教授が「女性」だからと拒否したのなら、なおさらとんでもない話です。次元の低い国旗国歌騒動といい、最近の東京都はすさまじく愚かな気がするのですが。たかが天皇ごときに女系が出るのより、こちらの方が何倍も重要なニュースであることだけは確かです。
 この件は覚え書きにとどめるとして、次です。「先の脱線事故で、JR東が病院の要請で取材を自粛するよう報道各社に申し入れたが、そういう事実はなかった」というニュース。いわば、JRが病院の発言をねつ造した形ですから、言うまでもなくほめられた話ではありません。批判を浴びるのも当然というものでしょう。
 しかし、JRに肩入れするわけではありませんが、あまり責める気がしないというのも本音です。例えば私がJR東の事故対応に当たる人間で、「せめてもの罪滅ぼしに、マスコミの非人間的な取材を少しは軽減して被害者の負担を少しでも減らしたい」と考えたとします。その場合、マスコミにどのように申し入れるのが良いでしょうか。
 素直に「取材を自粛してください」と言えば通じるほどマスコミのオツムがしっかりしているなら、最初からスクラムなど問題になりません。そんなことを言えば、あっという間に「JR東の責任逃れ 報道各社に取材自粛要求」と書かれることでしょう。これではJRの立場はなおさら悪くなりますし、当然スクラムも回避できません。
 それなら、どのように言うべきでしょう。「負傷者が嫌がっているから取材を自粛してください」では「嫌がっていない負傷者に取材させて」と返されますし、やはり「病院から自粛要請があった」と答える他ありません。後はそれが明るみに出なければ、被害者もスクラムが減って助かりますし、適切に済んでいたはずなのです。
 これはさすがにJRを評価しすぎですから、もう少し普通に考えてみます。先の尼崎脱線では「休暇中のボウリング」を批判したり、「社長を出せ」と暴言を吐くなど、マスコミの横暴が目立ちました。そして、今回もまた「JRだから」という理由だけですでに叩かれていました。JRはJRでも関係者は全員別人なのですから、「江戸の敵を長崎で討つ」ようなものです。以前にあんな醜態を見せられては、取材の自粛を申し入れたくなるのは当然です。
 その他、最近気になるのが、まさに「散々スクラムをした挙句、遺族から要望書が来てようやく節度ある取材を申し合わせ」の繰り返しです。しかも、「節度ある取材の申し合わせ」など、政治家の「景気を回復し、減税します」といった主張と何ら変わりません。マスコミの「申し合わせ」なるあいまい文言より、気象庁の半年天気予報の方が、よっぽど信用できます。
 そういえば、以前に広島女児殺害の遺族からの写真提供について「遺族がスクラムを嫌って提供したのでは」と予想を立てたことがありましたが(05/11/25分の記事を参照)、これが当たらずといえども遠からず。警察を通して伝えられた遺族のコメントによると、「このまま節度ある取材を続ければ、女児の写真3枚を渡したい。今後はこの写真を使ってほしい」ということでした。写真と引き換えに報道各社を黙らせたわけです。
 ちなみに、上の山形脱線についても、病院が「取材に応じる意向の被害者2人に対して、取材の便宜を図るから、他の人には取材しないで」と交渉したとか。対北朝鮮外交でもあるまいし。確かに「知る権利」は重要ですが、「好奇心を満たす権利」などありません。そこのところを拡大解釈した挙句、よくもまあ平気でこんなことができるものです。
 一部にはひどい警察もありますが、大部分の警察は被害者に配慮するようになってきています。報道機関は「警察の恣意的運用」を理由に被害者の匿名発表に文句をつけていましたが、では逆に問いたいのが「警察権力を監視すると言っていますが、Winny問題で警察権力に不当逮捕された人に対して、あなた方は何か支援をしてあげましたか?」。Winnyのような人命にかかわらない問題でさえ警察権力を止められないような連中が、殺人やテロといった大事件で警察権力の横暴を止められるわけがないでしょう。
 インターネットなどの普及によって多くの人が報道のひどさを知った今、被害者重視の機運が高まりつつあるのは分かります。今年が「報道被害解消元年」となることを願っています。
カテゴリ [開発魔法][社会問題][ゲーム開発] [トラックバック 0][コメント 0]

拉致・誘拐推進国家
2006/01/08(Sun)21:03:30
 さあ、明日は楽しい成人の日です。何がって、何を考えているのか全く意味不明な新聞社連中が「新成人へのエール」と称して意味不明なことをほざいて貴重な社説のスペースを潰すのがに決まっているでしょう。読んでみて「必死で文章をひねり出して書いた」ことが伝わる割に、「でも誰も読まないに違いない」という事実がミックスされて面白いのです。
 もし面白そうな記事がありましたら、明日の戦記ででも取り上げてみます。そもそも「成人のお祝い」というのは、子どもの多くが病気などで死んで成人できなかった昔と違い、いまやほとんど意味のないことです。成人の日まで子どもで、それを過ぎていきなり大人になるわけでもなし。昔は本当に七五三も成人の日も元服も非常に大きなお祝いにするだけの理由があったのですが、いまや医療技術の進歩でほとんどの人が成人しますから。
 とはいっても、人命の貴重さが変わるわけではありません。というわけで日赤に行ってはみたのですが、何度測っても心拍数が120前後という異常事態。それだけのためにそれなりの交通費を出して時間をかけて遠出したのに、かなりガッカリものでした。ただ、偶然「拉致被害者」の署名活動にバッタリ出会い、署名をしてきました。とにかく早く被害者全員が帰国することを願ってやみません。
 人命といえば、誘拐されていた乳児が無事に保護されました。久々の、まさに「被害者発表匿名化」以来のホットニュースです。その上、容疑者もすでに見つかっています。報道各社が協定を結んでいたのか、警察発表の段階で情報がシャットアウトされていたのかは知りませんが、人命優先のために報道が控えられてきただけに、状況が一気に進展した印象です。
 最近は「子どもが行方不明になっては殺害されて発見される」ような事件が続きましたので、関係者は一同に胸をなでおろしているところでしょう。さすがに今回は、イラクの時のように「火災と言われただけで子どもを手放した親には自覚が足りない。殺されて来い」などと言い出す最低劣悪な人間は存在しなかったようですが、とにかく報道関係者も今後一切の取材などは控えるべきでしょう。
 今回は身代金目的誘拐とのことですが、病院にいても子どもが誘拐される時代なのです。一部報道機関は「病院に見舞いに行ったのに患者の病室を教えない、などというのはおかしい」と個人情報保護の動きを批判していましたが、その「おかしい」ことの尊さを実感させられます。無差別ではなく最初から標的を決めての誘拐などの場合、おいそれと部屋を教えては大変なことになります。
 何にしても、今回は命が助かったので良かったですが、通学路はもちろん塾や病院にいても子どもが誘拐や殺害されるという状況には暗澹とさせられます。その上、小学生ばかりか乳児までもがターゲットになるのですから。本当にひどい世の中もあったものです。これが2006年の日本なのでしょうか。
 通学路の安全については、地域での監視やスクールバスなどでかなり危険を軽減できますが、塾や学校、病院についてはどうしようもありません。学校に関しては、武器を持って乱入するようなのはもちろん、教師も「聖職者」などと呼ばれてはいても人間です。殺されるとまではいかなくても、強制わいせつなどは1件見つかれば100件はあります。登下校中の連れ去り事件にしても、未遂は何千件もあることでしょう。
 私は登下校について「米国式の社会を導入した以上、犯罪が増えるのは至極当然である。今の路線を変えるつもりがなければ、米国と同じくスクールバスを導入するしかない」と主張していますが、では屋外、学校、病院、塾などのすべてから子どもを守る妙案があるかといえば、いくら考えたところでとても出てきません。
 福祉をとことん充実させれば、少なくとも強盗殺人や身代金目的誘拐は確実に減ります。小児性愛などにしても一種の病気であり、本人が直したいと考えている例もあるそうですから、これの治療なども福祉の中に含まれます。また、子どもが犯罪に走らないような環境を整えるのもまた福祉です。そもそも成金野郎の金を民に分配するのが政府の役割のはずです。
 小泉総理では確実に無理ですから、せめて次、次の次といった総理が福祉の充実を徹底してくれれば良いのですが。「通学路」や「病院」などに限ればそれぞれに安全対策は可能ですが、全般的に危険を減らすには、これ以外の手はありません。
 外国には手厚い福祉をウリにする国もあります。逆に、米国型社会は福祉などが最小限ですが、「米国人は個人主義」という印象に反して、車椅子の人を手助けしたり、電車でお年寄りに席を譲ったり、乳幼児を気にかけたりするのは当然という文化があります。ところが日本はどうか。それなりに福祉国家であったはずの日本は、米国型に路線変更しているわけですが、日本には米国のような文化がありません。だからイラク人質なども平気な顔で罵倒できるのです。
 言ってみれば、福祉国家は「国単位での助け合い」、米国は「個人単位での助け合い」なのですが、日本に後者の助け合い文化は極めて乏しいため、米国流に福祉切り捨てだけ導入しても上手くいくはずがないのです。その点で、小泉改革(といっても何もしていませんが)は「絶対に間違っている」と言い切れます。
 国が子どもや老人を大切にしないのですから、国民に子どもや老人を大切にさせることは不可能でしょう。また似たような事件が起こる前に、少しは状況が改善して欲しいと願うばかりですが、これが「夢物語」とみなされるのが現代の日本です。

 この前、データベースをXMLに落とすなどのプログラムを組んでみましたが、これで一応XMLの概念は理解できました。ネームスペースについても、例えば「サーラ」だけだと「Sara」や「Sarah」など聖書に出てくるほど有名なのですから、100%かぶります。ですから、当サイトでは「騎士サーラ」と呼ぶことにしています。この「騎士」がネームスペースの意味になるわけです。
 さて、友人とその話をしていたところ、「XMLって何の役に立つの?」とのお言葉。役に立ってたまりますか、あんな非効率的な記録方式MTをはじめ、このブログでもRSSを採用していますが、これはXMLです。人間が読んでもさっぱり意味が分かりませんが、これがもてはやされていることになります。
 といっても、人間がこれを読むすべがないわけではありません。そのままでは読みづらくても、これを人間にとって分かりやすい形式にフォーマット化すれば読みやすくなります。RSSリーダーなどは、まさにこのフォーマット化を行っていることになります。おかげで、どういうタイトルのどういうブログがいつ更新されたかを手軽に知ることができます。
 しかし、XMLごとに専用のリーダープログラムを作っているのでは非効率的です。例えばServletなどでも、毎回DOMやSAXでパースするプログラムを書くことを考えるとぞっとします。そこで存在するのが「XSLT」と呼ばれるもので、これを使えばXMLのデータをHTMLに書式化することができます。
 XSLTはXML用のスタイルシート言語ですから、それ自体は書式化情報しか持っておらず、XSLT自体にXMLをパースする機能はありません。つまり、XSLT内にはパース関連の記述(データソースを指定したり、ノードを読み込んだり)を書く必要がありません。しかし、XSLT自体がXMLをパースできない以上、サーバーもしくはクライアント側でXMLにXSLT書式を適用するパーサを用意し、それを使ってパースしなければなりません
 もちろんJavaにはXSLTパーサが用意されています。しかし、大半のPCに入っており、ブラウザがサポートしているであろう1.1ベースのVMでは動かないため、やはりここはServletで用いなければ。以前に作ったXML出力プログラムを改造し、XSLTのパースプログラムを記述してみました。
// まず Transformer を構築
javax.xml.transform.Transformer tf = 
	javax.xml.transform.TransformerFactory.newInstance().
	newTransformer(new javax.xml.transform.stream.StreamSource
	("webapps\\ROOT\\xslt.xsl"));

// エンコードを設定
tf.setOutputProperty("encoding" , "Shift_JIS");

// 結果出力用のストリームを設定
javax.xml.transform.stream.StreamResult sr = 
	new javax.xml.transform.stream.StreamResult(out);

// XMLにXSLTを適用して出力
tf.transform(new javax.xml.transform.stream.StreamSource
	("webapps\\ROOT\\db.xml") , sr);
 JSPですから、outをそのまま渡せば書式化したものをブラウザに出力してくれます。ここで使っている「db.xml」は、おそらく説明するまでもありませんが、この前作った「データベースの中身をXML化するプログラム」によって生成されたものです。このXMLの構造についてはこちらを見ていただくとしまして、次は「xslt.xsl」がなければ話になりません。
 といってもXSLTには初めて触れる私。有志翻訳のW3Cの日本語マニュアルを読みながら、四苦八苦して作成しました。とりあえず重要なのは「for-each」です。今回のXMLの場合、データはDBのレコード数やカラム数によって可変になりますから、最初から数が決まっていては話になりません。レコードは1つかもしれませんし、100個かもしれません。カラムにしても、1つだけのことがあれば、10項目あることもあります。XSLTでそれらを表示する方法は、for-eachを置いて他にありません。
 そんなこんなで今回作ってみたxslt.xslはこちら。
<?xml version="1.0" encoding="Shift_JIS"?>
<xsl:stylesheet 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">

<html>
<head>
<title>XSLT</title>
</head>
<body>

データベース yamicha のXMLを整形して表示しています。<br />
<br />

<xsl:for-each select="yamicha/Table">
<b><xsl:apply-templates select="@name" /></b>
<table border="1" cellspacing="0">

<xsl:for-each select="Record">
<tr>
<xsl:for-each select="Column">
<td><xsl:apply-templates /></td>
</xsl:for-each>
</tr>
</xsl:for-each>
</table>
<br />
</xsl:for-each>

</body>
</html>

</xsl:template>
</xsl:stylesheet>
 こうすることで、データがテーブルに変換されて表示されます。しかし、良く考えてみるとこのデータ、カラム名がないではありませんか。実はこれが厄介なのです。前に作ったdb.xmlは、まさかXSLTで書式化することになろうとは考えていませんから、カラム名の一覧など用意していません。ただ、Column要素のname属性にカラム名が入っているのみです。
 これを使ってカラム名を表示するにはどうするか。これはしばらく考えました。db.xmlの構造を変更するのが最善に違いないのですが、今回はそこまでやる気はありません。今回のXMLの場合、単なるfor-eachではカラム名表示が不可能なことだけは確かです。
 しかし、困り果ててW3Cの資料の「if」の項目を読んでいた時に、ようやくひらめきました。
<?xml version="1.0" encoding="Shift_JIS"?>
<xsl:stylesheet 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">

<html>
<head>
<title>XSLT</title>
</head>
<body>

データベース yamicha のXMLを整形して表示しています。<br />
<br />

<xsl:for-each select="yamicha/Table">
<b><xsl:apply-templates select="@name" /></b>
<table border="1" cellspacing="0">

<tr>
<xsl:for-each select="Record">
<xsl:if test="position() = 1">
<xsl:for-each select="Column">
<td bgcolor="#BBDDFF">
<xsl:apply-templates select="@name" />
</td>
</xsl:for-each>
</xsl:if>
</xsl:for-each>
</tr>

<xsl:for-each select="Record">
<tr>
<xsl:for-each select="Column">
<td><xsl:apply-templates /></td>
</xsl:for-each>
</tr>
</xsl:for-each>
</table>
<br />
</xsl:for-each>

</body>
</html>

</xsl:template>
</xsl:stylesheet>
 db.xmlの生成コードの性質上、NULLや空白などの値に対してもColumnタグの生成は行われますから(<Column name="column_name"/> のようにテキストノードのないタグが生成される)、Columnタグをループさせてname属性を取り出せば、必ずカラムを網羅することができます。さらに、position()はループのインデックスを返しますから(0ではなく1から始まるので注意)、ifを用いて1の場合のみ処理するようにしてやれば、カラム名の表が生成されるのはRecordの最初のループの時だけになり、レコードの数だけカラム名のリストが生成されるようなマヌケなことはなくなります。
 このXSLTを通してパースしたデータベースは、以下のように表示されます。

データベース yamicha のXMLを整形して表示しています。

sample
numbername
0イリアス
2管理者
1サーラ
3ハードゥン
4シェリー
(以下、XMLに記録されたDBの数だけテーブルが出るだけなので割愛)

 XSLTもなかなか面白いものです。これを上手く使えば、例えばRSSを読みやすい形に整形したりといったこともできてしまうわけですか。使う機会があるかはひたすら疑問ですが、XMLのデータがすでに存在する場合には、それを書式化する言語としてそこそこ便利なので、記憶にとどめておくとしましょう。
 JSP版のRSSリーダーも作ってみたいのですが、私のPCをサーバーにした時でなければ使えないのではとことん無意味です。そしてXSLTでもイリアスさん大活躍

 ここまですっかり忘れていましたが、魔道士イリアスといえばTactical Revolutionで「スムーズ スクロール」を導入しました。あのゲームではカーソルを画面端に持っていくとスクロールしますが、スクロール速度は常に一定に設定されていました。状況によっては、スクロールが速すぎたり遅すぎたりすることもままありました。
 そこで今回の機能なのですが、カーソルを画面端に近づけるほど高速でスクロールします。最高なら以前の2倍の速度で、最低では1ピクセルずつ動かすこともできるため、ゲームをプレイする上ではかなり効果的です。マウスやタブレットなど、繊細なカーソルさばきが可能なデバイスをお使いなら、非常に便利です。
 逆に、ノートのポインティングデバイスなど使いづらいデバイスをお使いの方は、「設定」から使用の有無を切り替えできます。ここで本機能を使わないように設定すれば、スクロールの仕様は以前と同じになります。デフォルトでは「使う」ことになっていますが、普通のデバイスならこちらの方が断然便利です。
 今回企画では、操作性の最適化といった芸の細かさにこだわったのですが、この機能もそれの集大成ということで。簡単そうに見えて、実装は意外と大変でした。
 芸の細かさといえば、実は「画面外にカーソルを出すとスクロールが止まる」のもちょっとした配慮です。わざわざmouseExitedで命令をキャッチしてカメラ移動の設定を変更しています。ゲーム中にカーソルを画面外に動かし、他のウィンドウを参照した後でゲームに戻ってもカメラが勝手に移動していないのはこれのおかげ。
 「一見どうでも良さそうなところにもこだわる」「操作性へのさりげない配慮」「植物の根は見えないが、根がなければ花は咲かない」。そういうサイトやプログラムを作りたいです。
カテゴリ [開発魔法][社会問題][ゲーム開発] [トラックバック 0][コメント 0]

名づけて「ガンマ戦争」
2006/01/05(Thu)15:07:42
 重い話題も何なので、まずは軽い話より。
 以前、福岡銘菓「ひよ子」(日本全国どこにでもありますが、材料の関係で福岡のがおいしいらしい)がヒトデやコウモリのサブレを本当に作っていましたが、本当にどうしてもひよ子でなければいけないものでしょうか。これは「ひよ子サブレ」だから売れているのでしょうか。
 そこで、Apache Tomcatのロゴの絵を描いて「トムキャット サーブレット」と題して母や愚妹に見せてみたところ、なんともらっても食べたくないとのお言葉。何たることでしょう。Tomcatとはそれほどヒドいロゴなのでしょうか。どうやら、ひよ子サブレはひよ子だから売れているようです。ヒトデやコウモリやトムキャットではいけないようです。
 さて、それではServletと参ります。といっても、戦記ではこれまでほぼすべての主要なServletの機能を取り扱い、APIドキュメントもほとんどが既読色になっています。拡張タグについては、今後気が変わる可能性はありますが、はなっから「取り扱わない」と決めていますから(そもそもJSPの機能であってクラス版のServletではほとんど無意味)、それを除去すれば未読色のリンクは「SingleThreadModel」インタフェースのみです。
 ややこしそうな名前ですが、メソッドは1つも存在せず、「インプリメントすれば1度に1つのスレッドしか使われないことが保証される」とのこと。何となく分かるような分からないような。何でも良いですが、とにかく使ってみます。推奨されていないようですから、単なる実験用ということで。動作はコンテナ依存でもあるようです(ちなみに環境はTomcat 5.5)。
// クラスの宣言
public class ClassName extends HttpServlet
	implements SingleThreadModel{
	public void service(HttpServletRequest request ,
		HttpServletResponse response)
		throws IOException, ServletException{
		PrintWriter out = response.getWriter();
		// ここにコードを記述
	}
}
 で、serviceメソッドの中身を色々変えて実験してみたのですが、
// 用例.A
long time = new Date().getTime();
while(time + 10000 > new Date().getTime())
	;
out.println("Start Time : " + time);
out.println("End Time : " + new Date().getTime());
 これで同時にアクセスされないと考えていたら甘かった。ブラウザを2つ開いて試してみたところ、しっかり同時にアクセスできます。もちろん一方の終了時間の前にもう一方の開始時間が食い込んでいます。こんなもので出入力の排他制御などやろうものなら、とんでもないことにならないでしょうか。
 となると、単に「それぞれのリクエストごとに新しいインスタンスが生成されている」ということになるのでしょうか。
// クラスの冒頭で
int count;

// Service内
count ++;
out.println(count);
 やっぱり撃沈。読み込むたびにしっかり数値は増えていきます。インスタンスが新しくできているわけでもなさそうです。それならということで、正しく変数の同期化が行われているかどうかを調べてみたところ、
count ++;

long time = new Date().getTime();
while(time + 5000 > new Date().getTime())
	;

out.println(count);
count ++;
 このプログラムの場合、普段は奇数のみしか出力されませんが、ウェイ途中に他のスレッドがデータにちょっかいを出してくれば、偶数が表示されることになります。これで試してみたところ、確かに偶数のデータが出ないことは保証されます。ところが、表示される数値がムチャクチャなのです。
 例えばブラウザを2つ開き、片方がウェイト中にもう片方でも読み込んでみれば、どういうわけか両方のウィンドウで「1」が表示されたりします。両方のウィンドウで適当にアクセスを繰り返すと、片方のウィンドウで「11」が表示されたばかりなのに、もう片方では「9」が出たりします。片方が読み込み終わったらもう片方、のように表示したり、1つのウィンドウで読み込んでいる限り、こういうことはありません。
 もう大混乱。一体どうなっているというのでしょう。しばらく悩みました。が、考え込んでも仕方がありません。それでは同期化をsynchronizedによって明示的に行ったらどうなるのかと、またもや実験してみました。
synchronized(this){
	long time = new Date().getTime();
	while(time + 5000 > new Date().getTime())
		;
}
 結果、全く効果ありません。それどころか、SingleThreadModelなしの時より悪化しています。結果は以下のようになりました。
ウェイトは5秒(5000ms)、スレッドA実行の2秒後にスレッドBを実行する

・SingleThreadModelなし
Thread A Start : 0
Thread A Lock : 0
Thread B Start : 2
Thread A End : 5
Thread B Lock : 5
Thread B End : 10

・SingleThreadModelあり
Thread A Start : 0
Thread A Lock : 0
Thread B Start : 2
Thread B Lock : 2
Thread A End : 5
Thread B End : 7
 明らかに変です。ということで、以上のデータを総合してしばし考えてみた結果、通常は1つのインスタンスを複数の接続にまたがって実行しているが、SingleThreadModelでは接続の数だけスレッドがあるのではないかという結論に行き着きました。つまり、スレッドの配列のようなものがあり、同時接続が1件だけなら1つ目のスレッド、2件以上なら2つ3つと使われていくのではないか、というわけです。
 そこで実験に使ったのが以下のプログラム。
count ++;
long time = new Date().getTime();
while(time + 5000 > new Date().getTime())
	;
out.println(count);
 これをまず繰り返し実行し(ただし同時には実行しない)、カウントを増やします。いくらかカウントが増えたら、2つのウィンドウで同時に実行します。これで証明は完了、片方の数値は以前のカウントに+1した数値、もう片方の数値は1になりました。つまり、配列に例えるなら、普段はthread[0]が実行され、これが実行中ならthread[1]が呼ばれるというわけです。thread[1]はthread[0]が実行中の時でなければ呼ばれませんから、普段はthread[0]の数値を参照しつつ、同時読み込みの場合のみthread[1]が参照され、上の実験でメチャクチャな数字が出ていたのです。また、スレッドごとにインスタンスが違うわけですから、synchronizedは意味を成しません。
 ということは、です。Googleで検索した結果、排他制御に近い形で使用しているような例をいくつか見かけたのですが、これはかなり危険なのでは。やっつけ仕事で申し訳ないのですが、即席でいい加減なソースを作って試してみました。
File file = new File("適当なディレクトリ\\text.txt");

byte b[] = null;
if(file.exists()){	// ファイルがあるなら読み込み
	FileInputStream is = new FileInputStream(file);
	b = new byte[is.available() + 1];
	is.read(b , 0 , b.length - 1);
	is.close();
}else	// ないなら空白のバイト配列を作る
	b = new byte[1];

// これが掲示板やチャットなどであれば、ここでデータの処理
// 今回はデータ処理の代わりに5秒のウェイトをはさんでいる
long time = new Date().getTime();
while(time + 5000 > new Date().getTime())
	;

b[b.length - 1] = 'A';	// 配列末尾に「A」を挿入

FileOutputStream os = new FileOutputStream(file);
os.write(b);
os.close();
 1度読み込むと「text.txt」が生成され、内容は「A」になっています。もう1度読み込むと、内容は「AA」に更新されます。どうやら動作に問題はないようです。
 それでは実験です。2つのブラウザからこれを同時に読み込んでみます。すると懸念は大当たり。2度読み込んだにもかかわらず、内容は「A」が1つ増えただけの「AAA」なのです。本来なら「AAAA」でなければならないはずなのですが。もう1度同時に読み込んでみると、今度は「AAAA」になっています。やはり「A」は1つしか増えていません。
 つまり、例えば何かしらのデータを読み込み、それを処理している間に他のスレッドに割り込まれると、データは壊れてしまいます。これなら前の変更が消えるだけなのでまだマシですが、最悪OutputStreamのフラッシュ中に他のスレッドが割り込めば、データはあえなく破損します。見ての通り、SingleThreadModelをファイル出入力の排他制御に使うのは極めて危険です。絶対にやめましょう
 これの使い道としては、例えば適当なクラス変数があるとして、それに対してリクエストごとに独自のデータを格納したいような場合(例えばserviceメソッドの冒頭でユーザー名を格納し、それを別のメソッドで用いたい場合など)に威力を発揮するでしょう。synchronizedロックと違って他のユーザーのスレッドを止めることもありません(Tomcatの場合)。
String name;

public void service(...){
	name = request.getParameter("name");

	long time = new Date().getTime();
	while(time + 5000 > new Date().getTime())
		;

	viewName(response.getWriter());
}
private void nameView(PrintWriter out){
	out.println(name);
}
 このような場合、SingleThreadModelでなければ、例えば「?name=ilias」という人がアクセスしてきて、ウェイト中に「?name=sara」という人がアクセスしてきた場合、イリアスさんのブラウザに「sara」が表示されてしまいます。これはsynchronizedで回避できるのですが、パフォーマンスが落ちてしまいます。
 しかし、こうまでして推奨されていない、しかもコンテナ依存の激しいものを使うなら、ローカル変数として変数を使うか、さもなくばServletRequest.setAttribute()を使ってデータを登録し、request変数を引数で渡して使い回せば良いのです。しかもSingleThreadModelを使うと、メソッドへのsynchronizedなどが意味を持たなくなってしまうため(ロック用のオブジェクトを作り、synchronized(object)が必要)、本当に同期が必要な場合に大変面倒なことになります。
 月並みですが、SingleThreadModelの使用はやめましょうということで。また、これを使ったところで、スレッドごとにデータを持つのが保証されるのは変数のみですから、ファイル出入力やDBへの書き込みを行うような場合には、その際に他のスレッドに割り込まれては困るなら、必ず排他機構を導入するようにしましょう。
 ちなみにServlet Chatは全データをメモリ上に保持することで極めて高速な動作を実現しているチャットですが、こちらは言うまでもなくsynchronizedで同期を取っています。synchronizedは確かにパフォーマンスを落としますが、PerlやPHPのsymlinkなどによるロックと比較すれば、速度はケタ違いです。
 別に四六時中synchronizedしなければならないわけでもありませんし、コンテナによってはservice自体をsynchronizedしたのと同じく、他のリクエストをブロックするものもあるとのことですので、SingleThreadModelを使うならsynchronizedに頼る方がまだタチが良いというものです。
 ああ、SingleThreadModelにはさらっと触れるだけのつもりが、仕様がひたすら怪奇なせいで他のことが書けなくなってしまいました。

 そろそろTactical Revolutionの新版を一般公開しても良いころかと、簡単なチューニングとインデックスページ作成。プレイすると結構ハマるらしいです、これ。
 何よりもとにかく戦略性を重視したゲームだけに、「本格戦略シミュレーションRPG」というわけです。別にTactical Revolutionが有名になることを望むわけではありませんが(有名になるがゆえの苦労を背負い込むなどゴメンですから。開発にも差し障ります)、かなり苦労して作ったものには変わりありませんから、多少はプレイ者が増えて欲しいところです。
 今回は(別に今回に限らずですが)とにかくCPUがやたら強いです。これでサーラさんまで敵に回ろうものなら、もう。ついでに紹介文を書くためにシステムをまとめてみたのですが、やはり「戦略」「MRシステム」「キャラクターの個性」がキーワードになります。
 私はこの正月にまた感染者を増やしたのですが、何といっても「implements TacticalRevolution」のごとく、共通インタフェース(話題)が増えるのが面白いところです。2、3人にまとめて感染させてしまえば、なおさら便利です。皆々様、1度試されてみては。私としては、純粋に「プレイヤーが増える」のがうれしいのであって、カウンター数など実のところどうでも構いませんから、直接リンク歓迎とさせていただいています。

 auの魅力的な携帯電話「A101K」、京セラ製です。とあるショップに実物が陳列されていたのですが、本気で欲しくなりました。番号のプッシュボタンに「通話」「切」の分かりやすいボタン。短縮ダイヤルはボタン1つで呼び出せる上、そのダイヤルの通話先をメモして貼っておけるシールまで付属しています。呼び出し音量は本体裏のツマミで調節でき、その上ディスプレイがないため、あの劣悪なユーザーインターフェイスに腹を立てることもありません。
 どうして今までああいう素晴らしい携帯電話がなかったのでしょう。不思議でなりません。ちなみに1年ほど前、似たようなコンセプトの携帯電話をツーカーが出しており、そこそこに売れたようです。その際にauショップの店員に「このような携帯電話はないか」と聞いたのですが、その当時は存在しなかったのです。
 唯一残念な点があるとすれば、モバイルに接続してインターネットを用いる機能がない点のみで、それ以外の点は最高の携帯電話です。以前「デジタルデバイド」の話を取り上げましたが、今の携帯電話は「ただの電話では満足できず、かといってPCをネイティブに使いきれるわけでもない」層をターゲットにしているような気がします。
 つまり、今の携帯電話は中間層をすくい上げる代わりに、それすら使えない下層の人間、及びPCをネイティブに使える上層(便宜上の定義。別に上層だから偉いわけではありません)の人間を取り残していたわけです。今回の「A101K」は、そうした「中間ではない」層を取り込むことができる携帯電話といえるでしょう。私も欲しくなりました。
 さて、これは携帯電話が「先祖がえり」しているようなものですが、最高に進歩がないのは人間の方なのでしょうか。今でも語り草になっている「VHS VS ベータ」の戦い21世紀版に少しずつ突入しつつあります。ついに東芝やソニーが次世代DVDデッキの発売を発表し始めたのです。
 この勝負の結果として、一部に「BD優勢」との観測がありますが、参考までに私の予想を書いておきます。少なくとも私は、この勝負の大勢が判断するまでDVDデッキを買うことはないでしょう。多くの人が買い控えることが予想されます。となると強いのは、「DVDを買わなくてもDVDが見られる」製品を投入できる側です。
 つまり、以前なら「プレイステーションをBD対応にできるソニーが有利」と言い切れましたが、今回ばかりはそうはいきません。MSがHDを支持しているためです。私はもう市販ゲームから離れた人間ですからどうでも良くはあるのですが、XboxもXbox360も日本ではパッとしません。ところが、日本市場以外ではそこそこの売り上げを出しています。今年3月にはHD対応の新機種を出すとのことですから、これが普及すれば結果は分からなくなります。
 となると困るのが消費者です。HDにもBDにも見たい商品があったりすれば、どうしようもなくなってしまいますし、仮にここでどちらかのデッキを買って、後にその陣営が敗北したりすれば、デッキはあっという間に粗大ゴミになってしまいます。かといって様子見を続けていては、いつまで経っても買うに買えません。最高に困るのは消費者です。
 これなどは、小泉総理の「改革」の行く末を暗示しているように見えないでしょうか。「競争原理」なるものを強調しておられるご様子ですが、その成果といえばリストラ、青息吐息の下請けの上で一部企業の大利益、談合、偽装建築など。しまいにはこういうDVDのようなことも発生し、しわ寄せは全部国民の側に来るのです。
 ちなみに、偽装建築されていなくても日本は強い地震であっさり壊滅しかねません。なぜなら、今の日本では「耐震強度基準を下回るな。かといって上回ってもいけない」というのが常識とのことですから。全く含みがないわけです。つまり、耐震基準以上の地震が来れば一発で壊滅する恐れが強いわけです。地震大国たる日本において、地震災害は北朝鮮ごときより何千倍も恐ろしいはずなのに、何たることでしょう。
 次世代DVD問題1つ取っても色々なことが見えてくるものです。ところで私が支持する次世代DVD規格ですが、あえて「保留」としておきます。これもまた利益重視の徒花なのですが、BD陣営の米ソニーBMGはコピーを規制したいがためにウィルス入りの音楽CDをバラまく愚行を犯し、HD陣営の東芝EMIは卑劣なコピーガードCDを売るありさまです。
 小泉サイド曰く、競争原理は国民のためになると称していますが、最終的には必ず利益の囲い込みのために国民を犠牲にすることになります。勝ち組・負け組などと程度の低い言葉もありますが、今回の場合はHDとBDのうち勝った方の規格のデッキを買えたら「勝ち組」、そうでなければ「負け組」というわけです。嫌な話ではありませんか。
 この際、携帯電話を見習って、当面VHSに逆戻りするのが良いかも知れません。今からDVDデッキを手に入れてもすぐに次世代DVDに取って代わられますし、どちらかのデッキを買ってもその規格が負ければ無駄になるのですから。
カテゴリ [開発魔法][社会問題][ゲーム開発] [トラックバック 0][コメント 0]

<-前のページ [1] [2] [3] [4] [5] [6] [7] 次のページ->
- Blog by yamicha.com -