It looks like it is almost working
This commit is contained in:
parent
bb748587c6
commit
0332081ccf
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,3 +1,7 @@
|
|||||||
|
data/plotto.1.json
|
||||||
|
data/plotto.2.json
|
||||||
|
data/plotto2.json
|
||||||
|
|
||||||
# Logs
|
# Logs
|
||||||
logs
|
logs
|
||||||
*.log
|
*.log
|
||||||
|
8690
data/plotto.json
8690
data/plotto.json
File diff suppressed because it is too large
Load Diff
220
fix.js
Normal file
220
fix.js
Normal file
@ -0,0 +1,220 @@
|
|||||||
|
'use strict'
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
this is some crazy messy code. don't judge me
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
const jsonPath = require('jsonpath');
|
||||||
|
const obj = require('./data/plotto.json');
|
||||||
|
const _ = require('underscore');
|
||||||
|
|
||||||
|
//console.log(JSON.stringify(Object.keys(obj.conflicts), null, '\t'));
|
||||||
|
let added = obj.conflicts;
|
||||||
|
for(let ck of Object.keys(obj.conflicts)) {
|
||||||
|
let conflict = obj.conflicts[ck];
|
||||||
|
|
||||||
|
let rg = /\[(\d+)\]/g;
|
||||||
|
let idxs = [];
|
||||||
|
let m;
|
||||||
|
while(m = rg.exec(conflict.description)) {
|
||||||
|
idxs.push({
|
||||||
|
index1: m.index,
|
||||||
|
index2: m.index + m[1].length + 2,
|
||||||
|
name: ck + '-' + m[1]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if(idxs.length == 0){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete obj.conflicts[ck];
|
||||||
|
|
||||||
|
//console.log(ck, ':', conflict.description);
|
||||||
|
|
||||||
|
let prefix = conflict.description.slice(0, idxs[0].index1);
|
||||||
|
|
||||||
|
for(let i=0; i<idxs.length; i++) {
|
||||||
|
|
||||||
|
let data = '';
|
||||||
|
if(i + 1 < idxs.length) {
|
||||||
|
data = conflict.description.slice(idxs[i].index2, idxs[i+1].index1).trim();
|
||||||
|
} else {
|
||||||
|
data = conflict.description.slice(idxs[i].index2).trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(data.indexOf(' or') === data.length-3) {
|
||||||
|
data = data.slice(0, data.length-3);
|
||||||
|
} else if(data.indexOf(' or,') === data.length-4) {
|
||||||
|
data = data.slice(0, data.length-4);
|
||||||
|
}
|
||||||
|
|
||||||
|
added[idxs[i].name] = Object.assign({}, conflict, {
|
||||||
|
description: prefix.trim() + ' ' + data.trim(),
|
||||||
|
conflictid: idxs[i].name
|
||||||
|
});
|
||||||
|
|
||||||
|
//console.log(idxs[i].name, ':', data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//console.log(JSON.stringify(added, null, '\t'));
|
||||||
|
let allKeys = Object.keys(obj.conflicts);
|
||||||
|
|
||||||
|
let stk = [];
|
||||||
|
for(let o of jsonPath.query(obj, '$.conflicts.*')) {
|
||||||
|
stk.push(o.conflictid);
|
||||||
|
for(let arrt of ['leadIns', 'carryOns']) {
|
||||||
|
stk.push(arrt);
|
||||||
|
o[arrt] = expand(o[arrt]);
|
||||||
|
stk.pop();
|
||||||
|
}
|
||||||
|
stk.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
function expand(item) {
|
||||||
|
|
||||||
|
if(typeof(item) == "string") {
|
||||||
|
|
||||||
|
let ret = item;
|
||||||
|
let rg = /^(\d+[a-z]?)\s+(\**)-(\**)/g;
|
||||||
|
let m = rg.exec(item);
|
||||||
|
if(m) {
|
||||||
|
|
||||||
|
ret = {
|
||||||
|
v: m[1]
|
||||||
|
};
|
||||||
|
|
||||||
|
if(m[0].length < item.length) {
|
||||||
|
ret.v = ret.v + ' ' + item.slice(m[0].length).trim();
|
||||||
|
}
|
||||||
|
ret.v = ret.v.trim();
|
||||||
|
ret.start = m[2];
|
||||||
|
ret.end = m[3];
|
||||||
|
|
||||||
|
//console.log(item, ' ---> ', JSON.stringify(ret));
|
||||||
|
}
|
||||||
|
let k = ret.v || ret;
|
||||||
|
if(!obj.conflicts[k]) {
|
||||||
|
|
||||||
|
let mm = k.match(/^\d+[a-z]? /);
|
||||||
|
let d = '';
|
||||||
|
if(mm) {
|
||||||
|
d = obj.conflicts[mm[0].trim()];
|
||||||
|
if(d) {
|
||||||
|
d = d.description;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mm = _.filter(allKeys, function(ak){
|
||||||
|
let rg = new RegExp('^'+k+'(?:(?:[a-z]?-\\d+)|[a-z])$','g');
|
||||||
|
return rg.test(ak);
|
||||||
|
});
|
||||||
|
|
||||||
|
if(mm && mm.length > 0) {
|
||||||
|
|
||||||
|
let ret2 = {};
|
||||||
|
if(ret !== item) {
|
||||||
|
ret2 = {
|
||||||
|
op: '?',
|
||||||
|
v: _.map(mm, function(x, y) {
|
||||||
|
return Object.assign({}, ret, {v: x});
|
||||||
|
})
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
|
||||||
|
ret2 = {
|
||||||
|
op: '?',
|
||||||
|
v: mm
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ret2.length == 1){
|
||||||
|
ret2 = ret2[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
//console.log('OUTLIER!!', stk.join('/'), '[' + k + ']:', item, ' ---> ', JSON.stringify(ret), ' ____ ', JSON.stringify(ret2));
|
||||||
|
ret = ret2;
|
||||||
|
} else {
|
||||||
|
//console.log('!!!!!OUTLIER!!', stk.join('/'), '[' + k + ']:', item, ' ---> ', JSON.stringify(ret), ' ____ ', d);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//console.log('"' + k + '",');
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
} else if(Array.isArray(item)) {
|
||||||
|
|
||||||
|
return item.map(expand);
|
||||||
|
|
||||||
|
} else if(item.v) {
|
||||||
|
|
||||||
|
item.v = expand(item.v);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
function fixToCh(tmpl) {
|
||||||
|
let orig = tmpl;
|
||||||
|
let didChange = false;
|
||||||
|
let ret = {
|
||||||
|
v: tmpl
|
||||||
|
};
|
||||||
|
|
||||||
|
let ch = /\s+ch (?:(?:[a-zA-Z0-9-]+|“[^”]+”) to (?:[a-zA-Z0-9-]+|“[^”]+”))(?:(?: &|,| and) (?:[a-zA-Z0-9-]+|“[^”]+”) to (?:[a-zA-Z0-9-]+|“[^”]+”))*(?: &|,| and)?/;
|
||||||
|
let m = ch.exec(tmpl);
|
||||||
|
|
||||||
|
if(m) {
|
||||||
|
|
||||||
|
let val = [];
|
||||||
|
val.push(tmpl.slice(0, m.index));
|
||||||
|
didChange = true;
|
||||||
|
|
||||||
|
let tfm = ret.tfm = ret.tfm|| {};
|
||||||
|
|
||||||
|
let dat = m[0];
|
||||||
|
let ch2 = /(?:([a-zA-Z0-9-]+)|“([^”]+)”) to (?:([a-zA-Z0-9-]+)|“([^”]+)”)/g;
|
||||||
|
let m2;
|
||||||
|
while(m2 = ch2.exec(dat)) {
|
||||||
|
tfm[(m2[1] || m2[2]).trim()] = (m2[3] || m2[4]).trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
val.push(tmpl.slice(m.index + m[0].length));
|
||||||
|
|
||||||
|
ret.v = val.join(' ').trim();
|
||||||
|
tmpl = ret.v;
|
||||||
|
}
|
||||||
|
|
||||||
|
let tr = / tr ([A-Z-0-9]+) & ([A-Z-0-9]+)(?:&| |,)*(?= |$)/;
|
||||||
|
m = tr.exec(tmpl);
|
||||||
|
if(m) {
|
||||||
|
|
||||||
|
let val = [];
|
||||||
|
val.push(tmpl.slice(0, m.index));
|
||||||
|
|
||||||
|
|
||||||
|
let tfm = ret.tfm = ret.tfm || {};
|
||||||
|
|
||||||
|
let dat = m[0];
|
||||||
|
tfm[m[1].trim()] = m[2].trim();
|
||||||
|
tfm[m[2].trim()] = m[1].trim();
|
||||||
|
|
||||||
|
val.push(tmpl.slice(m.index + m[0].length));
|
||||||
|
|
||||||
|
ret.v = val.join(' ').trim();
|
||||||
|
tmpl = ret.v;
|
||||||
|
|
||||||
|
didChange = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!didChange)
|
||||||
|
return tmpl;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(JSON.stringify(obj, null, '\t'));
|
168
index.js
168
index.js
@ -2,38 +2,31 @@
|
|||||||
const seedrandom = require('seedrandom');
|
const seedrandom = require('seedrandom');
|
||||||
const plotto = require("./data/plotto.json");
|
const plotto = require("./data/plotto.json");
|
||||||
|
|
||||||
|
function regEscape(s) {
|
||||||
|
return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
|
||||||
|
};
|
||||||
|
|
||||||
function pick(rng, arr) {
|
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 min = 0;
|
||||||
let max = arr.length;
|
let max = arr.length;
|
||||||
return arr[Math.floor(this.fn() * (max - min)) + min];
|
let i =Math.floor(rng() * (max - min)) + min;
|
||||||
}
|
let ret = arr[i];
|
||||||
|
//console.log(i, ':', JSON.stringify(ret), '!!!!', JSON.stringify(arr));
|
||||||
let ch = /\s+ch (?:([a-zA-Z0-9-]+|“[^”]+”) to ([a-zA-Z0-9-]+|“[^”]+”))(?:(?: &|,) ([a-zA-Z0-9-]+|“[^”]+”) to ([a-zA-Z0-9-]+|“[^”]+”))*/;
|
return ret;
|
||||||
|
|
||||||
function resolveConflict(id) {
|
|
||||||
|
|
||||||
var ids = id.split(',');
|
|
||||||
var mainId = ids[0].match(/^\d+/);
|
|
||||||
|
|
||||||
for(let i of ids) {
|
|
||||||
|
|
||||||
let conflictid = i;
|
|
||||||
if(conflictid.indexOf(mainId) != 0)
|
|
||||||
conflictid = mainId + i;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class PlotGenerator {
|
class PlotGenerator {
|
||||||
|
|
||||||
constructor({ seed=null, flipGenders=undefined, names=plotto.characters } = {}) {
|
constructor({ seed=null, flipGenders=undefined } = {}) {
|
||||||
this._rng = seedrandom(seed);
|
this._rng = seedrandom(seed);
|
||||||
this._names = names;
|
|
||||||
|
|
||||||
if(flipGenders === undefined) {
|
if(flipGenders === undefined) {
|
||||||
this._flipGenders = this._rng() < 0.5; //50% chance true/false
|
this._flipGenders = this._rng() < 0.5; //50% chance true/false
|
||||||
@ -45,34 +38,127 @@ class PlotGenerator {
|
|||||||
get flipGenders() { return this._flipGenders; }
|
get flipGenders() { return this._flipGenders; }
|
||||||
set flipGenders(flip) { this._flipGenders = flip; }
|
set flipGenders(flip) { this._flipGenders = flip; }
|
||||||
|
|
||||||
get names() { return this._names; }
|
|
||||||
set names(names) { this._names = Object.assign({}, plotto.characters, names); }
|
|
||||||
|
|
||||||
generate() {
|
generate() {
|
||||||
|
|
||||||
let a = pick(this._rng, plotto.masterClauseA);
|
let rootTransform = {};
|
||||||
let b = pick(this._rng, plotto.masterClauseB);
|
if(this._flipGenders) {
|
||||||
let c = pick(this._rng, plotto.masterClauseA);
|
rootTransform = {
|
||||||
|
"A" : "B",
|
||||||
return [
|
"A-2": "B-2",
|
||||||
a + ' ' + b.description,
|
"A-3": "B-3",
|
||||||
this._expand(b),
|
"A-4": "B-4",
|
||||||
c
|
"A-5": "B-5",
|
||||||
].join(' ');
|
"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"
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
_expand(b) {
|
let preamble = pick(this._rng, plotto.masterClauseA);
|
||||||
|
let resolution = pick(this._rng, plotto.masterClauseC);
|
||||||
|
let masterPlot = pick(this._rng, plotto.masterClauseB);
|
||||||
|
|
||||||
let initial = plotto.conflicts[pick(this._rng, b.nodes)];
|
let subject = [masterPlot.group, ' / ', masterPlot.subgroup, ': ', masterPlot.description].join('');
|
||||||
|
|
||||||
let leadIn = pick(this._rng, initial.leadIns);
|
let conflict = plotto.conflicts[pick(this._rng, masterPlot.nodes)];
|
||||||
let carryOn = pick(this._rng, initial.carryOns);
|
|
||||||
|
|
||||||
|
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;
|
exports.PlotGenerator = PlotGenerator;
|
||||||
|
|
||||||
|
let g = new PlotGenerator();
|
||||||
|
console.log(g.generate());
|
||||||
|
Loading…
x
Reference in New Issue
Block a user