2012-03-24 2 views
0

간단한 몬테카를로 시뮬레이션 프로그램을 작성하려고했습니다. 정확히 말하면, 공격과 방어 모두에서 군대 규모에 따라 전투 결과를 분석하고 싶었습니다. - http://en.wikipedia.org/wiki/Risk_(game)#Dice_probabilities액세스 위반이 있습니까?

지금 ... 위험 2 같은 시간 규칙은 다양한 종류의 도전 과제를 제공합니다. 군대 크기는 주사위의 다른 색깔을 의미합니다 (숫자에 대한 다른 분포 함수를 의미 함). 즉, 군대의 크기가 작을수록 군대의 크기가 클수록 1로 끝날 가능성이 높습니다. 더 많은 수의 롤로 끝날 가능성이 높습니다.

가능한 모든 조건에 대해 if 문을 사용하는 것이 가장 훌륭한 어리 석음 이었기 때문에 가능한 모든 롤링 결과를 5x12 배열로 집계했습니다. (모든 주사위에 12면, 5 가지 변화 강도가 있으므로 5x12가됩니다.)

각 공격/방어 조합마다 10000 개의 시뮬레이션을 수행 할 것을 생각했지만 9 백만 건이 넘는 계산을한다는 것을 깨달았을 때 콤비네이션 당 100을 줄이면된다.

다음은 코드입니다. 한번 실행하면 액세스 위반 오류가 발생합니다. 내가 어디서 실수를했는지 모르겠다. 당신이 제공 할 수있는 조언이 있다면, 나는 또한 그것을 감사 할 것입니다. 미리 감사드립니다.

/* Risk II Combat Result Table 

For starter, we shall consider one-direction attack in RISK II 
and generate the combat table for use. 

Machine: Pentium Dual Core E6600 
Ram: 6G 
OS: Windows 7 
Compiler: Visual Studio 2010 

Jimmy Smith, 24-March-2012 

*/ 

#include <cstdio> 
#include <cstdlib> 
#include <cmath> 

#include <iostream> 
#include <algorithm> 
using namespace std; 

/* Initializing: 

    Range legend: 

White = 1 ~ 6 
Yellow = 7 ~ 12 
Orange = 13 ~ 20 
Red = 21 ~ 30 
Black = 31 ~ 

First row of Dice array corresponds to white dice, and so on. 

*/ 

int Dice[5][12] = { {1, 1, 1, 1, 2, 2, 2, 3, 3, 4, 5, 6}, 
        {1, 1, 2, 2, 2, 2, 3, 3, 4, 4, 5, 6}, 
        {1, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 6}, 
        {1, 2, 3, 3, 4, 4, 5, 5, 5, 5, 6, 6}, 
        {1, 2, 3, 4, 4, 5, 5, 5, 6, 6, 6, 6} }; 

int Roll_Index [30]= {0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4}; 


int main() { 

float Table[30][30]; 

for (int i = 0; i < 30; i ++) 
    for (int j = 0; j < 30; j ++) 
     Table [i][j] = 0.0; 

int Result[100]; 

for (int i = 0; i < 100; i++) Result[i] = 0;  

float prob = 0.0; 

int Atk = 0; 
int Def = 0; //Number of attackers and defenders 


int A_Ind = 0; 
int D_Ind = 0; //Dice side index 

int A_Roll_Index = 0; 
int D_Roll_Index = 0; //Roll index on both sides 

int A_Dice = 0; 
int D_Dice = 0; //Roll result 

int Damage = 0; 

int Sum = 0; //Internal sum 

FILE* fp; 


//Time for hard core Monte-Carlo shit! 100 simulation for each situation 

for (Atk = 0; Atk<30; Atk++) { 

    for (Def = 0; Def < 30; Def++) { 

     for (int i = 0; i < 100; i++) { 

      int Attacker = Atk +1; 
      int Defender = Def +1; 

      while((Attacker>0)&&(Defender>0)) { 

       A_Ind = (int)(rand()*12); 
       D_Ind = (int)(rand()*12); //The die is cast! 

       A_Roll_Index = Roll_Index[Attacker-1]; 
       D_Roll_Index = Roll_Index[Defender-1]; 

       A_Dice = Dice[A_Roll_Index][A_Ind]; 
       D_Dice = Dice[D_Roll_Index][D_Ind]; 

       Damage = min(A_Roll_Index, D_Roll_Index) + 1; 

       if (A_Dice >= D_Dice) { 
        Defender -= Damage; 
        if (Defender == 0) Result[i] = 1; 
       } 
       else { 
        Attacker -= Damage; 
        if (Attacker == 0) Result[i] = 0; 
       } 
      } 
     } 

    for (int i = 0; i < 100; i++) Sum+=Result[i]; 

    prob = (float)(Sum/100); 

    Table[Atk][Def] = prob; 

    } 
} 
/* open new file for output and write a title */ 

fp = fopen("Combat.dat", "w+"); 

if(NULL == fp) { 
    printf("cannot open file\n"); 
    return(0); 
} 

for (Atk = 0; Atk < 30; Atk++){ 
    for (Def = 0; Def < 30; Def++) 
     fprintf(fp, "%16.8f", Table[Atk][Def]); 
    fprintf (fp, "\n"); 
} 
fclose(fp); 

return(EXIT_SUCCESS); 

}

+4

디버거에서 실행해야합니다. 그러면 오류의 원인이되는 코드 줄을 식별 할 수 있습니다. –

+0

int 결과 [100]; for (int i = 0; i <10000; i ++) 결과 [i] = 0; ? – inf

+1

여기 진짜 하드 코어 Monte-Carlo 똥이 있습니다. @ 밤비, 이제 모든 디버깅 재미를 망 쳤어. : – bzlm

답변

0

귀하의 코드

A_Ind = (int)(rand()*12); 
D_Ind = (int)(rand()*12); 

rand() 경우가 범위 [0,1) 숫자를 반환 생각하는 것을 나타냅니다. 대신 INT의 범위 [0, RAND_MAX]정수를 반환, 그래서 당신은 뭔가를해야

A_Ind = rand() * 12.0/RAND_MAX; 

시뮬레이션 통계적으로 정확해야하는 경우, <random> 라이브러리에서 난수 생성기와 떨어져 아마 더 나은 :

#include <random> 

typedef std::mt19937 rng_type; 
std::uniform_int_distribution<std::size_t> udist(0, 11); 

rng_type rng; 

// ... 

// seed rng first: 
rng.seed(some_seed_value); 

// roll dice 
std_size_t A_Ind = udist(rng), D_Ind = udist(rng); 
+0

정말 놀랍습니다. 결국 A & I는 범인이었다. 도와 주셔서 감사합니다. * 정말 기대하지 않았다 * –

관련 문제