【cocos2dx】重複のないランダムな数字を取り出す(追記あり)

【cocos2dx】重複のないランダムな数字を取り出す(追記あり)
   

2日前から、ずーと考えていたのが、「重複なしでランダムな数字」を取り出すことができないかということです。
現在考えているゲームなんですが、オブジェクトの位置を決めずに、ランダムに配置をしたいと考えています。ゲームを考え始めた時から懸念に感じていたことが、このオブジェクトの配置が実装できるかどうかでした。

これまで作成してきたゲームに関しては、オブジェクトの位置は固定されていたので、そのようなことは考えていなかったので、凄く悩みました。
本日、ようやく「重複なしでランダムな数字」を取り出すことに成功しましたので、そのやり方を今回、ブログで紹介をしたいと思います。

【追記 10/28】
twitterで、もっと簡単にできる方法を教えていただきましたので、追記をしています。


以下のような順番で説明をします。

  • ランダムな数字を取り出す
  • 整数型の配列
  • 実際のコード

ランダムな数字を取り出す

まずは、ランダムな数字を取り出す方法です。
これは、以前ブログにも書いたのですが、C++には専用のメソッドが用意されていますので、これを利用します。



    //これがないと、ランダムでも同じ数字になってしまう。
    srand((unsigned int)time(NULL));

  
    //rand()%の後に、どこまでの範囲から値を取得するかを指定(例では0~9までの整数)
    int randomNum = rand()%10;



【追記】
上記の方法でもランダムな数字を出すことができますが、以下のコードの方が簡単です。


    int randomNum = arc4random()%10;



上記のコードで、rand()を呼び出すごとに、ランダムな数字を取得できます。


整数型の配列

今回は、重複をしない数字を取り出すということで、以下のようにして、ランダムな数字を取り出します。
  1. 0~9の整数が格納されている配列を準備
  2. 配列から、rand()を利用して、数字を一つ取り出す
  3. 取り出した数字を除いた配列を作成する
  4. 2に戻る

このような方法で、ランダムな数字を一つづつ取り出していきます。

動的配列(vector)

まずは配列を作成しなくてはいけないのですが、cocos2dxの配列といえばCCArrayクラスがあります。
ただ、これはint型のオブジェクトを格納できないので、どうしようか色々と考えました。

それで利用したのが、「動的配列(vector)」というものです。

これは、C++から使えるモノみたいで、配列の生成、追加、削除ができるといったものです。


こんな感じで利用をしています。

std::vector<int>array;


 //0~9までの配列を作成
    for( int i = 0; i < 10; i++ )
	{
		array.push_back( i );
	}

  //配列の個数を取り出す
    int arrNUm  = array.size();

  //配列をクリアにする 
    array.clear();


&#91;/c&#93;


【追記】
配列に関しては、CCIntegerクラスを利用すれば、CCArrayで利用ができます。
これを利用すれば、もっと簡単です。

&#91;c&#93;

    CCInteger *hogehoge =CCInteger::create(1001);
    CCInteger *hogehoge2 =CCInteger::create(1002);

    CCArray *_arr = CCArray::create();

    _arr->addObject(hogehoge);
    _arr->addObject(hogehoge2);


    //int型で取り出すには、getValue()を使います。
    CCObject *obj = NULL;
    CCARRAY_FOREACH(_arr, obj){
        
        CCInteger *num= (CCInteger*)obj;
        
        CCLOG("%i",num->getValue());
        
        
    }


CCArrayについてはこちらのリファレンスを見れば、「追加」「削除」などが載っています。
CCArray | Cocos2d-x

こちらを参考にコードを組み立てて下さい。

参考

全く知識がないので、こちらのサイトを参考にしました。

配列よりSTL
動的配列(vector) …




実際のコード

実際のコードを書いていきます。
正しい値を返しているので、多分大丈夫だと思います。
もし、もっといい方法があれば教えて欲しいです。



std::vectorary1;



void GameLayer::setObject(){


srand((unsigned int)time(NULL));


//ランダムの数字の範囲(0~9)で配列を作成
for( int i = 0; i < 10; i++ )
{
ary1.push_back( i );
}


//取り出す数字の総数 (今回は5つの数字を取り出しています)
for (int i = 0; i < 5; i++) {


//下記メソッドから、ランダムな数字を取り出します。
int xPos = this->returnRandomNum(cary1);



//取り出した数字を利用して、オブジェクトを配置
GameObject *obj = GameObject::create();
obj->setPosition(32 + 64 * xPos,-300);
this->addChild(obj,3);

}


}




int GameLayer::returnRandomNum(std::vector array){


vector ary2;


//配列に格納されている数字の数を取り出す
int arrayNum = array.size();

//ランダムな数字を取り出す
int randomNum = rand()%arrayNum;

//配列から取り出した数字を取り出す(これが欲しい数字です)
int getNum = ary1[randomNum];





//取り出した数字を抜いた、新しい配列を作成します。
for( int i = 0; i < arrayNum; i++ )
{

if (i == randomNum) {



}else{

//新しい配列に数字を格納します。
ary2.push_back(ary1[i]);
}
}

//クリア
ary1.clear();


ary1 = ary2;


return getNum;


}



[/c]

最後に

全くと言っていいほど、プログラミングの知識がないので、この辺りの基礎をしっかりしないといけないなあと感じています。
おそらくとても簡単なことだとは思うのですが、とても苦労しています。
数字を取り出しただけど、まだ上手く利用ができていないので、もっと頭を使わないといけなあ。

もし、何か参考にできる部分があれば幸いです。

Related Posts Plugin for WordPress, Blogger...