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 件の中から 16-20 件を表示しています。
Namespace 小泉:偽改革
2006/01/03(Tue)14:22:19
 同じ組織で同じ名前の人間がいたら紛らわしいものです。上の名前が同じ人がいるからと、下の名前で区別しようとしてみても、やっぱり同じ名前の人が。大体、下の名前を知る機会はせいぜい名刺しかありませんし、フリガナなしの名刺だと一巻の終わりです。田中や鈴木といった名はありがちですし、地方によって多い苗字というのもあるそうです。
 ストーリーなどでも、「イリアス」はともかく「サーラ」はありがちな名前です。バッティングすると感情移入度が下がります。さすがに「騎士サーラ」が他に存在する可能性は低いでしょうが。ですから、サーラさんを呼ぶ時には「騎士サーラ」と接頭語をつけると確実に区別がつくわけです。当サイトでは今からこれを推奨することにします。ゲーム中の会話でも、キャラ名は「騎士サーラ」「剣聖ハードゥン」「聖騎士シェイン」のように表示されますし。
 ここまではともかく、さらに深刻なのがプログラミング時のバッティングです。例えばC/C++やJavaで「int」という名前の変数や関数は作れませんが、これはint型とバッティングするからです。その他、標準関数などでバッティングが起こりやすいので、既存の名前をうっかり使わないように注意する必要があります。
 ちなみに、Javaはこれを「パッケージ」の考え方で解決しています。例えば「Integer」というクラスを定義した場合、これを普通に呼び出すと自分が作ったIntegerが呼び出されることになります。しかし、Javaに用意された同名のクラスが使えなくなるわけではなく、「java.lang.Integer」と指定してやることでそちらのクラスも呼び出せます。
 といっても、パッケージ名までデタラメにつけられるようでは、これまた他とバッティングする恐れがあるため、ドメイン名を「com.yamicha.任意のパッケージ名」のように用いることが推奨されています。ドメインなら世界に1つしかないため、誰もがこの規則に従っている限り、バッティングすることがなくなります。
 さて本題。XMLにもこれと似たような機構があり、「Namespace」と呼ばれています。例えば私がブログのインデックスにXMLを使ったとして、「title」というタグが用いられている場合を考えると、これはHTMLのタイトル指定なのか、ブログのタイトルなのかが分かりません。別に分からなくても良いのですが、Namespaceでこれを解消できるとのこと。
 さて、Namespaceを使う際には、まず「宣言」なる面倒な工程を踏まなければなりません。とりあえず書いていればどんな風でも動くHTMLと違って、XMLは平気でパースエラーを投げてきますから。というわけで、宣言の文法ですが、
<Base 
xmlns="http://www.yamicha.com/default"
xmlns:ilias="http://www.yamicha.com/ilias" >
	<ilias:elementname ilias:attributename="value" />
</Base>

「Base」及び「ilias」部分はもちろん任意の名前でも可
 といったところです。まずお約束の記述として「xmlns」を用いなければならないのですが、宣言は「xmlns:ネームスペース名="URL"」のように行います。上の例のようにネームスペース名を省略すると、それがデフォルトのネームスペースになり、明示的にネームスペース名を指定しなかった時にはこれが用いられるとのことです。
 さて、上で指定されているURLですが、実は何の意味もありません。もちろんアクセスしても404エラーが返ってきます。何のために使うかといえば、これもまたURLは1つしかないからバッティングが避けられるというJavaそっくりの理由なのです。上の「ilias」というのは、いわばURLにエイリアス名をつけているようなものであって、つまりは「http://www.yamicha.com/ilias.elementname」とみなされているわけです。
 上の例の場合はデフォルトのネームスペースがありますから、ネームスペース名を指定せずに要素なり属性なりを書くと、自動的に「http://www.yamicha.com/default.elementname」のようにみなされることになります(実際にJavaのパーサもそのように認識しています)。
 ここまで分かれば十分でしょう。早速実装に参ります。色々と試行錯誤しつつ、例によって以下のようなXMLを作成しました。
<Base 
xmlns:ilias="http://www.yamicha.com/ilias" 
xmlns:sara="http://www.yamicha.com/sara">
	<ilias:Ability ilias:use="108">Conflagration</ilias:Ability>
	<sara:Ability sara:use="0">Hado-fueiken</sara:Ability>
	<sara:Ability sara:use="75">Hishu-renzan</sara:Ability>
	<ilias:Ability ilias:use="86">Resurrect Life</ilias:Ability>
	<sara:Ability sara:use="350">Soryu-kikoken</sara:Ability>
	<ilias:Ability ilias:use="126">Ruined World</ilias:Ability>
	<ilias:Ability sara:use="200">Ryufu-reigeki</ilias:Ability>
</Base>
 どれもアビリティを表すものなのですが、魔道士イリアスと騎士サーラではアビリティの性格も正反対です。ですから、イリアスさんのuse属性は消費MRを表しているのですが(消費MR量はサンプル用のデタラメです)、サーラさんにMRなんざありません。というわけで、こちらのuseは反動による消費LAを表しています。
 しかし、世の中には例外というものもありまして、魔道士イリアスといえども技が使えないわけではありません。となると、LAの方を消費するわけですが、そこで「ilias:Ability」としながら「sara:use」と記述、両方を混在させています(例の1番下のAbility要素参照)。
 これを踏まえて実装を書くと、このようになりました。
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
// 重要。これがないとNamespaceが認識されない
DocumentBuilder db = dbf.newDocumentBuilder();

Document d = db.parse("webapps\\ROOT\\ns.xml");

out.print("消費MR\t消費LA\tアビリティ\t使用者ネームスペース\n");

Element base = d.getDocumentElement();
NodeList nl = base.getChildNodes();
for(int i = 0; i < nl.getLength(); i++){
	if(nl.item(i).getNodeType() == Node.ELEMENT_NODE){
		Element e = (Element)nl.item(i);
		out.println(
		// ilias:use(消費MR)を表示
		e.getAttributeNS("http://www.yamicha.com/ilias" , "use") + "\t" +
		// sara:use(消費LA)を表示
		e.getAttributeNS("http://www.yamicha.com/sara" , "use") + "\t" +
		// Textノードを表示
		e.getFirstChild().getNodeValue() + "\t" +
		// ネームスペースを表示
		e.getNamespaceURI());
	}
}
 見ての通りこれはJSPですから、Content-typeをtext/plainにして吐き出させるなり、preタグで囲むなりすると、フォーマット化されて表示されます。大方ご想像の通りでしょうが、以下のような出力が得られました。
消費MR	消費LA	アビリティ	使用者ネームスペース
108		Conflagration	http://www.yamicha.com/ilias
	0	Hado-fueiken	http://www.yamicha.com/sara
	75	Hishu-renzan	http://www.yamicha.com/sara
86		Resurrect Life	http://www.yamicha.com/ilias
	350	Soryu-kikoken	http://www.yamicha.com/sara
126		Ruined World	http://www.yamicha.com/ilias
	200	Ryufu-reigeki	http://www.yamicha.com/ilias
 ちなみに、言うまでもありませんが、属性名が同じでもネームスペースが違う2属性を混在することは可能です。
