Articles tagged with: プログラム

アクアビット航海記 vol.45〜航海記 その29


あらためまして、合同会社アクアビットの長井です。
弊社の起業までの航海記を書いていきます。以下の文は2018/5/13にアップした当時の文章が喪われたので、一部を修正しています。
今回は新たな会社でシステムを独学で習得しまくる話です。この時の経験が私を起業に導いてくれました。

オフィス移転で恥をかく


新しい会社の日々は、とても刺激的でした。

まず、私が入社してすぐに社屋の引っ越しがありました。新しい五階建てのビル。すべてが空っぽです。なにもありません。ネットワークどころか電源の場所も考慮されていません。全ては私に任されており、完全に白紙でした。そこでまずレイアウトを検討し、電源やネットワークの位置を設計しました。入社して早々、各部署の方と話を進めながら。

ファシリティ設計もネットワーク設計や電源設計も、当時の私にとって全てが初めての体験てした。やったことがなくてもやらねばなりません。やるのです。結果が良ければ全てがよし。ぶっつけ本番。あたって砕けろ。すると、なんとかなってしまうのではないか。

もちろん、何もなく終わるはずはありません。いくらVisioで図面を書いてみたところで、いざ本番となれば想定外の出来事が起こります。そもそも設計はあくまで机上の計画に過ぎません。物が実際に設置された時、計画とずれるのは当然のことなのです。そもそも私自身がオフィスのレイアウトやネットワーク設定など全くやったことがなく、計画はずさんだったはず。案の定、引っ越し当日は右往左往しました。

例えばモールです。モールってご存じですか?LANケーブルを保護し、しまい込むための塩ビ製の細長いカバーです。
モールは上と下に分離し、カチッとはめ込む構造になっています。ベロンと上下を分け、そこにLanケーブルをしまい込み、最後にパチリと上下をはめ込みます。ところが私はそんなこともすら知りません。
上下に閉じたままのモールのすき間に無理やりLanケーブルを押し込もうとしました。不可能を可能にする男、長井の面目躍如といいたいのですが、そもそも入るわけがありません。この時、来てもらっていた工事業者さんのあ然とした顔は今も思い出せます。
本連載の第十六回で、IMEを切り替える方法を知らなかった私が、半角カタカナでデータを打ち込み「ニイタカヤマノボレじゃないんだから!」と怒られた芦屋市役所でのエピソードは書きました。この時のモールの一件は、その時に負けず劣らず恥ずかしいエピソードです。土壇場で電源の場所が変更になり、それをお願いしたい時の電気業者さんが見せた絶望と諦めの顔も思い出せます。

自分に恥をかきまくって成長する


結局、私の二十代とはそういう恥ずかしい記憶の集まりです。でも今から思うと、恥をかいては捨ててきた積み重ねが私の成長につながっています。全ては血となり肉となりました。
もちろん、成長のやりかたは人によってそれぞれです。一つ一つの作業を丁寧にOJTで教わりながら恥をかかずに成長していく人もいるでしょう。ただし、それはあらかじめ決められたカリキュラムに沿っています。カリキュラムとは、習得の到達度を考慮して設計します。ということはカリキュラムに乗っかっているだけでは、成長の上限もあらかじめ決められています。

私の場合、乗っかっているカリキュラムからはみ出し、一人で突っ走ってばかりでした。そして失敗を繰り返していました。でも、それもよいのではないでしょうか。カリキュラムからはみ出た時、人は急激に成長できるような気がします。少なくとも、この頃の私はそうでした。
私の人生で何が誇れるかって、ほとんどの技術を独学で学び、恥をかきまくってきたことだと思っています。

私にとってこちらの会社で学んだ事はとても大きな財産となりました。情報技術のかなりを独学で習得しました。そして自分に対して恥をかき続けました。
私がかいた恥のほとんどは自分に対しての恥でした。というのも、この会社に私より情報技術スキルを持つ方はいなかったからです。つまり、自分自身がかいた恥は誰にも気づかれず、誰からも指摘されず、ほとんどが私の中で修正され、処理されていきました。その都度、自分の乏しい知識をなげきながら。

でも、そうやって自分の未熟さに毎日赤面しながら、私は会社の情報処理、ファシリティや機器管理やパソコン管理、ネットワーク管理の知識を着々と蓄えていきました。
自らが知らないことを学び、自分の無知に恥をかき続ける。今でもそうです。自分が知っていて安心できる知識の中でのみ仕事をすれば失敗はないでしょう。そのかわり成長は鈍いはずです。失敗の数もまた人生の妙味だと思います。

恥をかきすぎたら成長できた


入社した当初は、私を試そうと圧力をかける方がいました。が、徐々に難癖を付ける方は何も言わなくなりました。やがて私は自分の思うがままに環境を作れる立場になっていました。
もちろん職権の乱用はしません。自分の判断でこの機能が必要と判断し、稟議書を書き、上長に上げます。そのうちの九割方は決裁してもらえたように思います。会社には何社もシステムベンダーの方に来ていただきました。臆せずに自分で展示会にも出かけていき、知見を広げました。

時期は忘れてしまいましたが、自分でサーバーを構築したのもこの時期です。DELLのサーバーを購入してもらい、そこにRed Hat Linuxをインストールしました。さらに自分でSamba(オープンソースのファイルサーバー)を入れました。全ては白紙からの挑戦でした。

そのサーバーには後日、Apache(ウェブサーバー)やMySql(データベース)やPHP(プログラム言語)も自力でインストールしました。そうして自分なりの社内イントラネットを構築していきました。

私が入社した当初、その会社の販売管理はオービック社の商蔵奉行が担っていました。受発注や伝票発行の全てをそれでまかなっていました。そもそも私がこの会社に呼ばれたのも、システムのオペレーションミスによる誤請求があったためです。そこでFAXをOCR変換して取り込む仕組みも作りました。EDIも何パターンか導入しました。夜間バッチでデータを自動で取得し、受注データへ変換する仕組みも構築しました。
その過程で私は社内の受発注の仕組みから勉強し、システムが備えている販売管理に関する機能の理解も深めました。販売管理を行う際は、在庫管理も欠かせません。その二つは表裏一体です。この会社は自社の倉庫も持っていました。となると在庫管理から物流の知識に至るまでの知識も修めなければ。

それらの新たな知識の習得と並行して、社内の全パソコンは私が管理していました。入社までの半年、土曜日に訪問して全パソコンのメンテナンスを行っていたことは書きました。新社屋に移る際、ネットワークや電源の構成やレイアウトも把握しました。そうした日々の中、パソコンのメンテナンス・スキルも身に付き、ネットワーク構築やサーバー設計にも経験を重ねていきます。遅いノートパソコンのメモリ増設ぐらいなら行えるぐらいまでに。

この時期の私がどれだけ充実していたか。今の私からはまぶしく思えるほどです。好きなだけ学び、存分に成長していました。しかもそれが会社の効率の改善につながっていました。とてもやりがいに溢れた時期でした。そして幸せでした。
学べること。成長できること。その成長を自分で実感でき、さらに人に対して目に見える形で貢献できること。

