radium.png
HOME | ARCHIVE | PRODUCTS | ABOUT | RSS

引越し

2003-09-01

職場の引越し作業で潰れた一日だった。

久しぶりの赤坂は,まあ正味な話,あまり変化していなくて,新鮮味に薄いものがあった。

ただ唯一,am/pm が街中に氾濫していることぐらいが特筆すべきことと言うか……正直,同じコンビニばかり乱立されたところで,何も嬉しくはない。中野は中野でサンクスばかりだったし……どうしてこうも集中するんかね。

さすがに疲れてしまったので,いつもよりも早めに帰り,早めに寝ることにした。


Leaky Abstraction

2003-09-02

最近,"Joel on Software" の記事を好んで読んでいる。この blog には,氏がソフトウェアの開発という過程において得た貴重な体験や,その体験から導き出された深い考察などが,豊富に含まれている。それは,必ずしも賛同できるような意見ばかりではないかもしれないけれど,純粋にエッセイとして読んだ場合に,とても面白いものであることには違いないと思う。

先日読んだ記事の中でも特に面白かったのが "The Law of Leaky Abstractions" - 「抽象性の破綻の法則」と題された記事だ。

http://www.joelonsoftware.com/articles/LeakyAbstractions.htm...

この意味深長な題名の付けられた記事は,そんな題名とは何の関連もなく,いきなり TCP プロトコルの解説から始められている。インターネットの基幹要素を構成するプロトコルのうち,TCP が特に重要なポジションを占めていることは周知の事実だ。いくつかある転送プロトコルの中でも,TCP は「通信の信頼性を保証する」という点において,その特徴を保持している。

しかし,この TCP が,非コネクション型のネットワークプロトコルである IP プロトコルの上に組み上げられたものであることを考えると,少し不思議な感じがする(IP は信頼性を保証しない)。そのベースとなる技術には信頼性が保証されていないにも関わらず,どうやって信頼性を確立することができているのだろうか。

ここで Joel 氏は,「ブロードウェイからハリウッドへ俳優を送り届けるサービス」という話を例に挙げて,TCP が IP の上に信頼性を作り出すその方法を説明している。これは,本当に突拍子の無いたとえ話だけれど,その原理を分かりやすく解説することには成功していると思う。要するに,そういう途方もなく面倒な手続きを繰り返すことによって,元は存在しない信頼性というものを「無から生み出す」ことに成功しているというわけだ。

BSD ソケットなどを使って通信を行うプログラムを書いたことのある人ならば,その「途方もなく面倒な手続き」のすべてが,TCP というレイヤの下に覆い隠されていることが分かると思う。ここで TCP というテクノロジは,信頼性を生み出すためのメカニズムを「抽象化」し,問題解決の過程を局所化することに成功しているわけだ。これは高度に完成されたテクノロジの一例と呼ぶことができるのではないかと思う。


しかし,驚くべきことに,これまでの話の中には Joel 氏の仕組んだ「罠」が隠されている。「信頼性を保証するプロトコル」であるはずの TCP も,実は完全な信頼性を実現することはできていないのだ。

例えば,LAN ケーブルがハブのソケットから抜け落ちてしまっていたとしたら,どうだろうか。あるいは,家に住み着いた鼠がケーブルを食いちぎってしまっていたとしたら,どうだろうか……。すると,ケーブルの上を流れるはずだったパケットの数々は行き場を失い,TCP の「信頼性」は脆くも崩れ去ってしまうことになる。

かくして,高度な技術の上に確立されたはずの「抽象性」が,容易に破綻をきたしてしまうわけだ。


氏は,これを "The Law of Leaky Abstractions" と呼び,次のような「法則」として定義している。

すべての単純でない抽象概念は,多くの場合,破綻しやすい性質を持っている

最も分かりやすい例は,2次元配列の持つ抽象性と,それが破綻する瞬間を指摘した話だ。2次元配列というデータ構造は,ユーザに対して2次元的な広がりを持つ記憶空間を提供する。このデータ構造における「列」と「行」という要素の間には,原理的な差は存在しない。それらは相互に交換可能な要素であるはずだ。

しかし,配列の規模が大きくなってくると,この抽象性は容易に破綻を迎える。メモリアクセスの都合から,「列」と「行」の間に大きな差異が生じてしまうからだ。例えば,行方向への連続アクセスは高速でも,列方向への連続アクセスは「非連続」なので効率が悪くなる。また,特定の「行」や「列」を切り出して1次元配列へ変換する際にも,この問題は処理速度へ大きく影響を与えることになる。つまり,「列と行を同じように扱うことができる」という抽象性は,ただ配列の規模を大きくするだけで決定的に失われてしまうわけだ。

また,C++ プログラマにとって身近な問題が,C++ 標準ライブラリの持つ「中途半端な抽象性」だ。例えば,Joel 氏も指摘しているように,string クラスを使った文字列操作は,多くの場面において抽象性を失ってしまう。また,STL の提供するジェネリシティ(総称性)は,一見すると抽象的な概念のように思えるのだけれど,実はほとんど抽象的ではない。ジェネリックプログラミングの手法は,データ構造とアルゴリズムに対して汎用性をもたらすものであるが,基本的に抽象性を実現するものではない。これは,STL や boost などのようにジェネリックなライブラリを利用する上において把握しておかなければならない基礎事実の1つだ。

先日の Raymond Chen の blog における "The secret life of GetWindowText" なども,"leaky abstration" の一種だと指摘することができる。Windows の API 層の裏に隠されたはずの抽象概念が,その内部に抱える複雑性のために破綻をきたしてしまっている。結局のところ,「見せかけの抽象性」をあてにするのではなく,内部構造と正面から向き合わないことには,その「本当の扱い方」を会得することはできないということだ。

Joel 氏は,このような問題に対して諦観の構えをとっているようだ。どんなに高級な概念が,素晴らしく高等な技術によって確立されたとしても,その抽象性が破綻を迎える瞬間というものが,必ずどこかに待ち受けている。ソフトウェア開発者である我々は,「抽象性の破綻」という泥沼に足を奪われながらも,常に前へ歩みつづけるしかないのだろうか……そのような諦めの感情が,最後の一文から感じられた。


Continuum Mechanics

2003-09-03

最近は,たまに気が向くと,Game Developer Magazine のバックナンバーCDから面白そうな記事を拾い上げて,それを印刷したものに目を通してみている。それで,先日ピックアップしてみたのは,2002/9 号より Jeff Lander 氏の記事 "Continuum Mechanics: Bending Stuff Past the Breaking Point" だった。この記事は "Continuum Mechanics" - つまり「連続体力学」の概念を導入することにより,ゲームに対して新たな物理現象のレパートリを追加しようという内容のものだ。

連続体力学とは,気体・液体・固体の運動を巨視的に扱うという物理学の一分野であり,流体力学や弾性力学の基礎となる学問だ。このような知識は,気体・液体の流動,それから,固体の変形・破壊といった現象を扱う際に必須とされる。

件の記事は,簡単なパーティクルモデル(ばねモデル)による物理シミュレーションから話を始めている。パーティクルモデルのような単純な物理モデルでも,応用次第で複雑な現象を扱うことができるということは,金子勇さんのデモなどを見れば分かることだ。しかし,このような簡易的なモデルによるシミュレーションには,様々な限界が存在する。特に「中身の詰まった物体」の運動を扱おうとすると,非常に効率が悪くなるということが指摘されている。

そこで Jeff Lander 氏は,有限要素法による連続体力学モデルを導入することによって,「中身の詰まった物体」の変形や破壊を効率良く解決できるということを示している。ただし,有限要素法自体については,ほんの導入部分について触れているに過ぎず,実践へ辿り着けるほどの情報は提供されていない。まあ,あくまでも「さわり」の記事だということだ。


有限要素法をベースとした解析技法は,物体の変形を扱う分野……特に建築工学において,必須の技術として扱われているようだ。この辺りはちょっと縁遠い分野なので,僕には手も足も出ない……。

http://www.labnet.or.jp/~nastran/femclass.htm

http://www.fem.gr.jp/

件の記事を書いた Jeff Lander 氏や,UCB の James O'Brien 氏,それから,お馴染み Chris Hecker 氏などが,この辺りの話をよく取り上げて記事や講演のネタにしているようだ。

http://www.techsem.com/gts2001/physics.htm

GDC 2003 においても,Lander 氏と O'Brien 氏が "Beyound Bouncing Boxes" と題した講演を行っている。ゲームに連続体力学のエッセンスを導入することによって,物体の変形や破壊を自由に扱えるようにしよう……という内容のものだ。

http://www.gdconf.com/archives/2003/Lander_Jeff.ppt

http://www.gdconf.com/archives/2003/O%27brien_James.pdf

また O'Brien 氏は UCB において有限要素法を利用した物体破壊シミュレーションの高速化技法を研究している。

http://www.cs.berkeley.edu/~job/Projects/Fracture/

これらの技術がゲームに利用されたという事例は,まだあまり耳にしたことがない。少ない既存の例として挙げられるのは,Pseudo Interactive 社の "Cel Damage" などだ。

http://www.celdamage.ea.com/

このゲームでは,前述のような連続体力学シミュレーションと,自由形状変形 (FFM) を導入することによって,ぐにゃぐにゃっと躍動的に動き回るキャラクタのビジュアルを作り出すことに成功している。

http://www.pseudointeractive.com/about.shtml

他にも色々と凝ったことをやっているようなのだけれど……正直なところ,それが効果的に用いられているかどうかという判定は難しいと思う。ゲーム内容は普通だからなあ……。


眠い日

2003-09-04

引越しも無事に完了し,徐々に普段の落ち着きを取り戻しつつある。そこで,新社屋の食堂に初めて行ってみたのだけれど……なんて言うか,色々な意味で衝撃的な内容だった。作った人は,さぞかし満足だろうよ……。

新しい社員証には電子マネー (Edy) 機能が付いているので,適当に使ってみている。

http://www.edy.jp/

コンビニ (am/pm) ぐらいでしか使えないのが残念だけれど,まあ,コンビニ専用と割り切ってしまえば,それなりに便利なものかもしれない。

ただし,この間抜けな効果音だけはどうしても解せない。もっとシンボリックな音を当てることはできなかったのだろうかと思う。コンビニ程度ならまだしも,それなりに雰囲気のある店でこんな間抜けな音が聞こえてきたとしたら……やはり問題があるだろうと思う。


有限要素法関連の資料を読んでいたら眠くなってしまった。まだ基礎も押さえられていないのだけれど……。

有限要素法と言えば,Francois Labelle 氏の Java アプレットによる弾性体シミュレータが面白い。

http://www.cs.berkeley.edu/~flab/elas/elasticity.html

作者の解説によれば,物理モデルから求められる2次の非線形常微分方程式をニューマーク法によって時間積分し,そこから得られた非線形システムをニュートン・ラフソン法によって解く,という方法を利用しているそうだ。とは言っても,その内容は全然理解できていない。もはや,何が何だかさっぱり……。


CEDEC

2003-09-05

結構忙しかった金曜日。夕方からちょっと早めに抜けて,非公式 CEDEC 呑み会こと「裏 CEDEC」に出席してきた。実は今回 CEDEC 自体には参加していないのだけれど,せめて裏だけは顔を出してみようと思ったわけだ……。

実際に会場に着いてから驚いたのだけれど,とんでもない数の人がずらっと席に並んでいた。しかも,それがとんでもない顔ぶればかりなものだから,こちらもどう振舞ったら良いものか訳の分からない状態になってしまった。去年まではもう少し小規模な感じの呑み会だったように記憶しているのだけれど,今回は手持ちの名刺が全然足りなかったほどだった。

この会を主催したIFさんの功績は素晴らしいものだと思います。正直な所,「来年もまたこんな感じでお願いします!」とは気軽に言えない感じになってしまいました……。

とにかく色々な分野の色々な人が顔を揃えていたように思えるのだけれど,いかんせん人数が多すぎて全部は把握し切れなかったのが残念だった。ただ,ゲーム職人の安藤さんが明るく爽やかな好青年だったということだけは鮮烈に覚えている……。やはりこういう集まりだと,声の大きな人の方が圧倒的に目立ちます。

いつもなら電車が動きはじめる頃にはグロッキー状態になっているものなのだけれど,今回に限っては,全然話足りていない感じがしていた。次の呑みはいつの機会か分からないけれど,そのときを楽しみにしようと思っている。


PLAY Studio

2003-09-06

最近,面白かった発見の1つが,"PLAY research studio" のウェブサイトだ。

http://www.playresearch.com/

この "PLAY Studio" は HCI (Human-Computer Intaeraction) 関連の研究を行っている組織であり,日常の生活空間やアミューズメントの分野に対するコンピュータの関わり方について調査と研究・開発を行っている。

この組織はスウェーデンのIT企業 Interactive Institute 社を母体としており,スウェーデン戦略財団 (Swedish Foundation for Strategic Research) をはじめとする公的機関の援助を受けて研究を行っているようだ。

http://w3.tii.se/

http://www.pref.gifu.jp/eurogifu/InteractiveInstitute.htm

http://www.stratresearch.se/eindex.htm


PLAY Studio および Interactive Institute 社の研究成果の一例として挙げられるのが "Smart-Its" だ。

http://civ.idc.cs.chalmers.se/projects/smart-its/

http://www.smart-its.org/

この "Smart-Its" は,ユビキタス・コンピューティングに対する HCI 方面からのアプローチの一例だ。現状における高度な半導体集積技術を活用すれば,日常生活に散在するオブジェクトに対して新たな「知覚」を与えることができる。Smart-Its とは,その際に利用されるべき適切な基盤技術を開発しようというプロジェクトだ。

Smart-Its の目指すビジョンについては,サイトのトップページに引用されている故 Mark Weiser 氏(ユビキタス・コンピューティングの提唱者として有名な人物だ)の言葉がよく表しているように思える。

「ユビキタス・コンピューティングの本質的な特徴とは
この世界に存在する物体同士を演算能力によって接続することだ」

Smart-Its のプレゼンテーションには,その具体的な応用のシナリオが,ムービーによって分かりやすく提示されている。

http://civ.idc.cs.chalmers.se/projects/smart-its/1_3.html

実際のハードウェアについてもプロトタイプの開発が進められている。おなじみ PIC プロセッサをベースとした RFM 無線モジュールのモデルと,Atmel 社のマイクロプロセッサをベースとした Bluetooth デバイスのモデルが実装されている。スウェーデンだから Bluetooth ってのは,当然の選択かもしれない……。

http://www.smart-its.org/artefacts/artefacts.html


PLAY Studio では他にも,こういったユビキタス・コンピューティングと HCI の関連研究を活発に行っている。その最たる例として挙げられるのが "Public Play Spaces" だ。

http://civ.idc.cs.chalmers.se/projects/pps/

例えば,ここで進められているプロジェクト "Sonic City" は,街全体を音楽創作におけるファクタとして利用してしまおうという試みだ。

http://www.playresearch.com/projects/soniccity

この "Sonic City" では,人が街を歩き回ると,その場所や時間,それから周囲の状況などによって,新たな音楽がリアルタイムに作り出されていく。ちょっと前衛的過ぎて,それが本当に面白いかどうかという点については判断しかねる部分があるものの,日常の生活空間をコンピューティングの要素として利用してしまおうというコンセプト自体には,とても興味を惹かれるものがある。


Ubiquitous Games

2003-09-07

PLAY Studio における研究の多くは,アミューズメントを重要な応用分野の1つとして捉えているようであり,研究内容をいわゆる既存の「ゲーム」と関連付けさせようとする動きを,その中に見つけることができる。

そうした動きの中でも面白いのが,Sus Lundgren 氏の Goteborg University における研究 "Joining Bits and Pieces" だ。

http://www.thegamesjournal.com/articles/BitsAndPieces.shtml

余談だけれど,"Goteborg" はスウェーデンの主要都市として有名な土地であり,「ヨーテボリ」と読むのが正しいそうだ……。

http://home.att.ne.jp/sigma/satoh/pictures/sweden/goteborg/g...

Lundgren 氏の研究は,ビデオゲームを現実世界に引き寄せるというよりかは,ボードゲームやカードゲームのような「現実世界のゲーム」に対してコンピューティングの要素を付加しようというものだと言うことができる。これらのゲームにおいてやりとりされるオブジェクトに対してコンピューティングの機能を与えれば,カードのやりとりやサイコロの振りだけでは実現しえなかった要素を新たに追加することができる。例えば,埋め込みのマイクロチップと読み取り機を利用したカードゲームや,コンピュータ駆動によって「場」を変化させるボードゲーム,あるいは,コンピュータという「仲介人」によって複雑な取り引きを行うことのできるモノポリー,等々……。

Lundgren 氏は,このような新たな可能性の数々を「デザインパターン」の形で提示している。例えば,氏の提示するパターンの1つである "Anonymous Trading" (匿名取り引き)とは,以下のような内容のものだ。

取り引き行為 (trading) における重要な側面の1つとして,「何をどの値で売買するか」
ということのほかに,「誰と売買を行うか」という要素が指摘される。これは,ある特定の
1人と取り引きを行う際には上手く行くが,複数の人と行うには難しいものがある。このよ
うな要素はゲームのフィーチャーとしてありうるものであるし,同様に,「匿名での取り引
き」というようなものもフィーチャーとしてあるうるものである。
(例えば,プレイヤが自分の欲しいものと払える金額を匿名で提示すると,組み込みのコン
ピュータがそれらの要求を処理し,結果を導き出す)

このように,氏を始めとする PLAY Studio の研究者たちは,自身の研究の内容を,具体的なアプリケーションの形で提示するだけでなく,他に応用の可能な抽象表現の形にまとめる作業を行っている。この時に用いられる手法が,「ゲームデザインパターン」の考え方だ。

http://www.gamedesignpatterns.org/

この件に関しては GDC などでも講演を行っている。

http://www.cmpevents.com/GDx/a.asp?option=C&V=11&SessID=796

ただし,この辺りの話は,氏らの研究の本質とは分離して扱うことのできる部分なので,またの機会に調べることにしたいと思う。


氏の具体的な研究内容については,氏の修士論文 "Joining Bits and Pieces - How to make Entirely New Board Games using Embedded Computer Technology" に提示されている。

http://civ.idc.cs.chalmers.se/publications/2002/lundgren_joi...

修士論文に相応しく長い論文なので(僕はよく知らないんだけど,修士論文って「最低ページ数制限」とかあるんだろうか?),正直なところ,とても全部は読んでいられない……まあ,大体の内容としては,「既存のオブジェクトと組み込みハードウェアの組み合わせによって,どのような可能性が新たに生み出されるだろうか」という点について,具体的なアプリケーションを提示しながら考察を行っているようだ。

氏は Goteborg University を卒業後,Interactive Institute 社の PLAY Studio に加わり,ユビキタス・コンピューティングの視点から行われるゲームの拡張という分野について研究を続けている。

http://www.playresearch.com/~she/

ワークショップ "Exploring Ubiquitous Computing Entertainment" におけるレポート "Designing Ubiquitous Computing Games" など,なかなか面白そうな内容だ。

http://civ.idc.cs.chalmers.se/~she/designingubigames.pdf

いずれ,この辺りの文献も,もう少し詳しく目を通してみたいと考えている……今はちょっと,新たに仕入れた情報を整理するので手一杯な感じだ。


Game Design Patterns

2003-09-08

"Joining Bits and Pieces" の Sus Lundgren 氏は,現在,研究の一環として "Game Design Patterns" と呼ばれるサイトの運営を行っている。

http://www.gamedesignpatterns.org/

このサイトは Lundgren 氏と,PLAY Studio (Interactive Institute) に所属する Staffan Bjork 氏,それに Nokia 社の Research Center に所属する Jussi Holopainen 氏らによって運営が行われている。氏らは,実際にはゲーム業界の従業者ではないのだけれど,氏らが「研究」としてゲームの調査・分析を行うにあたって,ここで提示されているような「ゲームデザインパターン」の概念を導入する必要性が見出されたということのようだ。

この「ゲームデザインパターン」の概要については Bernd Kreimeier 氏の記事 "The Case For Game Design Patterns" が良くまとまっている。

http://www.gamasutra.com/features/20020313/kreimeier_01.htm

この記事において Kreimeier 氏は,氏らの提案する「ゲームデザインパターン」について解説を行い,ゲームデザイン過程におけるその必要性を主張している。また同時に,記事中においていくつかの「パターン」の例を実際に提示している。分かりやすい例で言えば,「じゃんけん」 (paper-rock-scissors) の概念が,以下のような文書によってパターン化されている。

じゃんけん (PAPER-ROCK-SCISSORS)

問題:プレイヤの決断を安直な選択に落とし込んでしまうような,一方的な戦略の存在を
避ける。

解決法:いわゆる「じゃんけん」によって表されるような,複数の選択肢からなる固定的
な関連付けを導入する。

結果:プレイヤはもはや,あらゆる状況において最適となるような単一の戦略をとること
が不可能となる。プレイヤは再び決断を見直し,ゲームによって課された制約に従って状
況の調整を行うか,あるいは,短絡的な決断によってもたらされる結果を被らなくてはな
らなくなる。

例:Andrew Rollings の指摘によれば,Barry Murray と Dave Murray の "The Ancient
Art of War" における「戦士−蛮人−射手」の関係が例として挙げられる。また,氏は
Quake における武器とモンスターの関係も似たような性質を持っていると指摘している。
すなわち,nailgun は shambler に強く,shambler は rocket launcher に強く,rocket
launcher はゾンビに強く,ゾンビは nailgun に強いという特性を持つ。

氏らの主張によれば,このようなデザインパターンの概念を導入することによって,デザイン過程において必要とされる語彙を正確に定義することが可能となり,開発者間の意思疎通を迅速かつ確実なものにできるとされている。また,特定のアイデアを再利用可能な形で文書にまとめることができるというのも,氏らがデザインパターンを用いる上での大きなモチベーションの1つだ。

語彙を正確に定義することによって意思疎通が円滑化されるというのは,一般的な「デザインパターン」におけるモチベーションの中でも最も大きなものであるように思える。永和システムの平鍋氏の表現を借りるならば,それは「バレーボールのセッターが『Aクイック』というサインを出すのと似ている」。最適な形へと定型化され,特徴や短点などの知り尽くされた「パターン」を,簡潔な語彙として運用することによって,開発者間における確実な意思疎通を可能とする。アルゴリズムやデータ構造の分野においては,このような語彙が非常によく運用されているのだけれど,設計面においては意外と不足しているというのが実情のように思える。それを補強する要素として働くのが「デザインパターン」であるということだ。

「特定のアイデアを再利用可能な形で文書にまとめる」というのは,まさに Lundgren 氏らの行おうとしていることと合致している。すなわち,研究者が自らの研究において得た成果(新たな種類のゲームデザイン)を,産業に対して応用可能な形で伝えるには,どのようにしたら良いのだろうか? そこで持ち出すことになったのが,この「ゲームデザインパターン」なのだろうと思う。


"Game Design Patterns" サイトの publications セクションには,様々な文献へのリンクがあるのだけれど,基本的には上の Gamasutra の記事だけで十分だろうと思う。書いてあることは結局同じだから……。

http://civ.idc.cs.chalmers.se/projects/gamepatterns/publicat...