<ilias:Ability ilias:use="154" sara:use="255">Inclusion</ilias:Ability>
 XMLもなかなか面白いではありませんか。絶対に使う気にはなれませんが。

 Excelにも数学関数は用意されているため、昨日に続いて少しばかりベクトルの計算をしてみました。具体的には、これは色々な局面で使えそうなのですが、「跳ね返り」について。
 例えば80度の位置から物体が横の壁にぶつかった場合、反射方向ベクトルは
COS(RADIANS(80)) * -1 = -0.17
SIN(RADIANS(80)) = (約)0.98
 であり、これに物体の速度を掛け合わせたものが反射後に飛ぶベクトル及びスピードになるわけです。では、これを角度にするとどうなるのか。DeltaライブラリではACOSを使って計算しているのですが、ATAN2を使うと非常に楽であることが分かりました。
(DEGREES(
	ATAN2(
		COS(RADIANS(80)) * -1 ,
		SIN(RADIANS(80))
	)
) + 360) % 360 = 100
 つまり、100度の方向に反射することが分かります。ちなみにATAN2は180度以上の数値でマイナスを返す(185度なら-175、355度なら-5)のですが、逆に言えばマイナスの時のみ360を足すか、もしくは360を足してから360で割った余剰を求めれば、飛ぶ方向を角度で得ることができるわけです。難しい条件判定を使わずとも、上のように1行で記述することすら可能です。これが左右でなく上下の壁に反射する場合には、COSではなくSIN側の符号を反転させれば良いだけです。
 なお、三角関数は右(X 1 , Y 0)から始まって反時計回りに角度が増えていきます。それを頭の中で描いてやれば、計算が比較的容易に行えます。クイックファストのエフェクトを作った時など、時計が3時15分の位置から反時計周りに回転して驚いたものです。

 ここでお知らせなのですが、ブログのRSSの書式を変更しました。RSSリーダーをお使いの方はすぐにお分かりになったことでしょう。descriptとして記事の内容を500バイト程度まで表示するようにしてみたのですが、何といっても苦慮したのがタグの扱い方です。
 CDATAで囲んでいるため、HTMLのタグをそのまま書き出せるとはいっても、500バイト制限によってうっかり閉じタグが消えたりしては冗談になりません。それに、descriptの文字が大きくなったり太くなったりされても、HTML式のRSSリーダーなどをお使いの方にとっては大変迷惑でしょう。しかし、改行なしでは書式がぐちゃぐちゃになりますから、brだけは残したいところです。
 そこで出てきた課題が「<>以外のタグを全部削除せよ。ただし<日本語>のような明らかにタグではないものは削除しない」「文字制限に引っかかり、タグが<brのように中途半端な切れ方をした時に備え、これを消せるようにせよ」の2つです。とりあえず後者は簡単ですが、前者がなんとも。
 タグだけ消したいなら「s/<[0-9a-zA-Z\/!][^>]*>//g;」で何とかなりますし([^>]部分を.*?にすると、改行でマッチが行われないので不可。見落としがちなので注意)、これまたbrだけ残したいなら「s/<[^(?:br)][^>]*>//ig」とすれば良いわけですが、では「<br>ではなく、その上に先頭が英数字のもののみ削除」とするにはどうすれば良いのでしょう。
 探してみたのですが、あいにくカッコにOR(「|」で区切り)はあってもANDはありませんでした。だからといって、「s/<([^(?:br)]|[0-9a-zA-Z\/!])[^>]*>//g;」などと書こうものなら、「brでないもの、または先頭が英数の少なくとも片方に当てはまるもの」が削除されますので、<>で囲まれたあらゆるものが削除されてしまいます
 しばらく悩んだ挙句、トリッキーな方法を用いることにしました。分かりづらくなるばかりなので、本当は使いたくなかったのですが。「s/<(?!br|[^a-zA-Z0-9\/!])[^>]*>//ig」とすれば、「先頭がbr、もしくは英数以外の値」の場合に真になりますが、カッコの先頭で「?!」によって条件が反転されているため、「先頭がbrではなく、かつ英数であること」が条件になり、改行以外のタグのみを削除することができます。
 これでRSSも少しは読みやすくなるでしょうか。

 本日はどこの社説もなぜか「少子化」や「福祉」を取り上げているのですが、そういえば育児休暇を取らせた中小事業所に対して100万円を支給するという地域振興券並みの愚策が始まったのでした。念のために言っておきますが、事業所に対して支給するのであって、親の側には1円も入りません。それほど金が余っているのなら、いくらでも少子化対策できるというのに。
 これを発表したのがちょうど選挙の時でした。こんなザル制度、どうせまともに利用する企業の方が珍しく、育児休暇を創設すると見せかけて100万だけ取り上げる企業の方がよっぽど多いでしょうから、おそらく少子化対策を隠れ蓑にしたバラマキにより、中小企業票を呼び込む作戦だったのでしょう。このようなことをする内閣を選ぶ人間も選ぶ人間といったところです。
 この問題に関しては、あまりにバカバカしすぎてこれ以上語る気にもなれません。これは「小泉改革の代名詞」として、以前の「地域振興券」「IT革命」とともに3大愚策として語り継がれるべきものでしょう。
カテゴリ [開発魔法][社会問題][お知らせ][ゲーム開発] [トラックバック 0][コメント 0]

新年早々外交問題
2006/01/02(Mon)23:54:04
 新年早々、魔道士イリアスのご加護がなくなりそうな記事を見かけました。
