The abbreviations used for the difficulties and the numbers in the form [d6]/[d10] are as follows:
Code: Select all
Easy EZ [ 2]/[ 4]
Moderate MO [ 4]/[ 6]
Challenging CG [ 6]/[10]
Difficult DF [ 8]/[14]
Very Difficult VD [10]/[16]
Extremely Difficult ED [12]/[20]
Nigh Impossible NI [15]/[25]
Code: Select all
#D EZ ( 2) MO ( 4) CG ( 6) DF ( 8) VD (10) ED (12) NI (15)
=========================================================================
-6 23.257% 0.391% 0.000% 0.000% 0.000% 0.000% 0.000%
-5 27.908% 0.781% 0.000% 0.000% 0.000% 0.000% 0.000%
-4 33.490% 1.563% 0.002% 0.000% 0.000% 0.000% 0.000%
-3 40.188% 3.125% 0.013% 0.000% 0.000% 0.000% 0.000%
-2 48.225% 6.250% 0.077% 0.000% 0.000% 0.000% 0.000%
-1 57.870% 12.500% 0.463% 0.000% 0.000% 0.000% 0.000%
0 69.444% 25.000% 2.778% 0.000% 0.000% 0.000% 0.000%
1 83.333% 50.000% 16.667% 0.000% 0.000% 0.000% 0.000%
2 97.222% 80.556% 38.889% 8.333% 5.556% 2.778% 0.000%
3 99.537% 93.981% 60.648% 22.685% 15.278% 8.333% 0.926%
4 99.923% 98.380% 77.855% 39.892% 27.623% 16.512% 3.318%
5 99.987% 99.601% 89.185% 56.970% 41.088% 26.800% 7.446%
6 99.998% 99.908% 95.413% 71.727% 54.345% 38.398% 13.351%
7 100.000% 99.980% 98.279% 83.031% 66.382% 50.366% 20.869%
8 100.000% 99.996% 99.416% 90.750% 76.556% 61.795% 29.663%
9 100.000% 99.999% 99.817% 95.437% 84.581% 71.959% 39.271%
10 100.000% 100.000% 99.947% 97.957% 90.480% 80.410% 49.161%
11 100.000% 100.000% 99.985% 99.162% 94.512% 86.998% 58.801%
12 100.000% 100.000% 99.996% 99.683% 97.058% 91.825% 67.726%
13 100.000% 100.000% 99.999% 99.888% 98.536% 95.148% 75.588%
14 100.000% 100.000% 100.000% 99.963% 99.323% 97.292% 82.185%
The results for the d10 dice pool are:
Code: Select all
#D EZ ( 4) MO ( 6) CG (10) DF (14) VD (16) ED (20) NI (25)
=========================================================================
-6 5.765% 0.391% 0.000% 0.000% 0.000% 0.000% 0.000%
-5 8.235% 0.781% 0.000% 0.000% 0.000% 0.000% 0.000%
-4 11.765% 1.563% 0.000% 0.000% 0.000% 0.000% 0.000%
-3 16.807% 3.125% 0.001% 0.000% 0.000% 0.000% 0.000%
-2 24.010% 6.250% 0.010% 0.000% 0.000% 0.000% 0.000%
-1 34.300% 12.500% 0.100% 0.000% 0.000% 0.000% 0.000%
0 49.000% 25.000% 1.000% 0.000% 0.000% 0.000% 0.000%
1 70.000% 50.000% 10.000% 0.000% 0.000% 0.000% 0.000%
2 93.000% 78.000% 24.000% 4.000% 3.000% 1.000% 0.000%
3 98.700% 91.500% 39.700% 11.400% 8.600% 3.100% 0.200%
4 99.790% 97.130% 54.980% 21.310% 16.270% 6.360% 0.760%
5 99.969% 99.159% 68.329% 32.703% 25.402% 10.777% 1.806%
6 99.996% 99.786% 78.986% 44.563% 35.362% 16.278% 3.433%
7 99.999% 99.952% 86.844% 56.006% 45.540% 22.719% 5.706%
8 100.000% 99.990% 92.230% 66.369% 55.401% 29.902% 8.659%
9 100.000% 99.998% 95.675% 75.239% 64.516% 37.580% 12.297%
10 100.000% 100.000% 97.736% 82.449% 72.588% 45.483% 16.593%
11 100.000% 100.000% 98.888% 88.028% 79.449% 53.341% 21.490%
The program (for anyone interested):
Code: Select all
/***********************************************************************
*
*N {ricochet.c} -- Calculate probabilities for Rocochet dice pools.
*
***********************************************************************/
#include <stdio.h>
#include <stdlib.h>
/* Types. */
typedef unsigned char RicoDie;
typedef int Bool;
typedef struct {
RicoDie *dice;
RicoDie dieSize;
int diceCount;
int actualDiceCount;
} RicoDicePool;
/* The following define is platform dependent. For instance on Windows, it
is __int64, and on some Unix platforms long int. */
#define Int64 long
/* Constants. */
#define TRUE (-1)
#define FALSE (0)
#define MAX_DIE_SIZE 256
#define DIFFICULTY_COUNT 7
#define MIN_DICE_POOL -6
#define MAX_DICE_POOL 14
/* Utility macros. */
#define ACTUAL_COUNT(count) ((count > 0) ? count : (-count + 2))
/* Fixed data. */
static const char *DifficultyLabels[] = {"Easy",
"Moderate",
"Challenging",
"Difficult",
"Very Difficult",
"Extremely Difficult",
"Nigh Impossible"};
static const char *DifficultyTags[] = {"EZ","MO","CG","DF","VD","ED","NI"};
static const int DifficultyLevels6[] = {2,4,6,8,10,12,15};
static const int DifficultyLevels10[] = {4,6,10,14,16,20,25};
/***********************************************************************
*
*N {CreatePool} -- Create a dice pool, all initialized to 1's
*
***********************************************************************/
RicoDicePool * CreatePool (RicoDie size,
int count)
{
int actualCount,d;
RicoDicePool *pool;
/* Deal with dice counts < 1. */
actualCount = ACTUAL_COUNT (count);
/* Allocate structures. */
pool = (RicoDicePool *)malloc (sizeof(RicoDicePool));
if (!pool) return NULL;
pool->dice = malloc (sizeof(RicoDie) * actualCount);
if (!pool->dice) return NULL;
/* Initialize values. */
for (d = 0;d < actualCount;d++) pool->dice[d] = 1;
pool->dieSize = size;
pool->diceCount = count;
pool->actualDiceCount = actualCount;
/* Done. */
return pool;
}
/***********************************************************************
*
*N {FreePool} -- Free a dice pool.
*
***********************************************************************/
void FreePool (RicoDicePool *pool)
{
if (!pool) return;
if (pool->dice) free (pool->dice);
free (pool);
return;
}
/***********************************************************************
*
*N {IncrementPool} -- Increment a dice pool to the next value.
*
***********************************************************************/
Bool IncrementPool (RicoDicePool *pool)
{
int d;
for (d = 0;d < pool->actualDiceCount;d++) {
if (pool->dice[d] == pool->dieSize) {
if (d == (pool->actualDiceCount - 1)) return FALSE; /* Overflow! */
pool->dice[d] = 1;
} else {
pool->dice[d]++;
break;
}
}
return TRUE;
}
/***********************************************************************
*
*N {EvaluatePool} -- Determine the value of the supplied dice pool.
*
***********************************************************************/
int EvaluatePool (const RicoDicePool *pool)
{
int d,value,rollValue;
RicoDie dieCount[MAX_DIE_SIZE];
/* If there are zero or negative dice in the pool, just look for the lowest
value. */
if (pool->diceCount < 1) {
value = pool->dieSize;
for (d = 0;d < pool->actualDiceCount;d++)
if (pool->dice[d] < value) value = pool->dice[d];
}
/* Positive dice a bit trickier, since we need to detect multiple instances
of the same roll, so we'll count those first. (Multiple 1's don't count
so we don't add them up at the end.) */
else {
for (d = 1;d <= pool->dieSize;d++) dieCount[d] = 0;
for (d = 0;d < pool->diceCount;d++) dieCount[pool->dice[d]]++;
value = 1;
for (d = 2;d <= pool->dieSize;d++) {
rollValue = dieCount[d] * d;
if (rollValue > value) value = rollValue;
}
}
return value;
}
/***********************************************************************
*
*N {PoolSuccessStats} -- Determine success percentages for a given pool size.
*
***********************************************************************/
Bool PoolSuccessStats (RicoDie size,
int count,
const int *difficulties,
double *successPercentages,
int difficultyCount)
{
RicoDicePool *pool;
int value,d;
Int64 *successes,totalTests;
/* Create the pool to test. */
pool = (RicoDicePool *) CreatePool (size,count);
if (!pool) return FALSE;
/* Initialize test values. */
successes = (Int64 *)calloc (difficultyCount,sizeof(Int64));
if (!successes) return FALSE;
totalTests = 0;
/* Loop through all possible values of the dice pool, and record which ones
succeeded. */
do {
value = EvaluatePool (pool);
for (d = 0;d < difficultyCount;d++)
if (value >= difficulties[d]) successes[d]++;
totalTests++;
} while (IncrementPool (pool));
FreePool (pool);
/* Calculate percentages. */
for (d = 0;d < difficultyCount;d++)
successPercentages[d] = (double)successes[d] / (double)totalTests * 100.0;
free (successes);
return TRUE;
}
/***********************************************************************
*
*N {Main} -- Main function
*
***********************************************************************/
int main (int argc, char *argv[])
{
int poolSize,d;
double successPercentages[DIFFICULTY_COUNT];
/* Print Header and terms. */
printf ("Calculate success chances for Ricochet Dice Pools\n");
printf ("=================================================\n");
for (d = 0;d < DIFFICULTY_COUNT;d++)
printf ("%-24s %2s [%2d]/[%2d]\n",DifficultyLabels[d],DifficultyTags[d],
DifficultyLevels6[d],DifficultyLevels10[d]);
printf ("\nCalculate D6's\n");
printf ("\n#D %2s (%2d) %2s (%2d) %2s (%2d) %2s (%2d) %2s (%2d)"
" %2s (%2d) %2s (%2d)\n",
DifficultyTags[0],DifficultyLevels6[0],
DifficultyTags[1],DifficultyLevels6[1],
DifficultyTags[2],DifficultyLevels6[2],
DifficultyTags[3],DifficultyLevels6[3],
DifficultyTags[4],DifficultyLevels6[4],
DifficultyTags[5],DifficultyLevels6[5],
DifficultyTags[6],DifficultyLevels6[6]);
printf ("=================================================================="
"=======\n");
/* Print Calculations. */
for (poolSize = MIN_DICE_POOL;poolSize <= MAX_DICE_POOL;poolSize++) {
if (PoolSuccessStats (6,poolSize,DifficultyLevels6,successPercentages,
DIFFICULTY_COUNT)) {
printf ("%2d %7.3f%% %7.3f%% %7.3f%% %7.3f%% %7.3f%% %7.3f%% "
"%7.3f%%\n",
poolSize,
successPercentages[0],
successPercentages[1],
successPercentages[2],
successPercentages[3],
successPercentages[4],
successPercentages[5],
successPercentages[6]);
fflush (stdout);
}
}
printf ("\n\nCalculate D10's\n");
printf ("\n#D %2s (%2d) %2s (%2d) %2s (%2d) %2s (%2d) %2s (%2d)"
" %2s (%2d) %2s (%2d)\n",
DifficultyTags[0],DifficultyLevels10[0],
DifficultyTags[1],DifficultyLevels10[1],
DifficultyTags[2],DifficultyLevels10[2],
DifficultyTags[3],DifficultyLevels10[3],
DifficultyTags[4],DifficultyLevels10[4],
DifficultyTags[5],DifficultyLevels10[5],
DifficultyTags[6],DifficultyLevels10[6]);
printf ("=================================================================="
"=======\n");
/* Print Calculations. */
for (poolSize = MIN_DICE_POOL;poolSize <= MAX_DICE_POOL;poolSize++) {
if (PoolSuccessStats (10,poolSize,DifficultyLevels10,successPercentages,
DIFFICULTY_COUNT)) {
printf ("%2d %7.3f%% %7.3f%% %7.3f%% %7.3f%% %7.3f%% %7.3f%% "
"%7.3f%%\n",
poolSize,
successPercentages[0],
successPercentages[1],
successPercentages[2],
successPercentages[3],
successPercentages[4],
successPercentages[5],
successPercentages[6]);
fflush (stdout);
}
}
return EXIT_SUCCESS;
}