長い旅路の先に、ようやくオアシスの気配だ。さて、どんな知恵が湧いている泉だろうか。
遥か昔、私がまだ学生プログラマだった頃。アルバイト先に、Nくんという、一つ年下の天才がいた。ある日、彼は退屈しのぎに、1時間ほどで「テトリスもどき」を創り上げてしまった。そのコードを覗き込んだ私は、愕然とした。ブロックの移動計算が、私の知る魔法とは、全く異なっていたのだ。
キー入力を判定し、ブロックの座標(X・Y位置)を計算する。当然、if文(条件分岐命令)やswitch文(多分岐命令)で、キーの種類ごとに処理を分岐させるものだと思っていた。しかし、彼の羊皮紙には、if文のいの一字もない。ただ、無駄なく、そして美しく、たった2行の計算式が記されているだけだった。
その魔法は、周囲から「トリッキーだ」「邪道だ」と蔑まれた。しかし、それは本当に邪道だったのだろうか?否。それこそが、ブール代数(論理代数)という、この世の真理を映し出す、光り輝く宝石だったのだ。
この羊皮紙のあらまし
この羊皮紙が導く者
ifやswitchという、凡庸な魔法の連続に、魂の渇きを覚えている者- ロジックの根源的な美しさ、計算式が持つエレガンスを求める探求者
- 「邪道」と呼ばれた魔法の、その真の輝きを知りたい冒険者
- 分岐命令を減らし、コードの可読性と保守性を高めたいと願う実践者
砂漠の道標
- ブール代数(論理代数) - 真偽値(true/false)を用いた数学的演算体系。
- if文(条件分岐命令) - 条件の真偽によって処理を分岐させる命令。
- switch文(多分岐命令) - 複数の条件を効率的に分岐させる命令。
- ブール式(論理演算式) - 真偽値を返す論理演算の式。
- 論理和演算子(OR、||) - いずれかの条件が真なら真を返す演算子。
- 座標計算 - オブジェクトの位置(X、Y座標)を数式で算出する処理。
- WPF(Windows Presentation Foundation) - Windowsアプリケーション開発のためのUIフレームワーク。
謎の解明:天才が操った、2行の魔法
数年後、システム開発の荒波に揉まれる中で、私はふと、あの日の記憶を思い出した。Nくんが操った、あの不可解な2行の魔法。その理(ことわり)は、驚くほどシンプルだった。
彼は、座標計算の基本x = x + Δx、y = y + Δyを、プログラムで忠実に再現していたに過ぎない。
キー判定は、真(true)なら1、偽(false)なら0を返す、ブール式(論理演算式)だ。これに移動量を掛け合わせるだけだ。
- X座標:
x = x + (左キーが押されたか * -1) + (右キーが押されたか * 1) - Y座標:
y = y + (上キーが押されたか * -1) + (下キーが押されたか * 1)
キーが押されなければ、移動量はゼロ。押されれば、対応する移動量が加算される。ただ、それだけ。 なんとエレガントで、なんと美しい魔法だろうか。これを「邪道」と呼ぶのは、このロジックに秘められた数学的な美を、理解できぬ者の戯言に過ぎない。
応用編:ifなき世界の創造
この魔法の応用として、実際にWPFで動作するサンプルを創り上げてみよう。
この世界の理はこうだ。テンキーの数字(1~9)または矢印キーを押すと、そのキーの位置に対応してプレイヤーが移動する。 例えば、7を押せば左上へ、2を押せば下へ。この直感的な操作を、ifもswitchも使わずに、計算式だけで構築する。
魂の設計図(ソースコード)
その核心部分が、このPlayerクラスのMoveメソッドだ。
この魔法の真髄は、どのキーが押されたかを、膨大な||(OR、論理和演算子)で繋いだ、巨大なブール式(論理演算式)で判定する点にある。
public void Move(Key k) { // === ここが魔法の核心 === // 押されたキーが、どの方向の移動に属するかを、全てブール式で判定する var isLeft = k == Key.Left || k == Key.NumPad1 || k == Key.NumPad4 || k == Key.NumPad7 || k == Key.D1 || k == Key.D4 || k == Key.D7; var isRight = k == Key.Right || k == Key.NumPad3 || k == Key.NumPad6 || k == Key.NumPad9 || k == Key.D3 || k == Key.D6 || k == Key.D9; var isUp = k == Key.Up || k == Key.NumPad7 || k == Key.NumPad8 || k == Key.NumPad9 || k == Key.D7 || k == Key.D8 || k == Key.D9; var isDown = k == Key.Down || k == Key.NumPad1 || k == Key.NumPad2 || k == Key.NumPad3 || k == Key.D1 || k == Key.D2 || k == Key.D3; // 移動速度の計算(if文なし) Speed += -Convert.ToInt32(0 < Speed) * Convert.ToInt32(isSlow) + ...; // 移動式の計算(if文なし) var x = Point.X + Convert.ToInt32(isLeft) * -Speed + Convert.ToInt32(isRight) * Speed; var y = Point.Y + Convert.ToInt32(isUp) * -Speed + Convert.ToInt32(isDown) * Speed; // ... (境界判定と座標特定も、全て計算式で行う) ... }
羊皮紙を巻く前に
数年の時を経て、あの日の衝撃が、今ようやく言語化できる。ifやswitchを使わない、ブール式(論理演算式)を用いた条件判定。それは単なるトリッキーな技法ではない。それは、プログラムを、単なる命令の羅列から、数学的な美しさを宿した「数式」へと昇華させる、高貴な魔法なのだ。
ブール代数が示す、コードの真髄
- 論理的純粋性 - 分岐命令ではなく、数式として処理を表現する美しさ。
- 拡張性の高さ - 新たなキー入力の追加が、OR条件の追加のみで完結する柔軟性。
- 計算効率 - 分岐予測失敗によるパフォーマンス低下を回避できる可能性。
- 普遍的理解 - ブール代数という数学的基盤により、言語を超えた普遍性を獲得。
「邪道」の真実
確かに、この魔法は、一見すると難解で、仲間(他の開発者)に理解されないかもしれない。しかし、その根底に流れる普遍的な論理の美しさを知ってしまった者にとって、もはや凡庸な分岐命令だけの世界には、戻れないのだ。
まとめ
アルバイト先の社長は、かつて「ぷよぷよ」のコンパイル社の社長と知り合いだったという。Nくんといい、私といい、あの頃の我々は、ゲームという名の魔法が、すぐそばにあった、古き良き時代を生きていたのだ。
あの日「邪道」と呼ばれた魔法は、実は数学という普遍の光だった。この羊皮紙が、未来の旅人に、新たな視座をもたらすことを願って。
少し目が疲れてきた。星でも眺めながら、しばし休むことにするか。
砂漠で見つけた魔法のランプ
この羊皮紙に記された魔法の源流は、特定の書物ではない。 それは、「ブール代数」という、この世界の論理を司る、偉大にして普遍的な知の体系そのものである。興味がある者は、その深淵を覗いてみるといい。新たなる世界の扉が、開かれるかもしれぬ。
- ブール代数 - Wikipedia | この世の真理が記された、究極の古文書。論理演算の数学的基盤を学べる。
ラクダの独り言
ご主人が「計算式こそが、世界の真理だ!」なんて、また難しい顔で、ぶつぶつと独り言を言っている。俺に言わせりゃ、右に行きたきゃ右に行き、左に行きたきゃ左に行く。そんな当たり前のことに、なんでそんな小難しい理屈が必要なのかね。まったく、人間ってのは、簡単なことを難しくするのが好きだな。やれやれだぜ。