plottoriffic/index.js
2017-08-02 23:08:17 +00:00

165 lines
4.7 KiB
JavaScript

'use strict'
const seedrandom = require('seedrandom');
const plotto = require("./data/plotto.json");
function regEscape(s) {
return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
};
function pick(rng, arr) {
if(!arr) {
return null;
}
if(arr.length == 0)
return null;
if(arr.length == 1)
return arr[0];
let min = 0;
let max = arr.length;
let i =Math.floor(rng() * (max - min)) + min;
let ret = arr[i];
//console.log(i, ':', JSON.stringify(ret), '!!!!', JSON.stringify(arr));
return ret;
}
class PlotGenerator {
constructor({ seed=null, flipGenders=undefined } = {}) {
this._rng = seedrandom(seed);
if(flipGenders === undefined) {
this._flipGenders = this._rng() < 0.5; //50% chance true/false
} else {
this._flipGenders = flipGenders;
}
}
get flipGenders() { return this._flipGenders; }
set flipGenders(flip) { this._flipGenders = flip; }
generate() {
let rootTransform = {};
if(this._flipGenders) {
rootTransform = {
"A" : "B",
"A-2": "B-2",
"A-3": "B-3",
"A-4": "B-4",
"A-5": "B-5",
"A-6": "B-6",
"A-7": "B-7",
"A-8": "B-8",
"A-9": "B-9",
"B" : "A",
"B-2": "A-2",
"B-3": "A-3",
"B-4": "A-4",
"B-5": "A-5",
"B-6": "A-6",
"B-7": "A-7",
"B-8": "A-8",
"B-9": "A-9"
};
}
let preamble = pick(this._rng, plotto.masterClauseA);
let resolution = pick(this._rng, plotto.masterClauseC);
let masterPlot = pick(this._rng, plotto.masterClauseB);
let subject = [masterPlot.group, ' / ', masterPlot.subgroup, ': ', masterPlot.description].join('');
let conflict = plotto.conflicts[pick(this._rng, masterPlot.nodes)];
return [
subject,
preamble,
this._expand(conflict, rootTransform, {leadIns:3, carryOns:3}).replace(/\*/g, ''),
resolution
].join('\n\n').trim();
}
_expand(item, transform, ctx, start, end) {
let ret = [];
if(!item)
return 'NULL';
if(ctx.leadIns > 0 && item.leadIns) {
ctx.leadIns -= 1;
ret.push(this._expand(item.leadIns, null, ctx));
}
let carryon = null;
if(ctx.carryOns > 0 && item.carryOns) {
ctx.carryOns -= 1;
carryon = this._expand(item.carryOns, transform, ctx);
}
if(typeof(item) == "string") {
ret.push(this._expand(plotto.conflicts[item], null, ctx));
} else if(Array.isArray(item)) {
ret.push(this._expand(pick(this._rng, item), null, ctx));
} else if(item.conflictid) {
ret.push(item.description);
} else if(item.v) {
if(item.start || item.end) {
ret.push(this._expand(plotto.conflicts[item.v], item.tfm, ctx, item.start, item.end));
} else if(item.op == '+') {
for(let sub of item.v) {
ret.push(this._expand(sub, item.tfm, ctx));
}
} else {
ret.push(this._expand(item.v, item.tfm, ctx));
}
}
if(carryon) {
ret.push(carryon);
}
let str = ret.join('\n\n').trim();
if(transform) {
let ks = Object.keys(transform);
if(ks.length > 0) {
let pattern = '\\b(?:' + ks.map(function(s) {
return '(?:' + regEscape(s) + ')';
}).join('|') + ')(?=^|$| |,|\\.)';
let rg = new RegExp(pattern, 'g');
let cmp = {
before: str,
transform: transform
};
str = str.replace(rg,function(match) {
if(!match || match.length == 0)
return '';
let t = transform[match];
if(!t) {
console.log('Could not replace match in template: ' + match);
return match;
}
return t;
});
cmp.after = str;
//console.log(cmp);
}
}
return str;
}
}
exports.PlotGenerator = PlotGenerator;
let g = new PlotGenerator();
console.log(g.generate());