少し前の私は、こうした一連の仕組みを全くしりませんでした。結婚した翌年あたりに友人たちが私の家に来て、自作パソコンを組み立ててくれたことがあります。この時に来てくれたのは、大学の政治学研究部の後輩とスカパー・カスタマーセンターのオペレーターさんと義弟でした。珍しい組み合わせ。そして皆が私より年下。
それなのに、私は彼らがやってくれている作業のほとんどが理解できませんでした。
そんな私が今や、新たな会社で情報統括を行う立場となりました。少し前まではニイタカヤマノボレと怒られていた私が。モールの構造を知らずに無理やり押し込もうとした私が。

これが人生の面白さだと思います。

ただし、私の人生には大きな試練がまだ続きます。
その試練とは家の処分。本連載の第三十七回第三十八回三十九回にも書いた家の処分です。
私が転職した大きな理由の一つは、そもそもこの家を処分するためでした。
次回は家の処分を二回にわたって書いてみます。ゆるく長くお願いします。


人工知能はどのようにして「名人」を超えたのか?


本書は新刊で購入した。タイトルに惹かれたためだ。

人工知能が人類にどのような影響を及ぼし、人類をどのように変えていくのか。それは私が興味を持つ数多くのテーマの一つだ。

1997年に当時のチェス世界チャンピオンをIBMのディープ・ブルーが破った快挙は、人工知能の歴史に新たな扉を開いた。もう一つ、人工知能の歴史における偉業として挙げられるのは、2011年にアメリカの有名なクイズ番組「ジェパディ!」でこれもIBMが作ったワトソンが人間のクイズ王を破ったことだ。

これらの出来事は人類の優位を揺るがした。それでもなお、チェスよりもはるかに複雑で指し手の可能性が膨大にある囲碁や将棋において、人間が人工知能に後れをとることは当分こないとの予想が大勢を占めていた。それは、ゲーム中に現れる局面の指し手の数を比較すれば分かる。チェスが10の120乗だとすれば、将棋は10の226乗。囲碁は10の360乗にもなるからだ。
だが、2015年にGoogleのAlphaGoが世界のトップ棋士を破ったことは人間の鼻をへし折った。2017年には棋界においても人工知能「ponanza」が、人類のトップクラスの棋士を一敗地に塗れさせた。

本書は人工知能「ponanza」の開発者が、その開発手法や機械学習について語った本だ。

そもそも、人工知能はどのように将棋の指し手を覚えるのだろう。そして開発者はどのように将棋を人工知能に教え込むのだろう。
本書は、私が人工知能や機械学習に対して持っていたいくつかの誤解を正してくれた。それと同時にAlphaGoと「ponanza」の手法の違いにも気づきを与えてくれる。

本書の第1章「将棋の機械学習━プログラマからの卒業」では、まずコンピューターの歴史や、機械学習についての試行錯誤が語られる。ここで重要なのは、人工知能が人間の思考を模倣することを諦めたということだ。人間の思考を諦めたとは、どういうことだろう。
人間の思考とは、自分の脳内の動きを思い返すに、何かを判断する際にそれを過去の事例と照らし合わせ、ふさわしいと判断された結果だ。
だが、その評価基準や過去の事例の探索は、プログラムで模倣することが難しい。私も、自分自身の心の動きをトレースするとそう思う。

まず、プログラムによる判断からの卒業。それが将棋の人工知能の発展におけるブレイクスルーとなった。これは他の機械学習の考えにも通ずるところだ。むしろ本質ともいえる。

「ponanza」のプログラムには過去の棋譜や局面の情報は一切含めておらず、将棋のルールや探索の方法だけが書かれているという。局面ごとの評価そのものについては全て「ponanza」に任せているそうだ。
この構成は機械学習に通じている方にとっては当たり前のことだろう。だが、プログラムで一切の評価を行わない原則は誤解しやすい部分なので、特に踏まえておかねばならない。

局面ごとにそれぞれの指し手について、勝率が高い方を内部で評価する。その判断基準となるデータは内部で膨大に学習し蓄積されている。
人間の判断でも同じことを行っているはずだが、数値に変換して高い方を採用することまでは行っていない。
つまり統計と確率だ。その手法を採用したことに対する感情や情緒は「ponanza」は考えない。あくまでも数値を重んじる。

ところが「ponanza」は当初、機械学習を使っていなかったという。代わりにロジスティック回帰の手法を採用していたようだ。
つまり統計から確率を演算して予想する手法だ。「ponanza」が機械学習を採用したのは、まさに本書の執筆中だったと言う。

第2章「黒魔術とディープラーニング━科学からの卒業」では、機械学習について書かれる。
機械学習にもいくつかの問題があるという。例えば、単純な丸暗記ではうまく知能が広がらず、判断も間違うのだとか。そこで、わざといくつかの探索を強制的にやめさせるという。このドロップアウトと呼ばれる手法によって人工知能に負荷を与えたことによって、かえって人工知能の学習は進んだという。
重要なのはこの時、なぜそのような効果が生まれるのか科学者でも把握できていないことだ。他にも、技術者がなぜそうなるのか分かっていない事象があるという。たとえば、機械学習において複数の層を学習させると、なぜそれがうまく学習されるのか。また、ある問題を解くにあたって、複数のCPUで計算させる場合でも闇雲にCPUを増やすだけでは正解率は上がらない理由も分かっていないそうだ。むしろ、一つの課題を複数のCPUで同時に解くように指示した方が早く正確な解を導き出せるそうだ。だが、その理由についてもまだ解明できていないと言う。
著者はそれを黒魔術と言う言葉で表している。

細部の構造を理解すればそれが全体においても理解できる。つまり科学の還元主義だ。機械学習の個別の動きについては科学者でも理解できている。だが、全体ではなぜそのような結果が導かれるのかが理解できない。つまり、すでに人工知能は還元主義を超越してしまっている。

なぜ人工知能がシンギュラリティーに達すると、人の理解が及ばない知能を獲得してしまうのか。生みの親であるはずの技術者がなぜ人工知能を制御できないのか。黒魔術の例えは、誰もが抱くはずの根本の疑問を私たちにわかりやすく教えてくれる。
人工知能の脅威論も、技術者が理解できない技術が横行していることへの危機感から生まれているに違いない。

第3章「囲碁と強化学習━天才からの卒業」では、人類によって磨き上げられた知能が人工知能によってさらに強くなる正のフィードバックが紹介される。
囲碁の人工知能であるAlphaGoが驚異的な能力を獲得した裏には、画像のパターン認識があった。囲碁の局面ごとの画像を膨大に学習し、それぞれごとに勝率の良い方を判断する術。
画像認識の際に有用だったのがモンテカルロ法だ。これは、統計学の書物を読むとしばしばお目にかかる概念だ。たとえば円の面積を求めたい場合、いわゆる円周率πを使うのではなく、ランダムに打ち込んだ点が円の外にあるものと内にあるものを数える。するとその割合の数が増えれば、πに限りなく近くなる。

