블로그 이미지
Every unexpected event is a path to learning for you. blueasa

카테고리

분류 전체보기 (2794)
Unity3D (852)
Programming (478)
Server (33)
Unreal (4)
Gamebryo (56)
Tip & Tech (185)
협업 (11)
3DS Max (3)
Game (12)
Utility (68)
Etc (98)
Link (32)
Portfolio (19)
Subject (90)
iOS,OSX (55)
Android (14)
Linux (5)
잉여 프로젝트 (2)
게임이야기 (3)
Memories (20)
Interest (38)
Thinking (38)
한글 (30)
PaperCraft (5)
Animation (408)
Wallpaper (2)
재테크 (18)
Exercise (3)
나만의 맛집 (3)
냥이 (10)
육아 (16)
Total
Today
Yesterday

어제 프로젝트 관련된 코딩을 하다가 난수를 써야 할 일이 있어서
C#의 Random Class에 관해 알아 보았다!

사실 Random Class의 사용방법은 그리 복잡하지도 어렵지도 않지만;
내가 만들고 싶은 난수가 적절히 만들어 지지 않아 몇시간을 테스트한김에
이와 관련된 포스팅을 하게 되었다;

예전 C언어나 C++의 rand() 함수를 사용할때는

int random = rand()%50;
위의 코드를 수행하게 되면 random 변수에는 에는 0부터 49까지 난수가 들어가게 된다;
rand()에sms seed 값이 있어 저렇게만 수행할 경우
만약 랜덤한 수가 1 3 6 2 6 순으로 나왔다면; 프로그램을 껏다 켜도 똑같은 패턴으로 나오게 된다;
그래서 아래의 항목을 추가하게 되면 그것을 막을 수 있었다;

srand(time(NULL)); // 시간에 따른 난수 발생, 없을경우 실행때마다 같은 난수가 발생한다.


이제 C# 의 Random Class를 보자;

사용법 정말 간단하다;

Random r  = new Random();

생성자는 오버로딩 되어있어 생성시 시드값을 정할수 있고! 정하지 않을수 있다;

정할경우 위에 말한대로 계속 똑같은 패턴의 난수가 발생하며 디폴트일 경우에는 시스템의 시간을 이용하여 
시드값을 정하기 때문에 매번 다른 패턴의 난수
가 발생한다;

제공하는 매소드를 알아보자;

r.Next() : 범위가 없는 랜덤한 값을 리턴한다
r.Next(int maxValue) : 난수의 범위의 상한을 지정
r.Next(int minValue, int maxValue) : 난수의 범위의 하한과 상한을 지정!


여기서 중요한것은 난수의 하한은 난수에 포함 되지만 상한은 포함 되지 않는다는것이다;
즉 1부터 10의 값을 난수로 얻고 싶을때 Next(1,10); 을 호출하면 10은 죽어도 안나온다는 말인다;;
10을 난수로 얻고 싶다면 Next(1,11)을 호출 해야한다;

그외에
r.NextBytes()
r.NextDouble() 
메소드가 있는데 int값만 필요해서 사용하지는 않았지만 메소드 명으로 쉽게 짐작 할수 있다;

이제 본론으로 들어가서 이렇게 간단한 Random Class의 사용방법을  포스팅을 하게 된 이유는
내가 발생하고 싶은 난수가 특정시간에 여러개의 객체를 생성할때 각각의 객체마다 다른 
난수를 가지고 있게 하고 싶었지만 Seed값을 기본적으로 시간을 사용하기 때문에 
할수가 없어서이다;

다음의 예제를 보면;
class Program
{
        static void Main(string[] args)
        {
            for (int i = 0; i < 10; i++)
            {
                Item item = new Item();
            }
        }
}

class Item
{
        int num1;
        int num2;
        public Item()
        {
            Random r = new Random();
            num1 = r.Next(1, 100);
            num2 = r.Next(100, 200);
            Console.WriteLine("{0} , {1}", num1, num2);
        }
}



매우 간단한 구조이다 Main()에서는 Item 객체를 10개 만들고 
Item 객체의 생성자에서는 난수를 2개 (각각 1~99, 100~199 범위의 값) 발생시켜
출력한다;

어떤 결과가 나올까? 10개의 객체는 각각 다른 난수를 가지고 있을까?

-- 실행 결과 --

결과처럼 '아니오' 이다; 

이와 같은 발생의 이유는 기본적으로 난수발생의 시드가 시간이기 떄문이다;
위에 예제처럼 빠르게 10개의 객체를 생성할 경우 시드가 같아져 같은 결과가 나오는것이다;

어떻게 해결할까?

밑의 두가지 예제의 차이를 알게되면 쉽게 해결 가능하다;
예제1)
Random
r = new Random();
for (int i = 0; i < 10; i++)
{
     Console.WriteLine("{0}", r.Next());               
}

예제2)
for (int i = 0; i < 10; i++)
{
     Random r = new Random();
     Console.WriteLine("{0}", r.Next());
}

--결과 화면--


화면에서 보다싶이 Random 객체를 빠르게 10번 생성한 예제 2에서는  같은 번호가 나왔고
객체를 재사용한 예제1에서는 다른 결과가 나왔다;


이 차이를 이용해 위에서 실패한 Item class에 랜덤한값을 배치 할수 있는것이다;

Random 객체를 static으로 두고 하나만 계속 사용한다면 위의 예제도 우리가 원하는 난수를 갖게 될것이다;


출처 : http://crynut84.tistory.com/15

반응형

'Programming > C#' 카테고리의 다른 글

이펙티브 C# - 요점 정리  (0) 2010.07.19
Form Show()/Hide()  (0) 2010.07.19
화살표 그리기(.NET Pen Class)  (0) 2010.07.16
.NET 중복 실행 방지  (0) 2010.07.16
App.Config XML읽고 쓰기..  (0) 2010.07.15
Posted by blueasa
, |