Share your Code Snippets


Technology


1 person marked this as a favorite.

Ever write a short piece of code to help out in your games? If so, why not share it?

Rules:

1. Clearly explain what your >snippet< is supposed to do.

2. Program must be short in length.

3. Program must be easy to understand. Hey, comments!!

4. State the language at top.

.


This is an implementation of the random RUINS & RONIN Scenario Starts Generator from the free .pdf.

Written in PERL.

<Begin Code>

sub r() { my ($n)= @_; return int($n*rand()); }

@d4= ("Bathhouse", "Temple", "Market", "Tavern");
@d6= ("Village Elder","Village Elder","Village Elder","Sensei","Shugenja","Samurai");
@d10= ("Rebllion","Theft","Siege","Kidnap","War","Plague","Evacuation","Murder"," Mystery","Mystery");
@d8= ("Monsters","a Sorcerer","a Sorcerer","a Monster","a Monster","Yakuza","rival Samurai","Ninja");
@d20= ("haunted ruins","haunted ruins","haunted ruins","misty forest","hidden valley","ancient caves","mystic shrine","remote island","unholy realm","dark fortress","lost monastery","secret pass","demon temple","mountain lake","forbidden city","cursed village","spooky marsh","lawless port","barren desert","deserted town");
@d12= ("consult sage","consult sage","consult sage","solve puzzle","solve puzzle","capture foe","act as escort","storm place","win contest","find item","find item","find item");

$A= $d4 [ &r(4) ];
$B= $d6 [ &r(6) ];
$C= $d10[ &r(10) ];
$D= $d8 [ &r(8) ];
$E= $d20[ &r(20) ];
$F= $d12[ &r(12) ];

print "\nPC's meet in a $A with mentor/patron $B who speaks of $C possibly caused by $D. PC's must go to $E and $F.\n";

<End Code>


select *
from management
where clue > 0

no rows returned


DESCRIPTION: To test a Combat Strategy, sometimes you want to run a Monte Carlo Simulation. A normal/gaussian distribution is always great to have for this type of analysis. There are several other distributions which are useful too, e.g. poisson, exponential -- let me know if you want 'em.

This is a C function that draws from a Normal Distribution, N(mean,variance). You will need to replace the alea() call, in this snippet, with your own uniform (0,1) random number generator.

LANGUAGE: Witten in C. Plus, you need <math.h>.

<Begin code snippet>

double Normal(double mu, double var)
{
double v1, v2, r, N;
if (var>0)
{
do {
v1 = alea() * 2 - 1;
v2 = alea() * 2 - 1;
r = v1*v1 + v2*v2;
} while ( r >= 1 );
N= v2 * sqrt( -2*log(r)/r ) * sqrt(var) + mu;
} else {
N= mu;
}
return N;
}

<End code snippet>


DESCRIPTION: >Darktower< is a great board game from Milton Bradely back in the 80's.

When you fight brigands, the battle joins with you having a number of warriors, say i, going up againts a number of brigands, say b of them. For example, 15 warriors vs. 16 briggands is i= 15 and b= 16. What is the probability that you will win the encounter? Well, I made up a little simulator.

LANGUAGE: Written in Perl

<Begin code snippet>

# Darktower Combat simulator

for (my $i=1; $i<30; $i++) # let the number of warriors go from 1 to 30
{
my $rounds= 10000; # at each level, simulate 10000 battles
my $win= 0; my $winPerc= 0.0;
my $losses= 0; my $lossesPerc= 0.0;
my @out= ();
for (my $k=0; $k<$rounds; $k++) # let the battles begin
{
my @out= &fightBrigands($i);
$win += $out[0];
$losses += $out[1];
}
$winPerc= $win/$rounds;
$lossesPerc= $losses/$rounds;
print "$i -- $winPerc / $lossesPerc\n";
}

# the combat is based on my interpretation of how the game works.
# I did not have the real rules, so this is just a best guess.
sub fightBrigands
{ my ($w)= @_;
$b= int(&Norm($w,$w)); $b=1 if ($b==0); # Number of brigands is uniformly distributed around beginning number of warriors.
my $begin= $b;
# print "warriors = $w brigands = $b \n";
do {
my $p= .7 ; ### this is the probability you win a round, adjust this.
my $roll= rand();
if ($roll < $p ) { $b = int($b/2 - .5); } # if you win brigand numbers cut it half.
else { $w--; } # if you lose, only lose 1 warrior.
# print "warriors = $w brigands = $b \n";
} while ($w > 0 && $b > 0);
if ($w>$b)
{
my @a= (1, ($b-$begin)); # win/loss & number of losses
return @a;
}
else
{
my @a= (0, ($b-$begin));
return @a;
}
}

# Hey, we've seen this before :-)
sub Norm
{ # draw randomly from N(m,v)
my ($mu,$var)= @_;
my ($v1,$v2,$r,$G);
if ($var>0) {
do {
$v1= rand()*2 - 1; $v2= rand()*2 - 1;
$r= $v1*$v1 + $v2*$v2;
} while ( $r >= 1 );
$G= $v2 * sqrt( -2*log($r)/$r ) * sqrt($var) + $mu;
} else { $G= $mu; }
return $G;
}

<End code snippet>


DESCRIPTION: Gary Gygax and Flint Dille wrote a series of cool, little books about >“Sagard the barbarian”< . They are in choose-your-own-adventure style.

Gygax came up with a unique combat system for the books (you’ll have to get the books to learn it.) As I read, I had to make a decision to fight or to retreat. Before joining in combat, I wrote a little simulator that reports the probability of winning the fight, and the expected number of hit points I would have remaining at the end. Here it is.

LANGUAGE: Written in C++.

<Begin Code Snippet>

#include <iostream.h>

int rolld4() { return int(4*((float)rand()/RAND_MAX)); }

void main(void)
{
int fightTable[6][4]={{0,0,0,1},{0,0,1,1},{0,1,1,2},{1,1,2,3},{1,2,3,4},{2,3,3,4}};
srand(time(NULL));
// ask user to input stuff
cout << "Enter your Level: "; int myLevel; cin >> myLevel;
cout << "Enter your HP: "; int myHP; cin >> myHP;
cout << "\nEnter enemy's Level: "; int enemyLevel; cin >> enemyLevel;
cout << "Enter enemy's HP: "; int enemyHP; cin >> enemyHP;

// run the Sim
float win, sumHP, gameHP, gameEHP; win= 0.0; sumHP= 0.0;
int N= 10000;
for(int i=0; i<N; i++) // average 10000 games
{
gameHP= myHP; gameEHP= enemyHP;
for(;;)
{
gameEHP -= fightTable[myLevel][ rolld4() ]; // my level for enemy
if (gameEHP<1) break;
gameHP -= fightTable[enemyLevel][ rolld4() ]; // enemy's for me
if (gameHP<1) break;
}
if (gameHP>0) { win++; sumHP += gameHP; }
}
cout << "\n\n\nPr(win) = " << (win/N);
cout << "\tExpected HPs left = " << (int)(sumHP/N);
cout << "\n\n";
}// main