また,件の記事を執筆した Bernd Kreimeier 氏は "Game Design Patterns" と題した本を出版する予定のようだ。

http://www.amazon.co.jp/exec/obidos/ASIN/1556229674

どんな内容の本だか予想もつかないので,とりあえずレビュー待ちなのだけれど……amazon.com や出版社のサイトにはこの本の紹介が見当たらないのが意味深長だ。出版中止かな……。


ゲームデザインの初期段階において(たとえばコンセプトの決定段階などにおいて),このような手法が役に立つことはほぼ無いだろうと思う。しかし,デザインの細部を詰める段階においては,このような語彙の存在を充実させることが,デザインの洗練や意思疎通の過程において効力を発揮することがあるかもしれないと思う。


The Microsoft Sound

2003-09-09

眠い,眠過ぎる……。週の始めから夜更かしをしていたものだから,睡眠が足りなくて,どうしても日中に眠くなってしまう。まだ忙しくないからと言ってダラけていては駄目なのだけれど……。


Raymond Chen 氏の blog "The Old New Thing" の更新が高ペースでいい感じだ。

http://blogs.gotdotnet.com/raymondc/

この内容をまとめて一冊の本にでもしたら,それなりのものが出来てしまいそうな雰囲気だ。それほどまでに興味の惹かれるエピソードの数々がここに明かされている。

特に面白いと感じるのが,Windows 95 にまつわる「こぼれ話」の数々だ。なんだかんだ言って,僕の Windows 95 に対する思い入れは相当に深いものがある。学生時代のほぼ全域に渡って,自分に様々な可能性を与えつづけてくれたのが,この OS だった。プログラミングを本格的に覚えたのも,洋ゲーの洗礼を受けたのも,インターネットのだだっ広さを体験したのも,すべてこの OS の上での出来事だったように思える。


そんな Chen 氏の blog の最新の記事は,Windows 95 の起動音にまつわる小話だった。

http://blogs.gotdotnet.com/raymondc/PermaLink.aspx/d61f33c0-...

柔らかなアルペジオとピアノの余韻が印象的な,あの「曲」が,実は Brian Eno の作品だということは,意外と知られていない事実のように思える。話題に挙げられることは少ないのだけれど,media フォルダの中にある "The Microsoft Sound" の wav ファイルのプロパティを開いてみれば,作者の欄に Brian Eno の名が入れられていることが分かるはずだ。

氏は San Francisco Chronicle 誌のインタビュー記事において,あの「曲」が生み出されることになったその顛末を述べている。

http://www.sfgate.com/cgi-bin/article.cgi?file=/chronicle/ar...

Brian Eno は,いわゆるアンビエント・ミュージックの開祖として有名な人物だ。音楽というよりかはむしろ「音の集合」に近い感覚を持つ氏の楽曲群は,難解な要素を持った作品が多く,素人にはなかなか近づき難い雰囲気を放っている。僕は高校生の頃に "Neroli" というアルバムを聴く機会があったのだけれど,50分もの間ただ同じような音の繰り返しが演じ続けられるそのアルバムに対して,理解することを完全に放棄したような覚えがある。

http://www.amazon.com/exec/obidos/tg/detail/-/B0000035CM

とは言っても,どうやらこのアルバムは氏の作品群の中でも最も極端な部類に入るものであったようなので,いきなりこのアルバムを選んでしまったことを後悔すべきなのかもしれないと思う。他の作品は,結構普通に聴けるものがあるんだよね……。

http://ambient.x-y.net/b_room/Music%20For%20Films.htm


The Top Ten Misconceptions

2003-09-10

"Game Design Patterns" からのリンクを辿っていて,面白いページをいくつか見つけることができた。そのうちのひとつは,John Vlissides 氏の Object Magazine への寄稿記事 "Patterns: The Top Ten Misconceptions" だ。

http://researchweb.watson.ibm.com/designpatterns/pubs/top10m...

講演用の資料もある。

http://www.research.ibm.com/designpatterns/pubs/top10misc.pd...

John Vlissides 氏は,ソフトウェアデザインパターンの提唱者として有名な4人組 "GoF" (Gang of Four) の1人である人物だ。ソフトウェア工学の分野に対してデザインパターンの概念を広めるきっかけとなった氏自身が,世間にあるデザインパターンへの誤解を解くという内容のものだ。

この記事において氏は,デザインパターンに対する世間の認識の中に,過大評価や過小評価のような「誤認識」 (misconception) が存在することを指摘している。なかでも誤った認識を招きやすいのが,「デザインパターンとは何であるか」ということと,「デザインパターンとは何をするものか」ということであるようだ。

Vlissides 氏の解説によれば,パターンとは,それ自体が何かを生み出したり,何かを保証したりするものではない。それは,デザインの過程におけるヒントであったり,あるいは優れたデザイン方法の教育を促進するものであったり,技術者同士の意思疎通を円滑化するための手段であったりする。「道具」や「手段」というよりかは,もっと間接的な働きをもたらす「概念」の1つであるということだ。

簡潔に述べるならば,パターンとは「頭の食糧」なのであって,「道具の餌」ではない
(food for the brain, not fodder for a tool) ということだ。そこに方法論としての
有益性が潜在することはあれど,それは言わば「ケーキに被せるトッピング」のような
ものなのであって,それ自体がケーキとなるわけではないし,ケーキを構成する一層と
なることさえもありえない。

Vlissides 氏が最初に指摘している「誤解」は,「パターンとは,ある状況における問題に対しての解決法である」というものだ。これはデザインパターンの「元祖」であるところの Christopher Alexander 氏が行った定義の1つなのだけれど,Vlissides 氏はこれを真っ向から否定している。

ここで氏が反証として用いているのが,次のような「問題」と「解決法」の例だ。

問題:当選した宝くじを期限までに引き換えるには,どうしたらよいだろうか?

状況:期限の1時間前に,犬が宝くじの券を食べてしまった。

解決法:犬の体を切り開いて,券を引っ張り出して,最も近い引き換え所に駆け込む。

上の例は,問題に対する明らかな解決法を表しているものの,それは決して「パターン」ではない。パターンとして存在するべき「反復性」(別の同じような問題に対して適用を可能にする性質),「教育性」(応用を可能にするだけの十分な理解を与える性質),「名前」(パターンを指し示すための手段)が不足している。ここから,パターンとは単なる解決法や,直接的な手段を与えるものではなく,それを導き出すための一般的な概念を与えるものだということを示しているのだろうと思う。


Rubyist

2003-09-11

眠い……。職場が近くなったにも関わらず,生活態度はほとんど変わりがない。

けっこう,ダラけてるかもしれない。

なんとか気合を入れて,自分の中でのコアタイムを1時間繰り上げるぐらいの調子に移行したいと考えている(それでもなお,世間に比べれば十分に遅い時刻であることは変わりないのだけれど……)。


スクリプト言語 Ruby の作者として有名な Matz 氏の日記を,いつも欠かさず読んでいる。

http://www.rubyist.net/~matz/

Matz 氏の視点のユニークなところは,「世界に通用するオブジェクト指向言語を構築する」という野心的なテーマに取り組みながらも,プログラミング言語としての「使いやすさ」を追求するという課題に対して,常に純粋な姿勢を守り続けているということだ。

言語やツールの開発というものは,本来の意図とは異なる特定の思想に染められてしまいがちな性質を持っているように思える。「本当に自分の望むものを作る」という純粋な動機に基づいて開発を続けることは,実はとても難しいことだ。それでも Matz 氏は,「自らが使いやすいと考えるものを作る」という,単純だけれど奥の深いテーマを扱うことに成功している。そのビジョンの堅固さは,Ruby という言語が持つ魅力の1つにさえなっているように思える。

http://www.rubyist.net/~matz/20030910.html#p02


先月の日記の中でも,特に興味を惹かれたのが「継承は悪か」という題名の記事だった。

http://www.rubyist.net/~matz/20030806.html#p01

「下手な継承は OOP を破綻に導く」という,一般的に知られている教則の1つを挙げた上で,氏は次のような反論を展開している。

しかし、私は同意しません。

(ちゃんと考えた後でも)継承を使いたくなるケースでは、オブジェクトコンポジション
の方が継承よりも優れていることはまれだからです。むしろ、明示的な委譲の定義が繁雑
で、「こんなこと自分でしなくちゃいけないのは変だ」と感じます。そんなことを言語に
押しつけて自動で片付けるための仕組みが、オブジェクト指向言語の継承機能であったは
ずです。

ここでも姿を現すのが「使いやすいものは良いものだ」という考え方だ。とは言っても,決して Larry Wall のような短絡的な結論に飛びつくのではなく,自らのスタンスというものを見直した上で,問題に対して真面目に取り組む方法を模索し続けている。その真摯な態度と明快なビジョン,それから,我々に幸せをもたらしてくれるかもしれないという思い(「使いやすい言語」がプログラマを幸せにするために存在するという主張は,当然,あって許されるべきものであるはずだ)が,Ruby という言語を僕にとって特別なものとする要素として働いている。


しかし,ただ「継承は許される」と弁護しているわけではなく,利用には最低限の条件が存在することを提示している。

私個人が継承を用いるかどうかについての唯一絶対のルールは「is-aの関係にあるか」で
す。この関係が成立しない時に継承を使うのは純粋に間違いです。

まあ,ここはちゃんと押さえて,ね……。


Singleton (1)

2003-09-12

以前から,自分の中で結論を出すことのできていない問題のひとつとして,Singleton パターンの必要性に対する疑問というものがある。果たして Singleton パターンとは,パターンとして本当に「枯れた」ものなのだろうか,という疑問だ。

このような議論は,デザインパターンの応用の領域においても既に存在する問題のひとつであるらしく,例えば "c2 wiki" の "SingletonPattern" や "SingletonsAreEvil" の項を覗いてみれば,Singleton パターンの必要性に対して否定的な意見が少なからず挙げられていることが分かる。

http://c2.com/cgi/wiki?SingletonPattern

http://c2.com/cgi/wiki?SingletonsAreEvil


Singleton パターンの目的は,インスタンスの存在を唯一なものとして保つことだ。

http://home.earthlink.net/~huston2/dp/singleton.html

しかし,一般的に用いられている Singleton の実装には,いくつかの問題点が存在するように思える。そのうち明らかな問題点として挙げられるのが,「インスタンスの生成と廃棄のタイミングを曖昧なものにしてしまう」という問題だ。

これは,Singleton の一般的な実装が,「唯一のインスタンスを,インスタンス取得関数内の static オブジェクトとして実装する」というものか,あるいは「インスタンス取得関数が初めて呼ばれた際に生成を行う」というものであり,そのどれもが生成のタイミングを制御不可能な要素として隠してしまっていることに起因する。これは,複数のクラスにおいて生成の順序を制御する必要性などがある場合に,しばしば深刻な問題を引き起こすことになる。

そして次に,個人的に重要な問題として考えているのが,Singleton の実装自体が微妙に小難しいものであるということだ。単純に打鍵量が多いという問題もあるし,構造が混乱を招きやすいという問題も挙げられる。これは,Singleton における「クラスメソッドがクラス自身の生成に関わる」という動作が,OOP の基本にある「生産者と生成物」のメタファに反してしまっているように感じるためだ。

これらの問題は,プログラムの読解を多少難しいものに変えてしまう性質を持っているように思える。いくらコメントに「このクラスは Singleton です」と書かれていたとしても,慣れないうちは多少の混乱を招いてしまうだろうし,それが単純に慣れの問題として片付けられるべきものなのかという点については,もう少し深い考察を経てみないと分からないものがあると思う。


ここで出た問題に関して,Singleton の実装自体に対して改良を行うことも可能だと思うのだけれど,それ以前に考えられるのが,そもそも Singleton を使わずに済ませてしまうという方法だ。インスタンスの存在を唯一なものとして保つだけであれば,Singleton パターンを用いるまでもなく,安全に実現することができる。

