2009-09-29 4 views
5

좋아요. 주사위를 던지려면 ...C# 코드는 단계별로 예상 결과 만 제공합니까?

코드를 단계별로 실행하면 정상적으로 작동하며 '결과'에 정확한 수의 결과가 포함되어 있으며 코드를 남겨 둘 때 임의로 표시됩니다. 똑같은 번호를 만들어 낸 것과 똑같은 일을합니다.

나는 이것이 볼 수없는 논리적 오류라고 확신하지만 몇 시간 동안은 그다지 신경 쓰지 않아도 상황이 개선되지 않으므로 도움이 많이 필요하다. :)

class Dice 
{ 

    public int[] Roll(int _throws, int _sides, int _count) 
    { 
     Random rnd = new Random(); 
     int[] results = new int[_throws]; 
     // for each set of dice to throw pass data to calculate method 
     for (int i = 0; i < _throws; i++) 
     { 
      int thisThrow = Calculate(_sides, _count); 
      //add each throw to a new index of array... repeat for every throw 
      results[i] = thisThrow; 
     } 

     return results; 
    } 


    private int Calculate(int _sides, int _count) 
    { 
     Random rnd = new Random(); 
     int[] result = new int[_count]; 
     int total = 0; 
     //for each dice to throw put data into result 
     for (int i = 0; i < _count; i++) 
     { 
      result[i] = rnd.Next(1, _sides); 
     } 
     //count the values in result 
     for (int x = 0; x < _count; x++) 
     { 
      total = total + result[x]; 
     } 
     //return total of all dice to Roll method 
     return total; 
    } 
} 

답변

12

첫 번째 실수 : 단일 인스턴스를 사용하고, 통과, 임의의 여러 인스턴스를 사용하지 마십시오 그 다른 매개 변수와 함께.

+0

감사 수정 :) – Yoda

+0

젠장 빨리 그려! –

+1

@Ian : 나는 이것을 즉시 발견하지 못하여 너무 많은 일이 일어나는 것을 보았습니다. – leppie

-1

생성자에게 임의의 시드를 지정합니다. 그것이 문제이다.

http://msdn.microsoft.com/en-us/library/aa329890%28VS.71%29.aspx

Random r = new Random(DateTime.Now.Millisecond); 
+2

밀리 초를 시드로 사용하는 것이 기본값 인 틱보다 훨씬 나쁩니다. 진드기 씨드는 대부분 다른 경우처럼 Random 클래스를 다시 생성하지 않기 때문에 다시 동일한 값으로 다시 시드합니다. –

+0

Ah. 나는 C 스타일의 랜드 함수에 익숙하다. –

5

"임의의 rnd = 새 임의();" 그것은 현재 시간에 의해 파종된다. 시간이 걸리는 코드를 디버깅 할 때마다 매번 다르게 시드됩니다.

무작위로 1 인스턴스를 만들고 모든 곳에서 참조하십시오.

1

숫자를 만들 때마다 임의의 클래스를 만듭니다. 이렇게하면 열매 맺는 결과를 얻을 수 있습니다.

는 여기를 참조하십시오 : FROM MSDN

이 문제는 여러 사람이 아니라 하나의 임의의 객체를 생성 방지 할 수 있습니다.

성능을 향상 시키려면 하나의 임의 번호를 생성하기 위해 새로운 임의 개체를 반복적으로 만드는 대신 하나의 임의 개체를 만들어 시간 경과에 따라 많은 난수를 생성하십시오.

예. 등 무작위 이미지를 선택 주사위, 카드 게임 같은 것들에 대한 ... 앞서 언급 된 내용 외에도

1

...

를 사용하여 랜덤를 임의의 개인 인스턴스를 만듭니다. 보안을 위해 임의의 숫자를 생성해야하는 경우 System.Security.Cryptography.RandomNumberGenerator를 사용하십시오. 이 간단한 예제에서는 임의의 정수를 만드는 방법을 보여줍니다.

 RandomNumberGenerator gen = RandomNumberGenerator.Create(); 
     byte[] myBytes = new byte[4]; 
     gen.GetBytes(myBytes); 
     int myValue = (BitConverter.ToInt32(myBytes, 0)); 

보안이 필요한 경우가 아니면 이것을 사용하지 마십시오. 성능은 Random 클래스의 성능보다 작습니다. 나는 당신이 무작위로 씨앗을 뿌리기 위해 이것을 사용할 수 있다고 생각하지만 과잉이라고 할 수 있습니다.

편집 : 내가 이것을 테스트 한 적이 없다는 것이 나에게 발생했습니다. 빠른 성능 테스트는 다음을 보여주었습니다.

1,000,000 임의의 숫자 : RandomNumberGenerator : 2.6 초 랜덤 : .015 초.

그래서 무작위는 약 150 배 빠릅니다.

+2

두 가지. 첫째, 임의의 숫자를 사용하여 의사 난수 생성기를 시드해도 사실상 더 많은 임의성을 얻지는 못합니다. 의사 -RNG의 출력은 여전히 ​​예측 가능하다. –

+1

둘째, 암호화 강도 RNG의 성능은 수행해야 할 수학뿐만 아니라 RNG가 작동하기위한 엔트로피 *를 제공하는 기계의 능력에 따라 제어됩니다. RNG는 엔트로피를 아무것도 만들지 않습니다. 엔트로피는 어딘가에서 나왔고, 엔트로피는 대역폭, 메모리 또는 프로세서 시간과 같은 제한된 리소스로서 모든 것입니다. 초당 엔트로피가 너무 많습니다. 거대한 양의 엔트로피를 사용하려는 시도는 프로세서 또는 네트워크 대역폭 블록을 사용하려는 시도처럼 더 많은 엔트로피가 사용 가능할 때까지 차단됩니다. –

관련 문제