座標の位置によってその統計と確率を判断する。
それは囲碁のように白と黒の碁石が盤面で生き物のように変化するゲームを把握するときに有用だ。それぞれの点を座標として記憶し、その勝率を都度計算する。
AlphaGoはモンテカルロ法による勝率予想と機械学習の併用で作られている。画像処理の処理はまさに人工知能の得意分野だ。それによってAlphaGoの性能は飛躍的に上がった。

10の360乗と言う膨大な局面の最善手を人工知能が判断するのは困難とされていた。だが、AlphaGoはそれを成し遂げてしまった。
人間の知能を超越し、神として見なされるふさわしい圧倒的な知能。それは信仰の対象にすらなった。すでに人間の天才を超えてしまったのだ。

第4章「倫理観と人工知能━人間からの卒業」では、知能と知性について深い考察が繰り広げられる。

著者は、人工知能が人類を凌駕するシンギュラリティは起こると考えている。シンギュラリティを語る際によく言われる懸念がある。それは、人工知能が人類によって制御が不能になった際、人工知能の内部の論理が人間に理解できないことだ。人間は人工知能の判断の根拠を理解できないまま、支配され、絶滅させられるのではないかという恐れ。

著者は、その懸念について楽観的に考えている。
その根拠は、人類が教え込み、人類の知恵をもとに学習した人工知能である以上、人類の良い面を引き継いでくれるはずという希望に基づいている。
つまり人間が良い種族であり、良い人であり続ければ、人工知能が私たちに危害を加えない保証になるのではないかということだ。人が親、人工知能が子供だとすれば、尊敬と愛情を感じる親に対して、子は敬意を持って処遇してくれるはず。その希望を著者は語っている。

巻末ではAlphaGoの偉業について語る著者と加藤氏、さらに囲碁棋士の大橋氏との3者対談が収められている。

対談の中では、AlphaGoと対戦したイ・セドル氏との対戦の棋譜が載せられている。複雑な局面の中でなぜAlphaGoがその手を選んだのか。その手は勝敗にどのような影響を与えたのか。
それが解説されている。

早い時では第七手でAlphaGoが打った一手が、ずいぶん後の局面に決定的な影響を与える。まさに人工知能の脅威と、人類が想像もつかない境地に達したことの表れでもある。
私はあまり囲碁が得意ではない。だが、人間が狭い視野で見られていない部分を人工知能がカバーするこの事象は、人工知能が私たちに与える影響を考える上で重要だと思った。
おそらく今後と、人工知能がなぜそのようなことをするのか私たちには理解できない事例が増えているはずだ。

面白いことに、著者は対談の中でこのように語っている。
「コンピューターは、論理的に動くけれど、本当の意味での論理力は足りていないんです」(263ページ)。
つまり、人工知能とはあくまでも過去の確率から判断しているだけであって、もし人間が既存の棋譜や学習内容に含まれていない手を打ってきた時、人工知能はそれを論理的に捉えられず混乱するのだ。

もう一つ本書を読んで気づくのは、人類自身が囲碁や将棋の奥深さを人工知能に教えられることだ。人類が思いも寄らない可能性を人工知能によって教えられる。
それは、これからの人工知能と人間の共存にとって希望だと思う。人工知能から人間も学び、新たなヒントを得ていく。

これは著者のシンギュラリティへの態度と並んで楽観的な意見だと指摘されるはずだ。
だが、今さら人工知能をなかったことにはできない。私たちは何があろうとも人工知能と共存していかなければならないのだ。
本書は人工知能の本質を理解する上でとても優れた本だと思う。

‘2020/08/18-2020/08/18


不思議な数列フィボナッチの秘密


かつての私は、数列が苦手だった。
中学生の頃は、一年生の頃こそ数学のテストは全て百点を取っていたが、二次関数が登場する二年生以降は惨敗の連続だった。百点満点中、10点台や20点台を連発していたことを覚えている。

こうした数式を覚えて、いったい世の中の何の役に立つのか。当時の私にはそれが全くわからなかった。当時の教師もそうした疑問には全く応えてくれなかった。もっとも、こちらからそのような問いを発することもなかったのだが。
そんな気持ちのまま、二次関数や座標や配列、そして数式を一方的に教えられても全く興味が持てずにいた。それが当時の私だった。

ところがここ二十年、私はシステムの開発者として生計を立てている。
かつての私が全く人生に役に立たない、と切り捨てていた数学を普段から業務で用いている。
もし昔の私に会えるのなら、勉強を怠っていた自分に数学が役に立つことを教えたいくらいだ。実例を交えながら。

例えばExcelのVBAを使い、セルの値を得たい場合を考えてみる。
D列からデータが始まるセル範囲で、求めたいデータが三列おきに現れるとする。それをどうやってマクロで取り込むか。
そうした際に数列の考え方を使っているのだ。
具体的にはこのようにマクロを組む。
・繰り返しで一定の条件に達するまで処理を行う。
・繰り返しの処理の中で変数の値に1を加える。
・上記の変数に3をかける。
・その掛けた結果に4を加える。
すると、繰り返し処理の中で得られる変数の値は、一つ目は4、次は7、以降は10、13、16、19と続く。これらの列番号をExcelの列番号、つまりアルファベットに当てはめるとD、G、J、M、P、Sとなる。

そのように、一定の規則でつながるセルの位置や値を見極め、それを処理として実装する処理は事務作業で頻繁に発生する。そうした作業はExcelのデータを参照し、編集を行う際に必須だからだ。日常的に必要になってくるといえよう。Excelだけでなく、他のプログラムでもプログラム時に数列の考え方は必須だ。
私は当初、業務に必要になっていたからそうしたプログラムを覚えていた。そしてプログラムを日常の業務で当たり前に使うようになってきたある日、その営みこそ、私がかつて苦手としていた数列や配列そのものということに気づいた。

そもそも私はなぜ数学が苦手になってしまったのだろう。よくわからない。子供の頃は、数字の不思議な性質に興味を持っていた時期もあったはずなのに。
例えば切符に書かれた数字。最近では電車に乗る際に切符を買う機会がなくなってしまったが、かつては切符を買うとその横に四桁の数字が印字されていた。その四桁の数字のそれぞれを、四則演算を使って10にするという遊びは欠かさず行っていた。
その遊び、実は数論の初歩として扱われるそうだ。

そうした数字の不思議な性質は、子供心に不思議に思っていた。
今も、ネットで〇〇数を検索してみると、不思議な数の事例が書かれた記事は無数に出てくる。〇〇には例えば完全、素、三角、四角、友誼、示性、黄金などが当てはまる。

本書は、不思議な数の中でもフィボナッチ数に焦点を当てている。フィボナッチ数とは、並んだ数値の二つの和を次の項目の値としたものだ。0,1,1,2,3,5,8,13,21,34,55,89,144のように。数字が徐々に大きくなっていくのが分かる。しかもそれぞれの数字には一見すると規則性が感じられない。

