簡體   English   中英

違反訪問權限?

[英]Access violation?

我試圖編寫一個簡單的蒙特卡洛模擬程序。 確切地說,我想根據在進攻和防御上不同的軍隊規模來分析戰斗結果-與此類似: http : //en.wikipedia.org/wiki/Risk_(game)#Dice_probabilities

現在……Risk II同一時間規則帶來了不同類型的挑戰:不同的軍隊規模意味着不同的骰子顏色(這意味着數字的分布函數不同)簡而言之,您的軍隊規模越小,您越可能結局為1秒,而軍隊規模越大,結局的可能性就越大。

由於對所有可能的條件使用if語句在最大程度上是一個巨大的愚蠢,因此我將所有可能的滾動結果列表在5x12數組中。 (所有骰子中有12面,而強度各有5面,因此您得到5x12)

我本來打算為每種進攻/防守組合進行10000次模擬,但是一旦我意識到這意味着要進行超過900萬次計算,我決定將其簡化為每個組合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);

}

您的密碼

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);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM