Public
Edited
Dec 29
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
data = {
const d6 = dice(6);
let results = [];
while (results.length < 100_000) {
results.push(game(d6, throwStrategy));
if (Math.random() < 0.0001) yield results;
}
yield results;
}
Insert cell
pct = d3.format(".1%")
Insert cell
stats = {
let counts = d3.rollup(
data,
(ds) => ds.length,
(d) => d.result
);
let rv = {
orcs: counts.get("orcs"),
potatoes: counts.get("potatoes"),
destiny: counts.get("destiny"),
medianRolls: d3.quantile(data, 0.5, (d) => d.rolls)
};
rv.orcsPercent = rv.orcs / data.length;
rv.potatoesPercent = rv.potatoes / data.length;
rv.destinyPercent = rv.destiny / data.length;
return rv;
}
Insert cell
Insert cell
colors = [
d3.schemeCategory10[1],
d3.schemeCategory10[2],
d3.schemeCategory10[5]
]
Insert cell
function dice(sides = 6) {
return () => Math.floor(Math.random() * sides) + 1;
}
Insert cell
function game(d6, throwStrategy = "never") {
let destiny = 0;
let potatoes = 0;
let orcs = 0;
let darkness = 0;
let turns = 0;
let throws = 0;
let thrownPotatoes = 0;
let rolls = 0;
const maxTurns = 1000;

function roll() {
rolls += 1;
return d6();
}

function throwPotato() {
if (potatoes <= darkness) throw new Error("not enough potatoes");
if (orcs <= 0) throw new Error("no orcs");
orcs -= 1;
let amount = 1 + darkness;
potatoes -= amount;
throws += 1;
thrownPotatoes += amount;
}

while (destiny < 10 && potatoes < 10 && orcs < 10 && turns < maxTurns) {
const r1 = roll();
turns += 1;
if (r1 === 1 || r1 === 2) {
const r2 = roll();
if (r2 === 1) potatoes += 1;
else if (r2 === 2) {
potatoes += 1;
destiny += 1;
} else if (r2 === 3) {
destiny += 1;
orcs += 1;
} else if (r2 === 4) {
orcs += 1;
potatoes = Math.max(0, potatoes - 1);
} else if (r2 === 5) potatoes = Math.max(0, potatoes - 1);
else potatoes += 2;
} else if (r1 === 3 || r1 === 4) {
const r2 = roll();
if (r2 === 1) orcs += 1;
else if (r2 === 2) {
destiny += 1;
} else if (r2 === 3) {
destiny += 1;
orcs += 1;
} else if (r2 === 4) {
orcs += 2;
potatoes = Math.max(0, potatoes - 1);
} else if (r2 === 5) destiny += 1;
else potatoes += 2;
} else {
darkness += 1;
}

if (throwStrategy === "eager") {
while (orcs > 0 && potatoes > darkness) throwPotato();
} else if (throwStrategy === "desperate") {
while (orcs === 10 && potatoes > darkness) throwPotato();
} else if (throwStrategy === "cheap") {
while (orcs > 0 && potatoes > darkness && darkness < 3) throwPotato();
}
}

return {
destiny,
potatoes,
orcs,
darkness,
turns,
throws,
thrownPotatoes,
rolls,
result:
turns >= maxTurns
? "max-turns"
: orcs >= 10
? "orcs"
: destiny >= 10
? "destiny"
: potatoes >= 10
? "potatoes"
: null
};
}
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more