C++ シュミレーションゲームなど使える 再帰的な関数を使った処理

再帰的な関数を使った処理

再帰関数・・・関数の中で、同じ関数を実行することのある関数

作成時のルール

引数などのデータを使い、同じ関数を

実行するかどうか決める。

実行しない場合、returnで処理を終了させる。

、※Win32 Console Applicationで作成

#include <stdio.h>

void func1(int)

void main()

{

func1(3);

printf(“\n”);

func1(5);

printf(“\n”);

}

void func1(int Num)

{

if(Num > 0) //もし、引数が0より大きかったら、

{

printf(“Num = %d\n”,Num); //引数を表示

func(Num-1); //今の引数より1少ない数で、同じ関数を実行

}

return; //0以下だったら、return;

}

 

func1(3)

Num=3、と表示

Num>0なので、func1(3-1)を実行

|

∟→func1(2)

Num=2、と表示

∟――Num>0なので、func1(2-1)を実行

|

∟→func1(1)

Num=1

∟―――Num>0なので、func1(1-1)を実行

|

∟→func1(0)

∟―――Num>0ではないので、return;

 

ゲームでの使用例、シミュレーションゲームの移動


選択されたキャラが移動可能な範囲を

先に表示する。

移動可能な範囲を扱う配列を作る。

キャラのいる場所が3

1歩動くごとに2,1,0と減っていく。

(0でない場所は、移動可能)

このような配列を作るのに、再帰関数を用いる。

関数の機能

キャラの場所や、移動量(どれくらい動けるか)などのデータを元に、

移動可能な範囲を表す配列を作る。

[2][2]の場所に移動量3のキャラ

関数内の処理

・配列内の、指定された要素に、

キャラの移動量の数値を代入する。

・代入ができた場合、代入した要素の

上下左右のマスを、

移動量-1、で、同じように処理する。

(1マス動くたびに、移動量は1ずつ下に下がっていく)

・移動量が0になったら、そこで終了(return)。

・指定したマスに、他の数値が入っていた場合、

大きい方を使用。

・配列から、はみ出ないようにする。

関数の例、

マップチップの縦の枚数・・・MapH

横の枚数・・・MapW で、マクロ定義されているものとして説明

int MapMoveData[MapH][MapW];

//移動可能な範囲を表す配列。マップと同じ大きさ。

を外部変数として宣言しておく。

void Move(int x,int y,int MoveNum)

配列のどの要素を調べるか 移動量

{

//移動量が残っているか判定

if(MoveNum <= 0) return; //移動量が0以下なら、returnする。

//配列からはみ出ていないか判定

if(x >= MapW || y >= MapH || x < 0 || y < 0)

return; //x,yが配列の要素の範囲外だったら、return

//すでに、より大きな値が入っていないか判定(より効率の良いルートがあるかどうか)

if(MapMoveData[y][x] > MoveNum)

return;

//移動量を、配列に代入

MapMoveData[y][x] = MoveNum;

//移動量を1減らして、現在のマスの左右上下を、同じように調べる

Move(x,y-1,MoveNum-1); //

Move(x,y+1,MoveNum-1); //

Move(x-1,y,MoveNum-1); //

Move(x+1,y,MoveNum-1); //

return;

}

実行例

Move関数のプロトタイプ宣言、

MapWMapHのマクロ定義、

MapMoveData[][]の宣言は、各自で行うこと。

#include <stdio.h>

void main()

{

int i,j;

Zeromory(&MapMoveData[0][0],sizeof(itn)*MapH*MapW);

Move(2,2,3); //x=2y=2の場所に、

移動量3のキャラがいるものとして、配列に値を設定

for(i=0;i<MapH;i++) //配列を表示

{

for(j=0;j<MapW;j++)

{

printf(“%d”,MapMoveData[i][j]);

}

printf(“\n”);

}

}