「首相の靖国参拝問題を米国が本格的に懸念」
 靖国参拝問題については、「国益を損ねるだけの意味しかなく、日本側に利益が全くない」という理由のみで私は強く反対してきましたが、一部に「参拝するのが国益」のような、言葉のトリックを用いた主張を行う連中が存在するのも事実です。ただ、言葉のトリックは所詮子どもだましですから、最終的にはこうしてボロが出るというわけです。
 図式としては、例えばモグラ叩きで「靖国モグラ」(ワナで叩くと減点)を繰り返し叩きのめしている横で、「中国の圧力による自殺問題モグラ」(点数5倍)、「海洋権モグラ」(10倍)が横からニョキニョキ出てきて薄ら笑いを浮かべている、という状況です。小泉首相は「靖国はカードにならない」と分かったようなことを言っていましたが、実はこれがすでに中国側のペースにハマっているようなものです。
 ですから、実際のところ「米国が靖国参拝をやめるように言い始めた」というのは内閣にとってはショックでしょうが、私にとってはそれなりに悪くないニュースです。米国がそう言っているとなれば、日本人の命を売り渡してまで牛肉などを入れてやって米国に貢ぐのに賛成する、米国が大好きな皆さんも変なことは言えなくなります。
 今までは「靖国と中国」の関係を「日中関係」、ひいては「日米 VS 中国」の図式に見せかけて靖国参拝の正当性をアピールしていた連中は、構図が「日本 VS 米中」に変わったことで、少しはおとなしくなるでしょう。それでもなお「自称・首相の後継者」などが日中関係を悪くして、米国がそれを迷惑がるようなら、米国は圧力をかけてでも日本の行動をやめさせようとする可能性があります。米国とはそういう国です。無慈悲というよりは打算的です。
 日本が靖国参拝をやめれば、その分のエネルギーを海洋問題や自殺問題に振り向けることができます。ただ、自殺問題はまだどちらの主張が正しいともいえない状態ですから、万が一中国側の言い分の一部が正しかったことも考え、裏づけの上で抗議を行わなければ、「嫌中」の流れで下手に突っ走ると出し抜かれる恐れがあります。
 海洋問題については今さら遠慮は不要でしょう。日本側も今からガス田を作って利益が得られるならガス田を作り、損失の方が大きいなら圧力です。不法侵入には厳しく当たり、日本領への不法上陸者には裁判を受けていただけば良いのです。尖閣諸島の所有権、沖ノ鳥島は「岩」なのか、といった問題で、歴史的観点から日本側の言い分が正しいのであれば、いくら中国の影響力が強いといっても、国際社会からいくらかの同意は得られるでしょう。
 このように、誰でも考えれば分かるようなことを行わず、中国は綿密な計略に基づいて戦略を進めている間にも、「靖国」にうつつを抜かして国益を垂れ流すのはなぜか。仮に米国が日本なら、靖国は切り捨てて海洋問題を徹底的に追求するでしょう。結局のところ、「(否が応でも外交の利益や損失をかぶる立場である)自国民に対して真摯な外交姿勢」があるかないかの違いです。
 ところで沖ノ鳥島ですが、見たところ確かに「岩のオブジェ」といった印象です(200カイリの「岩」、すなわち「人が居住できる環境にない島」の定義とは別物)。時節柄、これを写真に採用したようなカレンダーもあるのでは。父島、母島、沖ノ鳥島。東京とは何とも海の美しいところではありませんか。

 先に扱ったXML。一時期は「次世代HTML」とかで騒がれ、一部には「<br />」のようなXML準拠型の表記も見かけますが、XML及びCSSは少なくとも当面HTML(またはその旧表記)に取って代われるような技術ではありません。両方「知っていればとりあえず便利」なものではありますが。
 HTMLにしても、そもそもfontタグ自体が推奨されておらず、全部CSSで定義しろと言われていますが、たかが1箇所文字を赤にしたいだけでCSS文を書いて名前をつけて、などやっていられますか。一応その場に書いてしまっても良いらしいのですが、推奨されていません。fontタグを使った方が何千倍も楽ですし、効率的です。
 CSSは少なくとも当分、「HTMLを補助的に修飾する外部記述可能なテンプレート」という位置づけのまま、格上げも格下げもなされないでしょう。「font:14px; bold」だの何たらかんたら書くのなら、「<b>」などと書いた方が簡単で楽で正確でミスもなくなります。実際問題、CSSが義務化などされれば、掲示板やブログの投稿で困りますし。
 さて、能書きはこの程度にしてXMLと参ります。以前に少々気になって調べてみたところによると、XMLには「エンティティ」なるものがあるそうで。使ってみました。
<!ENTITY class_1 "Dual Knight">
<Character name="Sara">&class_1;</Character>
 しかし、これをIEで表示してみたところ、EntityはDTDで宣言しろとのこと。いちいち書いていられますか、そんなモノ。仕方がないのでW3Cの資料をしばらく読みあさったところ、以下のような文法が出てきました。
<!DOCTYPE doc [
	<!ENTITY name "value">
	<!ENTITY name SYSTEM "filename">
	<!ENTITY name SYSTEM "name.gif" NDATA gif>
]>
 このように宣言することはできるようです。ただし、最初の2つはIEでも表示され、JavaのXMLパーサでも使えましたが、後の1つは何ともなりません。そもそもJavaのXMLパーサでは、値を得るメソッドの返り値はStringであり、InputStreamからファイルの値を受け取るようなことはできません。
 前には「Element」を主に用いましたが、今回は「Entity」及び「Text」も用いてみたいところです。例えば既存のHTMLタグをXMLとして解釈すると、リンクのタグなら以下のようになることでしょう。
<a href="http://www.yamicha.com/" target="_top">
ホームページへ戻る</a>

Node Name "a"
Element : href="http://www.yamicha.com/"
Element : target="_top"
	TextNode "ホームページへ戻る"
 ということで、今回はこのようなサンプルXMLを作ってみました。XML自体に文法エラーがあってはお話になりませんが、前もってIEで閲覧すればチェックできるため、比較的容易に正しいXMLを準備することができました。
// entity.txt
Revolution Witch

// entity.xml
<!DOCTYPE developersoul [
	<!ENTITY class_1 SYSTEM "./entity.txt">
	<!ENTITY class_2 "Dual Knight">
]>

<Base name="Characters">
	<Character name="Ilias">&class_1;</Character>
	<Character name="Sara">&class_2;</Character>
	<Character name="Harden">Sword Master</Character>
</Base>
 「!ENTITY」内で宣言した名前については、その後XMLのどこかで「&name;」とすれば、設定した値に置き換えて表示されます。この機能「だけ」はHTMLにも欲しいところです(ただしエンティティ呼び出しは&ではなく既存の文章とほとんどバッティングしない記述を使用)。JavaのXMLパーサでも勝手に置き換えてくれるため、かなり便利ではあります。
 それを踏まえて、早速Java側の実装に入ります。といっても、基礎はこの前と同じであり、非常に簡単なのですが。
// ドキュメント基底のエレメントを取得
Element base = d.getDocumentElement();
// ノードリストを取得
NodeList nl = base.getChildNodes();

for(int i = 0; i < nl.getLength(); i++){
	// ノード名「Character」のデータのみを得る
	if(nl.item(i).getNodeName().equals("Character")){
		Element e = (Element)nl.item(i);
		// 要素 name の値を取得
		out.print(e.getAttribute("name") + " : ");
		// ノードの子データ(text)を得る
		out.println(e.getFirstChild().getNodeValue());
	}
}

// Result
Ilias : Revolution Witch
Sara : Dual Knight
Harden : Sword Master
 簡単なものです。
 ついでですから、XMLパース時にエンティティを展開しない方法も実験してみます。具体的には、ファクトリに展開しない設定を行うことで、自動展開を封じることができるようです。
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setExpandEntityReferences(false);
db = dbf.newDocumentBuilder();
 まずは下調べにNodeTypeを吐かせてみたのですが、どうやら展開されていないエンティティ参照は1つの子要素として扱われているようです。ですから、例えば「Text」内にエンティティ参照と普通の文字を混在させると、2つ以上の子が返されます。
