mirror of
https://github.com/VickScarlet/lifeRestart.git
synced 2026-03-24 13:33:26 +08:00
add Event
This commit is contained in:
2
.vscode/launch.json
vendored
2
.vscode/launch.json
vendored
@@ -8,7 +8,7 @@
|
|||||||
"type": "node",
|
"type": "node",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"name": "test",
|
"name": "test",
|
||||||
"program": "${workspaceFolder}/app.js",
|
"program": "${workspaceFolder}/test.js",
|
||||||
"skipFiles": [
|
"skipFiles": [
|
||||||
"<node_internals>/**"
|
"<node_internals>/**"
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "xlsx_transform",
|
"name": "xlsx_transform",
|
||||||
"module": "true",
|
"type": "module",
|
||||||
"bin": "convert.js",
|
"bin": "convert.js",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"xlsx": "^0.17.0"
|
"xlsx": "^0.17.0"
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
class Condition {
|
class Condition {
|
||||||
constructor(prop) {
|
constructor(initialData={}) {
|
||||||
this._prop = prop;
|
this.initial(initialData);
|
||||||
|
}
|
||||||
|
|
||||||
|
initial({prop}) {
|
||||||
|
if(prop) this.prop = prop;
|
||||||
}
|
}
|
||||||
|
|
||||||
parse(condition) {
|
parse(condition) {
|
||||||
|
|||||||
95
src/event.js
Normal file
95
src/event.js
Normal 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;
|
||||||
90
src/prop.js
90
src/prop.js
@@ -1,20 +1,29 @@
|
|||||||
|
import {clone} from './util.js';
|
||||||
|
|
||||||
class Prop {
|
class Prop {
|
||||||
constructor(initialData) {
|
constructor(initialData={}) {
|
||||||
this._data = {};
|
this.initial(initialData);
|
||||||
for(const key in initialData)
|
}
|
||||||
this.set(key, initialData[key]);
|
|
||||||
|
initial(data) {
|
||||||
|
this._data = {
|
||||||
|
AGE: 0
|
||||||
|
};
|
||||||
|
for(const key in data)
|
||||||
|
this.set(key, data[key]);
|
||||||
}
|
}
|
||||||
|
|
||||||
get(prop) {
|
get(prop) {
|
||||||
switch(prop) {
|
switch(prop) {
|
||||||
case 'CHR':
|
case this.TYPES.AGE:
|
||||||
case 'INT':
|
case this.TYPES.CHR:
|
||||||
case 'STR':
|
case this.TYPES.INT:
|
||||||
case 'MNY':
|
case this.TYPES.STR:
|
||||||
case 'SPR':
|
case this.TYPES.MNY:
|
||||||
case 'LIF':
|
case this.TYPES.SPR:
|
||||||
case 'TLT':
|
case this.TYPES.LIF:
|
||||||
case 'EVT':
|
case this.TYPES.TLT:
|
||||||
|
case this.TYPES.EVT:
|
||||||
return this._data[prop];
|
return this._data[prop];
|
||||||
default: return 0;
|
default: return 0;
|
||||||
}
|
}
|
||||||
@@ -22,15 +31,16 @@ class Prop {
|
|||||||
|
|
||||||
set(prop, value) {
|
set(prop, value) {
|
||||||
switch(prop) {
|
switch(prop) {
|
||||||
case 'CHR':
|
case this.TYPES.AGE:
|
||||||
case 'INT':
|
case this.TYPES.CHR:
|
||||||
case 'STR':
|
case this.TYPES.INT:
|
||||||
case 'MNY':
|
case this.TYPES.STR:
|
||||||
case 'SPR':
|
case this.TYPES.MNY:
|
||||||
case 'LIF':
|
case this.TYPES.SPR:
|
||||||
case 'TLT':
|
case this.TYPES.LIF:
|
||||||
case 'EVT':
|
case this.TYPES.TLT:
|
||||||
this._data[prop] = this.clone(value);
|
case this.TYPES.EVT:
|
||||||
|
this._data[prop] = clone(value);
|
||||||
break;
|
break;
|
||||||
default: return 0;
|
default: return 0;
|
||||||
}
|
}
|
||||||
@@ -38,16 +48,17 @@ class Prop {
|
|||||||
|
|
||||||
change(prop, value) {
|
change(prop, value) {
|
||||||
switch(prop) {
|
switch(prop) {
|
||||||
case 'CHR':
|
case this.TYPES.AGE:
|
||||||
case 'INT':
|
case this.TYPES.CHR:
|
||||||
case 'STR':
|
case this.TYPES.INT:
|
||||||
case 'MNY':
|
case this.TYPES.STR:
|
||||||
case 'SPR':
|
case this.TYPES.MNY:
|
||||||
case 'LIF':
|
case this.TYPES.SPR:
|
||||||
|
case this.TYPES.LIF:
|
||||||
this._data[prop] += value;
|
this._data[prop] += value;
|
||||||
break;
|
break;
|
||||||
case 'TLT':
|
case this.TYPES.TLT:
|
||||||
case 'EVT':
|
case this.TYPES.EVT:
|
||||||
const v = this._data[prop];
|
const v = this._data[prop];
|
||||||
if(value<0) {
|
if(value<0) {
|
||||||
const index = v.indexOf(value);
|
const index = v.indexOf(value);
|
||||||
@@ -59,15 +70,18 @@ class Prop {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
clone(value) {
|
get TYPES() {
|
||||||
switch(typeof value) {
|
return {
|
||||||
case 'object':
|
AGE: "AGE",
|
||||||
if(Array.isArray(value)) return value.map(v=>this.clone(v));
|
CHR: "CHR",
|
||||||
const newObj = {};
|
INT: "INT",
|
||||||
for(const key in value) newObj[key] = this.clone(value[key]);
|
STR: "STR",
|
||||||
return newObj;
|
MNY: "MNY",
|
||||||
default: return value;
|
SPR: "SPR",
|
||||||
}
|
LIF: "LIF",
|
||||||
|
TLT: "TLT",
|
||||||
|
EVT: "EVT",
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
12
src/util.js
Normal file
12
src/util.js
Normal 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
74
test.js
@@ -152,39 +152,55 @@
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
import {readFile} from 'fs/promises';
|
||||||
import Prop from './src/prop.js';
|
import Prop from './src/prop.js';
|
||||||
import Condition from './src/condition.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) {
|
// debug(
|
||||||
for(const cond of conditions)
|
// '(STR<2&MNY>3)|(MNY<2&CHR<2)',
|
||||||
console.debug(condition.check(cond), '\t', cond);
|
// '(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(
|
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]',
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
import { readFile, writeFile, stat, readdir } from 'fs/promises';
|
// import { readFile, writeFile, stat, readdir } from 'fs/promises';
|
||||||
import * as XLSX from 'xlsx';
|
// import * as XLSX from 'xlsx';
|
||||||
import { join, extname, dirname } from 'path';
|
// import { join, extname, dirname } from 'path';
|
||||||
|
|
||||||
// const { readFile, writeFile, stat, readdir } = require('fs/promises');
|
const { readFile, writeFile, stat, readdir } = require('fs/promises');
|
||||||
// const XLSX = require('xlsx');
|
const XLSX = require('xlsx');
|
||||||
// const { join, extname, dirname } = require('path');
|
const { join, extname, dirname } = require('path');
|
||||||
|
|
||||||
async function transform(filePath) {
|
async function transform(filePath) {
|
||||||
const xlsxFileBuffer = await readFile(filePath);
|
const xlsxFileBuffer = await readFile(filePath);
|
||||||
@@ -16,14 +16,18 @@ async function transform(filePath) {
|
|||||||
const sheetRawData = sheets[sheetName];
|
const sheetRawData = sheets[sheetName];
|
||||||
if(!sheetRawData['!ref']) break;
|
if(!sheetRawData['!ref']) break;
|
||||||
const rawData = XLSX.utils.sheet_to_json(sheetRawData);
|
const rawData = XLSX.utils.sheet_to_json(sheetRawData);
|
||||||
const newData = [];
|
const newData = {};
|
||||||
data[sheetName] = newData;
|
data[sheetName] = newData;
|
||||||
rawData.shift();
|
rawData.shift();
|
||||||
for(const row of rawData) {
|
for(const row of rawData) {
|
||||||
const rowData = {};
|
const rowData = {};
|
||||||
newData.push(rowData)
|
let mainKey;
|
||||||
for(const key in row) {
|
for(let key in row) {
|
||||||
const cell = row[key];
|
const cell = row[key];
|
||||||
|
if(key[0] == "$") {
|
||||||
|
key = key.substr(1);
|
||||||
|
mainKey = cell;
|
||||||
|
}
|
||||||
if(key.includes(':')) {
|
if(key.includes(':')) {
|
||||||
const keys = key.split(':');
|
const keys = key.split(':');
|
||||||
const lastKey = keys.pop();
|
const lastKey = keys.pop();
|
||||||
@@ -39,6 +43,8 @@ async function transform(filePath) {
|
|||||||
rowData[key] = cell;
|
rowData[key] = cell;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(mainKey===undefined) return console.error('No Main Key', rowData);
|
||||||
|
newData[mainKey] = rowData;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
|
|||||||
Reference in New Issue
Block a user