<End Code snippet>


Oh my goodness.


I need the guts of a pente game.


... any planners, or tree-search stuff ?


DESCRIPTION: Creates a random Call of Cthulhu character. It is a bit long for a snippet, but its a complex game after all.

LANGUAGE: Python

<Begin Code Snippet>

#
import random

def d(S,N):
# roll NdS
sum= 0
for i in range(N):
sum += random.randint(1,S)
return sum

def damageBonusStat(STR,SIZ):
n= STR+SIZ
if ((n>=2) and (n<=12)): return "-1d6"
if ((n>=13) and (n<=16)): return "-1d4"
if ((n>=17) and (n<=24)): return "+0"
if ((n>=25) and (n<=32)): return "+1d4"
if ((n>=33) and (n<=40)): return "+1d6"
if ((n>=41) and (n<=56)): return "+2d6"
if ((n>=57) and (n<=72)): return "+3d6"
if ((n>=73) and (n<=88)): return "+4d6"
if ((n>=89) and (n<=104)): return "+5d6"
if ((n>=105) and (n<=120)): return "+6d6"
if ((n>=121) and (n<=136)): return "+7d6"
if ((n>=137) and (n<=152)): return "+8d6"
if ((n>=153) and (n<=168)): return "+9d6"
if ((n>=169) and (n<=184)): return "+10d6"
return "---"

def createStats():
pcName= input("Enter character's name: ")
pcSex = input("Enter character's sex: ")
print("\n\n\n")
print("Name: ", pcName, "\tSex: ", pcSex[0].upper(),"\n")
STR= d(6,3)
print( "STR ", STR)
CON= d(6,3)
print( "CON ", CON )
print( "DEX ", d(6,3) )
SIZ= d(6,2)+6
print( "SIZ ", SIZ )
print( "INT ", d(6, 2)+6 )
POW= d(6,3)
print( "POW ", POW )
print( "APP ", d(6,3) )
print( "EDU ", d(6,3)+3 )
print( " " )
print( "HP: ", (SIZ+CON)/2 )
print( "SAN: ", POW*5 )
print( "Damage Bonus: ", damageBonusStat(STR,SIZ) )

# main
createStats();

input("\n\nPress enter . . .")

<End Code Snippet>

p.s. now we see the weakness of using indentation for scope

Paizo Employee Senior Software Developer

public static NSArray stupidQuickSort(NSArray values) {
if (values.count() <= 1) {
return values;
} else {
Object pivot = values.objectAtIndex(values.count() / 2);
NSArray r = stupidQuickSort(EOQualifier.filteredArrayWithQualifier(values, new EOKeyValueQualifier("toString", EOQualifier.QualifierOperatorLessThan, pivot)));
r = r.arrayByAddingObjectsFromArray(EOQualifier.filteredArrayWithQualifier(valu es, new EOKeyValueQualifier("toString", EOQualifier.QualifierOperatorEqual, pivot)));
return r.arrayByAddingObjectsFromArray(stupidQuickSort(EOQualifier.filteredArrayWi thQualifier(values, new EOKeyValueQualifier("toString", EOQualifier.QualifierOperatorGreaterThan, pivot))));
}
}


DESCRIPTION: Someone emailed me this probability question the other day:

//A person dies and arrives at the gates to heaven. There are three identical doors: one of them leads to heaven, another leads to a 1-day stay in limbo, and then back to the gate, and the other leads to a 2-day stay in limbo, and then back to the gate. Every time the person is back at the gate, the three doors are reshuffled. How long, on the average, will it take to reach heaven?

Monte Carlo !!

LANGUAGE: C

//<begin code>

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void main()
{
srand(time(NULL));
int n= 0;
int simrun= 30000;
for(int i=0; i<simrun; i++)
{
int go= 1;
while(go)
{
double U= (double)rand()/RAND_MAX;
if (U < .3333)
go= 0;
else if (U < .6666)
n += 1;
else
n += 2;
}//while
}//for

double avg= (double)n/simrun;
printf("avg = %.0lf", avg);

}//main

//<end code>

The real answer is: N= (1/3)(0)+(1/3)(N+1)+(1/3)(N+2) => N= 3


DESCRIPTION: The HERO rules and GURPS are 3d6 based (in general.) I just started using both systems and want to know the Cummulative Distribution Function of rolling 3d6.

Here is some code to compute both the PDF and CDF of rolling 3d6 as determined by a Monte Carlo sim.