考えられる実装のうち最も単純なものは,古きよき C の作法を用いることだ。つまり,オブジェクトの存在を翻訳単位の中に閉じ込め,外部からのアクセスに必要とされるインタフェースのみを大域関数として露出させる方法だ。C++ の namespace を使えば,名前空間を浪費してしまうという問題も避けることができる。

serial.h:
  namespace serialcom {
  extern void initialize();
  extern void cleanup();
  extern void send(const char* data, int length);
  extern void recv(char* dest, int length);
  }

serial.cc:
  namespace { // local namespace
  int socket;
  char *buffer;
  ...
  }
  namespace serialcom {
  void initialize() { ... }
  void cleanup() { ... }
  void send(const char* data, int length) { ... }
  void recv(char* dest, int length) { ... }
  }

実装の手間で言えばこちらの方が楽だし,ミスリーディングを招きにくい構造になっているはずだ(少なくとも僕はそう思う!)。クラスを用いていないという点で「オブジェクト的な」扱いをすることができなくなっているものの,もともと Singleton とは,任意の文脈におけるオブジェクトの保持を不可能とするものであるのだから,むしろその実態を翻訳単位の中に閉じ込めてしまうというアプローチの方がしっくり来るものを感じる。

この方法には,オリジナルの Singleton と比較して明らかに劣る点が存在するものの(派生ができないし,テンプレートを適用することもできない),僕の疑問に対する解答の1つとして挙げられるものではあると思う。


Eve of Destruction (1)

2003-09-13

そろそろ足を洗おうと思っていたはずの Battlefield 1942 を,なぜか今もプレイしている。うう,おかしいなあ。こんなはずじゃなかったんだけど……。

どうやら,今この界隈では "Eve of Destruction" という mod が流行っているようだ。新しいバージョンが昨日(日本時間的には今日だったかもしれない)公開されたばかりで,僕もこの騒ぎに乗じて遊び倒している。

"Eve of Destruction" はベトナム戦を模した mod だ。プレイヤはアメリカ軍と北ベトナム軍に分かれて互いの陣地を獲り合うことになる。

http://www.planetbattlefield.com/eod/

密林での立体的な戦闘や,極限まで視界の限られた夜戦,あるいは,「ハンバーガー・ヒル」ばりに高地を獲り合う死闘など,本編の "Battlefield 1942" には無いユニークな展開を楽しむことができる。

このような mod は,自分達の親しんでいるゲームを,微妙に変更されたルールの上でプレイすることができるという点で,その「楽しさ」の多くの部分を構成しているのだけれども,どうもその点にばかり頼っているきらいが感じられることがある。この "EoD" も,真新しさの感じられるうちは面白いのだけれど,次第に調整の足りなさが目立ってくる。ほとんどのマップにおいてベトナム軍が有利となってしまっているし,兵装の面でもアメリカ軍の方が不利に見える(車両がいまいちなんだよなあ……)。

実際に50人規模で対戦していると,ベトナム軍の圧勝で終わることが多いようだ。ぬぬぬ……。


Eve of Destruction (2)

2003-09-14

昨日から "Eve of Destruction" をプレイしている。他にやったことと言えば,髪を切りに出かけたことぐらいで,非常に不毛な連休を送っている。

mod としての "EoD" の特徴は,専用のマップが多く用意されていることだと思う。 "DesertCombat" が「本編には無い派手な兵器を楽しむ」という性質の mod だったのに対して,"EoD" はマップの構成によって本編からの差別化を図るものとなっている。

特に,本編には存在しなかった要素である「夜戦」のマップが面白いかもしれない。これらのマップでは,限られた視界の中で敵を待ち伏せながら戦闘を行うことになる。敵と遭遇せずに目的地へ向かうのが得策なので,地形にうまく身を隠しながら移動することになるのだけれど,敵はそれを予測して待ち伏せをするものだから,こちらはさらにその裏をかいて……というような,深い駆け引きを要求される。

夜戦や密林では,みな視界の悪い所に身を隠すため,射撃を行うにも勘が要求される。姿は見えなくとも,曳光弾の弾道やマズルフラッシュから位置を特定することができるから,そこへ弾を撃ち込むか,手榴弾を投げ込むかすることになる。見事当たれば成功だけれど,外せば手痛い反撃が待ち受けているかもしれない。

そんな視界の極限を削り込むような銃撃戦ばかりやっていると,当然のごとく友軍攻撃も発生する。確実に視界に入っている状態でないと名前タグが表示されないような仕様になっているから,遠くの敵はマップでの表示や服装から見当を付けて判断するしかないんだけれど,いちいちマップなんぞで確認していたらこちらが先に撃たれてしまうし,服装はなんだか似たようなものばかりで,どうしても仲間を撃つシチュエーションが発生してしまう。

そんな状況だから,自分自身も敵として誤認されないような行動を心掛けることが必要になってくる。自陣に向かって匍匐接近しているヤツなんかは,確認無しに撃たれたって文句言えないってわけ……。


ところで,ベトナム戦をテーマとした "Battlefield" は,オリジナルの開発元である DICE (Digital Illusions CE) 社でも開発を行っているようだ。タイトル名 "Battlefield Vietnam" として既に情報が公開されている。

http://www.eagames.com/pccd/bf_vietnam/

ちなみに,開発元の DICE 社はスウェーデンのデベロッパであるようだ。いかにも米国的なゲームなんで,てっきり米国製かと思っていたんだけど……。

http://global.dice.se/

ストックホルムとヨーテボリにオフィスを構えているとのこと。北欧のデベロッパからこのような内容のゲームが発売され,しかもそれが全世界でベストセラーになっているという状況は,ちょっと珍しい現象のように思える。


Singleton (2)

2003-09-15

前述のような「Cスタイル」の方式は,いくつかの点において明らかなデメリットを指摘することができる。まず1つは,継承が利用できないということ。もう1つはテンプレートを利用できないということ。そして最後の1つは,インライン関数による高速化を期待することができないということだ。

上記のデメリットのうちの最後の1つ − インライン関数化の問題は,Cでのプログラミングにおいて頻出していた問題の1つとして関連付けることができる。データの隠蔽を「翻訳単位の中に閉じ込める」という手段でしか実現することができないために,インライン関数を利用した軽量なアクセスというものを,安全な方法によって実現することができないという問題だ。これは,実装の対象となる「唯一のインスタンス」が,プログラムの全域から頻繁に呼ばれるようなものである場合に,無視できない問題へと発展する可能性を秘めている。

これらの問題は,クラスメソッド(static メソッド)による実装を用いることによって,いくらか改善を試みることができる。

class serialcom
{
public:
  static void initialize();
  static void cleanup();
  static inline void send(const char* data, int length) { ... }
  static inline void recv(char* dest, int length) { ... }
private:
  serialcom() {} // forbidden
  static int socket;
  static char *buffer;
};

相変わらず継承には対応できていないものの,テンプレートへの対応や,「安全なインライン関数の実装」には近づくことができている。

c2 Wiki における Singleton パターンを巡る議論を覗いてみると,上の実装例に似たパターンとして "Monostate" と呼ばれるパターンが紹介されている。

http://c2.com/cgi/wiki?MonostatePattern

Monostate パターンとは,一言で表すならば「全てのメンバ変数が static として宣言されているクラス」のことだ。詳細については Robert Martin 氏の paper に述べられている。

http://www.objectmentor.com/resources/articles/SingletonAndM...

上の例に Monostate パターンを適用すると,以下のような実装になる。

class serialcom
{
public:
  void initialize();
  void cleanup();
  inline void send(const char* data, int length) { ... }
  inline void recv(char* dest, int length) { ... }
private:
  static int socket;
  static char *buffer;
};

Monostate パターンの利点として挙げられているのは,これが通常のオブジェクトと同じように扱えるものであること(透過性の存在)や,継承や多態の適用が可能であることなどだ。逆に欠点として挙げられているのが,「利用の度にオブジェクトの生成と廃棄が行われてしまう」という問題だ。

上のコードを見れば,このクラスのインスタンスには実質的にデータが存在しないことが分かると思うけれど,C++において「空のクラス」は大きさ "1" を持つという定義があるために,律儀にインスタンスの生成と廃棄が行われてしまうようだ。まあ実際には,スタックポインタを足したり引いたりしているだけなんだけれど,それでも無駄なオーバーヘッドであることには違いないと思う。

もうひとつ,Monostate パターンについて微妙な違和感を覚えることがある。それは,このクラスが,「変数の宣言がインスタンスの生成を意味する」というC++のセマンティクスを破ってしまっているように思えることだ。

例えば,下のような一節があったとする。もし,このコードとはまったく関係の無い人が,「serialcom クラスは Monostate である」という事実を知らずに読解を行ったとしたら,どのような印象を持つことになるだろうかと思う。

void process_1()
{
  serialcom com;
  com.initialize();
}
void process_2()
{
  serialcom com;
  com.send(data, data_length);
}
void process_3()
{
  serialcom com;
  com.recv(buffer, buffer_capacity);
  com.cleanup();
}

serialcom が Monostate であると分かっていれば,これは何の他愛も無い内容かもしれない。しかし,ユーザが常に「特殊な状況」を理解してくれることを期待して設計を行ってしまって良いものだろうかと思う。もっとミスリーディングの発生しにくい,より良い「パターン」が存在するはずだ……そのように思えてならない。

ともかく,以上のような考察から,継承や多態を必要としない場合に,単純な Monostate を用いることには魅力を感じない。将来に渡って継承が必要されないと判断できる状況であれば,メソッドもすべてクラスメソッド (static) 化して,余計な生成を必要としない設計にまとめるべきであると思う。


Singleton (3)

2003-09-16

これまでに挙げたいくつかの例からも分かるように,「インスタンスを唯一に保つ」という目的を達成するにも,様々な方法を用いることができる。結局のところ,どの方法を,どのようなシチュエーションにおいて用いるべきなのだろうか,という話になってくるのだろうと思う。

個人的には,「メンバ変数およびメンバ関数をすべて static として宣言し,かつ,露出する必要の無いものは翻訳単位の中に閉じ込める」というスタイルを好んで利用している。これは,Cでの開発経験が長かったがゆえに,このような方法を好むのかもしれないと思う。もしかしたら,「最初に覚えた言語がC++」なんていうプログラマにとっては,この嗜好は理解し難いものがあるかもしれないと危ぶんでいる。


僕が Singleton の利用を避けている理由が,実はもう1つ存在する。"pimpl" イディオムと併用した場合に実装が複雑化してしまうという問題だ。

"pimpl" イディオムは,ヘッダファイル間の相互参照性を減らすために用いられるテクニックのひとつだ。

http://www.gotw.ca/gotw/024.htm

http://c2.com/cgi/wiki?PimplIdiom

大規模なソフトウェア開発の現場においては,クラス間のコンパイル時依存性をできるだけ減らすことが重要な課題となってくる。そこで,この "pimpl" イディオムのようなテクニックを常に意識して用いなくてはならない。

しかし,例えば Singleton パターンなどは,それ単体でも結構ややこしい構造をしているために,そこへ更に pimpl のような構造を混ぜてしまうと,どうしても流れの把握しにくい実装ができあがってしまう。

下のコードは,単純な Singleton クラスに pimpl イディオムを混ぜてみたものなのだけれど,僕にとってこのコードは,不必要に複雑な構造をしているように感じられる(ちなみに,生成と廃棄のタイミングを明示的に指定するために,通常の Singleton には存在しない initialize 関数と cleanup 関数を特別に設けている)。

---- component.h --------------------------------

struct ComponentImpl;

class Component
{
public:
    static Component& getInstance()
    {
        assert(instance);
        return *instance;
    }

    static void initialize()
    {
        assert(!instance);
        instance = new Component;
    }

    static void cleanup()
    {
        assert(instance);
        delete instance;
        instance = 0;
    }

    void run();

private:
    Component();
    ~Component();
    ComponentImpl* _pimpl;
    static Component* instance;
};

---- component.cc --------------------------------

struct ComponentImpl
{
    inline void run() { puts("Hello world!"); }
};

Component* Component::instance = 0;

Component::Component()
{
    _pimpl = new ComponentImpl;
}

Component::~Component()
{
    delete _pimpl;
}

void Component::run()
{
    _pimpl->run();
}

これを「メンバをすべて static 化」のスタイルに変更し,できるだけ構造をシンプルに保つよう意識してコーディングしてみると,以下のようなコードが出来上がる。

---- component.h --------------------------------

class Component
{
public:
    static void initialize();
    static void cleanup();
    static void run();
};

---- component.cc --------------------------------

namespace {

struct ComponentImpl
{
    inline void run() { puts("Hello world!"); }
};

ComponentImpl* component_pimpl = 0;

} // local namespace

void Component::initialize()
{
    assert(!component_pimpl);
    component_pimpl = new ComponentImpl;
}

void Component::cleanup()
{
    assert(component_pimpl);
    delete component_pimpl;
    component_pimpl = 0;
}

void Component::run()
{
    component_pimpl->run();
}

上の2つのうち,どちらが適切な実装だと言えるだろうか。デザインパターンに精通しているのであれば,前者の Singleton の実装でも問題無いのかもしれない。しかし個人的には,シンプルに保とうと思えば保てるはずのコードを,「パターンに当てはめる」という理由のためにわざわざ複雑化させる理由は無いだろうと思う。僕にとっては,後者のコードの方が理解しやすく,メンテナンス性の高いものであると感じる。もし周囲の人間も同様に感じるようであれば,迷わずに後者を選択すべきだと思う。

もし,自分が単なるライブラリの利用者であれば,Singleton の方が使いやすいと感じるかもしれないし,その方が「よりスマートな実装」だと感じるかもしれない。しかし開発の現場においては,自分はコードを書く人間であり,それをメンテナンスする立場の人間でもある。単なる外見上の問題だけではなく,内部構造のメンテナンス性も含めた上で判断を行おうとするならば,ある程度の「泥臭さ」を許容する態度が必要になるだろうと思う。


Modern C++ Design

2003-09-17

僕が Singleton パターンを避ける理由の1つとして挙げたものに,「コードの余計な複雑化を避けるため」というものがあった。実は,これをさらに回避するいい方法が C++ には存在する。強力なテンプレートライブラリを利用するという方法だ。

例えば,Andrei Alexandrescu 氏の "Modern C++ Design" で有名なテンプレートライブラリ "Loki" には,Singleton パターンを実装するためのテンプレートとして "SingletonHolder" と呼ばれるテンプレートクラスが用意されている。

http://www.moderncppdesign.com/

http://www.amazon.co.jp/exec/obidos/ASIN/4894714353

"Loki" のソースコードは SourceForge から入手することができる。

http://sourceforge.net/projects/loki-lib/

ただし,このパッケージにはドキュメントの類が添付されていない。本格的な導入を行うには,書籍の方を購入する必要があるだろうと思う。

これに関連する話題として,"The Code Project" の Lai Shiaw San Kent 氏の記事 "Singleton Pattern: A review and analysis of existing C++ implementations" では,C++ 上における Singleton の種々の実装方法について,詳細な考察を行っている。

http://www.codeproject.com/useritems/singleton.asp

ううむ……たしかに,あれもこれもと凝り出してしまえば,ここまで突き詰めることになってしまうのかもしれないけれど……個人的には,ちょっとオーバースペック気味だ。

もし仮に,Loki がある程度のポピュラリティを持っており,コード自体も十分に安定したものとなっているようであれば,これを導入するという線も考えられるかもしれない(ちなみに Loki は MIT 形式のライセンスによって配布されている)。しかし実際には,Loki は比較的マイナーなライブラリのひとつであり(知名度は高いかもしれないけれど,実際に使っている人は少ないと思う),少ない情報から自前でノウハウの蓄積を行うというプロセスが必要になるだろうと思う。

そこで自分はと言えば,そもそもテンプレート自体に対しても馴染みが薄いというのに,ましてや Loki のような変態ライブラリを使いこなせるかというと……実に難しいものを感じる。

この手のテンプレートを気軽に利用したいのであれば,shinichiro.h さんの公開している Singleton テンプレートを引っ張ってくるのがいいかもしれない。これくらいシンプルな実装であれば,内容を十分に把握した上で利用することが可能であるはずだ。

http://user.ecc.u-tokyo.ac.jp/~s31552/wp/template/singleton....

多くの場合,Singleton クラスに対して派生や多態を必要とすることは無いので,このようなシンプルな実装でも十分に役立てることができる。あとは,場合によってはスレッドセーフ化を考える必要があるかも,って程度かな……。

しかし,これほどシンプルな内容であるにも関わらず,ConcreteSingleton が Singleton<ConcreteSingleton> を継承している辺りなどで,ちょっとクラっときてしまう。この手のテンプレートプログラミングにはまったく慣れていないものだから,処理の流れを追うだけでも一苦労だ。

まあ,いざとなったら,テンプレートの部分をすべて手書きに直す,ってぐらいの気構えでいれば良いのかもしれないと思う。


Designing for Local Interaction (1)

2003-09-18

最近は PLAY Studio の周辺からリンクを辿り,読書ネタを探ることが多くなった。例えば今は,Johan Redstrom 氏の論文 "Designing for Local Interaction" を読んでみている。

http://www.math.chalmers.se/~redstrom/

http://www.math.chalmers.se/~redstrom/papers/local_interacti...

氏はユビキタス・コンピューティングおよびインタラクション・デザインの分野における研究者であり,この論文は,情報の相互交換における「局所性」が,その手段に対してどのように影響を与え得るだろうか,という点について研究を行ったものだ。

この内容が,研究としては未成熟なものであるものの,様々な可能性を示唆しているようで面白かった。特に,導入部分の内容がよくまとまっており,氏の取り組んでいる研究の内容を分かりやすく提示するものとなっているように思える。

これを翻訳し,以下に転載してみようと思う。


情報とは一般に,その発信源から極端に遠くへと伝えられることは無い。標識は視界に入らなければ読むことができないし,音による合図は可聴範囲に入らなければ聴くことができない。このように,我々の知覚器官が持つ能力の限界と,物理空間を用いた情報の伝播に伴う物理的特性(例えば,音の波長を変化させることにより,壁や床や屋外の地形などを透過して伝えることが可能である)などが組み合わさると,それが「情報のフィルタ」として働くと言うことができる。ゆえに,複数の異なる情報発信源から情報を得るには,周囲の環境を歩き回る必要があるし,誰か互いに会話を交わすには,どこかに自らの位置を据えなければならない。

これらの制限は,物理空間における通信の持つ欠点であり,我々は情報技術を用いることによってこれを排除しようと試み続けてきた。電信装置はメッセージを長距離まで届けることを可能とし,電話は異なる場所にいる人々が会話を交わすことを可能とした。また最近では,コンピュータ産業によって導入されたグローバル・ネットワークの機構が,世界中の人々と瞬時に交信を行い,情報の共有を行うことを可能とした。ポケベルや携帯電話のようなモバイル・デバイスが導入され,人々が常にこれを身に付け持ち歩くようになると,「場所」という概念の持つ重要性は更に低下することとなるだろう。

しかしそれでも,「距離感」 (proximity) の概念は,ものごとの妥当性 (relevance) を論じる際の良い基準であり続けている。我々は重要な意味をもつものを自らの側に置くか,あるいは,それを用いるべき場所の側に置こうとするだろう。誰かの机の上にある文書や本の類は,キャビネットや本棚の中に収められているそれらよりも,現在の仕事により関連のあるものと捉えることができるだろう。オフィスにおいて偏在する施設の類(例えば,電源のコンセントや,水道の蛇口や,トイレなど)を考慮する際には,距離の概念が妥当な判断基準となるだろう。また我々は,誰かと話すチャンスを得るために周囲を歩き回ったりすることもある。

情報の配信における制約手段として「場所」 (location) の概念を用いることの有効性は,この概念が取り除かれたときに最もよく見えるようになったと思われる。今や我々は,いつどこに居ても,誰とでもコンタクトを取ることができ,あらゆる情報へ即座にアクセスすることができるようになった。しかし,そのとき我々は,「情報の氾濫」 (information overload) や「通信の氾濫」 (communication overload) を経験することとなった。これに対して,局所的な相互干渉(例えば直接の会話など)の持つ重要性や,局所的な可搬性(いわゆる「ローミング」と呼ばれる概念)を人や施設の検索手段として導入することが試みられてきたが,実行されたものは少ないと言わざるを得ない。

我々は,情報配信における制約手段として「距離感」を用いることの有効性に関して研究を行い,まず,人々の位置情報に関して認識を与える手段の開発から始めることにした。この論文ではその研究の内容について述べている。ここではまず関連する研究の紹介から行い,次に,局所的な相互干渉の利用に主眼を置いた3つのプロジェクトについて報告を行う。最後に我々の経験に関して検討を行い,それらの関連事項と今後の方針について要点を述べる。


Designing for Local Interactions (2)

2003-09-19

030919.jpg

"Designing for Local Interactions" の中で Redstrom 氏らは,氏らの行った3つのプロジェクトの内容について触れている。1つ目は "Hummingbirds" と呼ばれるデバイスの開発であり,2つ目はそれを改良した "Generalised Hummingbirds" の開発,そして3つ目は "The NewsPilot" と呼ばれるデバイスの開発だ。

"Hummingbirds" は周囲 100m への無線通信機能を備えたウェアラブル・デバイスであり,自機の周辺に存在する同デバイスの認識を行うことができるというものだ。無線版の "ICQ" のようなものだと考えればいいかもしれない。これを発展させたデバイス "Generalised Hummingbirds" は,端末として GameBoy を利用するようになっており,カートリッジを入れ替えることによって異なるアプリケーションを動かすことができるようになっている(無線デバイス自体は対戦用シリアルポートへと繋ぐようだ)。

"Generalised Hummingbirds" とオリジナルのデバイスとを比較した場合に見られる変更点は,端末として一般的なもの(ここでは GameBoy 本体)を用いるようにしたことと,デバイスを持つのが人とは限らない……つまり,各ノードの存在がより一般化されている,というところだ。

最も特徴的とも言える応用法は,このデバイスを「場所」や「物」と結び付けるというアイデアだ。例えば,デバイスを建物の廊下に偏在させ,付近の部屋の状態と結び付けてやれば,その部屋の中にどのような人物がおり,どのような活動が行われているかということを,デバイスを通じて検知することが可能になる。あるいは,デバイスをコーヒーメーカに取り付けてやれば,淹れたてのコーヒーが飲める状態というものを,デバイスを通じて検知することができるようになる。

この研究が示唆しているのは,特定の情報源に対してネットワークによる配信機能を与えるのに,オリジナルの Hummingbirds デバイスに備えられている以上の機構を用意する必要が無いという事実だ。Hummingbirds デバイスには,周辺に存在するデバイスの検知と,その状態を取得する機能しか備えられていない。それにも関わらず様々な応用形態をとり得ることが研究の結果によって示されている。

これは,情報配信のプロセスに対して「局所的な相互干渉」という概念を導入すると,それが自ずと情報の検索手段になるという事実を表している。コーヒーメーカの情報を取得するのに,わざわざ URL を入力したり,特定のリンクをクリックしたりする必要は無い。ただ,10m 向こうにあるコーヒーメーカに向かってデバイスを指し向けてやるだけでいい。誰も地球の裏側に存在するコーヒーメーカの状態を知りたいとは思わないだろうし,もし仮に知りたいと思ったならば,そのコーヒーメーカのレプリカを設置して,それに取り付けるデバイスを件のコーヒーメーカ(地球の裏側のそれ)とリンクさせてやるというのが良い方法だ。