上のXMLを改変して
<Character name="Sara">The &class_2;</Character>
と記述し、Text部分の子ノードリストを走査すると、ノードタイプとして
「TEXT_NODE」と「ENTITYREFERENCE_NODE」が返る
 展開するのが本来の使い方ですし、普段は展開しない方法を使う必要はなさそうですが。

 さて、最後に少しばかりゲーム企画らしきものに触れておきます。世には「ブロックくずし」というものがあるわけですが、仮にそういうもの、またはモドキを作るとしたら、どのような実装が必要になるのか。
 これを作るに当たっては、当然重力及び空気抵抗は完全無視です。重力があっては飛んだボールが落ちてくることになりますし、空気抵抗があってはどんどん速度が落ちていき、しまいにはその場で停止してしまいます。つまり、ブロックくずしには力の制御がない状態ということになります。そこはゲームですから。
 では、ボールが壁にぶつかったらどういうリアクションを取るべきか。まさか「壁の材質がフニャフニャ」ということはないでしょうから、反射力は「1」(壁が全く力を吸収しない状態。考えてみればどういう材質なんだか)とします。壁が衝撃を吸収して速度を薄めてしまうようでは、しまいにはボールが進まなくなりますから。
 反射ベクトルとしては、例えば左上45度に進んでいるボールが左側の壁にぶつかると、速度はそのままで右上45度に反射することになります。1時の方向から横の壁にぶつかると、5時の方向に飛ばなければなりません。といっても、例えば飛んでいるベクトルのSIN値が0.1の状態で横の壁にぶつかったら、-0.1のASIN値の方向に飛ばせば良いわけですが。
 後はラケットですが、これも壁と同じ処理では永久に飛ぶ角度が変わらないわけですから、当たった場所によって角度を変化させるのがポピュラーです。反射としては、SIN値はそのまま反転させ、COSはラケットの場所に応じて変化させれば良いだけです。
 もちろん、「斜め45度なら速度は横0.5、縦0.5」ではお話になりませんから、SINとCOSを使って横0.707、縦0.707にするのは当然です。単に角度を変換すれば良いだけなので、ここは難しい話ではありません。
 さて、このインチキ物理法則、何かに使うことがあるのでしょうか。新年最初の戦闘記録でありました。
カテゴリ [開発魔法][社会問題][ゲーム開発] [トラックバック 0][コメント 0]

ねつ造に懲りて記事を吹く
2005/12/28(Wed)20:12:10
 今までで大体のプログラム技術は試したということで、今日はしばし新ステージ作り、なのですが、今回の新ステージは「属性」がキーワードです。
 Tactical Revolutionには属性の概念があり、クラスによってダメージが変化するようになっています。プリエステスにスペリングカースをかけるのと、暗黒魔道士たる魔道士イリアスにかけるのでは、仮にステータスが同じであっても、かなりダメージが違ってきます。さほど目立つ要素ではありませんが、芸の細かい要素ではあります。
 アビリティは1つ以上の属性を持ち(持たない場合は「無属性」)、複数の属性を持つ場合は有利なものが使われます。属性は多いほど良いのですが、無属性については特殊で、あらゆるキャラに対して必ず100%のダメージを与えられることが保証されています。つまり、無属性と他の属性を併せ持つ場合には、ダメージが100%を下回ることはありません
 属性はパーセンテージ計算であり、もともと0ダメージの攻撃は属性耐性が0%でも1000%でも0ですし、逆に元のダメージが大きい場合には、10%や20%の違いが大きく影響してきます。「大盾」を持っているキャラについては、物理ダメージが15%(元のダメージから15%分。つまり、もともとの物理耐性が80%の場合は12%)軽減されます。プロテクテッドは物理を50%(かけた直後なら)、フォースリフレクトは物理以外の全攻撃属性を50%軽減します。いずれも無属性の攻撃に対する効き目はありません。
 とまあ、ここまでが技術仕様なのですが、今回のステージは敵に対して特定の属性以外の攻撃が全く通用しません。まさに「かすり傷の1つ残せもしない人」です。何が効くかは敵によって違います(名前で判別できます)。その代わり、弱点を突けば大ダメージを与えることができます(当社比5.12倍)。足場が悪くない限り、当てさえすれば大抵1撃です。
 つまり、今回のステージの意義は「敵の弱点を突いた攻撃を用い、手早く倒していく」ことにあります。というのも、制限ターン以内に敵を全滅させなければゲームオーバーなのです。無属性攻撃は一応誰にでも効きますが、ダメージは必ず100%であることが保証されているため、これではなかなか倒せません。属性攻撃を使うべきでしょう。
 味方キャラは魔道士イリアス、騎士サーラ、魔法剣士イグリアなのですが、魔道士の2人は各属性の魔法をドカドカ持っています。サーラさんは一見すると使えないように見えますが、こちらも活躍が期待できます。物理が弱点の相手も存在する上、アビリティ「魔封破邪剣」「毒牙採命剣」はそれぞれ聖及び暗の剣技です。技術者集会でいい加減名前を決定したい「名称未定義剣」は、反動が辛いためおいそれとは使えませんが、色々属性を持っています。
 ターン制限はそれほど厳しいものではありませんが、誰かを遊ばせているようではクリアは遠いです。上手く使ってあげましょう。とにかく魔法を連発しなければならないため、MR管理も重要です。MRはこのゲームの醍醐味の1つであり、重要な戦略要素なのですから、自在に操れるようにしておきましょう。ベストセラーの「さおだけ屋はなぜ潰れないのか」は(私は読んでいませんが)「会計学のススメ」ともいえる本とのことですが、MRは下手すると会計学に近いですから。
 Tactical Revolutionは、(上手な)人間とCPUが(攻撃の命中なども含めて)全く同じ条件で戦えば、絶対に人間が勝てるゲームです。数ターン先のMRを考えたり、魔法によるカウンター使用後のMRを考えたり、次のターンの相手や味方との距離を考え、相手のREGまで調べた上で、MR及びCONの数値を見て次ターンの行動を決定しておくなど、CPUには絶対できない芸当です。
 私のチューニングテストプレイでは、所要ターンは7ターンでした。これより良い記録も出るのではないかと考えています。
 補足事項としては、敵のチーム名はランダム名リストを使用しています。「聖風騎士団」や「神竜騎士団」ならまだしも、「メディナ師団」(イラク旧政府の部隊)や「バラ革命軍」(かの有名な革命)、「砂漠の自由軍」(米軍の中東攻撃作戦名)、「ハードゥン心理教」(アレフに改称)、「自由民主党」(詐欺集団の名称)などという名前が出たりしたら、冗談になりません。

 ようやく犯罪被害者が少しは救われる、これが今年のクリスマスプレゼントか、と喜んだのもつかの間、マスメディアの怖さが少しずつ露呈し始めました。

・匿名発表 見識を疑います、猪口さん(毎日 12/22)
・匿名発表「警察の恣意的な運用が心配だ」(読売 12/26)
・犯罪被害者 安易な匿名化は避けよ(朝日 12/28)
・匿名社会 「羹に懲りて膾を吹く」愚(産経 12/28)

 こうして同じ話題を連続して戦記で取り上げなければならないのも、マスコミ連中が総力をもって犯罪被害者に配慮した案を、自分たちの「警察からの実名発表」という既得権益を守るために必死で叩き潰そうとしているからです。
 恐ろしい点は2つ。1つ目が、普段から有事法制万歳、政府万歳、現内閣が信任された以上、イラク派遣も信任されたのだと声を張り上げる、さほど頭が良くも見えない報道機関までもが徹底的な反対に回っている点です。これも信任された内閣の決定ですし、有事法制で国民が縛られるのは当然だが、マスコミは縛られてたまるか、とでも言いたいのですか?
 2つ目ですが、言論機関にも色々な考え方があります。田中知事の発言をねつ造するのもいれば、イラク戦争で大量破壊兵器をでっち上げたのもいます。しかし、相当考えの違うはずの各社が、どういうわけか「匿名発表はふざけるな」という点では一致を見ています。「匿名発表に問題がないとは言わないが、我々の今までの行動をかんがみれば当然だ。被害者が実名発表できるような報道体制を作りたい」と主張するマスコミは1つもないのです。
 朝日などは「警察は実名は発表するが、被害者が匿名を希望している場合はその旨もあわせて伝えるのが良いのではないか」と主張していますが、とんでもない話です。マスコミに伝わった情報は100%漏れます。さらに、どこかの新聞社なりテレビ局が1社でも実名を報じれば、それですべて終わりであり、他社が匿名にすることに意味がなくなってしまいます。極めて危険な案です。
 産経新聞も、いつもの彼らの主張から考えれば、ここは「匿名発表は当然だ」と主張するところでしょう。それを「羹に懲りて膾を吹く」とは。そもそも「イラクに大量破壊兵器がある」などと米国の論文を提示してまでねつ造報道するような新聞社の情報など、例え膾に見えても吹いて食べなければ危険というものでしょう。「中学教科書の通信簿」コーナーで扶桑社の教科書のみをひたすらヨイショしたことといい(一応注釈をつけておきますが、評価対象は戦後史のみではなく、神話の時代から現代までのすべてです)、他の誰もが産経のねつ造や偏向を忘れたとしても、私は絶対に忘れません。
 毎日新聞に関しては、遺族のマスコミ批判などを取り扱った点で好感が持てなくもないのですが、ライブドア問題の時の論説委員やコラムニストのものすごい自画自賛には辟易させられたので、全く信用できません。これは言い切っても良いのですが、今の日本にジャーナリズムなど存在しません
 「田中真紀子氏の娘」報道に対する主張など、読売も筋は通っているのですが、「警察の恣意的運用」なる言い訳は当たりません。被害者が警察に実名発表を要請したのに、警察がそれを隠そうとするなら、自分からマスコミに告発すれば良いのです。匿名化によってスクラムに飢えているであろう彼らのことですから、きっと嫌になるほど取材してくれるでしょう。
 ここでマスコミが主張すべきことこそ、私が上に書いたように、「我々のしてきたことを考えれば匿名化はやむを得ない。だが、被害者が実名を発表できるような環境を作るのは今からでも遅くない」という具合に、今までの自分の非を真摯に受け止め、報道の原点に立ち返るような主張なのです。それを言い訳などとは、聞き苦しいばかりです。
 私が匿名化に賛成する理由としては色々ありますが、今回はこの一言だけで十分でしょう。
「匿名発表化は自業自得というのに、どこも政府決定を批判するばかりで、反省の弁を述べた大手新聞社は1つもない。こんな連中に実名など渡してたまるか」
 実際問題として、大体の人は「ニッポン放送 VS ライブドア」も「TBS VS 楽天」も知っているのですが、「ニレコの毒薬条項差し止め」「ポッカ及びワールドの上場廃止」「松下 VS ジャストシステム」「過去最高額の賠償請求が無効となったアルゼ特許判決」「夢真HD VS 日本技術開発」「日清紡と新日本無線」などを知る人はほとんどいません(どれも今年のニュース)。どれもこれもライブドア問題と同程度の騒ぎなのに、なぜなのでしょう。これもすべて、自分にかかわる場合は世論を喚起して味方につけた上に買収者を叩く必要があり、その他は自分らにとってどうでも良いからに他なりません。私もライブドアは大嫌いですが、マスコミも同程度に嫌いです。
 今回の各社の社説にしても、どうにかして世論喚起して決定を撤回させるのが目的なのでしょうが、私は絶対にだまされません。「判断はすべて警察任せ。被害者には介在させない」というなら私も反対しますが、「被害者の意向を尊重」するとしている以上、政府は絶対に案を撤回または修正すべきではありません。
カテゴリ [開発魔法][社会問題][ゲーム開発] [トラックバック 0][コメント 0]

本年最後のホットニュース
2005/12/26(Mon)20:13:23
 本日はJavaの言語研究を色々と。かなり体力を使うものです。
 まず簡単なところでは、ボクシングという拳闘のような機能です。別にサーラさん大活躍というわけではなく、要は
Integer i = 100;	// この構文
System.out.println(i.toString());
 これだけの話です。そんなのC++の演算子のオーバーロードで何十年前から存在するでしょう。今さらそんなものを新機能と言われましても。
 お次は「リフレクト」です。以前、クラス名を指定しての呼び出しをやってみましたが、ではコンストラクタがある場合はどうするのか。メソッドは呼び出せるのか。そういう疑問に答えを与えるのがjava.lang.reflectなのです。本日はメインが「ジェネリック」なので手短に。
// コンストラクタの使い方 : String(String)
Class c = Class.forName("java.lang.String");
Constructor cr = c.getConstructor(String.class);
String s = (String)cr.newInstance("文字列");
 流れとしては、まずClassオブジェクトを取得し、c.getConstructor(Class...)を用いてConstructor型を取得します。今回は「String.class」を渡すことで、「String(String)」コンストラクタを呼ぶことを明示的に指定しています。getConstructer()は1.5から引数が可変になっているようですが、以前のスタイルにあわせるなら単に配列を渡すように書き直せばいい話で、たいした問題ではありません。
 なお、String.classもClass.forName("java.lang.String")も等価です。どちらでも構いませんが、混在しているのは説明のため、及び気分の問題です。
 それでは、メソッドを呼ぶ場合には。
Class c = Class.forName("java.lang.String");

byte b[] = {'I' , 'J'};	// 配列に I 及び J を代入

Constructor cr = c.getConstructor(byte[].class , Integer.TYPE , Integer.TYPE);
// コンストラクタ String(byte[] , int , int)
// 基本型は Integer.TYPE や Float.TYPE のように指定できる

String s = (String)cr.newInstance(b , new Integer(0) , new Integer(1));
// コンストラクタ String(b , 0 , 1) をコール

Method m = c.getMethod("concat" , String.class);
// メソッド String.concat(String); を準備

System.out.println((String)m.invoke(s , "lias"));
// メソッド s.concat("lias"); をコールし、戻り値をStringと解釈して出力
 ややこしいですが、分かってしまえば簡単です。
 さて、これより本題、「ジェネリック」に参ります。はっきり言って私はこの機能が大嫌いなのですが。APIに使われている以上、使ってメリットのある状況もいくらか存在するのでしょうが、こんなものに頼ってプログラムをナポリタン仕上げにする人間など開発者ではありません。ややこしいばかりです。
 しかし、APIで「ClassName <T , S>」や「method <? extends T>」のような意味不明な記述がしてある以上、覚えておかなければドキュメントを読むのにさえ不具合が生じます。私のアプレット開発は1.1ベースのため、使うとしてもServletの時だけでしょうが、少々使ってみます。なお、実はこのプログラムもJSPで書いていたりします。
class Genes<T>{
	private T var;
	public Genes(T v){
		var = v;
	}
	public String getString(){
		return var.toString();
	}
}

Genes<String> g = new Genes<String>("String");
out.println(g.getString());
 とりあえず、使い方はこのようになっているようです。これ自体は何の意味も持ちませんが。ジェネリックとは「Object型への型キャストを自動化し、間違ったキャストにはエラーを出せるようにしたもの」とのことですから、そのうちServletのgetAttribute辺りで使われるかもしれません。値を複数渡す際には、<T , S>のように引数の要領で記述します。名前は何でも構わないながら、APIでは大文字1字が使われていますので、ここでもそれに従います。
class Attribute<T>{
	private T var;
	public Attribute(){
	}
	public void setAttribute(T v){
		var = v;
	}
	public T getAttribute(){
		return var;
	}
}

Attribute<String> a = new Attribute<String>();	// 型を指定
a.setAttribute("Dual Knight");	// キャストは要らない
String s = a.getAttribute();	// 同じくキャスト不要
out.println(s);
 この方法なら、あらゆる型を扱うことができる上、キャストも必要ありません。なお、これはメソッドに対しても使うことができ、値を代入する場合には型宣言さえいらないため、かなりお手軽に扱えます。ただ、関数のジェネリックはローカルのため、他の関数で用いることはできません。また、値を渡す場合には型が自動認識されましたが、値を受け取る時にはどうしようもありませんでした(当たり前ですが)。
// 先ほどの改造系
class Attribute{
	Object var;
	public <T>void setAttribute(T v){
		var = v;
	}
	public String toString(){
		return var.toString();
	}
}

Attribute a = new Attribute();
a.setAttribute(new String("Dual Knight"));
// コンストラクタの際には必要になっていた型の宣言が必要ない

out.println(a.toString());
 ここまでならせいぜい「Object型にキャストする・しないの違いだけ」なのですが、この先が違います。何と渡す値に制限をつけることができるそうなのです。
class Base{
	public String getString(){
		return "Base Class";
	}
}
class Child extends Base{
	public String getString(){
		return "Child Class";
	}
}
class Dummy{
}

class Sample<T extends Base>{
	T var;
	public Sample(T v){
		var = v;
	}
	public String getValue(){
		return var.getString();
	}
}

Sample<Base> b = new Sample<Base>(new Base());
out.println(b.getValue());

Sample<Child> c = new Sample<Child>(new Child());
out.println(c.getValue());

// Error! : Baseを継承していない
// Sample<Dummy> d = new Sample<Dummy>(new Dummy());
// out.println(d.getValue());
 これなんか、コンストラクタでBase型を受けるだけで普通に防止できる気がしますが。何の役に立つのでしょう。実はinterfaceも制限にできるとのことです。例えば、以下のような宣言を行ったとしましょう。
class Sample
<T extends KeyListener & MouseListener & MouseMotionListener>{
	private T var;
	public Sample(T v){
		var = v;
	}
	public void callListener(){
		// テスト用にでたらめなイベントを構築
		KeyEvent ke = new KeyEvent
		(new Container() , 1 , 1 , 1 , 1 , 'a');
		MouseEvent me = new MouseEvent
		(new Container() , 1 , 1 , 1 , 1 , 1 , 1 , true);

		var.keyTyped(ke);
		var.mousePressed(me);
		var.mouseClicked(me);
		var.mouseDragged(me);
	}
}
 上の型記述については、インタフェースは&で区切っていくつでも指定できますが、クラスは1つのみ、しかも先頭(extends の直後)に置かなければいけません。Javaは単一継承であり、extendsを2つ以上持つクラスは存在しないため、当然ではあります。
 さて、このような指定がなされた場合には、上記の全リスナがインプリメントされたクラスが渡されることが保証されます。Tactical Revolutionで使いたかったほどです。
class Listener
implements KeyListener , MouseListener , MouseMotionListener{
	// 全リスナをインプリメント
}

Listener l = new Listener();
Sample<Listener> s = new Sample<Listener>(l);
s.callListener();
 このような場合、通常なら必要な全インタフェースを拡張したインタフェースを提供するか、インプリメントして空宣言なりabstractしたクラスを提供するしかありませんが、これならそうしたものを用意する必要もありません。
 その先、避けて通れないのが ? 宣言です。APIにも出てくるのですが、何のことやらさっぱり。調べてもほとんど資料がないありさまです。プレースホルダでもあるまいし。これなのですが、どうやら型なんざどうでもよろしい、という場合に使うとのことです。ワイルドカードと呼ばれているそうな。
class Base<T>{
	private T var;
	public Base(T v){
		var = v;
	}
	public T getObject(){
		return var;
	}
}
class Sample{
	public String getString(Base <?>b){
		return b.getObject().getClass().getName();
	}
}

Base <Boolean>b = new Base<Boolean>(new Boolean(true));
out.print(new Sample().getString(b));

// Result
java.lang.Boolean
 今回使ったメソッドを見てみると、getClass()はObjectクラスからの派生であり、あらゆるクラスが実装しています。すなわちこの場合、BaseのgetString()を呼び出すにあたって明示的に型を渡す必要はありません。ですから「?」でも大丈夫です。もちろん、Booleanにかかわるメソッドを呼び出すことはできません。例えばgetBooleanValue()を呼び出した場合、ジェネリックの型指定が「Boolean」なら動作しますが、「?」の場合は動きません。
 これでは少々不便ですから、「?」に対してもextends、さらにsuperなる記述が利用できるようになっています。extendsは以前に述べた通りですから、superについて。
class Gene<T>{
	private T var;
	public Gene(T v){
		var = v;
	}
	public String getString(){
		return var.toString();
	}
}

class Base{
	public String toString(){
		return "Base Class";
	}
}
class Child extends Base{
	public String toString(){
		return "Child Class";
	}
}
class Dummy extends Child{
	public String toString(){
		return "Dummy Class";
	}
}
class Sample{
	public String getString(Gene <? super Child>g){
		return g.getString();
	}
}

Gene <Child>g = new Gene<Child>(new Child());
out.print(new Sample().getString(g));
 extendsとsuperの組み合わせは、試したところでは無理でした。例えばこのsuperなのですが、今回は「super Child」としています。これによりDummy extends Childクラスを呼ぶとエラーになります。Child、もしくはChildより上の階層のクラスでなければなりません。ただし、そうすると「Object 〜 Child」の間のどの型も渡せてしまうことになり、型の厳密性はObject型と同じになりますので、(キャストなしには)Object型に定義されているメソッド以外を使うことはできません。ということで、今回はtoString()をオーバーライドしてみました。それから、型の上ではChild以下のことが保障されますが、あらゆるクラスはObject型にキャストできますので、オブジェクトとしては何でも渡ってしまいます。
 以上、本日はこの程度で。コードがスパケティ化しかねませんので、できれば多用したくない記述です。

 やりました。ついにやりました。「被害者の匿名発表」の原案が修正されずに決定されることが決まりました。この決定に当たって、私のブログの主張などほとんど何の役にも立ってはいないでしょうが、まるで自分のことのようです。これでようやく、犯罪被害者の苦難の長い道のりが実を結ぶのです。
 実は本日、読売新聞も社説で「削除もしくは修正すべき」と主張しており、こうした圧力を受けて内閣が方針転換したら、日本は被害者に厳しい国に逆戻りすることになります。そういうわけで、議論の行方を不安視していたのです。仮に削除や修正がなされたら、大した影響力がないことは承知の上で、政府にメールで抗議文を送ろうとさえ考えていたところでした。
 所詮、報道など半分は興味本位でできていますから、私もブログでニュースでも取り扱う時には、興味本位で記事を集めて書いていました。ところが、様々な記事を読めば読むほど、マスコミのひどさが身にしみてくるのです。こうなると、いくら部外者の私とはいえ「どうして被害者ばかりがこうなるのか」と怒りを覚えるのは無理のないことです。
 今年にしても、奈良の事件の両親コメント不掲載から始まって、女児殺害事件では必ずメディアスクラムを行いました。今年最大のニュースである脱線事故では、休日にボウリングに行った社員や、その場に自分が残ってもできることなどたかが知れている、それならダイヤを乱すわけにはいかない、と考えたのかは知りませんが、電車の運行に間に合わせるために別ルートで出勤した運転手らを袋叩き。
 総選挙では自民党をひたすらヨイショして不公平報道を行い、テレビを長く見た層の多くが自民党支持、そうでない層は比較的バラバラという驚くべき数字を叩き出し、NHKと朝日の戦いにしても、NHKは自社に都合の良い放送をひたすら流し、それでさらに信頼を失って受信料制度が揺らぎ、民営化が現実的な選択肢として出てくると、そのあおりを食う民放連は猛反発。
 こんないい加減な連中に「自主規制」ができるわけがありません。郵政民営化はいい加減な改革、国債発行枠は辞任年度分でようやく達成、道路公団も高速を全部建設し、外交はアジアを怒らせるどころか、米国を追うだけで理念なし。自衛隊費用も無駄遣いの小泉内閣で、唯一高く評価されるべき案件は、ズバリ「被害者の匿名発表」に他なりません。
 後は加害者サイドのスクラムですが、加害者については「責められて当然」との考えもありますし、こちらは議論の必要がありますが、加害者の知人・親族・友人などでも一切責任のない人に対するスクラムを回避する取り決めは今すぐにでも作れるはずです。次の目標はここでしょう。「被害者の匿名化」をゴールと考えず、政府はしっかりこの問題に取り組むべきです。
 そして何より、「被害者が指定しない限り匿名」とした点を高く評価します。これが逆の場合、表現はさほど変わりませんが、有名無実化は確実になっていたでしょう。「唯一弱者に配慮した小泉政策」として、この決定は非常に大きいです。
 それから、これもいつもの小泉パターンですので少々不安なのですが、今さら「匿名化を決めてはみたが、やっぱり国民からの支持が得られていない。撤回する」と言い出さないようにしてください。お願いですから。

 最後に「バグではなく仕様です」情報を。Tactical Revolutionでとあるアビリティの効果による2回攻撃にエフェクトをつけてみたのですが、その上でサーラさんに3回攻撃アビリティの「飛襲連斬」を使わせたところ、「攻撃 -> エフェクト -> 攻撃x2 -> エフェクト -> 攻撃x2 -> エフェクト -> 攻撃」という良く分からないことになり、少々あせりました。
 が、処理の優先順位としては「攻撃 -> 反動 -> 複数回攻撃効果(エフェクト) -> アビリティの複数回攻撃特性 -> 反撃 -> 格闘型の2回攻撃効果」となっているため、上記の処理は実は「攻撃 -> エフェクト -> 攻撃」を3ブロック繰り返していたのです。
 以上を踏まえて、複数回攻撃アビリティの場合、攻撃と攻撃の間に500msのウェイトを導入し、攻撃の区切りを分かりやすくしてはみましたが、変に見えてもバグ呼ばわりしないようお願いします。
カテゴリ [開発魔法][社会問題][ゲーム開発] [トラックバック 0][コメント 0]

万能ねつ造
2005/12/25(Sun)18:48:11
 韓国のES細胞ねつ造事件。はっきり言って下手な韓流・嫌韓流・靖国ごときより何倍も大きなニュースです。実に大変なニュースなのです。
 科学は下積みの上に物を置くような作業ですから、例えば「1 + 1 = 2」という作業があるとして、それを踏まえて「1 + 1 + 1 = 3」という答えを出したとしましょう。ところが、そこで実は「1 + 1 = 2」はニセモノと分かったらどうしましょう。「1 + 1 + 1」の成果まで意味のないものになってしまうのです。
 全く、日本は技術大国のくせに研究者を邪険に扱ってばかりといいますが、韓国では変な手厚さがこうした問題を引き起こしたわけですから、研究者バッシングも成果主義もロクな結果を生んでいません。青色LEDといい、他の研究といい。
 さて、私に韓国バッシングをする趣味はありませんから、ES細胞について。これの研究を推進しているのは、韓国とせいぜい英国程度のものといいますが、米国などがこれを行わないのは宗教上の理由が大きいのでしょう。科学面からではなく宗教面から進化論にたてついたり、中絶を強く非難したりするのですから。
 では日本はこれを研究すべきか。一言で言ってしまえば、絶対に開始すべきです。倫理観の面から議論を深めたいところではありますが、すでに他国が研究を開始しています。悠長なことを言っていられるような状況ではありません。クローン人間作りを禁止するのは構いませんが、研究自体を縛るのはいけません。
 というのも、例えばこのまま日本がズルズル規制緩和を先延ばししている間に、英国辺りが技術を確立したとしましょう。そして、今までは治療が困難とされていた病気がES細胞で治癒することが分かったとします。ここで問題です。治療困難な重病で余命の少ない患者は一体どのような行動を取るでしょうか
 この辺りは、現在の「渡米移植」を見れば分かります。外国に飛んでES細胞を用いた治療を受けて返ってくる人が出るに決まっています。外国での移植にしても「我が国にも移植待ちの人がいるのに日本人が臓器をかっさらって行った」と非難を浴びているのに、ES細胞でまで同じことを繰り返しますか。研究開始は嫌でもやむを得ません。
 さらに、研究開始が他国より遅れれば、他国に大量に特許を取られることになります。そうすると治療に大量のコストがかかるようになり、貧困度が全世界中で十指に入る日本としては致命的です。これが福祉国家のように「医療費はできるだけ国で負担」というなら、弱者でも治療の道が開かれるため、後から研究を始めても医療は行き渡るのですが。日本はすでに医療格差国ですから、仕方ありません。
 倫理上の問題にしても、「リンリ、リンリと鈴虫のよう」とはよく言ったものですが、例えば目の前に重病で苦しむ人がいるとしましょう。どのような治療をしても、余命も少なくなっています。しかし、この人にES細胞の治療を行えば、治癒が期待できます。この人におとなしく苦しんで死んでいただくのと、ES細胞を用いて治療を施すのと、どちらが倫理的に正しいでしょうか。私は後者の考えです。ですから、ES細胞研究を支持します。
 それにしても、黄教授は辞任、姉歯元建築士は建築士剥奪、朝日記者はクビ、大量破壊兵器をねつ造したブッシュ政権はピンチ。ねつ造は怖いのです。

 本日はいよいよもってネタ切れのため、「管理者」のページを更新です。いわゆるプロフィールというものですが、そんなページを更新して意味があるのやら。Tactical Revolutionのマニュアルページにしても、かなり仕様が変わっているのですから、本当は更新しなければいけないのですが。
 現在のトップページはブラウザ依存があるため、この際だからコンテンツリストをMySQLで作ろうとも考えています。ただ、そうすると項目選択のたびにトップページを読み直さなければならず、動作が重くなりますから、その点は困り者です。
 後はTactical Revolutionのバグつぶしです。メッセージウィンドウとチョイスウィンドウを組み合わせ、片方が閉じたらもう片方を表示するような場面では、片方がチラついたりしていたのですが(正確には「片方のクローズ後に1フレームだけ何も描画されない」)、これはチュートリアルなどでかなり目につく動作をしていました。1フレームが表示される時間はたかだか50msなのですが、これで結構気になるものです。
 具体的には、Tactical Revolutionは大量にスレッドを使っており、しかも多くにsynchronizedロックをかけている関係上、ロックを一時的に解除するwait()メソッドを用いて他のスレッドとデータ交換をしているのですが、その構造はこうなっています(例えば「メッセージを表示して、それが閉じられるまで待機する」場合。言うまでもなく要点のみ。分かりやすさのため簡略化しましたので、実際の実装とは一部異なっています)。
public class Sample ...{
	MessageList ml;
	...
	// 戦闘処理メインスレッド
	synchronized public void process(){
		ml = new MessageList("メッセージ");
		ml.wait(this);
	}
	synchronized public void mousePressed(KeyEvent e){
		ml.next();
		// MessageList は本来メッセージリストなので
		// 複数のメッセージを next() で進める
	}
	synchronized public void draw(Graphics g){
		if(ml.getExist())
			ml.draw(g);
	}
	...
}

public MessageList ...{
	boolean exist;
	...
	public MessageList(...){
		exist = true;
		...
	}
	public void wait(Thread t){
		while(exist){
			try{
				t.wait(0 , 1);
			}catch(InterruptedException e){
			}
		}
	}
	...
}
 とまあ、大まかにこういった流れになっています。別スレッドがexistをfalseにしたらループを脱するようになっています。本来なら「t.notify()」、最悪でも「interrupt()」を用いたいところなのですが、existの値を監視しなければならないため、MessageListをマルチスレッド化して「existがfalseになったらt.notify()」とでもしない限り、それは難しくなっています。スレッドをバカバカ立てると管理も難しくなりますし、リソース及び動作速度の関係上、この方法が最善と判断しました。
 さて、この場合のデータの流れなのですが、スレッドとロックを良く知っておかなければ頭がこんがらがってしまいます。現時点で競合の可能性があるスレッドは3本、process()メソッドで走らせているメインスレッド、リスナのスレッド、描画スレッドです(描画に関しては、外部のスレッドが50msに1度repaint()をコールしています)。
 まずprocess()のsynchronizedですが、これによって明示的にwait()をかけない限り、process()の処理中に他のスレッドが割り込まないことが保証されます。process()ではキャラをマップに追加・削除したり、配置を変更したり、動かしたりといった基本的な動作も記述しますから、下手に描画などが割り込むと最悪NullPointerやOutOfBoundsで落ちます
 また、これと同時に、描画中にリスナの処理が実行されたり、リスナ処理中に描画がなされたりすることも行われないことが保証されます。ただ、process()がメインスレッドである以上、明示的にwait()を呼び出さない限り、process()を抜けるまで描画は一切行われなくなりますし、途中でクリック操作を待機するような場面ではデッドロックを起こします(process()がロックを得てクリック待ち、しかしsynchronizedによってmousePressed()の呼び出しが待機される。描画もできず、永久に進まない)。
 ですから、メッセージリストの待機など、あらゆる待機時にはwait(0 , 1)を呼び出し、mousePressed()やdraw()の命令を処理できるようにしています。例えば上記のプログラムでは「existの値を調べてはウェイト」を繰り返しています。falseになったら離脱するため、process()に制御が戻る仕組みです。
 ここまでは実装論ですが、バグの原因はここからです。上記mousePressed()ではnext()メソッドを呼び出していますが、これは「メッセージリストのリスト残数をチェック、全部表示した後にnext()されていたらexistをfalse」といった処理がなされていました。こうなれば、wait()を終えた後にはexistがfalseになっており、process()に制御が戻りますから、process()のml.wait(this)の下に選択ボックスの処理を記述しておけば、メッセージを表示し終えた後に項目をチョイスするウィンドウを出すことができます。
 しかし、これがチラツキの原因になっていたのです。というのも待機中にmousePressed()の要求とdraw()の要求の両方が呼ばれる場合があるのです。MessageList.wait()のループ中に両方の命令がスタックに送られていれば、t.wait()を呼び出した途端に両方が実行されるわけですから、当然ではあります。
 そして、まずmousePressed()が実行されてnext()処理がなされ、existがfalseにセットされます。その後にdraw()が呼ばれるわけですが、if(ml.getExist())はfalseにセットされていますから、メッセージウィンドウの描画がなされません。その後にMessageList.wait()が制御を回復し、existがfalseであることを確認してprocess()に制御を戻す流れになりますが、process()で選択ウィンドウを作ったとしても、上記のように1フレームだけ描画されない時間が生まれてしまいます。以上がチラツキの原因です。
 それならということで、next()でexistの設定を行うのをやめ、MessageList.wait()メソッド内でメッセージ終端チェックを行うようにしました。例えばメッセージが5個で、next()によって6個目のメッセージが指し示されている場合、今まではnext()の時点でexistをfalseにしていたため、その後にdraw()が入るとチラついていましたが、これならそういうことはありません。t.wait()を終えてループに復帰した後に判定するのですから。が、オチはご想像の通りです。ArrayIndexOutOfBoundsException。
 今回はmousePressed()の後にdraw()が呼び出されるとマズかったのです。mousePressed()でnext()が呼ばれても、上の改良によりインデックスが6個目を指し示した時点ではexistがfalseにされませんから、draw()で6個目を呼び出そうとして制限オーバーというわけです。全く、参ってしまいます。
 仕方がないので、インデックスが配列個数より大きい場合は末端の配列を示すようにしました。これでチラツキはなくなりますし、例外も出ません。修正はほんの数行なのに、考えるのにここまでの時間を要するとは。因果なものです。
カテゴリ [開発魔法][社会問題][ゲーム開発] [トラックバック 0][コメント 0]

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