Advertisement
Guest User

dicetest final

a guest
Sep 21st, 2011
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.99 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <math.h>
  3. #include <time.h>
  4. #include <stdlib.h>
  5. #include <limits.h>
  6.  
  7.  
  8. #define DIFF 0 // difficulty to cast spell, >=0
  9. #define BACKLASH 0 // 1=backlashing spells, 0=no
  10. #define ACING_DICE // if defined, dice can ace
  11. //#define OUTPUT_CSV // if defined, output will be CSV format
  12.  
  13.  
  14. #define MAX_T 40 // maximum toughness
  15. #define DICETHROWS 1000000 // number of dicethrows, should be <UINT_MAX
  16. #define DIV (DICETHROWS/1000) //output values in per mill
  17.  
  18.  
  19.  
  20. typedef struct dres_s
  21. {
  22.     unsigned backlash;
  23.     unsigned nosuccess;
  24.     unsigned shaken;
  25.     unsigned wounded;
  26. } dres_t;
  27.  
  28.  
  29.  
  30. /********************
  31.  * Rolls a dice with a specified number of sides. If ACING_DICE is
  32.  * defined, dice can ace. Do not call with sides<=1.
  33.  * Be aware that on some systems, the use of rand() with the % operator
  34.  * can result in bad random numbers.
  35.  ********************/
  36. unsigned diceroll(unsigned sides)
  37. {
  38.     unsigned ret = 0;
  39.     unsigned roll = 0;
  40.  
  41.     if (sides <= 1) return 0;
  42.  
  43.     #ifdef ACING_DICE
  44.     do
  45.     {
  46.         roll = rand() % sides +1;
  47.         if (UINT_MAX - ret < roll) return UINT_MAX;
  48.         else ret += roll;
  49.     } while (roll == sides);
  50.     #else
  51.     ret = rand() % sides +1;
  52.     #endif
  53.  
  54.     return ret;
  55. }
  56.  
  57.  
  58.  
  59. /********************
  60.  * Roll damage, e.g. dmgroll(6,3) rolls 3d6.
  61.  ********************/
  62. unsigned dmgroll(unsigned sides,unsigned num)
  63. {
  64.     unsigned ret = 0;
  65.     unsigned roll = 0;
  66.  
  67.     while (num--)
  68.     {
  69.         roll = diceroll(sides);
  70.         if (UINT_MAX - ret < roll) return UINT_MAX;
  71.         else ret += roll;
  72.     }
  73.  
  74.     return ret;
  75. }
  76.  
  77.  
  78.  
  79. /********************
  80.  * Reset dice result counter
  81.  ********************/
  82. void dres_reset(dres_t* dr)
  83. {
  84.     dr->backlash = 0;
  85.     dr->nosuccess = 0;
  86.     dr->shaken = 0;
  87.     dr->wounded = 0;
  88. }
  89.  
  90.  
  91.  
  92. /********************
  93.  * Main function. Sets spellcasting (d4 - d12) and toughness (1 - MAX_T)
  94.  * and rolls the spellcasting throw and damage DICETHROWS times per
  95.  * spellcasting die and toughness value, for each bolt variant (3x 2d6
  96.  * and 3d6).
  97.  * Output will be how many times the throw result was shaken,
  98.  * wounded (>=1 wounds), no success or a critical miss. Backlashing
  99.  * will be interpreted as critical miss, if enabled. Critical misses
  100.  * result in no damage dealt.
  101.  ********************/
  102. int main(int argc, char *argv[])
  103. {
  104.     unsigned i,j;
  105.     unsigned spellcasting;
  106.     unsigned roll_1,roll_2,roll_3,roll_wc;
  107.     dres_t multiple,strong;
  108.  
  109.     srand ( time (NULL) );
  110.  
  111.     // print header
  112.     printf("dicetest program. results for 3x2d6/3d6 are:\n\n");
  113.     #ifdef OUTPUT_CSV
  114.     printf("spellcasting,toughness,%% no success 3x2d6,%% shaken 3x2d6,%% wounded 3x2d6,critical miss 3x2d6,%% no success 3d6,%% shaken 3d6,%% wounded 3d6,critical miss 3d6\n");
  115.     #else
  116.     printf(" spellc. | toughness | %% no success |  %% shaken   |  %% wounded  | critical miss\n\n");
  117.     #endif
  118.  
  119.     // calc stuff
  120.     for (spellcasting = 4; spellcasting<=12; spellcasting+=2)
  121.     {
  122.         for (i=1; i<=MAX_T; ++i)
  123.         {
  124.             // reset
  125.             dres_reset(&multiple);
  126.             dres_reset(&strong);
  127.  
  128.             for (j=0; j<DICETHROWS; ++j)
  129.             {
  130.                 // 3x 2d6
  131.  
  132.                 // roll spellcasting dice
  133.                 roll_1 = diceroll(spellcasting);
  134.                 roll_2 = diceroll(spellcasting);
  135.                 roll_3 = diceroll(spellcasting);
  136.                 roll_wc = diceroll(6);
  137.  
  138.                 // backlash?
  139.                 if ( ((BACKLASH)||(roll_wc==1)) &&
  140.                      ((roll_1==1)||(roll_2==1)||(roll_3==1)) )
  141.                 {
  142.                     multiple.backlash++;
  143.                     multiple.nosuccess++;
  144.                 }
  145.                 else
  146.                 {
  147.                     // replace wild die
  148.                     if (    (roll_1<roll_wc) &&
  149.                             (roll_1<roll_2) &&
  150.                             (roll_1<roll_3) )
  151.                         roll_1 = roll_wc;
  152.                     else if (    (roll_2<roll_wc) &&
  153.                                 (roll_2<roll_3) )
  154.                         roll_2 = roll_wc;
  155.                     else if (roll_3<roll_wc)
  156.                         roll_3 = roll_wc;
  157.  
  158.                     // include DIFF
  159.                     roll_1 = roll_1 > DIFF ? roll_1 - DIFF : 0;
  160.                     roll_2 = roll_2 > DIFF ? roll_2 - DIFF : 0;
  161.                     roll_3 = roll_3 > DIFF ? roll_3 - DIFF : 0;
  162.  
  163.                     // roll damage
  164.                     if (roll_1 >= 8) roll_1 = dmgroll(6,3);
  165.                     else if (roll_1 >= 4) roll_1 = dmgroll(6,2);
  166.                     else roll_1 = 0;
  167.                     if (roll_2 >= 8) roll_2 = dmgroll(6,3);
  168.                     else if (roll_2 >= 4) roll_2 = dmgroll(6,2);
  169.                     else roll_2 = 0;
  170.                     if (roll_3 >= 8) roll_3 = dmgroll(6,3);
  171.                     else if (roll_3 >= 4) roll_3 = dmgroll(6,2);
  172.                     else roll_3 = 0;
  173.  
  174.                     // calc result
  175.                     if (roll_1 >= i+4) // wounded
  176.                     {
  177.                         multiple.wounded++;
  178.                     }
  179.                     else if (roll_1 >= i) // shaken +X
  180.                     {
  181.                         if (roll_2 >= i) multiple.wounded++;
  182.                         else multiple.shaken++;
  183.                     }
  184.                     else // no success yet
  185.                     {
  186.                         if (roll_2 >= i+4) // wounded
  187.                         {
  188.                             multiple.wounded++;
  189.                         }
  190.                         else if (roll_2 >= i) // shaken + X
  191.                         {
  192.                             if (roll_3 >= i) multiple.wounded++;
  193.                             else multiple.shaken++;
  194.                         }
  195.                         else // no success yet
  196.                         {
  197.                             if (roll_3 >= i+4) multiple.wounded++;
  198.                             else if (roll_3 >= i) multiple.shaken++;
  199.                             else multiple.nosuccess++;
  200.                         }
  201.                     }
  202.                 }
  203.  
  204.                 // 3d6
  205.  
  206.                 // spellcasting throw
  207.                 roll_1 = diceroll(spellcasting);
  208.                 roll_wc = diceroll(6);
  209.  
  210.                 // backlash?
  211.                 if ( ((BACKLASH)||(roll_wc==1)) && (roll_1==1) )
  212.                 {
  213.                     strong.backlash++;
  214.                     strong.nosuccess++;
  215.                 }
  216.                 else
  217.                 {
  218.                     // replace wild die
  219.                     if (roll_1 < roll_wc) roll_1 = roll_wc;
  220.  
  221.                     // include DIFF
  222.                     roll_1 = roll_1 > DIFF ? roll_1 - DIFF : 0;
  223.  
  224.                     // roll damage
  225.                     if (roll_1 >= 8) roll_1 = dmgroll(6,4);
  226.                     else if (roll_1 >= 4) roll_1 = dmgroll(6,3);
  227.                     else roll_1 = 0;
  228.  
  229.                     // calc result
  230.                     if (roll_1 >= i+4) strong.wounded++;
  231.                     else if (roll_1 >= i) strong.shaken++;
  232.                     else strong.nosuccess++;
  233.                 }
  234.             }
  235.  
  236.             // output
  237.             #ifdef OUTPUT_CSV
  238.             printf("%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n",
  239.                 spellcasting,i,
  240.                 multiple.nosuccess/DIV,multiple.shaken/DIV,
  241.                 multiple.wounded/DIV,multiple.backlash/DIV,
  242.                 strong.nosuccess/DIV,strong.shaken/DIV,
  243.                 strong.wounded/DIV,strong.backlash/DIV
  244.             );
  245.             #else
  246.             printf("    %2d   |     %2d    | %4d / %4d  | %4d / %4d | %4d / %4d | %4d / %4d\n",
  247.                 spellcasting, i,
  248.                 multiple.nosuccess/DIV, strong.nosuccess/DIV,
  249.                 multiple.shaken/DIV, strong.shaken/DIV,
  250.                 multiple.wounded/DIV, strong.wounded/DIV,
  251.                 multiple.backlash/DIV, strong.backlash/DIV
  252.             );
  253.             #endif
  254.         }
  255.     }
  256.  
  257.     return 0;
  258. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement