본문 바로가기

BSMath

Random의 객체 기반 설계

객체 기반 Random이 필요한 이유

 기존에 사용하던 C언어의 rand(), srand()와 UE4의 Random(Random Stream 제외)은 전역 State 기반 랜덤이다. 그렇기에 어디서 난수를 뽑더라도 그것이 다른 곳에 영향을 미치게 된다. 이는 특히 네트워크 환경에서 난수를 동기화하거나, 멀티 스레드 환경에서 프로젝트를 진행할 때 문제가 된다. 이를 객체 기반으로 하면 해결할 수 있다. 객체의 시드만 맞춰주면 다른 객체에 영향을 주고받지 않으면서 원하는 난수를 얻을 수 있다. 그리고 객체로 하면 Engine과 Distributor를 자유롭게 설정할 수 있다는 장점이 존재한다.

구현

Random 코드

 코드와 함께 보도록 하자. 단순히 보면 C++ 11의 random 객체를 wrapping 한 것이긴 하다. T는 난수의 타입, Engine은 랜덤 엔진으로 보통 Mersenne Twister 엔진이다. Distributor는 uniform_int_distribution이나 normal_distribution 등의 난수 분포이다. Seed와 Parameter는 표준 규격에 정의된 타입을 통해 추론한다. 여기서 random_device만 부모 함수로 뺀 이유는 코드 비대화를 막기 위해서이다. (Effective C++ 항목 44 참고) 이를 통해 모든 Random 객체가 하나의 random_device를 사용하게끔 제작하였다.

활용

 Int와 Float 등의 Distributor는 이미 STL에 정의되어있기에 이를 이용한 Random 객체를 Type화 하면 된다.

Int와 Float의 Random 객체

 벡터와 행렬의 Distributor는 직접 제작할 필요가 있다. 간단히 난수를 길이만큼 뽑아서 조합하게끔 구현하였다. 다음은 행렬의 정규 분포 난수 Distributor이다. 추후 개발할 Quaternion이나 Rotator 등의 객체 역시 이렇게 간단히 확장 가능하다.

Normal Matrix Distribution의 코드