(this morning, i found i could no longer remember how to write down the 'counting' coefficient, so i was forced to write a loop. but i'll study and 'get it' back.)

LANGUAGE: C

//<begin code>

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define M 1000000

int d6(int);

void main()
{
srand(time(NULL));

long A[]= {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
long sum= 0;

// Build the sample
for(int i=0; i<M; i++)
A[d6(3)]++;

printf("\n\n______PDF______CDF__\n");
for(int k=3; k<=18; k++)
{
sum += A[k];
double cdf= (double)sum/M;
double pdf= (double)A[k]/M;
if (k<10) printf(" ");
printf("%d - %.4lf - %.4lf\n", k, pdf, cdf);
}

}//main

int d6(int n)
{
int sum= 0;
for(int k=0; k<n; k++)
{
int r= rand() % 6 + 1;
sum += r;
}
return sum;
}//d6

//<end code>


1 person marked this as a favorite.

Description: Select logic to execute based on certain criteria.

Language: C#

switch (<criteria>)
{
case true:
//criteria is met
<put success logic here>
break;

case false:
//criteria is not met
<put failure logic here>
break;

default:
//default fallback
<put fallback logic here>
break;
}


DESCRIPTION: Creates a random Call of Cthulhu character.

LANGUAGE: QBASIC ( click > to download < )

qbasic code:

REM
REM This program rolls up a random Call of Cthulhu PC
REM July 9, 2011
REM

DECLARE FUNCTION damageBonusStat$ (str AS INTEGER, siz AS INTEGER)
DECLARE FUNCTION roll! (n AS INTEGER, d AS INTEGER)

RANDOMIZE TIMER

DO
PRINT
PRINT

DIM pcName AS STRING
INPUT "Name: ", pcName

DIM pcSex AS STRING
INPUT "Sex : ", pcSex
PRINT

DIM str AS INTEGER
str = roll(3, 6)

DIM con AS INTEGER
con = roll(3, 6)

DIM dex AS INTEGER
dex = roll(3, 6)

DIM siz AS INTEGER
siz = roll(2, 6) + 6

DIM intel AS INTEGER
intel = roll(2, 6) + 6

DIM pow AS INTEGER
pow = roll(3, 6)

DIM app AS INTEGER
app = roll(3, 6)

DIM edu AS INTEGER
edu = roll(3, 6) + 3

DIM hp AS INTEGER
hp = (siz + con) / 2

DIM san AS INTEGER
san = 5 * pow

DIM db AS STRING
db = damageBonusStat(str, siz)

REM PRINT "Name: "; pcName, "Sex: "; pcSex
PRINT "STR "; str
PRINT "CON "; con
PRINT "DEX "; dex
PRINT "SIZ "; siz
PRINT "INT "; intel
PRINT "POW "; pow
PRINT "APP "; app
PRINT "EDU "; edu
PRINT
PRINT "HP: "; INT((siz + con) / 2)
PRINT "SAN: "; 5 * pow
PRINT "Damage Bonus: "; db

PRINT
INPUT "Continue (y/n)"; a$

LOOP WHILE a$ <> "n"

END

FUNCTION damageBonusStat$ (str AS INTEGER, siz AS INTEGER)

DIM n AS INTEGER
DIM bonus AS STRING

n = str + siz
bonus = " - "

IF (n >= 2 AND n <= 12) THEN
bonus = "-1d6"
END IF
IF (n >= 13 AND n <= 16) THEN
bonus = "-1d4"
END IF
IF (n >= 17 AND n <= 24) THEN
bonus = "+0"
END IF
IF (n >= 25 AND n <= 32) THEN
bonus = "+1d4"
END IF
IF (n >= 33 AND n <= 40) THEN
bonus = "+1d6"
END IF
IF (n >= 41 AND n <= 56) THEN
bonus = "+2d6"
END IF
IF (n >= 57 AND n <= 72) THEN
bonus = "+3d6"
END IF
IF (n >= 73 AND n <= 88) THEN
bonus = "+4d6"
END IF
IF (n >= 89 AND n <= 104) THEN
bonus = "+5d6"
END IF
IF (n >= 105 AND n <= 120) THEN
bonus = "+6d6"
END IF
IF (n >= 121 AND n <= 136) THEN
bonus = "+7d6"
END IF
IF (n >= 137 AND n <= 152) THEN
bonus = "+8d6"
END IF
IF (n >= 153 AND n <= 168) THEN
bonus = "+9d6"
END IF
IF (n >= 169 AND n <= 184) THEN
bonus = "+10d6"
END IF

damageBonusStat$ = bonus

END FUNCTION

FUNCTION roll (n AS INTEGER, d AS INTEGER)
DIM sum AS INTEGER
DIM count AS INTEGER

sum = 0
FOR count = 1 TO n
sum = sum + INT(RND * d) + 1
NEXT count

roll = sum

END FUNCTION


DESCRIPTION: An approximate Vigenère cipher. This program
applies a repeated key to a plaintext using XOR.

LANGUAGE: C

C Code:

#include <stdio.h>
#include <string.h>

void encipher(FILE *out, FILE *in, char *key)
{
size_t klen = strlen(key);
unsigned char ch;
size_t i = 0;

while(fread(&ch, 1, 1, in))
{
ch ^= key[i++];
fwrite(&ch, 1, 1, out);
i %= klen;
}
}

int main(int argc, char **argv)
{
if(argc > 3)
{
FILE *in = fopen(argv[1], "rb");
if(in != NULL)
{
FILE *out = fopen(argv[2], "wb");
if(out != NULL)
{
encipher(out, in, argv[3]);

if(ferror(out))
{
fputs("Output error.\n", stderr);
}
fclose(out);
}
else
{
fputs("Can't open output file.\n", stderr);
}
if(ferror(in))
{
fputs("Input error.\n", stderr);
}
fclose(in);
}
else
{
fputs("Can't open input file.\n", stderr);
}
}
else
{
fputs("Arguments required are: inputfile outputfile key.\n", stderr);
}
return 0;
}


DESCRIPTION: Compare the distribution of the 2d20 Advantage system versus the 2d20 Disadvantage system.

LANGUAGE: C

C Code:

// Advantanged: roll 2d20 and take highest
// Disadvantaged: roll 2d20 and take lowest

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void main()
{
srand(time(NULL));
int sample[21];
for(int i=0; i<21; i++) sample[i]= 0;

for(int i=0; i<100000; i++)
{
int roll1= rand() % 21 + 1;
int roll2= rand() % 21 + 1;
int it;
roll1 > roll2 ? it= roll1 : it= roll2;

sample[it]++;
}

for(int i=1; i<21; i++) printf("%d\n", sample[i]);

}


DESCRIPTION: Calcuates the average point buy using a Monte Carlo method.

LANGUAGE: Java

Spoiler:
import java.util.Random;
import java.math.*;
public class MCS {
public static void main(String[] args){
int b=0;
int f=0;
int r1=0;
int r2=0;
int r3=0;
int r4=0;
int sum=0;
int c=0;
int stat=0;
int point=0;
int w=0;
Random r=new Random();
for(int i=0;i<1000000;i++){
b=0;
f=0;
point=0;
for(int j=0;j<6;j++){
r1=r.nextInt(6)+1;
r2=r.nextInt(6)+1;
r3=r.nextInt(6)+1;
r4=r.nextInt(6)+1;
stat=r1+r2+r3+r4-Math.min(Math.min(Math.min(r1,r2),r3),r4);

if(stat<8)
point-=4;
else if(stat==8)
point-=2;
else if(stat==9)
point-=1;
else if(stat==11)
point+=1;
else if(stat==12)
point+=2;
else if(stat==13)
point+=3;
else if(stat==14)
point+=5;
else if(stat==15)
point+=7;
else if(stat==16)
point+=10;
else if(stat==17)
point+=13;
else if(stat==18)
point+=17;

if(stat>=14)f++;
b+=(stat-10)/2;
}
if(f>0 && b>0){
sum+=point;
c++;
if(point>=20)w++;
}
}
sum/=c;
System.out.println(w);
System.out.println(c);
System.out.println(sum);
}
}

Grand Lodge

Description: parse a Herolab xml custom output and return a Java object conforming to the Herolab dtd specification.
Language: Java

Spoiler:

public Object parse(File xmlFile, Class documentClass ) throws JAXBException {
JAXBContext ctx = JAXBContext.newInstance(new java.lang.Class[] { documentClass });
Unmarshaller um = ctx.createUnmarshaller();
Object o = um.unmarshal( xmlFile );
return o;
}


DESCRIPTION: A Text Engine Game -- you are a wizard’s apprentice and must explore your master's house.

LANGUAGE: LISP

LISP Codez:

(defparameter *nodes* '((living-room (you are in the living-room.
a wizard is snoring loudly on the couch.))
(garden (you are in a beautiful garden.
there is a well in front of you.))
(attic (you are in the attic.
there is a giant welding torch in the corner.))))

(defun describe-location (location nodes)
(cadr (assoc location nodes)))

(defparameter *edges* '((living-room (garden west door)
(attic upstairs ladder))
(garden (living-room east door))
(attic (living-room downstairs ladder))))

(defun describe-path (edge)
`(there is a ,(caddr edge) going ,(cadr edge) from here.))

(defun describe-paths (location edges)
(apply #'append (mapcar #'describe-path (cdr (assoc location edges)))))

(defparameter *objects* '(whiskey bucket frog chain))

(defparameter *object-locations* '((whiskey living-room)
(bucket living-room)
(chain garden)
(frog garden)))

(defun objects-at (loc objs obj-loc)
(labels ((is-at (obj)
(eq (cadr (assoc obj obj-loc)) loc)))
(remove-if-not #'is-at objs)))

(defun describe-objects (loc objs obj-loc)
(labels ((describe-obj (obj)
`(you see a ,obj on the floor.)))
(apply #'append (mapcar #'describe-obj (objects-at loc objs obj-loc)))))

(defparameter *location* 'living-room)

(defun look ()
(append (describe-location *location* *nodes*)
(describe-paths *location* *edges*)
(describe-objects *location* *objects* *object-locations*)))

(defun walk (direction)
(labels ((correct-way (edge)
(eq (cadr edge) direction)))
(let ((next (find-if #'correct-way (cdr (assoc *location* *edges*)))))
(if next
(progn (setf *location* (car next))
(look))
'(you cannot go that way.)))))

(defun pickup (object)
(cond ((member object (objects-at *location* *objects* *object-locations*))
(push (list object 'body) *object-locations*)
`(you are now carrying the ,object))
(t '(you cannot get that.))))

(defun inventory ()
(cons 'items- (objects-at 'body *objects* *object-locations*)))

(defun have (object)
(member object (cdr (inventory))))

(defun game-repl ()
(let ((cmd (game-read)))
(unless (eq (car cmd) 'quit)
(game-print (game-eval cmd))
(game-repl))))

(defun game-read ()
(let ((cmd (read-from-string (concatenate 'string "(" (read-line) ")"))))
(flet ((quote-it (x)
(list 'quote x)))
(cons (car cmd) (mapcar #'quote-it (cdr cmd))))))

(defparameter *allowed-commands* '(look walk pickup inventory))

(defun game-eval (sexp)
(if (member (car sexp) *allowed-commands*)
(eval sexp)
'(i do not know that command.)))

(defun tweak-text (lst caps lit)
(when lst
(let ((item (car lst))
(rest (cdr lst)))
(cond ((eql item #\space) (cons item (tweak-text rest caps lit)))
((member item '(#\! #\? #\.)) (cons item (tweak-text rest t lit)))
((eql item #\") (tweak-text rest caps (not lit)))
(lit (cons item (tweak-text rest nil lit)))
(caps (cons (char-upcase item) (tweak-text rest nil lit)))
(t (cons (char-downcase item) (tweak-text rest nil nil)))))))

(defun game-print (lst)
(princ (coerce (tweak-text (coerce (string-trim "() " (prin1-to-string lst)) 'list) t nil) 'string))
(fresh-line))


DESCRIPTION: A while ago >Yellow Dingo asked me< to convert
an old QBasic program into Lisp. Well guess what, I had some free time,
and thought it would be neat to do. I want a basic DnD character generator
in Lisp anyways.

Actually, this is just an approximation to the original code: you can only be
Human. Plus, it does not have all the racial and stat modifiers -- why? Because it was not
until I was done that I realized they where in there. (And at this time, I'm not going back
to do a re-write and work them into the code.)

So, you'll have to take this snippet as-is and consider it a launch point for doing your
own program.

-----

A note on running this snippet:

Make a directory like: "c:\code\lisp" and copy this snippet to a file
named "dndgen.cl" ( .cl for Common Lisp ).

Then, Grab this executable Lisp Listener: > gcl.exe < And put it into the SAME directory.

Run gcl.exe

At the prompt type:
>>(load "dndgen.cl")

then, to use it:
>>(make-character)

(quit) to quit, and ":q" to reset your Listener if it freaks out. ok? cool.

LANGUAGE: Common Lisp

CODE SNIPPET:

;; DnD Generator v500.3

(defparameter *pc* nil)
(defparameter *classes* '((Cleric 8) ;;; (<class> <hit-die>)
(Fighter 10)
(Magic-User 4)
(Thief 6)
(Monk 8)
(Bard 8)))

(defun roll (s) (apply #'+ (mapcar #'(lambda (x) (1+ (random x))) s)))

(setf pc-stat '(6 6 1 1 1 1 1 1)) ;;; 2d6+6 3d6 would be '(6 6 6)
(setf d4 '(4))
(setf d6 '(6))
(setf percentile '(100))

(defun age () (+ 15 (roll d4))) ;;; d4+15

(defun gold () (roll '(4 4 4 4 4))) ;;; 5d4

(defun class () (car (nth (random (length *classes*)) *classes*)))

(defun alignment ()
(let ((n (roll d6)))
(cond
((< n 4) 'Lawful)
((or (= n 4) (= n 5)) 'Neutral)
((= n 6) 'Chaotic ))))

(defun social-status ()
(let ((n (roll percentile)))
(cond
((< n 31) 'Penniless)
((< n 61) 'Struggling)
((< n 76) 'Comfortable)
((< n 86) 'Wealthy/Untitled)
((< n 96) 'Wealthy/Titled)
((< n 101) 'Royal-Family))))

(defun hometown ()
(let ((n (roll d6)))
(cond
((= n 1) 'Pittsburgh)
((= n 2) 'Atlanta)
((= n 3) 'Chicago)
((= n 4) 'Syndney)
((= n 5) 'Tokyo)
((= n 6) 'Seattle))))

(defun hp () (roll (list (cadr (assoc (cadr (assoc 'class *pc*)) *classes*)))))

(defun test-gen-pc ()
(setf *pc* `((race human) (age ,(age)) (class ,(class)) (alignment ,(alignment)) (gold ,(gold)) (str ,(roll pc-stat)) (int ,(roll pc-stat)) (wis ,(roll pc-stat)) (dex ,(roll pc-stat)) (con ,(roll pc-stat)) (chr ,(roll pc-stat))))
(list *pc* `((hp ,(hp)) (social-status ,(social-status)) (hometown ,(hometown)))))

(defun make-character ()
(let ( (myPC `((race human) (age ,(age)) (class ,(class)) (alignment ,(alignment)) (gold ,(gold)) (str ,(roll pc-stat)) (int ,(roll pc-stat)) (wis ,(roll pc-stat)) (dex ,(roll pc-stat)) (con ,(roll pc-stat)) (chr ,(roll pc-stat)))))
(princ #\newline)
(princ "========================================")
(princ #\newline)
(princ "DUNGEON & DRAGONS CHARACTER SHEET")
(princ #\newline)
(princ #\newline)
(princ #\newline)
(princ "Name: ______________________")
(princ #\newline)
(princ #\newline)
(princ "Race: HUMAN")
(princ #\newline)
(princ "Class: ") (princ (cadr (assoc 'class myPC)))
(princ #\newline)
(princ "Alignment: ") (princ (cadr (assoc 'alignment myPC)))
(princ #\newline)
(princ "Starting Gold: ") (princ (cadr (assoc 'gold myPC)))
(princ #\newline)
(princ #\newline)
(princ "HP: ") (princ (roll (list (cadr (assoc (cadr (assoc 'class myPC)) *classes*)))))
(princ #\newline)
(princ #\newline)
(princ "STR: ") (princ (cadr (assoc 'str myPC))) (princ #\newline)
(princ "INT: ") (princ (cadr (assoc 'int myPC))) (princ #\newline)
(princ "WIS: ") (princ (cadr (assoc 'wis myPC))) (princ #\newline)
(princ "DEX: ") (princ (cadr (assoc 'dex myPC))) (princ #\newline)
(princ "CON: ") (princ (cadr (assoc 'con myPC))) (princ #\newline)
(princ "CHR: ") (princ (cadr (assoc 'chr myPC))) (princ #\newline)
(princ #\newline)
(princ #\newline)
(princ "CHARACTER BACKGROUND")
(princ #\newline)
(princ #\newline)
(princ "Social Status: ") (princ (social-status))
(princ #\newline)
(princ "Home Town: ") (princ (hometown))
'________________________________________))


DESCRIPTION: Wander through five rooms till the end of time.
Can you map them ?

LANGUAGE: Basic ( click > to download < )

CODE SNIPPET:

5 rem Rooms-Forever
6 rem
10 DIM a(5, 4)
20 FOR b = 1 TO 5
30 FOR c = 1 TO 4
40 READ a(b, c)
50 NEXT c
60 NEXT b
70 DATA 0,2,3,0
80 DATA 1,0,5,0
90 DATA 0,4,0,1
91 DATA 3,5,0,0
92 DATA 4,0,0,2

95 CLS : PRINT : PRINT "`n' = North, `s' = South, `e' = East, `w' = West"
96 PRINT "`q' to quit": PRINT :
98 r0 = 1
99 WHILE (1)
100 PRINT "You are in room number "; r0
110 IF a(r0, 1) <> 0 THEN PRINT "A door leads North"
120 IF a(r0, 2) <> 0 THEN PRINT "There is an exit to the South"
130 IF a(r0, 3) <> 0 THEN PRINT "You can leave via the East exit"
140 IF a(r0, 4) <> 0 THEN PRINT "A doorway opens to the West"

150 PRINT : INPUT "Which Direction"; d$
160 IF d$ = "n" AND a(r0, 1) = 0 THEN PRINT "You cannot move that way": GOTO 100
170 IF d$ = "s" AND a(r0, 2) = 0 THEN PRINT "You can't walk through walls": GOTO 100
180 IF d$ = "e" AND a(r0, 3) = 0 THEN PRINT "Try another direction": GOTO 100
190 IF d$ = "w" AND a(r0, 4) = 0 THEN PRINT "There is no door to the west": GOTO 100

200 IF d$ = "n" THEN r0 = a(r0, 1)
210 IF d$ = "s" THEN r0 = a(r0, 2)
220 IF d$ = "e" THEN r0 = a(r0, 3)
230 IF d$ = "w" THEN r0 = a(r0, 4)
240 IF d$ = "q" THEN END

300 WEND


DESCRIPTION: We pounded this out at the gaming table about 2 years
ago. But I don't remember the situation and why a sim was needed.
Anyways, it's goofy so it needs to be posted.

Ten enemy Wizards stand in a circle with 30' between them (along the
arc of the circle). They all cast 1 lightning bolt at another enemy
Wizard chosen at random. Casting is simultaneous, and a particular wizard could
get hit more than once, and some not at all.

- Damage is <level>d6 with save for one-half.
- Save is a reflex save (D20+dex mod+ref mod) while the DC for what
he/she casts is 10+spell level+int mod.

QUESTION: What is the expected number of Wizards still standing after
the round is over???

notes:
o Every 2 points above 10 is a +1 dex mod & int mod.
o For Wizards, reflex save is 1/3 his level.
o Remember the Wizard will be gaining +1 INT at 4th, 8th, 12th, 16th and
o 20th levels. And taking wealth into account, assume +2 INT at 4th level,
o +4 INT at 7th level, and +6 INT at 11th level.

Spell Focus: Evocation. Greater Spell Focus: Conjuration Elemental Focus [electricity], Greater Elemental Focus [electricity], Heighten Spell.

LANGUAGE: C

CODE SNIPPET:

// Ten enemy Wizards stand in a circle with 30' between them (along the arc
// of the circle). They all cast 1 lightning bolt at another enemy Wizard
// chosen at random. Casting is simultaneous, and a particular wizard could
// get hit more than once. Damage is <leve>d6 with save for one-half.
// Save is a reflex save (D20+dex mod+ref mod) while the DC for what he/she
// casts is 10+spell level+int mod.
//
// What is the expected number of Wizards still standing after the round
// is over???
//
// notes:
// Every 2 points above 10 is a +1 dex mod & int mod.
// For Wizards, reflex save is 1/3 his level.
// Remember the Wizard will be gaining +1 INT at 4th, 8th, 12th, 16th and
// 20th levels. And taking wealth into account, assume +2 INT at 4th level,
// +4 INT at 7th level, and +6 INT at 11th level.
//
// Spell Focus: Evocation. Greater Spell Focus: Conjuration Elemental Focus [electricity], Greater Elemental Focus [electricity], Heighten Spell.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <malloc.h>

#define K 1000

struct Wizard {
int Level;
int HP;
int DEX;
int INT;
};

int castAtSomeoneNotYourself(int, int);
int dueling(Wizard*, int, int);
int lightningBoltDamage(int);
int roll(int, int);
int save(Wizard);
void showWizards(int, Wizard *);
void usage(char *);

void main(int argc, char *argv[])
{
if (argc != 3) { usage(argv[0]); }
int N= atoi(argv[1]);
if (N==1) { printf("\nYou need 2+ wizards to duel.\n"); exit(1); }
if (N>100) { printf("\nThat's too many wizards.\n"); exit(1); }
int L= atoi(argv[2]);
srand(time(NULL));

Wizard *wizards = (Wizard *)malloc(N*sizeof(Wizard));

printf("\n\nLevel\tAvg. living +/- (95 perc. confidence interval)\n");
printf("-----\t-------------\n");
// Last minute change, run all levels from 5th to 20th.
for(int level=5; level<=20; level++)
{
// run the test
int sum= 0; int sum2= 0;
for (int i=0; i<K; i++)
{
int c= dueling(wizards,N,level);
sum += c;
sum2 += (c*c);
}

double avg= (double)sum/K;
double avg2= (double)sum2/K;
double se= 1.9645* pow( (avg2 - avg*avg), 0.5 );
printf(" %d\t",level);
printf("%.2lf +/- %.2lf\n", avg, se);
}
delete(wizards);
}//main

int dueling(Wizard *wizard, int N, int L)
{
// build each spell caster
for(int i=0; i<N; i++)
{
wizard[i].Level= L;
wizard[i].HP = roll(6,L);
wizard[i].DEX = roll(6,3);
wizard[i].INT = roll(6,3);
}

//showWizards(N, wizard);

for(int k=0; k<N; k++)
{
// one round of death -- simultaneous casting
int tango= castAtSomeoneNotYourself(N,k);
//printf("wizard[%d] is attacking wizard[%d] ", k, tango);
int damage= lightningBoltDamage(L);
if ( save( wizard[tango] ) )
{
wizard[tango].HP -= damage/2;
//printf("for %d points of damage.\n", damage/2);
}
else
{
wizard[tango].HP -= damage;
//printf("for %d points of damage.\n", damage);
}
}

// count those left
int alive= 0;
for(int k=0; k<N; k++)
if (wizard[k].HP > 0) alive++;

//if (alive <1) printf("< 1 wizard still alive.\n");

return alive;
}//dueling

int save(Wizard wizard)
{
// add your saving throw mechanics here.
return 0;
}

int lightningBoltDamage(int L)
{
return roll(6,L);
}

int castAtSomeoneNotYourself(int N, int k)
{
int r;
do {
r = rand()%N;
} while ( r == k);
return r;
}

void usage(char *s)
{
printf("\n\nUsage: %s <number wizards> <level>\n\n",s);
exit(1);
}

int roll(int d, int n)
{
int sum= 0;
for(int k=0; k<n; k++)
{
sum += rand()%d + 1;
}
return sum;
}

void showWizards(int N, Wizard *wizard)
{
for(int i=0; i<N; i++)
{
printf("wizard[%d].Level = %d\n", i, wizard[i].Level);
printf("wizard[%d].HP = %d\n", i, wizard[i].HP);
printf("wizard[%d].DEX = %d\n", i, wizard[i].DEX);
printf("wizard[%d].INT = %d\n", i, wizard[i].INT);
printf("\n");
}
}

// -= end =-


1 person marked this as a favorite.

DESCRIPTION: A Command Line dice roller.

I'm currently traveling in a country where being seen rolling dice
(that is, "public displays" of dice rolling) is considered evil; and, I
could prolly get the death penalty, or perhaps a nasty tattoo on
my forehead intended to disgrace me for life.

Anyways, to combat this oppression I wrote a dice roller in C. (I don't
trust the apps you can download to your phone, because chinese
hackers release those to track your movements.)

To use:

>>roll 3d6+1
or
>>roll 6: 3d6+1 <- this rolls it 6 times, like for stats.

LANGUAGE: C

CODE SNIPPET:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#define N 99
#define DEBUG 0

int r(int); // roll
int set(char*, int*);

int main(int argc, char *argv[])
{
if (argc<2)
{
fprintf(stdout,"\n\nUSAGE: roll [iterations:] <n>d<dice-size> [+-*/ modifier]\n\n");
exit(1);
}
srand(time(NULL));

char buf[N]; *buf='\0';
for(int i=1; i<argc; i++) strcat(buf,argv[i]);

int i=0, iters=0, n=0, d=0, mod=0, modset=0;
char *p=buf, tok[N], op='+';
while (*p != '\0')
{
tok[i]= *p;
if (DEBUG) printf(" -%c- ", tok[i]);
switch (*p)
{
case ':':
if (DEBUG) printf("got : ");
iters= set(tok, &i);
break;
case 'd':
if (DEBUG) printf("got d ");
n= set(tok, &i);
break;
case '+':
case '-':
case '*': // doesn't do anything yet
case '/': // doesn't do anything yet
op= *p;
if (DEBUG) printf("got %c ",*p);
d= set(tok, &i);
modset= 1;
break;
}
p++; i++;
}//while
if (n==0) n= 1;
if (iters==0) iters= 1;
if (modset)
mod= set(tok, &i);
else
d= set(tok, &i);
if (DEBUG)
{printf("\niters= %d\nn= %d\nd= %d\nmod= %c%d\n",iters,n,d,op,mod);}

// roll the dice, and collect stats
fprintf(stdout,"\n");
int sum=0, summ=0, summ2=0;
for(int k=0; k<iters; k++)
{
for(int j=0; j<n; j++)
{
sum += r(d);
}
switch (op)
{
case '+': sum += mod; break;
case '-': sum -= mod; break;
}
fprintf(stdout,"%d ", sum);
// descriptive statistics
summ += sum;
summ2 += sum*sum;
sum= 0;
}
float avg = (float)summ/iters;
float avg2= (float)summ2/iters;
float var = (float)(avg2-avg*avg);
if (iters>1)
fprintf(stdout,"\n\nsum= %d avg= %.2f var= %.2f\n\n", summ, avg, var);

return 0;
}//main

int set(char *token, int *i)
{
int z= 0;
token[*i]= '\0';
if (DEBUG) printf("- %d ->%s<--\n", *i, token);
z= atoi(token);
token[0]= '\0';
*i= -1;
return z;
}//set

int r(int d)
{
if (d < 1)
return 0;
else
return (1+rand()%d); // this makes me vomit
}//r


MediaWiki Parser script template that returns the ability score modifier of the ability score passed to it:

Usage:

  • {{AbMod|Ability Score}} (+/- signed modifier)
  • {{AbModU|Ability Score}} (unsigned modifier)

AbMod wrote:
{{#ifexpr: {{{1}}} > 9 |+|}}{{#expr: trunc(({{{1}}}-10)/2)}}
AbModU wrote:
{{#expr: trunc(({{{1}}}-10)/2)}}


MediaWiki Parser script template that returns the d20pfsrd.org URL containing the spell name passed to it (requires the Variables extension):

Usage:

  • {{S|Spell Name}}
  • {{S|Spell Name|Displayed Spell Name}}

S wrote:

<includeonly><noinclude>

</noinclude>{{#vardefine:b1|{{lc:{{#replace:{{{1}}}| |-}}}}}}<noinclude>
</noinclude>{{#vardefine:b2|{{#replace:{{#var:b1}}|,-lesser|}}}}<n oinclude>
</noinclude>{{#vardefine:b3|{{#replace:{{#var:b2}}|,-greater|}}}}< noinclude>
</noinclude>{{#vardefine:b4|{{#replace:{{#var:b3}}|lesser-|}}}}<no include>
</noinclude>{{#vardefine:b5|{{#replace:{{#var:b4}}|greater-|}}}}<n oinclude>
</noinclude>{{#vardefine:b6|{{#replace:{{#var:b5}}|mass-|}}}}<noin clude>
</noinclude>{{#vardefine:b7|{{#replace:{{#var:b6}}|,-mass|}}}}<noi nclude>
</noinclude>{{#vardefine:bookmark|{{#replace:{{#var:b7}}|'|-}}}}<n oinclude>
</noinclude>[http://www.d20pfsrd.com/magic/all-spells/{{lc:{{#sub:{{{1}}}|0|1}}}}/{{#var:bookmark}} {{{2|{{{1}}}}}}]</includeonly>


MediaWiki Parser script template that creates a friendly PRD-style anchor/bookmark from the text passed to it (requires the Variables extension):

Usage:

  • {{A|Anchor Text to Display}}
  • {{A|Anchor Text|}} (Invisible Anchor)
  • {{A|Anchor Text|Text to Display}}

A wrote:

<includeonly><noinclude>

</noinclude>{{#vardefine:a1|{{lc:{{#replace:{{{1}}}| |-}}}}}}<noinclude>
</noinclude>{{#vardefine:a2|{{#replace:{{#var:a1}}|à|a}}}}<noinclu de>
</noinclude>{{#vardefine:a3|{{#replace:{{#var:a2}}|á|a}}}}<noinclu de>
</noinclude>{{#vardefine:a4|{{#replace:{{#var:a3}}|â|a}}}}<noinclu de>
</noinclude>{{#vardefine:a5|{{#replace:{{#var:a4}}|ä|a}}}}<noinclu de>
</noinclude>{{#vardefine:a6|{{#replace:{{#var:a5}}|æ|ae}}}}<noincl ude>
</noinclude>{{#vardefine:a7|{{#replace:{{#var:a6}}|é|e}}}}<noinclu de>
</noinclude>{{#vardefine:a8|{{#replace:{{#var:a7}}|ê|e}}}}<noinclu de>
</noinclude>{{#vardefine:a9|{{#replace:{{#var:a8}}|ë|e}}}}<noinclu de>
</noinclude>{{#vardefine:a10|{{#replace:{{#var:a9}}|í|i}}}}<noincl ude>
</noinclude>{{#vardefine:a11|{{#replace:{{#var:a10}}|î|i}}}}<noinc lude>
</noinclude>{{#vardefine:a12|{{#replace:{{#var:a11}}|ï|i}}}}<noinc lude>
</noinclude>{{#vardefine:a13|{{#replace:{{#var:a12}}|ó|o}}}}<noinc lude>
</noinclude>{{#vardefine:a14|{{#replace:{{#var:a13}}|ô|o}}}}<noinc lude>
</noinclude>{{#vardefine:a15|{{#replace:{{#var:a14}}|ö|o}}}}<noinc lude>
</noinclude>{{#vardefine:a16|{{#replace:{{#var:a15}}|ú|u}}}}<noinc lude>
</noinclude>{{#vardefine:a17|{{#replace:{{#var:a16}}|û|u}}}}<noinc lude>
</noinclude>{{#vardefine:a18|{{#replace:{{#var:a17}}|ü|u}}}}<noinc lude>
</noinclude>{{#vardefine:anchor|{{#replace:{{#var:a18}}|'|-}}}}<no include>
</noinclude><span style="white-space: nowrap;" id="{{#var:anchor}}">{{{2|{{{1}}}}}}</span></includeonly>


DESCRIPTION: Shadowrun random run generator.

LANGUAGE: Python 3+

CODE SNIPPET:

import random
MEET_LOCATIONS = ["at a bar, club, or restaurant", "at a warehouse, loading dock, or other underused location","in the barrens district or some other urban hell hole","in a moving vehicle","in a Matrix host","in Astral space"]
EMPLOYERS = ["a secrect society (Black Lodge, Human Nation)","a political or activist group (Humanis Policlub, Mothers of Metahumans)","a government or goverment agency","a minor corporation","a minor corporation","a minor corporation","a megacorporation","a megacorporation","a megacorporation","a criminal syndicate (Yakuza, Mafia)","a magical group (Illuminates of New Dawn)","a private individual","an exotic or mysterious being (free spirit, dragon, AI)"]
JOB_TYPE = ["a data steal","an asassination or demolition","an extraction or insertion","a misdirection","a protection","a delivery"]
MACGUFFINS = ["a key employee","a prototype product","cutting edge technology research","a bioengineered life form","a magical object","an urban building, rural location, or infrastructure object"]
TWISTS = ["security is unexpectedly high","a third pary is also interested","the target is not what it appears to be (group was lied to)","the job requires a rare piece of equipment","the target has been moved or is being moved","the employeer decides to double-cross them"]
theRun = "The runners go to a meet " + MEET_LOCATIONS[random.randint(0,5)] + " for their next job. They are hired by " + EMPLOYERS[random.randint(0,11)] + " for " + JOB_TYPE[random.randint(0,5)] + " job, targeting " + MACGUFFINS[random.randint(0,5)] + ". The run gets complicated when " + TWISTS[random.randint(0,5)] + "!"
print(theRun)
input("\nEnd of Line.")


A commonly used Random Number Generator.
(In fact, you may have used it today without knowing it.)

.

---------------------------------------------
RND():
x1 = ( x0 * a + c ) MOD (2^24)
return x1

where:

x1 = new value
x0 = previous value (1st value is a Seed)
a = 1140671485
c = 12820163

---------------------------------------------------------------

.

:-:

(same thing in c++)

#include "stdafx.h"

int main(int argc, char* argv[])
{
unsigned long rndVal;

rndVal = 0x50000L;
int i;
float rndFloat;

for (i=0;i<10;i++)
{
rndVal = (rndVal * 0x43fd43fdL + 0xc39ec3L) & 0xffffffL;
rndFloat = (float)rndVal / (float)16777216.0;
printf("Value is %.15f\n",rndFloat);
}
return 0;
}


DESCRIPTION: Calculate the probability of the "observed data" for a bunch of coins being flipped. (Note: 'p' ranges from 0 to 1 by 0.10, and then I normalized the output values just for fun.)

LANGUAGE: C++

code:

// observedCoin.cpp
//
// usage: observedCoin hhthth

#include <stdio.h>
#include <string.h>
#include <math.h>

#define N 99

int main(int argc, char *argv[])
{
char buf[N];
for(int i=1; i<argc; i++)
{
strcat( buf, argv[i] );
}
char *p= buf;
int h=0;
int t=0;
while(*p != '\0')
{
if (*p == 'h' || *p == 'H') h++;
if (*p == 't' || *p == 'T') t++;
p++;
}
printf("h = %d\nt = %d\n", h, t);
double c[] = {0.0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0};
double pr[] = {0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0};
double sum = 0.0;
for(int i=0; i<11; i++)
{
pr[i] = pow(c[i],h) * pow(1.0-c[i],t);
sum += pr[i];
}
for(int i=0; i<11; i++)
{
pr[i] = pr[i]/sum;
printf("%.2f- %f ", c[i], pr[i]);
int s = 100*pr[i];
for(int j=0; j<s; j++)
{
printf("*");
}
printf("\n");
}
} //main


DESCRIPTION: get a tro glyph.

LANGUAGE: Bash

code:

#!/bin/bash

function err_message() {
echo " (Use '_' as space and Capialize_All_Words.)";
echo
}

# only accecpt the first command line argument
if [ $# -lt 1 ]; then
echo -n "USAGE: `basename $0` <mech>"
err_message
exit
fi

# all this to get the pic's filename
mechName=$1; shift
mechName="${mechName^}"; # capitalize it
landingPage="https://www.sarna.net/wiki/$mechName"
picName=$(curl -s $landingPage | awk '/class\=\"image\" title/ { print $0;}' | sed -e 's/.*File:\(.*\.[jpJPgG][pnPNiI][gGfF]\)".*/\1/')

# check for the need of (BattleMech)
if [[ $picName == "" ]]; then
landingPage=$landingPage"_(BattleMech)"
picName=$(curl -s $landingPage | awk '/class\=\"image\" title/ { print $0;}' | sed -e 's/.*File:\(.*\.[jpJPgG][pnPNiI][gGfF]\)".*/\1/')
#echo $picName
fi

# now make the link to the image
previewPage="https://www.sarna.net/wiki/File:$picName"
picPage=$(curl -s $previewPage | awk '/fullImageLink/ { print $0; }' | sed 's/.*id="file"><a href="\(.*\)"><img alt.*/\1/')
if [[ "$picPage" == *https* ]]; then
target="$picPage"
else
target="https:$picPage"
fi

# grab the image file
echo "name: $mechName ( $picName )"
#echo $previewPage
#echo $picPage
#echo $target

if curl -# -o $picName $target ; then
echo " "
else
echo
echo -n " Oops.. "
err_message
fi


DESCRIPTION: Sometimes `barrier` hangs and I have to ssh in from another machine, and end multiple processes. I got tired of doing the finger dance, so I went scripty.

LANGUAGE: Bash

code:

#!/bin/bash

ps_line=$(ps -ef | grep barrier);
echo -n $ps_line;

proc=$(echo $ps_line | sed 's/barrier/\n/g' | awk '{ if (NR==1) {print $2;} if (NR==2) {print $2;} }')

for k in $proc; do
kill -9 $k
done

echo
ps -ef | grep barrier
echo


When you roll 4d6 and add up the best 3 for ability score generation, what would the average be? In 2011 I wrote a program to determine the answer and posted the results in the following thread:

Dice averages

That was simple. After all, it was only 1296 possibilities. But I'm a D&D 3.0 fan, so one little point bugged me: In the D&D 3.0 and 3.5 handbooks, the official, default method for ability score generation is 4d6-and-take-the-best-3... but with one additional bonus. If the ability score array you roll is too low (before racial adjustments), you may scrap it and roll a new array. Your ability scores are considered "too low" if your total modifiers are 0 or less, or if your highest score is 13 or lower.

So I wondered: how does that affect the average?

Nine years later, I finally wrote code to find out. I wrote it in Python and in Java, posted my source code on GitHub, and linked to that source code in that thread I linked to above. The TL;DR version is that the average goes up from 12.2 to 12.5. You can read more details in that thread and/or see my source code here:

Here's the Python version.
Here's the Java version.

Sorry; I know that the rules are that I have to post the code into this thread, but I'm afraid I can't deal with paizo.com's inability to indent.

Community / Forums / Gamer Life / Entertainment / Technology / Share your Code Snippets All Messageboards

Want to post a reply? Sign in.
Recent threads in Technology