休みの日は寝すぎる。
とりあえず
一発ネタはできた。
もうちょっと考えるか。
■
というわけで、C++テンプレートを覚えたばかりの人が書きそうな若さあふれるコードを書いてみた。そんなに量は無いけど。
C++で書くときは、メソッドにアルゴリズムを書いてはいけない、というような気がした。オブジェクトは、どういう特性を持ってるかだけを記述しておいて、アルゴリズムは、それ以外の場所に書くようにするのだ。
ゲームの宇宙船(SpaceShipクラス!オブジェクト指向っぽいという超偏見!)を考える。
class SpaceShip { float x; float y; float idou_kyori_x(); float idou_kyori_y(); public: void move( ) { x += idou_kyori_x(); y += idou_kyori_y(); } };
とりあえず、できた。
けど、これだと、壁を突き抜けてってしまうので、壁を考えとこう。
class SpaceShip { float x; float y; public: void move( ) { x += idou_kyori(); if ( x < 0 ) x = 0; else if ( x > x_bound ) x = x_bound; y += idou_kyori(); if ( y ... } };
んで、次に、何故か宇宙なのに、右側から風が吹いてくるステージが必要になってしまった、と、
class SpaceShip { float x; float y; public: void move( ) { ... } void kaze_no_naka_wo_move() { move(); x -= wind_power(); } };
次は重力だ!!
class SpaceShip { float x; float y; public: void move( ) { ... } void kaze_no_naka_wo_move() { ... } void gravity() { move(); y -= grav(); } };
次は、重力のあるところで風の中を進む宇宙船だ!もはや宇宙船じゃない!!
class SpaceShip { float x; float y; public: void grav_wind_xxx() {} ...
いや、何かおかしい。ステージの特性が変わるごとに、宇宙船がややこしいことになっていく。いや、リアルにあったら、実際大変なことになってると思うけど。
実世界をモデル化っつったって、別に、必要も無いのに実際の複雑さまで真似することはなかろうて。
こういうときは、アルゴリズムを外へ出してしまうんだ。
class SpaceShip { public: float x; float y; float idou_kyori_x(); float idou_kyori_y(); }; /* 直進 */ template <typename Obj> void linear_move( Obj &o ) { o.x += o.idou_kyori_x(); o.y += o.idou_kyori_y(); } /* 壁あり直進 */ class KabeMove { public: const float bound_x; const float bound_y; KabeMove( float bound_x, float bound_y ); template< typename Obj > void operator() ( Obj &o ) { linear_move( o ); if ( o.x < 0 ) o.x = 0; else if ( o.x > bound_x ) o.x = bound_x; ... } };
あとは、同じ要領でぽこぽこしていけば。宇宙船は変わらない。
あと、重要な点は、linear_moveと、KabeMoveはオブジェクトに対して、
「xとyを持ってて、それが変更できて、あと、x、yの移動速度を持ってる」
というのしか求めていないという点。たとえば、このあと、飛んでくる隕石?とか、を考えだすと、こう、ね。隕石と宇宙船で親子関係を作らないでよいのですよ。とか。
オブジェクトにアルゴリズムを持たせてはいけない。そんなことしたら、そのアルゴリズムが他で使えなくなってしまう。
アルゴリズムが求めるオブジェクトの特性を抜き出して、それとこれをアレ。