mirror of
https://github.com/unanmed/ginka-generator.git
synced 2026-05-14 21:01:12 +08:00
132 lines
3.9 KiB
TypeScript
132 lines
3.9 KiB
TypeScript
import { writeFile } from 'fs/promises';
|
|
import { autoLabelTowers } from './auto/auto';
|
|
import { IAutoLabelConfig, TowerColor } from './auto/types';
|
|
import { GinkaDataset, GinkaTrainData } from './types';
|
|
|
|
const [, , output, towerInfo, ...folders] = process.argv;
|
|
|
|
// 根据结果手动屏蔽一些满足条件但是不适合的塔
|
|
const ignoredTower: string[] = [
|
|
'blossom',
|
|
'cxzl_imprisoned',
|
|
'hpxwzwy',
|
|
'jianchuan1',
|
|
'MC2D',
|
|
'minecraft',
|
|
'waterfultowerx',
|
|
'xieyuhouxu'
|
|
];
|
|
|
|
const ignoredFloor: Record<string, string[]> = {
|
|
cxzl2: ['MN5', 'MN7', 'MN8', 'MN49', 'MN57', 'MQ77', 'MT85', 'MZ75'],
|
|
cxzl: ['MT63', 'MT186', 'MT256', 'MT304', 'MT313', 'MT314', 'MT334'],
|
|
gl: ['MH2'],
|
|
gooTower2: ['MT96'],
|
|
levelstower: ['LV0c'],
|
|
lzlltete: ['MT0'],
|
|
myslmdrydtwo: ['MT49'],
|
|
OneStepToHell: ['MT02', 'MT05', 'MT07', 'MT09', 'MT44'],
|
|
ousha: ['MT152', 'MT158', 'MT160'],
|
|
Pacificwar: ['MT102', 'MT131'],
|
|
tiandijinghz: ['MT54', 'MT41', 'A21', 'MT50', 'MT110'],
|
|
wdg3: ['MT37'],
|
|
xiangyaochumo: ['A4', 'A8', 'A9', 'MT62'],
|
|
xinxin2: ['B02'],
|
|
yishizhishen: ['MT8'],
|
|
zd1: ['MH9', 'MT10'],
|
|
zhenshishenghuo: ['MT52', 'MT131', 'MT132']
|
|
};
|
|
|
|
const labelConfig: IAutoLabelConfig = {
|
|
allowedSize: [[13, 13]],
|
|
allowUselessBranch: false,
|
|
maxWallDensityStd: 0.25,
|
|
minEnemyRatio: 0.02,
|
|
maxEnemyRatio: 0.3,
|
|
minWallRatio: 0.1,
|
|
maxWallRatio: 0.6,
|
|
minResourceRatio: 0.02,
|
|
maxResourceRatio: 0.3,
|
|
minDoorRatio: 0,
|
|
maxDoorRatio: 0.2,
|
|
minFishCount: 0,
|
|
maxFishCount: 2,
|
|
minEntryCount: 1,
|
|
maxEntryCount: 4,
|
|
ignoreIssues: true,
|
|
customTowerFilter: info => {
|
|
if (info.color !== TowerColor.Blue && info.color !== TowerColor.Green) {
|
|
return false;
|
|
}
|
|
if (info.people < 1000) {
|
|
return false;
|
|
}
|
|
if (info.name.startsWith('51') && info.name.length > 2) {
|
|
return Math.random() > 0.98;
|
|
}
|
|
if (ignoredTower.includes(info.name)) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
},
|
|
customFloorFilter: floor => {
|
|
if (floor.info.topo.graphs.length > 1) {
|
|
return false;
|
|
}
|
|
if (floor.data.hasCannotInOut) {
|
|
return false;
|
|
}
|
|
if (floor.info.topo.unreachable.size > 5) {
|
|
return false;
|
|
}
|
|
if (ignoredFloor[floor.tower.name]?.includes(floor.mapId)) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
(async () => {
|
|
const result = await autoLabelTowers(towerInfo, folders, labelConfig);
|
|
// 转换格式并写入文件
|
|
const dataset: GinkaDataset = {
|
|
datasetId: Math.floor(Math.random() * 1e12),
|
|
data: {}
|
|
};
|
|
result.forEach(tower => {
|
|
tower.maps.forEach(floor => {
|
|
const id = `${tower.tower.name}::${floor.mapId}`;
|
|
const width = floor.data.map[0].length;
|
|
const height = floor.data.map.length;
|
|
const info = floor.info;
|
|
const data: GinkaTrainData = {
|
|
map: floor.data.map,
|
|
size: [width, height],
|
|
tag: Array(64).fill(0),
|
|
val: [
|
|
info.globalDensity,
|
|
info.wallDensity,
|
|
0,
|
|
info.doorDensity,
|
|
info.enemyDensity,
|
|
info.resourceDensity,
|
|
info.gemDensity,
|
|
info.potionDensity,
|
|
info.keyDensity,
|
|
info.itemDensity,
|
|
info.entryCount,
|
|
info.specialDoorCount,
|
|
info.fishCount,
|
|
0,
|
|
0,
|
|
0
|
|
]
|
|
};
|
|
dataset.data[id] = data;
|
|
});
|
|
});
|
|
await writeFile(output, JSON.stringify(dataset), 'utf-8');
|
|
console.log(`结果已写入 ${output}`);
|
|
})();
|