ところがこの数字の並びを図形にしてみるとさまざまな興味深い動きを描く。例えばカタツムリの殻。螺旋が中から外に広がるにつれ徐々に大きくなる。この大きくなる倍率はすべてフィボナッチ数列に従っている。またあらゆる植物の葉のつき方を真上から見ると、それぞれが日の当たるように絶妙に配置されている。これらも全てフィボナッチ数列の並びに近い。
ほかにもひまわりの種やDNAの螺旋構造など、自然界でフィボナッチ数列が現れる事例は多いという。自然は効率的な生態系を作るにあたってフィボナッチ数を利用しているのだ。

最近では昆虫や植物の機能や動きを研究する動きがある。バイオミメティクスと呼ぶこれらの研究から、科学上の発見や、新たな素材の開発や商品の機能が生まれることがあるという。
フィボナッチ数列を学ぶことで、私たちの非効率的な営みが、より効率的に変わるかもしれないのだ。

本書にはフィボナッチ数にまつわる不思議な性質や計算結果が豊富に紹介される。
正直に言うと、それらの計算結果を実生活や科学の何かに役立てられる自信は私にはない。だが、そうした法則を見つけてきたことで、人類はこれまで科学を発展させてきた。

おそらくフィボナッチ数に隠された可能性はまだあるのだろう。フィボナッチ数は、未来の人類が技術的なブレークスルーを達成する際に貢献してくれると期待している。
例えば、私が思いついたのは暗号だ。暗号化にフィボナッチ数を役立てられるように思える。
暗号の一般的な原理は、ある数とある数を掛けて出来た数値からは何と何を掛けた結果なのかが推測しにくい性質に基づいている。例えば桁数が約300桁ある二つの素数のそれぞれを掛けた数があったとしても、それが掛けられた二つの素数を見つけ出すのに、最新鋭のスパコンでも何億年もかかり、量子コンピューターでも非現実的な時間を要するという。

この暗号を作る際、フィボナッチ数列を使って作るのはどうだろう。フィボナッチ数列も数が膨大だが、それらは全て数式で表せる。
これを何かの解読キーとして用い、何番目のキーを使わなければ復号できないとすれば、暗号として利用できるように思う。もちろん、私が思いつくような事など、数学者がとっくの昔に思いついているだろうけど。
だが、暗号以外にも情報処理の分野でフィボナッチ数が活用できるかもしれないと考えてみた。
私のような素人でも暗号への使い道がすぐに思いつけたほどだから、優秀な数学者が集まればフィボナッチ数列のより有用な使い道を考えてくれるはずだ。

かつての私のような数学が苦手な人にこそ、本書は読んでもらいたい。

‘2020/07/12-2020/07/18


Cybozu OfficeのスケジュールをCalendar Plusで(だいぶ)再現!


カレンダーPlus Advent Calendar 2020の5日目の記事です。

  Topへ↓

先日のCybozu Days 2020 Osakaの後、Calendar PlusのAdvent Calendarに空きがあると聞き、やってみましょうか?と言ってしまいまして。
言った以上はエントリーせねば。というわけで翌日、神戸で商談する前に中華街で飯を食べながら記事にエントリー宣言。

さて、エントリーしたのはいいが、何を書けばええんやろ?しかもエントリーしたタイミングは前日やし(^^;)。これはひょっとして勇み足をやらかしてしまったのではなかろうか。

迷いを振り切った私が商談に臨むと、なんとお客様がCybozu Officeのスケジュールを愛用しており、それをkintoneに載せ替えたいとのこと。しかもkintone標準の標準のカレンダー機能は表現に乏しく、Calendar Plusを検討してみたけど、プラグイン設定の色設定の種類が少なくてなぁ。と悩みを吐露されまして。商談からネタが転がってきた瞬間です。
これはCybozu Officeのスケジュールアプリの画面です。

私は今までも何回かCalendar Plusは提案してきました。けれど、本格的なユーザーではないし、弊社のkintone納入実績からするとCalendar Plusの納品実績は一割もありません。熟練のユーザーではないのです。

が、Calendar Plus JavaScript APIを使ったカスタマイズの経験はあります。API使えば、ある程度ならCybozu Officeの体裁にCalendar Plusを合わせられるんちゃうの?という見切り発車でした。

Calendar Plusのプラグイン設定画面

  Topへ↑

うーむ、確かにCalendar Plusの色設定は12種類か。

そして、お客様のCybozu Officeのスケジュールの色設定で設けた種別は25種類。つまり倍。

確かにお客様がkintoneへの移行をためらわれるのもわかるなあ。

アプリを作る

  Topへ↑

じゃあ、ちょっと試しにアプリを作ってみよう。こんな感じで。

あらよっと、Cybozu Officeと同じようにレコードを登録してみました。さて、Calendar Plusで見るとどうなる・・・?

あかん・・・Calendar Plus側の色設定をしていないのですべて同じ緑地になってる。
しかも予定の状況がカレンダー上に表示されておらず、直行なのか直帰なのかが一目で区別できない。
やはり見にくいなあ・・・・これは、Calendar Plus JavaScript APIの出番かな。

コーダーモード発動

  Topへ↑

ということで、ガリガリとコーディングすること2時間。うん、こんな感じになりました。


というわけで最低限、記事にできるところまでこぎつけたのでいったん寝ます。アップ当日になってしまいましたが、AM2時前なのにもう眠い。年や。

プログラム開示

  Topへ↑
さて、アップ当日の朝、旅に出かける前に少しだけ記事を書きまして。
ここにコードを開示しておきます。すみません。洗練されたコードとは程遠くて・・・・。

(function () {
  "use strict"

  // 関数本体
  const calenderformat = function (event) {
    // Calendar Plusのイベントリスナー定義
    const calendareventslist = ["cp.event.show"];
    // kintoneのイベントの書き方と似ててわかりみ
    calendarplus.events.on(calendareventslist, function (calendarevent) {
      // kintoneのイベントのjson(上記イベントで対象データループしてくれます)
      const record = calendarevent.record;
      // kintoneのイベントの要素
      const element = calendarevent.element;
      // テーブルだけkintoneのイベントの要素
      const tdelement = document.getElementsByClassName("fc-event-container");
      // Cybozu Officeの時刻表示に合わせるため(ださいかも)
      const starttime =
        ("00" + new Date(record.開始時刻.value).getHours()).slice(-2) +
        ":" +
        ("00" + new Date(record.開始時刻.value).getMinutes()).slice(-2);
      const endtime =
        ("00" + new Date(record.終了時刻.value).getHours()).slice(-2) +
        ":" +
        ("00" + new Date(record.終了時刻.value).getMinutes()).slice(-2);
      // 左端の行高がCalendar Plusでは縮まるため、Cybozu Officeの行高っぽくする
      tdelement[0].style.minHeight = "90px";
      tdelement[1].style.minHeight = "90px";
      tdelement[2].style.minHeight = "90px";
      tdelement[3].style.minHeight = "90px";
      tdelement[4].style.minHeight = "90px";
      // リンクするためのurl
      const baseurl =
        kintone.api.url("/k/").replace(".json", "") +
        kintone.app.getId() +
        "/show#record=" +
        record.$id.value;
      // 予定の状況にあわせてSwitch(ださい)
      switch (record.予定の状況.value) {
        case "ーーー":
          // 枠の背景色
          element[0].style.backgroundColor = "#FFFFFF";
          // 文字色(本当はhoverとかの定義も必要。そもそもcssにまとめたほうがよい)
          element[0].style.color = "#006bac";
          // 折り返してくれなかったので折り返し(そもそもcssにまとめたほうがよい)
          element[0].style.whiteSpace = "break-spaces";

          // 終日フラグかどうか
          if (record.終日.value.length > 0) {
            // 頭に・をつける
            element[0].innerText = "・" + element[0].innerText;
          } else {
            // 頭に時刻をつけて改行
            element[0].innerHTML =
              starttime +
              "-" +
              endtime +
              "
 " +
              '<a href="' +
              baseurl +
              '">' +
              record.予定.value +
              "</a>";
          }
          break;
        case "直行":
          // 枠の背景色
          element[0].style.backgroundColor = "#ebf7ef";
          // 枠の線色
          element[0].style.borderColor = "#d8f2e0";
          // 文字色(本当はhoverとかの定義も必要。そもそもcssにまとめたほうがよい)
          element[0].style.color = "#006bac";
          // 折り返してくれなかったので折り返し(そもそもcssにまとめたほうがよい)
          element[0].style.whiteSpace = "break-spaces";
          // 終日フラグかどうか
          if (record.終日.value.length > 0) {
            // 頭に・をつけ、予定の状況を枠で囲む
            element[0].innerHTML =
              "・<span style="background-color:#32a759;color:#fff;" class="scheduleMarkEventMenu">" +
              record.予定の状況.value +
              "</span>" +
              record.予定.value;
          } else {
            // 頭に時刻をつけ、予定の状況を枠で囲む(以下コメントは省略)
            element[0].innerHTML =
              starttime +
              "-" +
              endtime +
              "
 " +
              '<a href="' +
              baseurl +
              '">' +
              '<span style="background-color:#32a759;color:#fff;" class="scheduleMarkEventMenu">' +
              record.予定の状況.value +
              "</span>" +
              record.予定.value +
              "</a>";
          }
          break;
        case "直帰":
        case "直行/直帰":
          element[0].style.backgroundColor = "#e8f2fc";
          element[0].style.borderColor = "#dae8f7";
          element[0].style.color = "#006bac";
          element[0].style.whiteSpace = "break-spaces";
          element[0].innerHTML =
            "・<span style="background-color:#3182dc;color:#fff;" class="scheduleMarkEventMenu">" +
            record.予定の状況.value +
            "</span>" +
            record.予定.value;
          break;
        case "転送":
        case "納品":
        case "設定":
        case "設置":
        case "移設":
          element[0].style.backgroundColor = "#f4fce8";
          element[0].style.borderColor = "#e5f2d3";
          element[0].style.color = "#006bac";
          element[0].style.whiteSpace = "break-spaces";
          element[0].innerHTML =
            "・<span style="background-color:#83cb26;color:#fff;" class="scheduleMarkEventMenu">" +
            record.予定の状況.value +
            "</span>" +
            record.予定.value;
          break;
        case "点検":
          element[0].style.backgroundColor = "#fff4e3";
          element[0].style.borderColor = "#fae8cd";
          element[0].style.color = "#006bac";
          element[0].style.whiteSpace = "break-spaces";
          element[0].innerHTML =
            "・<span style="background-color:#ef9201;color:#fff;" class="scheduleMarkEventMenu">" +
            record.予定の状況.value +
            "</span>" +
            record.予定.value;
          break;
        case "デモ":
        case "営業":
        case "商談":
        case "打合せ":
        case "来客":
          element[0].style.backgroundColor = "#faf6f2";
          element[0].style.borderColor = "#f2e9df";
          element[0].style.color = "#006bac";
          element[0].style.whiteSpace = "break-spaces";
          element[0].innerHTML =
            "・<span style="background-color:#c3a88b;color:#fff;" class="scheduleMarkEventMenu">" +
            record.予定の状況.value +
            "</span>" +
            record.予定.value;
          break;
        case "当番":
          element[0].style.backgroundColor = "#fcfae8";
          element[0].style.borderColor = "#f2efd3";
          element[0].style.color = "#006bac";
          element[0].style.whiteSpace = "break-spaces";
          element[0].innerHTML =
            "・<span style="background-color:#dfc506;color:#fff;" class="scheduleMarkEventMenu">" +
            record.予定の状況.value +
            "</span>" +
            record.予定.value;
          break;
        case "休み":
        case "有休":
        case "リフ":
        case "代休":
          element[0].style.backgroundColor = "#ffebeb";
          element[0].style.borderColor = "#fcdede";
          element[0].style.color = "#006bac";
          element[0].style.whiteSpace = "break-spaces";
          element[0].innerHTML =
            "・<span style="background-color:#f44848;color:#fff;" class="scheduleMarkEventMenu">" +
            record.予定の状況.value +
            "</span>" +
            record.予定.value;
          break;
        case "午前半休":
        case "午後半休":
          element[0].style.backgroundColor = "#fff2f5";
          element[0].style.borderColor = "#f7e9d2";
          element[0].style.color = "#006bac";
          element[0].style.whiteSpace = "break-spaces";
          element[0].innerHTML =
            "・<span style="background-color:#f3a4b4;color:#fff;" class="scheduleMarkEventMenu">" +
            record.予定の状況.value +
            "</span>" +
            record.予定.value;
          break;
        case "土曜当番出勤":
        case "出張":
        case "会議":
          element[0].style.backgroundColor = "#f5edfc";
          element[0].style.borderColor = "#ebe1f5";
          element[0].style.color = "#006bac";
          element[0].style.whiteSpace = "break-spaces";
          element[0].innerHTML =
            "・<span style="background-color:#b592d8;color:#fff;" class="scheduleMarkEventMenu">" +
            record.予定の状況.value +
            "</span>" +
            record.予定.value;
          break;
        case "土曜振休":
          element[0].style.backgroundColor = "#ffebeb";
          element[0].style.borderColor = "#fcdede";
          element[0].style.color = "#006bac";
          element[0].style.whiteSpace = "break-spaces";
          element[0].innerHTML =
            "・<span style="background-color:#f44848;color:#fff;" class="scheduleMarkEventMenu">" +
            record.予定の状況.value +
            "</span>" +
            record.予定.value;
          break;
      }
      return calendarevent;
    });
  };
  // kintone自体のイベント
  const eventslist = ["app.record.index.show"];
  kintone.events.on(eventslist, (event) => {
    // ビューが一致したら本体の関数呼び出し
    if (event.viewId === 5543487) {
      calenderformat(event);
    }
    return event;
  });
})(jQuery);

あと、cssも全体のフォントに関する設定と予定の状況の枠に対して設定しています。

div#calendarPlus {
    font-family:"ヒラギノ角ゴ Pro W3", "Hiragino Kaku Gothic Pro", ヒラギノ角ゴシック, "Hiragino Sans", メイリオ, Meiryo, "MS Pゴシック", "MS PGothic", sans-serif;
    font-size:14.4px;
    font-weight:400;
}
    
div#calendarPlus span.scheduleMarkEventMenu{
    display: inline-block;
    padding: 1px 2px;
    color: #fff;
    margin: 0 1px 2px 1px;
    line-height: 1.2em;
    border-radius: 2px;
    font-size: 12px;
    vertical-align: middle;
}
    

まとめ

  Topへ↑

てなわけで、日中は記事のことは一切忘れて徳島のあちこちをめぐっておりました。で、21時前に実家に帰ってきました。
では、早速記事の続きを。うん、あらためて確認しても表示はこんな感じで大丈夫かと。

本当は実装すべきなのは週だけでなく、他の日や月でも同じように表示できるか試さねばならないですね。また、Cybozu Officeのスケジュールアプリの日時と曜日の行見出しの部分はCalendar Plusでは再現していません。
まあこんな感じですが、記事の主旨は満たせたと判断し、今宵はここまでにしてアップしたいと思います。

あとは、金曜日に商談したお客様がこの実装でご満足いただけるかどうかでしょうか。なにしろ、お客様に商談の御礼のメールを送るより先に、こちらの記事をアップしてしまったので(^^;)。おいおい。

本稿がCybozu Officeからkintoneへの移行をお考えの皆様にとって少しでも手助けになれば幸せです。

もしお困りの際は弊社までご連絡くださいませ。

当エントリーの参考にさせていただいたブログ

  Topへ↑

最後になりましたが、このエントリー作成にあたり、以下のサイトからの情報を参考にさせていただきました。
ラジカルブリッジの斎藤さんにはいつも感謝です。内容にやばい内容が含まれていたら直しますね。
ありがとうございました。

 Calendar Plus JavaScript APIのリファレンス


freee & kintone BizTech Hackでオンラインハンズオンの講師を務めました


4/24(金)に行われた「freee & kintone BizTech hack」で、セミナーとハンズオンを弊社代表が担当させていただきました。
今回、初めての開催でありながら、全てがzoom上で行われました。100%ピュアのオンラインです。

ハンズオンとは講師が壇上に立ち、スクリーンに映した作業の一部始終を参加者に見てもらいながら、参加者にも同じ操作を再現してもらうセミナーの形態です。

ハンズオンは、どこか一つでも参加者が手順を誤るとうまく動きません。ですから通常は数名のメンターやサポートスタッフが会場を巡回し、参加者が課題を完遂できる様に導きます。
それでも多くの方が途中で脱落してしまいます。
私も参加したハンズオンのうち、完遂できなかったことがあります。

今回はそのハンズオンをオンライン上で行いました。つまり、難しさはさらに上がります。

弊社代表は、参加者を会場に集めてのハンズオン講師の経験は持っていましたが、オンラインハンズオンの講師は初めてです。
初めてだったのは弊社代表だけではありません。運営側の全員がほぼ未経験でした。
そのため、リハーサルは三回行いました。

皆さんにどうやったらわかりやすく内容を伝えられるか。どうやれば皆さんにハンズオンの課題を完遂してもらえるか。
手順を省くことは許されません。参加者がどこまで理解しているかも予断できません。

矛盾のない内容になっているか。話す速度は大丈夫か。提供するプログラムは破綻していないか。
リハーサルではそうした確認を行い、運営者の皆さんから指摘してもらいました。KPT法にのっとり、keep、problem、tryを繰り返しつつ。

結果として、15名の参加者の皆さんに最後まで完遂してもらうことができました。これも運営の皆さんと参加者の皆さんのご協力のたまものです。ありがとうございました。
公式開催報告:(https://fk-biztech.qloba.com/activities/7256

私にとって、今回の経験はとても得難いものでした。
ハンズオンの講師は、内容を完全に理解していなければ務まりません。
今回、ハンズオンでOAuthの仕組みを扱うにあたり、今まで何となく扱っていたOAuthについてさらに理解を深めました。
学びを通して自分の中にOAuthの仕組みをきちんと落とし込めたことは、今後の業務にとって助けとなるはずです。

ハンズオンの前のセミナーでお話しした通り、これからはSaaS同士の連携が欠かせません。
セミナー資料:(https://slides.com/yoshikazunagai/freee-kintone-biztech-hack-seminar
既存の構成から、新たな仕組みへと。
技術者に求められる役割はこれからも多岐にわたることでしょう。私たち技術者が学ぶべきことは多く、しかも新たな技術を取り入れねばなりません。

今後もオンラインでハンズオン講師を務める機会はあるでしょう。
私もできる限り、力を尽くしたいと思います。
より多くの人にエコシステムを使ってもらうために。より多くの技術者にオープンプラットホームの世界で活躍してもらうために。

すでに今回、ご好評をいただいたことで、次回の開催が決まっています。
freee & kintone BizTech Hackの二回目が5/22に行われます。
申込サイト:(https://fk-biztech.qloba.com/
次回は私は登壇しませんが、スタッフとして皆さんをサポートさせてもらえればと思います。
よろしくお願いします。


アクアビット航海記 vol.14〜航海記 その3


あらためまして、合同会社アクアビットの長井です。前回にも書きましたが、弊社の起業物語をこちらに転載させて頂くことになりました。前々回からタイトルにそって弊社の航海記を書いていきます。以下の文は2017/11/9にアップした当時の文章が喪われたので、一部修正しています。

違う環境に身を置くこと

もう一つ。起業にとって大きな糧となったこと。その糧は、大学のキャンバス内ではなく、大学の外で得ました。当時、ダブルスクールという言葉がありました。ダブルスクールとは、大学以外の別の学校でも学ぶことを指します。そこに入るきっかけはどうだったか覚えていません。多分、電話セールスだったはず。

世間知らずの私は言葉巧みに会う約束を交わされ、そして契約してしまったのです。正直、その金額は覚えていませんが、80万くらいだったのではないかと思います。しかもあろうことか、私はこの学校の名前を忘れていました。この連載までずっと。トリニティー・アカデミーという学校です。今、調べたところ、名前が変わったみたいですね。しかも当時の勧誘方法に問題があったことまでWikipediaに書かれています。営業の方のお名前や顔も覚えていないし、どういう営業トークだったかも覚えていません。ですが、言葉巧みな営業トークで契約まで追い込まれたのでしょうね。親に払ってもらったことにとても感謝しています。

学校の名前すら憶えていなかったくらいなので、そこでの交流関係は当時も今も全くありません。友人は一人も作れなかったし。ところが、そこで得たスキルが今なお役に立っているのだから、何事もやってみるものです

確かこの学校のカリキュラムはワープロとパソコン、英会話の三コースから成り立っていました。パソコンの授業内容は今から思えばベーシック言語で丸や図形を描くといった、ビジネスではまったく使えない類の授業。英会話も当時ならったスキルが自分にどう身に付いたのか心もとないです(第十二回で書いた台湾一周旅行には役立ったのかもしれませんが)。ですが、ワープロコースだけは違いました。なぜなら、私はブラインドタッチをこのコースでマスターしたためです。私はワープロ検定の3級と2級を持っているのですが、その試験もこの学校で受けました。ブラインドタッチこそ、私が後年、パソコンで身を立てる素地となったのです。

もともと中学の頃から家にあったワープロ(確かSANYO製SWP-330だったはず)で、大名家の家系図作りや、アドベンチャー・ゲームを作っていました(うーん、インドアやなぁ)。ところがキータッチは完全に自己流。とても仕事で使えるレベルではありませんでした。でも、この学校で覚えたブラインドタッチが、私にとって重要な武器となったのです。

これだから人生どうなるか分からない。もちろん、私がプログラミングやシステムエンジニアで食っていくなど、当時は想像すらしません。ましてや起業するなど。

もし本連載を読んでいる学生の方がいらっしゃったら、違う環境に身を置いてみること、と忠告しておきたいです。

アルバイトも社会経験の一つです

最後に糧になったこと。それはアルバイト経験です。

建前をいえば、大学生は学ぶことが本分です。アルバイトにうつつを抜かすなどもってのほか、という声があることも理解できます。その上で敢えて言います。社会経験としてアルバイトは必要だと思います。今、せっかく新卒で入った会社を性に合わないとすぐやめてしまう方が多いといいます。ま、私もあまり人のことはいえませんが。それでも私があえて言うとすれば、大学時代になるべく大変なアルバイトを、しかもいろんな職種を経験しておくべきだと思うのです。そうすれば社会人になってもある程度応用は効くはず。ま、入った会社によってまちまちな環境であることは承知の上ですけどね。

私自身のバイト経験ですが、高校の頃は甲子園球場の売り子、年末年始の年賀状配達ぐらいでした。大学に入ってからはダイエー塚口店で日配食品売り場の整理。プランタン甲子園店で自転車整理。プランタン甲子園店の電機売り場でワープロの販売員。そして都ホテル甲子園を拠点とした配膳スタッフを順にこなしました。特に最後の二つは後年の起業を語る上で欠かせません。

ワープロの販売などやったこともない中で、自転車整理から電機売り場にスカウトされまして。もちろん販売ノウハウなどあるわけありません。私はカシオ計算機の販売スタッフとして、カシオのワープロを売っていました。当時のワープロ市場でもカシオ社製はメジャーではありませんでした。ただ、上に書いた通り中学のころからワープロには親しんでいた私。販売員として店頭に立ちながら、自分なりに工夫して売っていたのです。そして私のセールストークで何台も売り上げることもできました。これは自信になりましたね。商談して提案して販売する快感を得たのはこの時だったと思います。実際、カシオ社からは辞める際に引き留められたくらいなので。

また、最後の配膳スタッフは大学3,4回生の2年間を捧げました。配膳スタッフとは結婚式の料理を配膳するホールスタッフと思ってもらえればよいです。これがまた大変なお仕事。表向きの優雅な給仕とは違い、裏側は体育会系の怒号乱れる現場なのです。時間単価は高かったので大学卒業まで勤め上げましたが、よくぞ自分でも続けたものだと思います。もちろん私は、落ちこぼれの配膳スタッフだったと思います。ミスもヘマも何度もしでかしましたし。

こういうチームワークや協力関係が求められる現場は、私はとても向いていないと思いました。自分の仕事のやりかたや向き不向きを知ったことだけでもとてもよい経験だったと思います。ワープロ販売員と配膳スタッフの経験は、私に社会に出る前に自分の素養を教えてくれました。とても得難い経験です。アルバイト関係の交流は、ダイエー塚口店のアルバイト仲間との交流を除いて、今や消滅してしまいました。残念です。

もし本連載を読んでいる学生の方がいらっしゃったら、社会経験を積め、と忠告しておきたいです。

大学時代のまとめ

大きく四つ、大学時代の私を振り返ってみました。こうやって書いていても、当時の私からは、”起業”して社会に活躍するイメージが全くわいてきません。自分のことなのに。いや、当時は当時なりに頑張って生きていたのでしょう。

キャンバスライフをステレオタイプに分けたとして、体育会系で上下関係を叩き込まれる、サークルでぶいぶい言わせる、学術に没頭して学問の世界にのめりこむ、の三つがあります。でも、私のキャンバスライフは三つのどれにも当てはまりません

でも、当時こそ全く気づいていなかったのですが、今から思えば”起業”するための素養は大学のキャンバスライフで養われていたのですね。起業には直接関係ないので触れませんでしたが、他にも大学生活では今から考えると貴重な経験を積まさせていただきました。本当に関わった皆様には感謝です。遊んでばかりいたように思っていましたが、人生で過ごす時間に無駄なものは一つもない、と逆説を言っておきたいです。

次回は、漂流を始めた私の日々を書きます。


テトリス・エフェクト―世界を惑わせたゲーム


本書はテトリスについての物語だ。テトリスの名前を知らない人はあまりいないと思う。私の娘たちも知っていたくらいだから。単純明快。それでいて中毒性を持つのがテトリス。上から落ちてくる四マスからなる四種類の図形を回転させ、横一列にマスを埋めれば消える。上まで積み上がればゲームオーバー。ゲームの歴史を彩った名作は多々あるが、テトリスは単純さと中毒性において屈指のゲームといえるだろう。

私がどうやってテトリスを知ったのかは覚えていない。ゲーセンのアーケードゲームなのか、任天堂のゲームボーイだったのか。その頃、ある程度テトリスをやり込んだ記憶はある。が、それほどはまらなかったように思う。少なくとも本書で紹介されたような人々が陥った中毒症状ほどには。むしろ、私がはまったのはテトリスの系譜を継ぐゲームだ。それは例えばCOLUMNS。またはキャンディ・クラッシュ・サーガ。それらの持つ中毒性には当てられてしまった。だからこそ、ゲームの世界に落ち物ジャンルうを打ち立てたテトリスには興味があるし、それを扱った本書にも興味を抱いた。なお、余談だが私は本書を読み始めてすぐ、読み終えるのを待ちきれずにiPad版のテトリスをダウンロードしてプレイした。その体験は久々で懐かしかったが、中毒になるまでは至らなかった。

テトリスの歴史や魅力のほかにもう一つ、本書が私に教えてくれたことがある。それは、契約の重要性だ。本書は契約の重要性を知らしめてくれたことでも印象に残った。

本書はロシア製のテトリスがどうやって世界中に販売され、受け入れられていったかのドキュメントだ。当時、ソ連はペレストロイカ前夜。社会主義の国是が色濃く残っていた時期。契約についての観念も薄かった。そのため、テトリスの版権や著作権、そして販売代理店や手数料など、西側の資本主義国のビジネスマンがこの不思議な魅力を持ったゲームを販売するにはいくつもの障害を乗り越えねばならなかった。本書はそうしたテトリスにまつわる契約のあれこれが描かれている。巨額の利権を産んだテトリスの権利をめぐる攻防。それは商売における契約の重要性を的確に示している。もちろん、本書はそうした契約上の文言を開示しない。一字一句掲示したところで野暮なだけだ。だが、契約をめぐる熾烈な競争は、私のように、情報サービスの契約を日頃から結ぶ身としてはとても興味深い。

もちろん、技術者としてもとても本書は面白い。テトリスがどういう発想から生み出されたのか。テトリスのプログラムがどういったマシン上で動作し、それを他の機種に移植する苦労。今と違って貧弱な当時のハードウエアの制限をどうやって克服したのか。技術者としてはとても興味をそそられる。

平面のさまざまな形を組み合わせ、別の組み合わせを作るペントミノと回転。それを横一列にそろえて列を消すだけの単純なルール。それは、イデオロギーも言葉や民族の違いを超えて人々を魅了した。また、当時のソ連のマシンは西側に比べ圧倒的に遅く、初期のテトリスは文字だけで実装されたプログラムだったという。アレクセイ・パジトノフがエレクトロニカ60で初期版のテトリスを開発した時、文字だけで動作するゲームしか作れなかった。そして、そんなマシンでも動くゲームだったからこそテトリスは人々をとりこにしていったのだろう。

貧弱なマシンが、当時のソ連にもわずかながら存在したギーク(ワジム・ゲラシモフ)によって別のマシンに移植され、それが当時唯一西と東をつないでいたハンガリーを通って西に出ていき、あっという間に西のマシンにインストールされていくいきさつ。それは、まさに歴史のダイナミズム。ベルリンの壁が崩壊する前、ハンガリーで開かれたピクニックが東から西への人々の移動を勃発させ、それが東西冷戦の終結への流れを生み出した事実は有名だ。テトリスもまた、歴史の舞台の展開に一役買っている。それは歴史が好きな向きにとっても見逃せない。本書には「テトリスをソ連が世界に貢献した唯一の物」と言う文が収められているが、まさにソ連とはそういう存在だったのだろう。

冒頭にも書いたとおり、私が初めてテトリスに触れたのは任天堂のゲームボーイだ。ところが、任天堂がテトリスを出すまでには、一山も二山も超えなければならなかった。その中で大きな役割を果たした人物こそがヘンク・ロジャースだ。彼こそが本書の主人公といってもよいだろう。ところが彼はがテトリスのライセンスを巡る物語のなかでは後発組だ。

最初にテトリスに目を付けた西側で最初の人物は、ヘンク・ロジャースではなく、ロバート・スタインだ。マクスウェル社のスタインは、ハンガリーから西側に登場したテトリスに真っ先に目を付け、そのライセンシーを獲得しようと奔走する。ところがスタインは、テトリスの開発者アレクセイ・パジトノフと直接コンタクトを取り、FAXでやりとりをして契約を結ぼうとする。それはもちろん過ちだった。よりによって一人のプログラマーに過ぎないパジトノフに西洋流の契約についての知識はない。もちろんスタインも正式な調印無しに事を進めることの危険性を理解していたはず。だが、テトリスの製品化は西側のプログラマによってあっという間に進められてしまう。そして未契約のまま西側で製品を流通させたことに焦ったスタインが時間を稼いだにもかかわらず、西側の市場に出回ってしまう。ソ連側や開発者のパジトノフにまったく利益が還元されないまま。スタインは板挟みになり、ますます契約締結を焦る。

それ以降の本書は、ヘンクがどうやってスタインに先行されたテトリス・ビジネスの劣勢を挽回していくかの物語になる。本書の冒頭で、ヘンクはつてもコネもアポも全くないままモスクワを訪れる。何もあてがなかったヘンクは街中でチェス愛好家と知り合い、それを手がかりにソ連の情報関連の管理を一手に行うERLOGに接近することに成功する。そしてスタインとの契約がソ連側に何ももたらさなかったことを、ERLOGの責任者アレクサンドル・アレクセンコに知らせる。そのことを知らされたERLOGのアレクサンドル・アレクセンコはスタインとの契約に失望を覚え、怒りにかられる。

そこでヘンクはまず契約の不公平さをあらためるため、即座に小切手でソ連が本来取るべきだった取り分を提示する。この誠実さに打たれたERLOGの担当は感銘を受け、ヘンクを信頼する。アレクサンドル・アレクセンコも、後継者のエフゲニー・ベリコフも同じ。ただし、スタインに悪気があったわけではない。ただ、スタインがやってしまった失敗とは、契約の調印が済んでいないのに、FAXのやりとりだけを頼りに西側への販売権をマクスウェル社やスペクトラム・ホロバイトに販売してしまったことだ。

スタインに比べ、後発のヘンクには、先人スタインの犯した過ちを挽回するチャンスも機転もあった。彼はまず誠実な対応をとり、ヘンクという人間を売り込む。ヘンクの対応はベリコフを信頼させるのに十分だった。そこでベリコフはスタインとの契約にとある修正をほどこす。その修正はスタインとERLOGの間に交わされた契約の条項にハードウエアの条件を書き加えるものだ。その修正はスタインの契約をパソコンに限定させる効力を持っていた。それに気づかぬまま調印したスタインは、ヘンクにまんまとポータブルゲームや家庭用業務ゲーム機器にライセンスを与える契約をさらわれてしまう。

ヘンクはその勢いで、テトリスをめぐるアタリ社やテンゲン社とのライセンス契約締結の競争にも勝利する。ヘンクの勝利の裏には、任天堂の山内溥、荒川實、そしてハワード・リンカーンの全面的なバックアップがあった。彼らに共通していたのは、任天堂が発売するゲームボーイに載せるゲームとして、テトリスがもたらす巨大な可能性を見抜く先見性だ。目的を一つにした彼らは、ライバルに契約面で勝利を収め、テトリスとゲームボーイのセットを世界中で売りまくる。

かつてファミコンが世界を席巻する前、ゲーム業界はアタリ社が優勢を占めていた。そのアタリ社が事実上、ゲーム業界で任天堂に覇者の座を譲ったのは、このできごとがきっかけだったのではないだろうか。

本書はパソコンの、そしてゲーム専用機の黎明期、さらに商売の面白さと怖さを知る上でも興味深い。

また、本書はテトリスの歴史に欠かせないヘンクの経歴にも触れる。その中で、ヘンクが開発したザ・ブラックオニキスの話など、初期のゲーム開発の苦労がよくわかるのが面白い。私はザ・ブラックオニキスの名前は知っていたが、プレイしたことがない。本書を読んでいてやってみたくなった。

本書はここまでのいきさつだけでも読み物として十分に面白い。が、それだけでない。本書にはテトリスの科学的な分析が三つのコラムとして挿入されている。BONUS LEVEL 1-3と題されたそれぞれのコラム。そこではプログラムの面からみたテトリス。テトリスの中毒性を心理学からみた考察。PTSDの治療にテトリスを使う試み。それらのどれもが知的興奮を誘う。

また、各章にもミニ知識としてテトリスに関するあれこれの豆知識が仕込まれている。例えば初期のテトリスにはボスが来た(1キー押下で仕事をしている振りを見せる画面を表示させる)機能があったり。

本書はすべての技術者やゲーマーにおすすめできる一冊だと思う。さらには、私のような契約の実務にも携わる方や営業に駆け回る方にも良い教材として勧めたい。

‘2018/05/10-2018/05/17