特に,Hummingbirds から Generalised Hummingbirds への発展の過程において,通信距離の制限が 100m から 50m へと意図的に下げられているという点が面白い。通信距離を狭めるということが,情報配信の局所性を強化し,アプリケーションにより適したスペックになると考えられたためだ。


3つ目のプロジェクトである "NewsPilot" は,Viktoria Institute にて行われた別のプロジェクトである "MobiNews" に便乗して開発されたデバイスだ。地元のラジオ局である Swedish Radio Station へと実験的に導入されている。実際に導入が行われたのは,同ラジオ局においてニュース番組の編成を担当している部署であり,そこでニュース情報の管理を行うという目的で開発されたのが同デバイスであるということだ。

NewsPilot は,前述の2つのプロジェクトと比較すると,よりアプリケーションに特化されたデバイスだと言うことができる。端末としては 3Com の Palm III を利用しており,無線機を利用して周辺のデバイスと通信を行うことができるようになっている。

機能的なことに関しては,前のプロジェクトからさほど変化はしていない。その機能とは,周辺に存在するデバイスの名前と,そのデバイスに入力された「1行メッセージ」を表示するだけという,極めてシンプルなものだ。この「1行メッセージ」には,自分が今関わっている記事や仕事の内容を表す短いメッセージを入力しておく。すると,デバイスを覗くだけで周囲の人間がどのような記事を扱っているのか知ることができるようになる。当のラジオ局においては多彩なニュースを扱っているため,どの人がどの記事を扱っているかという情報を知り,その人との間で相互に情報を交換することが,ニュースの内容を充実させるにあたって重要な要素となるということだ。

NewsPilot における特徴的な応用法は,やはり,このデバイスを「場所」と結び付けるというアイデアだ。例えば,件のラジオ局のオフィスの中央には,最新の新聞を揃えた棚とテーブルが設置されている。このテーブルを訪れる人たちは,この新聞に代表されるような内外部の情報源を求めて来ていると考えることができる。そこで,このテーブルの隅に据え付け型のデバイスを設置し,外部のソースから得られた情報をここから配信するような機構を用意した。すると,この据え付けデバイスに対して自分のデバイスを近づけるだけで,外部のソースからの情報を得ることが可能になるということだ。

面白いことに,NewsPilot の通信範囲は前の2つと比較して更に狭くなっており,約 10m にまで下げられている。これは,この距離が件の現場における「局所性」として適切なものであると判断されたためだ。


Desining for Local Interaction (3)

2003-09-20

Redstrom 氏らが "Desining for Local Interaction" の中で指摘しているのは,これらの「局所的な相互通信」を行うデバイスが,人同士の直接のコミュニケーション (face-to-face communication) を補助する能力を持っているということだ。

論文の中では,たとえ話の1つとして,次のようなものが挙げられている……例えば,AさんがBさんが廊下で擦れ違ったときに,Aさんがある本を脇にかかえていたとする。その本とは,実はBさんも読んでいる本であるとする。すると,Bさんはその本が自分の読んでいる本であることに気付き,共通の本を読んでいるということで,何らかの会話が始められるかもしれない。それが非常に有益な情報の交換へと発展することも考えられるだろう。

このとき,会話が開始されるのに必要な条件とは,AさんとBさんが同じものに興味を持っていたということだけではなく,Aさんの興味の対象についてBさんが知ることができたという点にある。もしAさんが本を持ち歩いていなかったら,この会話は始められることが無かっただろう。

氏らの3つのプロジェクトの中にあった "NewsPilot" が実現していたこととは,まさにこの状況を作り出すことだ。ニュース編成セクションの人間が互いに現在の仕事を表明することによって,直接のコミュニケーションにおいて情報を交換する機会が与えられる。この非常にシンプルなデバイスが,「情報をうまく見つけ出す能力」 (serendipity) の強化に寄与しているということだ。


他にも氏らは,これらのデバイスの持つ局所性と「距離感」の概念が,情報配信における直感的なフィルタリングの機能として働き得ることを指摘している。また,NewsPilot の「新聞の棚」の例にもあったように,本来のデバイスが持つ以上に複雑な機構を,その単純なインタフェースの奥に隠すことが可能であると述べている。

論文の中で今後の方針として述べられているのは,「距離」の概念をより具体性のあるものへと発展させたいと考えていることだ。氏らは,一般に言う「距離」の概念は,「空間」や「場所」という要素に支配されていることが多いと指摘している。NewsPilot の例で言うならば,単に "10m" という物理空間上での距離で制限を行うよりも,「同じフロア」や「同じセクション」,「同じ部屋」などのように,空間的な単位によって区切られた方が,より自然な感覚を与えることができるはずだ。

しかし,「空間」の概念は,単なる物理的距離と比較して非常に複雑な要素を含んでいる。例えば「会議室」という空間を扱う際には,その会議室の扉が開いているか閉じているかによって,外の空間との関係が変化してくる。扉が開いているならば,それは廊下と連続した空間であると捉えることが可能であるし,また,扉が閉じているならば,廊下とは完全に断絶された空間であると見なさなければならない。

このように,より自然な空間の認識能力を与えるには,単に無線出力の物理特性からフィルタリングを行うだけでは不可能であり,もっと高等なインフラストラクチャを用意する必要があるだろうと述べている。


Desert Combat

2003-09-21

いい加減に Battlefield 1942 はやめようと思っていたのだけれど,先週は "Eve of Destruction" が出るは,今週は "Desert Combat" の v0.40 が出るはで,しょうがなく(?)プレイを続けている。

http://www.desertcombat.com/

今回のバージョンでは,兵器の追加・調整が行われているほか,新たに3つのマップが追加となっている。

3つの新マップは,どれもユニークな構成のものばかりで面白い。今までになかったミッション系のマップも追加されている。ミッション系のマップは基本的に防御側が有利な設定になっているので,攻撃側に乱れがあると膠着状態に陥ってしまうものの,うまくチームのバランスが取れていれば,緊迫したプレイを楽しむことができる。

3つ目の追加マップであるところの "DC Basrahs Edge" は,映画 "Black Hawk Down" を彷彿とさせる市街戦のマップだ。僕も "Black Hawk Down" を DVD で観たばかりなので,こういうシチュエーションはやたら興奮してしまう。ヘリが来たら RPG で落とすんだ! 数が少ないんでなかなか飛んでこないけどね……。

こういった市街戦マップでの立体的な大人数対戦は,Battlefield 1942 の醍醐味の1つとなっているように思える。Desert Combat のもう1つの市街戦マップ "DC Lost Village" も,僕が特に好んでいるマップの1つだ。

余談だけど,今回のバージョンアップで Stinger ミサイルの命中度が異様に上がっているため,Anti-Armor 装備でヘリを撃ち落とすのがかなり楽になった。あの憎たらしいブラックホークを携行装備で撃ち落すのは非常に爽快だ。"DC Lost Village" でも,にわかヘリキラーとして Stinger を背負って駆け回っている。


……とまあ,かなり楽しい感じなんだけど,またハマると時間を無駄にしてしまうので,そろそろ本当に断とうと考えている。また新たな mod が出たタイミングなどに,軽く遊ぶ程度に留めておこうと思う。


Killzone

2003-09-22

なんとなくいつもの調子で Gaming Age の掲示板を覗いていると,SCEE の最新タイトル "Killzone" のスクリーンショットが貼られていた。

http://www.gamespot.com/ps2/action/killzone/screenindex.html

どうやら最新のスクリーンショット集が公式サイトの方で公開されたということのようだ。Killzone のゲーム内容についてはひとまず置いておくとして,スクリーンショットを見ていて面白いのが,これらのスクリーンショットにモーションブラーが入っているというところだ。

http://www.gamespot.com/ps2/action/killzone/screens.html?pag...

これは恐らく「超高解像度スクリーンショット」と同じように,特殊なプロセスによって生成された広報素材用の画像なのだろうと思う。いくらなんでも,実機でここまでまともなモーションブラーを入れることはできないはずだ。

僕も,単に解像度を上げるだけではなく,モーションブラーのように時間軸方向へ拡張をかけることができたら面白いだろうなとは考えていたものの,実装の面倒さから手を出すことはできずにいた。いかにインチキとは言えども,まともなモーションブラーを実現するには,フレーム間の動きを細分割してやる必要があるからだ。


非ネットワーク対応の家庭用ゲームにおいては,ゲーム本体の処理と描画処理を同期させる方式が一般的なものとなっているように思われる。要するに,ゲーム上の単位時間を 1/60 秒の倍数に設定し(PAL の場合は 1/50 秒),画面の垂直同期信号と完全に同期させた状態で,ゲーム処理と描画処理を交互に行うわけだ。同期が間に合わなくなった場合(いわゆる「処理落ち」の状態)には描画処理をスキップさせる等の対処を施すことがあるものの,基本的に,ゲーム処理と描画処理が同期しているという原則が崩れることは無い。

しかし,PCゲームやネットワークゲームの分野においては,ゲーム処理と描画処理を非同期に進行させる方式を利用する場合が多いというような話をよく聞く。環境によって処理速度が一定しないことや,ネットワークゲームのように描画とは関わりの無い部分において進行を管理しなくてはならないシチュエーションが存在するため,そのような方式が用いられるのだろうと思う。

ゲームと描画を非同期に進行させるには,描画処理側の進行に一定の遅延を持たせてやるのが良い方法だろうと思う。そうすれば,ゲーム処理側の最新2コマ分から内挿を行い,滑らかな動きを実現することができるからだ。そうでもしないことには,内挿無しのガタついた動きになってしまうか,あるいは,外挿法のように安定の保証されない手段を用いなくてはならない。


上記のような「非同期描画+内挿アニメーション」の方式を実装すれば,"Killzone" にあるような即席モーションブラーを簡単に実現することができる。内挿を使って何度でもレンダリングしてやればいいというわけだ。きっと上の画像にあるような綺麗なモーションブラーを出すことができるだろうと思う。

この他にも,非同期描画の方式には色々と応用面でのメリットが存在するように思える。実装はそれほど難しくないはずなので,そろそろこの方式へ移行するべきなのかもしれないと感じつつも,従来の方式が持つ機構としての明快さに魅力を感じているため,本格的な移行にはなかなか踏み込めないでいる。

今のコードだと,描画処理がゲーム自体の処理と密に結合してしまっているから,非同期にすると色々と面倒な問題が発生しそうなんだよなあ……ううむ。


ちなみに,"Killzone" の制作を担当している "Guerrilla Games" は,オランダは Lost Boys 社の一部門であるようだ。

http://www.guerrilla-games.com/

http://www.lostboys.nl/

新鋭の集団であるだけに,なかなか全貌が見えてこない……早く動いている所を見てみたいものだと思う。


秋分の日

2003-09-23

今日は普通の休日。ええと,秋分の日だっけ。急に肌寒くなったものだから,服でも買いに出かけようかと思っていたのに,結局,夕方までだらだらと寝てしまった。最近は休日と言えばこんな過ごし方ばかりしている。だらしない……。

そういえば,中国には基本的に祝日の類が存在しないという話を聞いた。あるのは,新年の休みと旧正月,それからメーデーと建国記念日だけだ。

http://searchina.ne.jp/basic_guide/005.html

休日が少し減ったところでどうとも思わないけれど,祝日がほとんど無いというのも,ちょっと寂しい気がする。


最近,PC の調子が顕著に悪くなってきたので,いい加減に買い換えることにした。ドライブの類が異音をたてるんだよね……。

