Probability in Char. Gen.

Gene, in your other thread I actually did brute force it (albeit not with taking out the hopeless characters because I tried to do that and realised it would take something in the 10^18 calculations) and got 25.467592 (with the 592 repeating).
 

log in or register to remove this ad


Rystil Arden said:
Gene, in your other thread I actually did brute force it (albeit not with taking out the hopeless characters because I tried to do that and realised it would take something in the 10^18 calculations) and got 25.467592 (with the 592 repeating).

Above (Post #7) are the numbers for 4d6dl as PB value without removing worthless characters (both with 3-7 counts as 0 points and -5 to -1 points).

The result is 29.134 (if all scores of 8 or lower count as 0 PB) and 28.546 (if scores below 8 count as -1, -2, -3, -4 and -5 PB respectively).

Bye
Thanee
 

Thanee said:
Above (Post #7) are the numbers for 4d6dl as PB value without removing worthless characters (both with 3-7 counts as 0 points and -5 to -1 points).

The result is 29.134 (if all scores of 8 or lower count as 0 PB) and 28.546 (if scores below 8 count as -1, -2, -3, -4 and -5 PB respectively).

Bye
Thanee
Oh, I was calculating the Point Buy of the average character, which is what Gene asked for in the first post. Those numbers are correct for the average Point Buy integral, rather than the Point Buy of the average. Even better, then.
 

I haven't done programming in 20 years, but in programming language pastiche I think it would look something like this:

define function PBV(x)
if x<15 then PBV=x-8 [or whatever]
if x=15 then PBV=8
if x=16 then PBV=10
etc.

define function prob(x)
if x = 3 then prob = [something from dcollins]
if x = 4 then prob = [something from dcollins]
etc.

V = 0
P = 0

for str = 3 to 18
for dex = 3 to 18
for con = 3 to 18
for int = 3 to 18
for wis = 3 to 18
for chr = 3 to 18

if str<15 and dex<15 and con<15 and int<15 and wis<15 and chr<15 then next
if integer((str-10)/2)+integer((dex-10)/2)+integer((con-10)/2)+integer((int-10)/2)+integer((wis-10)/2)+integer((chr-10)/2) <1 then next

value = PBV(str)+PBV(dex)+PBV(con)+PBV(int)+PBV(wis)+PBV(chr)
probability = prob(str)*prob(dex)+prob(con)*prob(int)*prob(wis)*prob(chr)

V= V+value*probability
P=P+probability


next
next
next
next
next
next

Average =V/P


That's 16^6 loops, which should be doable. Did I miss anything?

-RedShirt
 


Charwoman Gene said:
The definition of "worthless" is +0 or lower total modifier, or no ability score above 14.
It probably doesn't need to be pointed out but I'll just mention that it should be "no ability score above 13" in case this is overlooked during all the math.

Otherwise please ignore, I'm much more interested in your results.
 

Well, I made a program in Java to try and roll up every character imaginable, and ditch the "worthless" ones (worthless being +0 or less total mods OR no score higher than 13).

It's running right now, and I've got it giving me a "status update" every 6^8 characters... They're roughly 1 second apart. Which I believe means it should take around 6^16 seconds, which is well over 700 MILLION hours.

Here's the code, if anyone wants to try to optimize it (I'm a java noob) or port it to a faster, native language...

Code:
package com.asmor.dnd4d6dlcalc;

public class dnd4d6dlcalc {

public static int getMod(int stat) {
    return (stat/2)-5;
}

public static int getStat(int die1, int die2, int die3, int die4) {
    int dice[]={0, 0, 0, 0, 0}, lowest, i, toReturn;
    dice[1]=die1;
    dice[2]=die2;
    dice[3]=die3;
    dice[4]=die4;
    lowest=1;
    for (i=1; i<5; i++) {
        if (dice[i]<dice[lowest]) {
            lowest=i;
        }
    }
    toReturn=0;
    for (i=1; i<5; i++) {
        if (lowest!=i) {
            toReturn+=dice[i];
        }
    }
    
    return toReturn;
}

public static void main(String[] args) {
int r01=0, r02=0, r03=0, r04=0, r05=0, r06=0, r07=0,r08=0, r09=0, r10=0, r11=0, r12=0, r13=0, r14=0, r15=0, r16=0, r17=0, r18=0, r19=0, r20=0, r21=0, r22=0, r23=0, r24=0;
int scores[]={0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, stats[]={0, 0, 0, 0, 0, 0, 0}, mods[]={0, 0, 0, 0, 0, 0, 0}, toss, i, totalMod;

for (r01=1; r01<7; r01++) {
for (r02=1; r02<7; r02++) {
for (r03=1; r03<7; r03++) {
for (r04=1; r04<7; r04++) {
for (r05=1; r05<7; r05++) {
for (r06=1; r06<7; r06++) {
for (r07=1; r07<7; r07++) {
for (r08=1; r08<7; r08++) {
for (r09=1; r09<7; r09++) {
for (r10=1; r10<7; r10++) {
for (r11=1; r11<7; r11++) {
for (r12=1; r12<7; r12++) {
for (r13=1; r13<7; r13++) {
for (r14=1; r14<7; r14++) {
for (r15=1; r15<7; r15++) {
for (r16=1; r16<7; r16++) {
for (r17=1; r17<7; r17++) {
for (r18=1; r18<7; r18++) {
for (r19=1; r19<7; r19++) {
for (r20=1; r20<7; r20++) {
for (r21=1; r21<7; r21++) {
for (r22=1; r22<7; r22++) {
for (r23=1; r23<7; r23++) {
for (r24=1; r24<7; r24++) {

    stats[0]=getStat(r01, r02, r03, r04);
    mods[0]=getMod(stats[0]);
    stats[1]=getStat(r05, r06, r07, r08);
    mods[1]=getMod(stats[1]);
    stats[2]=getStat(r09, r10, r11, r12);
    mods[2]=getMod(stats[2]);
    stats[3]=getStat(r13, r14, r15, r16);
    mods[3]=getMod(stats[3]);
    stats[4]=getStat(r17, r18, r19, r20);
    mods[4]=getMod(stats[4]);
    stats[5]=getStat(r21, r22, r23, r24);
    mods[5]=getMod(stats[5]);
    
    toss=1;
    for (i=0; i<6; i++) {
        if (stats[i]>13) {
            toss=0;
        }
    }
    totalMod=mods[0]+mods[1]+mods[2]+mods[3]+mods[4]+mods[5];
    if (totalMod<=0) {
        toss=1;
    }
    
    if (toss==0) {
        for (i=0; i<6; i++) {
            scores[stats[i]]++;
        }
    }

}}}}
}}}}
System.out.print(r01+" "+r02+" "+r03+" "+r04+" "+r05+" "+r06+" "+r07+" "+r08+" "+r09+" "+r10+" "+r11+" "+r12+" "+r13+" "+r14+" "+r15+" "+r16+" "+r17+" "+r18+" "+r19+" "+r20+" "+r21+" "+r22+" "+r23+" "+r24+"\n");
}}}}
}}}}
}}}}
}}}}

String outString="";

for (i=3; i<19; i++) {
    outString+=i+": "+scores[i]+"\n";
}

System.out.print(outString);

}
}
 

Asmor said:
Well, I made a program in Java to try and roll up every character imaginable, and ditch the "worthless" ones (worthless being +0 or less total mods OR no score higher than 13).

It's running right now, and I've got it giving me a "status update" every 6^8 characters... They're roughly 1 second apart. Which I believe means it should take around 6^16 seconds, which is well over 700 MILLION hours.

You can't optimize it. It will still take millions of hours. This is the brute force idea I posted originally.

My new method is to use the known probability of each number coming up to "weight" a stepping through of every possible character which brings the iterations down to 16^6, which is big, but workable.

My program is running.

I'll post an update and code in the morning.
 
Last edited:


Remove ads

Top