というわけで、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の移動速度を持ってる」
というのしか求めていないという点。たとえば、このあと、飛んでくる隕石?とか、を考えだすと、こう、ね。隕石と宇宙船で親子関係を作らないでよいのですよ。とか。


オブジェクトにアルゴリズムを持たせてはいけない。そんなことしたら、そのアルゴリズムが他で使えなくなってしまう。
アルゴリズムが求めるオブジェクトの特性を抜き出して、それとこれをアレ。