난수 생성하기

Ryan Ham·2024년 5월 16일
1

C++

목록 보기
5/26

게임 업계에서는 확률형 보상 아이템이 거의 주 수입원이라고 할 수 있을 만큼 확률을 이해하고 생성하는 것은 매우 중요하다. 오늘은 cpp standard library에 포함되어 있는 cstdlib의 rand()와 srand()를 통해 난수 생성 방법을 알아보자.

#include <iostream>
#include <cstdlib>

using namespace std;

int main(){

	cout << "Print out random number " << rand() << endl;

위 예시는 rand()를 사용한 아주 간단한 난수 생성 방법이다. rand()는 0부터 RAND_MAX라는 상수 사이에 존재하는 임의의 값을 반환한다. 이 상수는 cstdlib header file에 존재한다고 하는데 필자의 cpp에서 돌려본 결과 이 값은 32767이었다.


Seed

난수는 매번 다른 값을 반환한다고 생각할 수 있는데 이는 조건에 따라 틀린 말이 될 수도 있다. 정확히 말하자면 난수 생성기는 seed를 가지고 난수 값을 생성하게 되는데 만약 이 seed값이 동일하면 같은 trial에 대해서 같은 난수 값을 반환한다. 따라서 보통 매번 변하는 값인 현재 시간을 seed로 삼고 난수를 생성하게 된다.

#include <iostream>
#include <cstdlib>
#include <ctime>

using namespace std;

int main(){

	srand(time(0)); // 현재 시간을 seed로 설정.
    rand();
    
    cout << "First random value : " << rand() << endl;
    cout << "Second random value : " << rand() << endl;

시드를 설정하고 생성하는 첫번째 rand()는 보통 discard한다. srand()와 rand()를 사용하는 방법은 순수 rand()만 사용하는 코드에 비해 크게 다르지 않는데, 우선 현재 시간값인 time(0)을 srand()에 넣어주고, 그 뒤는 rand()로 난수를 생성하면 된다.


범위 안의 난수 생성 방법

예를 들어서 0부터 10000까지의 지정된 범위안에서 난수 생성을 하고 싶다고 가정하자. 더 나아가서, 난수가 1이 나올때까지 몇번의 try를 하는지 count 변수에 담아서 뽑아보자.

#include <iostream>
#include <cstdlib>
#include <ctime>

using namespace std;

int main(){

	int count = 0;
    srand(time(0));
    rand(); // seed를 설정하고 난 첫번째 rand()값은 버린다. 첫번째 랜덤 값은 규칙성이 좀 있다고 한다. 
    
    while(true){
    	++count;
        if(rand()%10001 == 1) // 0 ~ 10000사이의 값을 뽑아야 하니 mod 10001을 해야 한다. 
        {
        	cout << "Hurray! Total count is : " << count << endl;
            break;
		}
	}
}

random cpp stl

rand()는 C스타일의 매우 역사가 오래된 함수라고 한다. cpp에는 더 개선된 스타일의 "random"이라는 난수 생성기가 존재하는데, 더 나은 RNG(Random Number Generator)와 Mersenne Twister 엔진을 사용해서 난수를 생성한다고 한다.

profile
🏦KAIST EE | 🏦SNU AI(빅데이터 핀테크 전문가 과정) | 📙CryptoHipsters 저자

0개의 댓글