いつもなら,ここでパーツを集めて自作を始めるところなんだけれど,今回は特にこだわりとか目的とかが存在しないので,無難にメーカー製の PC をあたってみることにした。

条件は,それなりに小さな筐体であることと,それなりに高性能であることと,それなりのビデオカードを積んでいることだ。個々のパーツについては「それなりに」でも,全体としてバランスの取れた製品を探すのは難しいように思える。

NEC, 富士通,ソニー,Dell, 等々をあたってみたものの,どうにも適当なモノが見つからない。どれも選択の幅がいまいち狭いんだよね……。結局,Sotec の BTO カスタムマシンを選ぶことにした。

http://www.sotec.co.jp/direct/v7000/index.html

これならば,スリムタワー型のケースにファンレスの RADEON 9600 を積むことができる。あとは適当にパーツを選んで,と……しめて10万円程度に抑えることができた。コストパフォーマンスもいい感じだ。

これでやっとPCが新しくなる。取り急ぎの用事があるわけじゃないんだけれど,この中途半端にオンボロな PC ともお別れできるかと思うと,ちょっと気分がせいせいする。


Pin & Play

2003-09-24

最近は PLAY Studio の周辺からユビキタス・コンピューティング関連のネタを漁ってくることが多くなった。先日まで読んでいたのは,イギリスは Lancaster University とスウェーデンは Viktoria Institute の間で共同で行われているプロジェクト "Pin & Play" の関連資料だった。

http://ubicomp.lancs.ac.uk/pin&play/

この "Pin & Play" プロジェクトは,典型的なユビキタス・コンピューティングの応用例と呼べるものだ。建物を構成する壁の表面に電源とネットワーク回線を埋め込むことができれば,そこから壁面を媒体としたネットワークを構築することができる。そうすれば,対応機器を壁面に貼り付けるだけで,ネットワークを介した高度なオペレーションを行うことが可能になるのではないか……というものだ。

http://ubicomp.lancs.ac.uk/pin&play/pictures.htm

実装には,伝導体によって構成された薄い布状の素材が用いられている。これを絶縁体によって挟み込めば,面状の「回線」を構成することができる。こうして構成された回線は,通常のワイヤを用いた回線とは異なり,レイアウト面において非常に高い自由度を持っている。壁面のどこにでも機器を貼り付ければ,それだけでネットワークと接続することできるというわけだ。

http://ubicomp.lancs.ac.uk/pin&play/technology.htm

最も分かりやすい応用の例は,"Pin & Play" を用いた「壁スイッチ」の実装ではないかと思う。この「壁スイッチ」は,「壁面ネットワーク」へのアクセス機能と,それぞれのデバイスに固有な ID を保持している。この ID による識別を用いれば,それぞれのスイッチに対して特定の照明を割り当てることが可能になる。

すると,この「壁スイッチ」を,壁面のどこでも好きな所へ貼り付けるだけで,特定の照明を操作するスイッチとして機能させることが可能になる。複雑な配線やデバイスの設定などを考えてやる必要は何も無い。ただ自分の好きな所にスイッチを貼り付けてやるだけでいい……この画期的な利便性が,ユビキタス・コンピューティングによってもたらされる可能性の一例であるということだ。


"Pin & Play" プロジェクトでは,最初の実装例として「画鋲」のコンピュータ化に取り組んでいる。10円硬貨程度の大きさの,ちょっと大きめな「画鋲」の中に,Dallas 社のマイクロチップ DS1994 を組み込むことによって,壁面ネットワークへのアクセス機能を実現している。

この DS1994 というチップは,Dallas 社のマイクロチップ "iButton" シリーズの一製品だ。

http://www.maxim-ic.com/quick_view2.cfm/qv_pk/3794

この小さなチップの中には,小規模なメモリとリアルタイムクロック,それから "MicroLAN" と呼ばれる単線によるネットワーク通信機能が組み込まれている。1本の信号線とグランドさえ用意されれば,それだけでホストデバイスとの通信を行うことができるという優れものだ。しかも,その信号線は電源と兼用することができるというのだから,この "Pin & Play" のような用途にはまさにうってつけな仕様となっている。

http://pdfserv.maxim-ic.com/an/jp/AD0403J.pdf

こうしてできた Pin & Play 式の「画鋲」は,ホストデバイス側から個体の認識を行うことが可能となっている。また,個々の画鋲には LED が取り付けられており,ホスト側からの制御によってこれを点滅させることが可能だ。あとは,デザイナの創造力次第で様々な応用を作り出すことが可能だろうと思う。


この Pin & Play 式の「画鋲」は,MIT Media Lab の "Pushpin Computing" プロジェクトを参考にしているようだ。

http://web.media.mit.edu/~lifton/Pushpin/

ただ,この "Pushpin Computing" にはホストという存在が無く,個々の画鋲がノードとなって相互通信を行うという,どちらかといえば分散コンピューティングに近い性質を持っている研究だったようだ。また,この実装においては,壁面は単なる電源の供給源でしかない。

MIT の "Pushpin Computing" と "Pin & Play" を比較した場合に,最も顕著に異なる点と言えば,デバイス1個辺りの単価かもしれない。"Pushpin Computing" の方は,個々のデバイスが高機能なのでどうしても単価が上がってしまうのだけれど,"Pin & Play" の方は,前述のようにポピュラーなハードウェアを用いているために,1個あたりの単価は非常に安くあがっている。氏らが試作したプロトタイプでさえ,1個あたり $10 以下という安価を実現することができているそうだ。


OpenTrek

2003-09-25

030925.jpg

モバイル・コンピューティングやユビキタス・コンピューティングの分野に焦点を当ててみると,スウェーデンやフィンランドなどのような,北欧の IT 先進国の存在が際立って見えてくるように思える。Ericson, Nokia 等の有名企業が存在するほか,Bluetooth 規格の制定において中心的役割を果たすなど,我々にとって身近な部分においても大きな影響を及ぼしている。

そんな IT 立国であるところのスウェーデンにおいて,特に面白い研究を行っているのが,Interactive Institute 社の "PLAY Studio" と,Viktoria Institute 社の "Future Applications Lab" だ。

http://www.playresearch.com/

http://www.viktoria.se/fal/

"PLAY Studio" の活動内容については,今までさんざ覗いてきたので,ここでは置いておくとして……もう1つの "Future Applications Lab" の活動内容も,非常に興味をそそられるものばかりだ。

まず最初に興味を惹かれたのは,アドホック通信プラットフォーム "OpenTrek" の開発だった。

http://www.opentrek.com/

この "OpenTrek" は,Future Applications Lab に在籍する Johan Sanneblad 氏が,在学のインターン時代に研究の一環として開発を行ったもののようだ。

http://www.sanneblad.se/johan/

OpenTrek の概要については,上記の OpenTrek のウェブページのほか,論文 "OpenTrek: A platform for prototyping interactive ad hoc networking games on handheld devices" の中にまとめられている。

http://www.dcs.gla.ac.uk/~pd/Workshops/papers/sanneblad.pdf

まあ,技術的なことを言うならば,特に変わったことをやっているわけでもない。単に,アドホック通信用のお手軽なライブラリを開発した,ということのようだ。API の構造は DirectX (DirectPlay) を模しており,セッションの確立やロビーの作成などを簡単に行えるようになっている。

ちょっと地味な仕事だけれど,目の付け所は面白いと思う。


Sanneblad 氏は,このプラットフォームをプログラミングの教育用途に利用することを視野に入れていたらしく,実際にヨーテボリ大学の講義において,これを教材として利用したようだ。その顛末については前述の論文の中で述べられているほか,下記の論文 "Designing Collaborative Games on Handheld Computers" の中でも,その代表的な作品について解説が行われている。

http://www.viktoria.se/fal/publications/2003/siggraph2003-co...

生徒にはターゲットマシン (IPAQ H3630) と開発環境を与えた上で,約4週間で1つのゲームを制作するという課題を与えた。生徒達は基礎的な C++ のプログラミング能力を持っているほか,1週目にゲームプログラミングの基礎に関する講義を受けている。

そんな厳しい条件下においても,なかなか独創的な作品が生み出されているのが面白い,例えば,1個目の作品例である "PacMan Must Die" は,「モンスターを操作して,パックマンから逃げつつ,自分の色のドットを食い尽くす」という,一見平凡なゲーム内容なのだけれど,「画面端に設置されたゲートから他プレイヤの画面へと侵入することができる」というギミックが付け足されることによって,ユニークな遊びの要素を作り出すことに成功している。

自分の色のドットは他プレイヤの画面上にも配置されているため,どうしても「他プレイヤの画面に侵入する」という作業が要求される。このとき,侵入先のプレイヤの画面を覗き込みながらプレイを行うことになるのだけれど,これには細心の注意が必要とされる。侵入したモンスターを画面上に残したまま,そのプレイヤが IPAQ を持って逃げ出してしまうかもしれないからだ(上の写真を参照)。

もう1つの作品 "Earth Defenders" も,プレイヤー同士の直接のコミュニケーションをテーマとしたゲームだ。プレイヤは2つのチームに分かれ,4つの異なる機能を持つキャラクタを操作して対戦を行う。この4つのキャラクタの能力はそれぞれ大きく異なっており,それぞれが然るべき役割を果たしながら協力し合うことで,はじめて効果的に戦闘を行うことが可能となる。

そこで,仲間同士で互いの画面を覗き合ったり,口頭で指示を交わしたりしながら協調を実現するのだけれど,それと同時に,そのすぐ近くに居るはずの敵チームのことも考慮しながら行動しなければならない。ひそひそ話で指示を交わすだとか,嘘の情報を口で言ってみるだとか,敵チームの画面をこっそり覗き見てみるだとか……そういった,実世界の側での直接のコミュニケーションを,うまくゲームの要素として取り込んでしまおうというコンセプトを持っているわけだ。


これらの作品の内容については,Johan Larsson 氏の修士論文 "Collaborative Games - Makes People Talk" の方に詳しくまとめられている。

http://www.handels.gu.se/epc/archive/00002634/01/Nr_5_JL.JS....

この論文では,これらの作品群から得られたゲームデザイン上のコンセプトを,いくつかの「デザインパターン」として提示している。ちょっと長めの論文なので,まだ全部に目は通していないのだけれど,いずれちゃんと読んでみようかと思っている。


TGS

2003-09-26

今日は東京ゲームショーの日。幕張に直行して,各社ブースを適当に見学してまわった後,赤坂のオフィスへと帰社した。

ショー自体は,まあ,色々あったんだけれど……個人的に最も驚いたのは,任天堂の岩田氏の基調講演の中にあった,ポケモンの無線ネットワーク対応の話だった。

http://www.zdnet.co.jp/games/tgs/2003/news/0926/19.html

正直な感想を言うならば,ものすごく悔しい。もう既に回答を出す準備は整っていたというわけだ。お値段据え置きでこのデバイスをバラ撒こうって言うんだから,その本気の程が伝わってくるというものではないかと思う。

もしかしたら,この発表を聞いて,単にケーブルが無くなって接続が便利になっただけだと受け取った人もいるかもしれない。そういう人にとっては,この発表は驚きでも何でも無かっただろうと思うし,ましてや悔しさなどを感じられるものでも無いだろうと思う。

しかし,あと1年もすれば,この変化が意味していた本当のところを,皆が目の当たりにすることだろうと思う。その結果が成功なのか,あるいは失敗なのかは,今は誰にも分からない。それでも,制作者本人は成功を確信しているだろうし,僕もそれを確信することができる。確信できるからこそ,悔しい気分になるんだ……。


新マシン

2003-09-27

