Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <math.h>
- #include <time.h>
- #include <stdlib.h>
- #include <limits.h>
- #define DIFF 0 // difficulty to cast spell, >=0
- #define BACKLASH 0 // 1=backlashing spells, 0=no
- #define ACING_DICE // if defined, dice can ace
- //#define OUTPUT_CSV // if defined, output will be CSV format
- #define MAX_T 40 // maximum toughness
- #define DICETHROWS 1000000 // number of dicethrows, should be <UINT_MAX
- #define DIV (DICETHROWS/1000) //output values in per mill
- typedef struct dres_s
- {
- unsigned backlash;
- unsigned nosuccess;
- unsigned shaken;
- unsigned wounded;
- } dres_t;
- /********************
- * Rolls a dice with a specified number of sides. If ACING_DICE is
- * defined, dice can ace. Do not call with sides<=1.
- * Be aware that on some systems, the use of rand() with the % operator
- * can result in bad random numbers.
- ********************/
- unsigned diceroll(unsigned sides)
- {
- unsigned ret = 0;
- unsigned roll = 0;
- if (sides <= 1) return 0;
- #ifdef ACING_DICE
- do
- {
- roll = rand() % sides +1;
- if (UINT_MAX - ret < roll) return UINT_MAX;
- else ret += roll;
- } while (roll == sides);
- #else
- ret = rand() % sides +1;
- #endif
- return ret;
- }
- /********************
- * Roll damage, e.g. dmgroll(6,3) rolls 3d6.
- ********************/
- unsigned dmgroll(unsigned sides,unsigned num)
- {
- unsigned ret = 0;
- unsigned roll = 0;
- while (num--)
- {
- roll = diceroll(sides);
- if (UINT_MAX - ret < roll) return UINT_MAX;
- else ret += roll;
- }
- return ret;
- }
- /********************
- * Reset dice result counter
- ********************/
- void dres_reset(dres_t* dr)
- {
- dr->backlash = 0;
- dr->nosuccess = 0;
- dr->shaken = 0;
- dr->wounded = 0;
- }
- /********************
- * Main function. Sets spellcasting (d4 - d12) and toughness (1 - MAX_T)
- * and rolls the spellcasting throw and damage DICETHROWS times per
- * spellcasting die and toughness value, for each bolt variant (3x 2d6
- * and 3d6).
- * Output will be how many times the throw result was shaken,
- * wounded (>=1 wounds), no success or a critical miss. Backlashing
- * will be interpreted as critical miss, if enabled. Critical misses
- * result in no damage dealt.
- ********************/
- int main(int argc, char *argv[])
- {
- unsigned i,j;
- unsigned spellcasting;
- unsigned roll_1,roll_2,roll_3,roll_wc;
- dres_t multiple,strong;
- srand ( time (NULL) );
- // print header
- printf("dicetest program. results for 3x2d6/3d6 are:\n\n");
- #ifdef OUTPUT_CSV
- printf("spellcasting,toughness,%% no success 3x2d6,%% shaken 3x2d6,%% wounded 3x2d6,critical miss 3x2d6,%% no success 3d6,%% shaken 3d6,%% wounded 3d6,critical miss 3d6\n");
- #else
- printf(" spellc. | toughness | %% no success | %% shaken | %% wounded | critical miss\n\n");
- #endif
- // calc stuff
- for (spellcasting = 4; spellcasting<=12; spellcasting+=2)
- {
- for (i=1; i<=MAX_T; ++i)
- {
- // reset
- dres_reset(&multiple);
- dres_reset(&strong);
- for (j=0; j<DICETHROWS; ++j)
- {
- // 3x 2d6
- // roll spellcasting dice
- roll_1 = diceroll(spellcasting);
- roll_2 = diceroll(spellcasting);
- roll_3 = diceroll(spellcasting);
- roll_wc = diceroll(6);
- // backlash?
- if ( ((BACKLASH)||(roll_wc==1)) &&
- ((roll_1==1)||(roll_2==1)||(roll_3==1)) )
- {
- multiple.backlash++;
- multiple.nosuccess++;
- }
- else
- {
- // replace wild die
- if ( (roll_1<roll_wc) &&
- (roll_1<roll_2) &&
- (roll_1<roll_3) )
- roll_1 = roll_wc;
- else if ( (roll_2<roll_wc) &&
- (roll_2<roll_3) )
- roll_2 = roll_wc;
- else if (roll_3<roll_wc)
- roll_3 = roll_wc;
- // include DIFF
- roll_1 = roll_1 > DIFF ? roll_1 - DIFF : 0;
- roll_2 = roll_2 > DIFF ? roll_2 - DIFF : 0;
- roll_3 = roll_3 > DIFF ? roll_3 - DIFF : 0;
- // roll damage
- if (roll_1 >= 8) roll_1 = dmgroll(6,3);
- else if (roll_1 >= 4) roll_1 = dmgroll(6,2);
- else roll_1 = 0;
- if (roll_2 >= 8) roll_2 = dmgroll(6,3);
- else if (roll_2 >= 4) roll_2 = dmgroll(6,2);
- else roll_2 = 0;
- if (roll_3 >= 8) roll_3 = dmgroll(6,3);
- else if (roll_3 >= 4) roll_3 = dmgroll(6,2);
- else roll_3 = 0;
- // calc result
- if (roll_1 >= i+4) // wounded
- {
- multiple.wounded++;
- }
- else if (roll_1 >= i) // shaken +X
- {
- if (roll_2 >= i) multiple.wounded++;
- else multiple.shaken++;
- }
- else // no success yet
- {
- if (roll_2 >= i+4) // wounded
- {
- multiple.wounded++;
- }
- else if (roll_2 >= i) // shaken + X
- {
- if (roll_3 >= i) multiple.wounded++;
- else multiple.shaken++;
- }
- else // no success yet
- {
- if (roll_3 >= i+4) multiple.wounded++;
- else if (roll_3 >= i) multiple.shaken++;
- else multiple.nosuccess++;
- }
- }
- }
- // 3d6
- // spellcasting throw
- roll_1 = diceroll(spellcasting);
- roll_wc = diceroll(6);
- // backlash?
- if ( ((BACKLASH)||(roll_wc==1)) && (roll_1==1) )
- {
- strong.backlash++;
- strong.nosuccess++;
- }
- else
- {
- // replace wild die
- if (roll_1 < roll_wc) roll_1 = roll_wc;
- // include DIFF
- roll_1 = roll_1 > DIFF ? roll_1 - DIFF : 0;
- // roll damage
- if (roll_1 >= 8) roll_1 = dmgroll(6,4);
- else if (roll_1 >= 4) roll_1 = dmgroll(6,3);
- else roll_1 = 0;
- // calc result
- if (roll_1 >= i+4) strong.wounded++;
- else if (roll_1 >= i) strong.shaken++;
- else strong.nosuccess++;
- }
- }
- // output
- #ifdef OUTPUT_CSV
- printf("%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n",
- spellcasting,i,
- multiple.nosuccess/DIV,multiple.shaken/DIV,
- multiple.wounded/DIV,multiple.backlash/DIV,
- strong.nosuccess/DIV,strong.shaken/DIV,
- strong.wounded/DIV,strong.backlash/DIV
- );
- #else
- printf(" %2d | %2d | %4d / %4d | %4d / %4d | %4d / %4d | %4d / %4d\n",
- spellcasting, i,
- multiple.nosuccess/DIV, strong.nosuccess/DIV,
- multiple.shaken/DIV, strong.shaken/DIV,
- multiple.wounded/DIV, strong.wounded/DIV,
- multiple.backlash/DIV, strong.backlash/DIV
- );
- #endif
- }
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement