add Event

This commit is contained in:
Vick Scarlet
2021-08-15 22:05:43 +08:00
parent 8d0eb0a600
commit dcc9cd2383
8 changed files with 227 additions and 80 deletions

2
.vscode/launch.json vendored
View File

@ -8,7 +8,7 @@
"type": "node",
"request": "launch",
"name": "test",
"program": "${workspaceFolder}/app.js",
"program": "${workspaceFolder}/test.js",
"skipFiles": [
"<node_internals>/**"
]

View File

@ -1,6 +1,6 @@
{
"name": "xlsx_transform",
"module": "true",
"type": "module",
"bin": "convert.js",
"dependencies": {
"xlsx": "^0.17.0"

View File

@ -1,6 +1,10 @@
class Condition {
constructor(prop) {
this._prop = prop;
constructor(initialData={}) {
this.initial(initialData);
}
initial({prop}) {
if(prop) this.prop = prop;
}
parse(condition) {

95
src/event.js Normal file
View File

@ -0,0 +1,95 @@
import {clone} from './util.js';
class Event {
constructor(initialData={}) {
this.initial(initialData);
}
initial({prop, condition, events, pools}) {
if(prop) this.prop = prop;
if(condition) this.condition = condition;
if(events) this.events = events;
if(pools) this.pools = pools;
}
random() {
const age = this.getProp(this.prop.TYPES.AGE);
const pool = this.filterPool(
this.getPool(age)
);
let totalWeights = 0;
for(const [,weight] of pool)
totalWeights += weight;
let random = Math.random() * totalWeights;
for(const [event,weight] of pool)
if((random-=weight)<0)
return event;
}
check(eventId) {
const { Include, Exclude } = this.get(eventId);
if(Exclude && this.checkCondition(Exclude)) return false;
if(Include) return this.checkCondition(Include);
return true;
}
checkCondition(condition) {
return this.condition.check(condition);
}
filterPool(pool) {
return pool.filter(([event])=>this.check(event));
}
get(eventId) {
const event = this.events[eventId];
if(!event) console.error(`[ERROR] No Event[${eventId}]`);
return clone(event);
}
getPool(age) {
return clone(this.pools[age].Pool) || [];
}
getProp(prop) {
return this.prop.get(prop);
}
get prop() {return this._prop;}
set prop(p) {this._prop = p;}
get condition() {return this._condition;}
set condition(c) {this._condition = c;}
get pools() {return this._pools;}
set pools(p) {
this._pools = p;
for(const age in p)
p[age].Pool = p[age].Pool?.map(v=>{
const value = v.split('*').map(n=>Number(n));
if(value.length==1) value.push(1);
return value;
});
}
get events() {return this._events;}
set events(e) {
this._events = e;
for(const id in e) {
const event = e[id];
if(!event.branch) continue;
event.branch = event.branch.map(b=>{
b = b.split(':');
b[1] = Number(b[1]);
return b;
});
}
}
}
export default Event;

View File

@ -1,20 +1,29 @@
import {clone} from './util.js';
class Prop {
constructor(initialData) {
this._data = {};
for(const key in initialData)
this.set(key, initialData[key]);
constructor(initialData={}) {
this.initial(initialData);
}
initial(data) {
this._data = {
AGE: 0
};
for(const key in data)
this.set(key, data[key]);
}
get(prop) {
switch(prop) {
case 'CHR':
case 'INT':
case 'STR':
case 'MNY':
case 'SPR':
case 'LIF':
case 'TLT':
case 'EVT':
case this.TYPES.AGE:
case this.TYPES.CHR:
case this.TYPES.INT:
case this.TYPES.STR:
case this.TYPES.MNY:
case this.TYPES.SPR:
case this.TYPES.LIF:
case this.TYPES.TLT:
case this.TYPES.EVT:
return this._data[prop];
default: return 0;
}
@ -22,15 +31,16 @@ class Prop {
set(prop, value) {
switch(prop) {
case 'CHR':
case 'INT':
case 'STR':
case 'MNY':
case 'SPR':
case 'LIF':
case 'TLT':
case 'EVT':
this._data[prop] = this.clone(value);
case this.TYPES.AGE:
case this.TYPES.CHR:
case this.TYPES.INT:
case this.TYPES.STR:
case this.TYPES.MNY:
case this.TYPES.SPR:
case this.TYPES.LIF:
case this.TYPES.TLT:
case this.TYPES.EVT:
this._data[prop] = clone(value);
break;
default: return 0;
}
@ -38,16 +48,17 @@ class Prop {
change(prop, value) {
switch(prop) {
case 'CHR':
case 'INT':
case 'STR':
case 'MNY':
case 'SPR':
case 'LIF':
case this.TYPES.AGE:
case this.TYPES.CHR:
case this.TYPES.INT:
case this.TYPES.STR:
case this.TYPES.MNY:
case this.TYPES.SPR:
case this.TYPES.LIF:
this._data[prop] += value;
break;
case 'TLT':
case 'EVT':
case this.TYPES.TLT:
case this.TYPES.EVT:
const v = this._data[prop];
if(value<0) {
const index = v.indexOf(value);
@ -59,15 +70,18 @@ class Prop {
}
}
clone(value) {
switch(typeof value) {
case 'object':
if(Array.isArray(value)) return value.map(v=>this.clone(v));
const newObj = {};
for(const key in value) newObj[key] = this.clone(value[key]);
return newObj;
default: return value;
}
get TYPES() {
return {
AGE: "AGE",
CHR: "CHR",
INT: "INT",
STR: "STR",
MNY: "MNY",
SPR: "SPR",
LIF: "LIF",
TLT: "TLT",
EVT: "EVT",
};
}
}

12
src/util.js Normal file
View File

@ -0,0 +1,12 @@
function clone(value) {
switch(typeof value) {
case 'object':
if(Array.isArray(value)) return value.map(v=>clone(v));
const newObj = {};
for(const key in value) newObj[key] = clone(value[key]);
return newObj;
default: return value;
}
}
export { clone };

74
test.js
View File

@ -152,39 +152,55 @@
// }
import {readFile} from 'fs/promises';
import Prop from './src/prop.js';
import Condition from './src/condition.js';
import Event from './src/event.js';
const prop = new Prop({
CHR: 5, // 颜值 charm CHR
INT: 5, // 智力 intelligence INT
STR: 5, // 体质 strength STR
MNY: 5, // 家境 money MNY
SPR: 5, // 快乐 spirit SPR
LIF: 5, // 生命 life LIF
TLT: [5], // 天赋 talent TLT
EVT: [5], // 事件 event EVT
});
const condition = new Condition(prop);
// function debug(...conditions) {
// for(const cond of conditions)
// console.debug(condition.check(cond), '\t', cond);
// }
function debug(...conditions) {
for(const cond of conditions)
console.debug(condition.check(cond), '\t', cond);
// debug(
// '(STR<2&MNY>3)|(MNY<2&CHR<2)',
// '(STR<2&MNY>3)',
// '(STR>2&MNY>3)',
// '((((STR>2&MNY>2))))',
// '((((STR>2&MNY>2)|(MNY<2&CHR<2))))',
// '((((STR>2&MNY>2)|(MNY<2&CHR<2)&(STR>2&MNY>3))))',
// '((((STR>2&MNY>2)|(MNY<2&CHR<2))&(STR>2&MNY>3)))',
// 'EVT![1,2,3]',
// 'EVT![1,2]',
// 'EVT?[1,2,3]',
// 'EVT?[1,2]',
// );
// const events = await axios('excel/events.json');
// const pools = await axios('excel/pools.json');
async function debug() {
const events = JSON.parse(await readFile('excel/events.json'));
const pools = JSON.parse(await readFile('excel/pools.json'));
const prop = new Prop();
const condition = new Condition();
const event = new Event();
prop.initial({
CHR: 5, // 颜值 charm CHR
INT: 5, // 智力 intelligence INT
STR: 5, // 体质 strength STR
MNY: 5, // 家境 money MNY
SPR: 5, // 快乐 spirit SPR
LIF: 5, // 生命 life LIF
TLT: [5], // 天赋 talent TLT
EVT: [5], // 事件 event EVT
});
condition.initial({prop});
event.initial({events, pools, prop, condition});
console.debug(event.random());
}
debug(
'(STR<2&MNY>3)|(MNY<2&CHR<2)',
'(STR<2&MNY>3)',
'(STR>2&MNY>3)',
'((((STR>2&MNY>2))))',
'((((STR>2&MNY>2)|(MNY<2&CHR<2))))',
'((((STR>2&MNY>2)|(MNY<2&CHR<2)&(STR>2&MNY>3))))',
'((((STR>2&MNY>2)|(MNY<2&CHR<2))&(STR>2&MNY>3)))',
'EVT![1,2,3]',
'EVT![1,2]',
'EVT?[1,2,3]',
'EVT?[1,2]',
);
debug();

View File

@ -1,10 +1,10 @@
import { readFile, writeFile, stat, readdir } from 'fs/promises';
import * as XLSX from 'xlsx';
import { join, extname, dirname } from 'path';
// import { readFile, writeFile, stat, readdir } from 'fs/promises';
// import * as XLSX from 'xlsx';
// import { join, extname, dirname } from 'path';
// const { readFile, writeFile, stat, readdir } = require('fs/promises');
// const XLSX = require('xlsx');
// const { join, extname, dirname } = require('path');
const { readFile, writeFile, stat, readdir } = require('fs/promises');
const XLSX = require('xlsx');
const { join, extname, dirname } = require('path');
async function transform(filePath) {
const xlsxFileBuffer = await readFile(filePath);
@ -16,14 +16,18 @@ async function transform(filePath) {
const sheetRawData = sheets[sheetName];
if(!sheetRawData['!ref']) break;
const rawData = XLSX.utils.sheet_to_json(sheetRawData);
const newData = [];
const newData = {};
data[sheetName] = newData;
rawData.shift();
for(const row of rawData) {
const rowData = {};
newData.push(rowData)
for(const key in row) {
let mainKey;
for(let key in row) {
const cell = row[key];
if(key[0] == "$") {
key = key.substr(1);
mainKey = cell;
}
if(key.includes(':')) {
const keys = key.split(':');
const lastKey = keys.pop();
@ -39,6 +43,8 @@ async function transform(filePath) {
rowData[key] = cell;
}
}
if(mainKey===undefined) return console.error('No Main Key', rowData);
newData[mainKey] = rowData;
}
}
return data;