いつものように家で惰眠を貪っていると,騒々しい宅配便の配達員がやってきて(インターフォンを連打された),Sotec の新しいマシンを玄関口に置いて行った。たしか,このマシンを注文したのは23日だったから……発注から4日で届いたことになる。組み立ては国内でやっているのかな……ここまで速いとは予想していなかった。

http://www.sotec.co.jp/direct/v7000/index.html

さっそく動かしてみた。最も気にしていたのは動作音なのだけれど,これはまあまあ静かだ。Xbox 程度の動作音というと分かりやすいかもしれない……柔らかいノイズが常に出ている感じだ。

静音性で言えば,職場で使っている Dell の Dimension マシンが素晴らしいレベルを達成している。

http://arena.nikkeibp.co.jp/rev/pc/20030624/105099/

電源が入っているかどうか,音では判別できないほどの静かさだ。このレベルを知ってしまうと,このマシン (Sotec) でも,ちょっと不満に感じてしまうものがある。まあ,以前のマシンと比べれば,よっぽどマシだけれど……。


飯を食うついでに,近所の電器屋で LAN ケーブルとテーブルタップを買ってきた。一時的にマシンを増やすことを考えて,ルータタイプ(ハブ内蔵4ポート付き)の ADSL モデムを選んでおいたのだけれど,このおかげで LAN を構築するのにケーブルを買うだけで済ますことができた。

最近はなぜか,ハブとルータを内蔵したタイプの ADSL モデムという製品が少なくなってきているようだ。モデムはモデム,ルータはルータ,ハブはハブとして別売りするのが普通になっているようで……高速回線や無線 LAN など,多種多様なオプションが登場してきているためだろうか。とにかく,僕が ADSL を導入したときには,唯一存在した NTT の製品を選ぶしかない状態だった。

http://www.ntt-west.co.jp/kiki/consumer/flets/620m/index.htm...

どうせ,環境が変われば全部買い換えになってしまうんだから,なんでもかんでも一緒になっていた方が使いやすいと思うのだけれど……。


とりあえず新しいマシンでも Battlefield 1942 を動かしてみた。さすがにグラフィック設定を「高」にしても,余裕で動いてくれるようになった。しかし,いくらマシンがパワーアップしたところで,通信のラグまでは解消してくれないから,プレイアビリティにはほとんど変化が無いようだ。うーむ……。


日曜日

2003-09-28

何も無い日曜日。ちくちくと新マシンの環境を構築していた。

旧環境のデータを移植したり,ソフトをインストールしたり,細かい作業を延々とこなしていく。昔はこういう作業も楽しんでやってたものだけれど,今は面倒くさくてしょうがない。環境の移行は定期的に発生する作業だから,今はできるだけ身軽な装備になるよう心がけている。

USB 版の Happy Hacking Lite2 が日本語配列で認識されてしまって困っている。どうやら,Windows 2000 以降の OS では,PS/2 キーボードで利用されているレイアウトが,そのまま USB キーボードにも適用されるという仕様になっているようだ。

http://www2.117.ne.jp/~ryo-h/q_a/xp024.htm

僕のように最初から US 配列の USB キーボードを接続していると,デフォルト値であるところの日本語配列が適用されてしまうというわけ……うーむ。

PFU のページを覗いてみると,一応トラブルシューティングのようなものが載っていた。

http://www.pfu.co.jp/hhkeyboard/hhkb_support/index.html#USB

要するに,レジストリを直接に書き換えて,設定を上書きすれば直るということのようだ。無理やりくさいなあ。


面倒な作業をこなすかたわら,色々とソフトを動かして新環境の能力を試してみている。とりあえず Masa さんの rthdribl は 15 fps 程度で動くようになった。やはり RADEON 9600 pro ではその程度が限界のようだ。まあ,今まではまったく動かなかったわけだし,一応ミドルレンジには手が届いたというわけで……。


Non-Virtual Interface Idiom

2003-09-29

先日,とあるクラスの宣言を書いている最中に,「仮想関数は private に組み込むべきだ」と Herb Sutter 氏が指摘していたのを突然に思い出した。これは非常に印象的な一節だったのだけれど,何故かその理由を思い出すことができない。本棚(とは言っても,ただのボール紙の箱だ)から "Exceptional C++" と取り出して,該当する箇所を探してみるのだけれど,いつまで経っても問題の一節を見つけることができないでいる。あれ……おかしいな……。たしか,Herb Sutter がいつものように唱えているマントラの一つだったように記憶しているのだけれど……。


これではまったく埒があかないので,Herb Sutter 氏のページを直接に探してみることにした。その結果見つかったのが,次の C/C++ Users Journal の記事 "Virtuality" だ。

http://www.gotw.ca/publications/mill18.htm

この記事において Sutter 氏は,仮想関数のアクセス制御指定の決定方法について,いくつかの明快なルールを提示している。


まず,仮想関数の典型的な利用例として引き合いに出されているのが,いわゆる "Template Method" パターンの実装だ。

class AbstractClass
{
public:
    virtual bool PrimitiveOperation1(int n) = 0;
    virtual int PrimitiveOperation2(char* s) = 0;
};

Template Method パターンのコンセプトは,「クラス内の特定の挙動をカスタマイズ可能にするために,抽象基底クラスにおいて仮想関数インタフェースを定義し,その実装を派生クラスへと委譲する」というものだ。このコンセプト自体は,ごく日常的に利用されている仮想関数の応用方法の一つであり,それほど難しいことでもない。いわゆる「フック」のことだと言えば分かりやすいかもしれない。

http://home.earthlink.net/~huston2/dp/templateMethod.html

ここで Template Method パターン自体に問題は無い。問題となっているのは,上の例において仮想関数が public として外部に露出されていることだ。Sutter 氏は,このように仮想関数を直接に露出するのは避け,代わりに,非仮想関数による仲介関数を設け,それを露出すべきだとしている。そして氏は,このような設計手法を "Non-Virtual Interface Idiom" − 略して "NVI" と名付けて呼んでいる。

class AbstractClass
{
    virtual bool DoPrimitiveOperation1(int n) = 0;
    virtual int DoPrimitiveOperation2(char* s) = 0;

public:
    inline bool PrimitiveOperation1(int n)
    {
        return DoPrimitiveOperation1(n);
    }

    inline bool PrimitiveOperation2(char* s)
    {
        return DoPrimitiveOperation2(s);
    }
};

しかし,何故このような「遠回り」を行う必要があるのだろうか − その理由として最も大きなものは,元の設計において仮想関数が「2つの役割」を同時に担わされてしまっているという問題に関するものだ。

もともと Template Method パターンは,「特定の挙動の実装を派生クラスへ委譲する」というのが目的であったはずだ。しかし上の前者の例では,そのカスタマイズを行うための「フック」が public として外部に露出してしまっている……つまり,この仮想関数は,カスタマイズのための「フック」と,外部からの利用のための「インタフェース」と,2つの重要な役割を兼任してしまっているというわけだ。

氏の指摘によれば,このような設計は,いわゆる「粒度の荒い」状態であり,もっと詳しく役割の分離を行うべきだとしている。前者の設計は拡張性について不備を抱えているだけでなく,クラス内のポリシーを明確化できていないという欠点をも持つ。このような実装の不明瞭さは,ユーザのミスリーディングを招く原因となり,運用面での問題も抱えることとなってしまう。


設計面における薀蓄を色々とたれる以前に,仮想関数を NVI 化する分かりやすいメリットを1つ挙げることができる。仮想関数を呼ぶ際の「前処理」や「後処理」を簡単に入れることができるということだ。

inline bool AbstractClass::PrimitiveOperation2(char* s)
{
    assert(s);
    bool result = DoPrimitiveOperation2(s)
#ifdef DEBUG
    if (!result) cerr << "PrimitiveOperation2 failed" << endl;
#endif
    return result;
}

このようなチェック処理の類は「実装」ではなく「インタフェース」に含めるべきであり,そうしてすべてのサブクラスの実装に対してチェックを強制することができるようにしておくべきものだ。これだけでも「仮想関数を直接に露出すべきではない」という主張の十分な理由付けとして成り立たせることができるのではないかと思う。


Virtuality

2003-09-30

Herb Sutter 氏は件の記事において,もう1つの仮想関数のルールとして,仮想デストラクタの扱いについて述べている。

仮想デストラクタと言われてまず思い出すのは,「基底クラスのデストラクタは必ず virtual にすべきである」という有名なルールだ。例えば,"Effective C++" において Scott Meyers 氏は,その必要性を分かりやすく解説している。

基本的には Meyers 氏の提示するルールで十分に通用するのだけれど,これに対して Sutter 氏は,もう一歩踏み込んだ解説を行っている。

2つ目の古典的な問題は,デストラクタにまつわる,お定まりの問題だ − 「基底クラス
のデストラクタは virtual であるべきか?」

ふう……(ため息)。私は,このような質問は FAQ の中だけにとどめておいて欲しいもの
だと思っている。しかし何たることか,これは最も頻繁に交わされる議論のネタでもある。
もし,私がこの議論を目にするたびに1ペニーづつ貯金していったとしたら,今頃コーヒー
の1杯でも飲めていることだろう……それも,ただのコーヒーじゃなくて,正真正銘スター
バックスのベンティ・ダブル=バレンシア・ラッテを,だ(私の最近のお気に入りだ)。
もしかしたら,自前でもう10セント付け足せば,2杯目も飲めてしまうかもしれない。

この質問に対する普通の答えは,次のようなものだ − 「はあ?もちろん,基底クラスの
デストラクタは,常に virtual にするに決まってるじゃないか!」しかし,この答えは正
しくない。私はC++標準ライブラリの中からいくつもの反例を挙げることができる。こ
の答えは,ほとんどの場合において十分に通用するため,もしかしたら正解なんじゃない
かという幻想を抱かせてしまうわけだ。

これよりも頻度は少ないけれど,もうちょっとまともな答えとして挙げられるのが,次の
ようなものだ − 「はあ?もちろん,ポリモーフィックに delete する場合に限って
virtual にするに決まってるじゃないか!」この答えは,ある意味合っているんだけど,
まだ正解には程遠い。

そして,氏の提示するルールは次のようなものだ − 「基底クラスのデストラクタは,public かつ virtual であるか,あるいは,protected かつ非 virtual であるべきだ」

「public かつ virtual」については,Scott Meyers 氏の主張がそのまま当てはまる。問題となるのは,「継承は行うけどポリモルフィズムは考えない」というケースだ。このケースには,例えば STL にある関数オブジェクトの基底クラステンプレート(unary_function, binary_function 等)が該当する。

template <class _Arg, class _Result>
struct unary_function {
  typedef _Arg argument_type;
  typedef _Result result_type;
};

この基底クラスは,STL から参照される型情報を提供するために継承を行うものであり,ポリモルフィズムを意識したものではない。このようなクラスに関しては,デストラクタを protected として定義することにより,ポリモーフィックな delete を明示的に禁止すべきだと Sutter 氏は述べている(たとえ標準ライブラリがそうしていないとしても,だ)。

基底クラスのデストラクタを protected かつ非 virtual として定義するとどうなるか……この場合,デストラクタは非仮想関数なので,派生クラスのデストラクタが基底クラスのそれをオーバーライドすることになる。そうすると,派生クラスを生成・破棄する分には問題無いのだけれど,基底クラスの破棄はできない(コンパイル時エラーになる)という構図ができあがる。つまり,「ポリモーフィックに delete することを禁じる」ことができるわけだ。


"Effective C++" や "Exceptional C++" において提示されるルールの数々は,どれも簡潔な言葉の中にコンセプトが凝縮されており,明快で分かりやすいし覚えやすくもある。たとえその理由を失念してしまったとしても,何か心に引っかかるものがあれば,後で本を読み直すなりして復習することが可能であるはずだ。そのような分かりやすさとコンセプトの簡潔さが,これらの本の魅力なのだろうと思う。