mirror of
https://github.com/unanmed/ginka-generator.git
synced 2026-05-21 18:31:13 +08:00
chore: 调整数据集
This commit is contained in:
parent
10166fa073
commit
df2bd80bec
@ -103,7 +103,14 @@ const ignoredTower: string[] = [
|
|||||||
'zjhy1',
|
'zjhy1',
|
||||||
'zrsz',
|
'zrsz',
|
||||||
'zuozuozhieX_renewed',
|
'zuozuozhieX_renewed',
|
||||||
'ZZZE50Ex'
|
'ZZZE50Ex',
|
||||||
|
'1DQSJ',
|
||||||
|
'againstcov',
|
||||||
|
'Alive',
|
||||||
|
'Aria',
|
||||||
|
'atom',
|
||||||
|
'bdf1',
|
||||||
|
'bingyuanhouzhuan'
|
||||||
];
|
];
|
||||||
|
|
||||||
const ignoredFloor: Record<string, string[]> = {
|
const ignoredFloor: Record<string, string[]> = {
|
||||||
@ -119,7 +126,8 @@ const ignoredFloor: Record<string, string[]> = {
|
|||||||
'MT71',
|
'MT71',
|
||||||
'ML26',
|
'ML26',
|
||||||
'ML27',
|
'ML27',
|
||||||
'MQ28'
|
'MQ28',
|
||||||
|
'MT104'
|
||||||
],
|
],
|
||||||
cxzl: [
|
cxzl: [
|
||||||
'MT63',
|
'MT63',
|
||||||
@ -153,11 +161,11 @@ const ignoredFloor: Record<string, string[]> = {
|
|||||||
zd1: ['MH9', 'MT10'],
|
zd1: ['MH9', 'MT10'],
|
||||||
zhenshishenghuo: ['MT52', 'MT131', 'MT132'],
|
zhenshishenghuo: ['MT52', 'MT131', 'MT132'],
|
||||||
CatLegend: ['MT20', 'MT63', 'MT67'],
|
CatLegend: ['MT20', 'MT63', 'MT67'],
|
||||||
cxzl_wycx: ['MT304', 'MT777'],
|
cxzl_wycx: ['MT304', 'MT777', 'MT494'],
|
||||||
evernight: ['MT30'],
|
evernight: ['MT30'],
|
||||||
bits1: ['MT28'],
|
bits1: ['MT28'],
|
||||||
bits2: ['dltsd5'],
|
bits2: ['dltsd5', 'hdxd5'],
|
||||||
bits114514: ['bysl7', 'byxd3', 'mkpy6', 'sdhxmiddle1'],
|
bits114514: ['bysl7', 'byxd3', 'mkpy6', 'sdhxmiddle1', 'zlzl1', 'zlzl2'],
|
||||||
Black: ['MT12'],
|
Black: ['MT12'],
|
||||||
chaoshuang2: ['MT153'],
|
chaoshuang2: ['MT153'],
|
||||||
EasyPreduct: ['PT40'],
|
EasyPreduct: ['PT40'],
|
||||||
@ -214,10 +222,36 @@ const ignoredFloor: Record<string, string[]> = {
|
|||||||
WhiteLily_1521: ['B9'],
|
WhiteLily_1521: ['B9'],
|
||||||
xsdsj: ['MT40'],
|
xsdsj: ['MT40'],
|
||||||
xxchuanshuo0: ['D35', 'D38', 'D39'],
|
xxchuanshuo0: ['D35', 'D38', 'D39'],
|
||||||
yesterdayReturn: ['MT6-1']
|
yesterdayReturn: ['MT6-1'],
|
||||||
|
'9922': [
|
||||||
|
'Ch4_15',
|
||||||
|
'East3',
|
||||||
|
'East7',
|
||||||
|
'MT12',
|
||||||
|
'East11',
|
||||||
|
'North2',
|
||||||
|
'North3',
|
||||||
|
'North4'
|
||||||
|
],
|
||||||
|
amiyamiya: ['MT27']
|
||||||
};
|
};
|
||||||
|
|
||||||
const labelConfig: IAutoLabelConfig = {
|
const labelConfig: IAutoLabelConfig = {
|
||||||
|
classes: {
|
||||||
|
empty: 0,
|
||||||
|
wall: 1,
|
||||||
|
decoration: 2,
|
||||||
|
commonDoors: [3],
|
||||||
|
specialDoors: [6, 6],
|
||||||
|
keys: [7],
|
||||||
|
redGems: [10],
|
||||||
|
blueGems: [13],
|
||||||
|
greenGems: [16],
|
||||||
|
potions: [19],
|
||||||
|
items: [23],
|
||||||
|
enemies: [26],
|
||||||
|
entry: 29
|
||||||
|
},
|
||||||
allowedSize: [[13, 13]],
|
allowedSize: [[13, 13]],
|
||||||
allowUselessBranch: false,
|
allowUselessBranch: false,
|
||||||
maxWallDensityStd: 0.25,
|
maxWallDensityStd: 0.25,
|
||||||
@ -228,19 +262,25 @@ const labelConfig: IAutoLabelConfig = {
|
|||||||
minResourceRatio: 0.02,
|
minResourceRatio: 0.02,
|
||||||
maxResourceRatio: 0.3,
|
maxResourceRatio: 0.3,
|
||||||
minDoorRatio: 0,
|
minDoorRatio: 0,
|
||||||
maxDoorRatio: 0.2,
|
maxDoorRatio: 0.12,
|
||||||
minFishCount: 0,
|
minFishCount: 0,
|
||||||
maxFishCount: 2,
|
maxFishCount: 2,
|
||||||
minEntryCount: 1,
|
minEntryCount: 1,
|
||||||
maxEntryCount: 4,
|
maxEntryCount: 4,
|
||||||
ignoreIssues: true,
|
ignoreIssues: true,
|
||||||
customTowerFilter: info => {
|
customTowerFilter: info => {
|
||||||
|
// if (info.name !== 'Apeiria') {
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
// if (info.color !== TowerColor.Blue && info.color !== TowerColor.Green) {
|
// if (info.color !== TowerColor.Blue && info.color !== TowerColor.Green) {
|
||||||
// return false;
|
// return false;
|
||||||
// }
|
// }
|
||||||
if (info.people < 1000) {
|
if (info.people < 1000) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (info.name.startsWith('50') && info.name.length > 2) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (info.name.startsWith('51') && info.name.length > 2) {
|
if (info.name.startsWith('51') && info.name.length > 2) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -250,7 +290,6 @@ const labelConfig: IAutoLabelConfig = {
|
|||||||
if (ignoredTower.includes(info.name)) {
|
if (ignoredTower.includes(info.name)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
customFloorFilter: floor => {
|
customFloorFilter: floor => {
|
||||||
@ -267,7 +306,7 @@ const labelConfig: IAutoLabelConfig = {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (floor.tower.name === 'Apeiria') {
|
if (floor.tower.name === 'Apeiria') {
|
||||||
return Math.random() > 0.9;
|
return Math.random() < 0.2;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -94,7 +94,7 @@ export async function autoLabelTowers(
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// 转换楼层
|
// 转换楼层
|
||||||
const converted = convertTowerMap(result, floor);
|
const converted = convertTowerMap(result, floor, config);
|
||||||
const floorInfo = parseFloorInfo(info, converted.map);
|
const floorInfo = parseFloorInfo(info, converted.map);
|
||||||
const floorData: IConvertedMapInfo = {
|
const floorData: IConvertedMapInfo = {
|
||||||
data: converted,
|
data: converted,
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { readFile } from 'fs/promises';
|
import { readFile } from 'fs/promises';
|
||||||
import { IFloorInfo, ITowerInfo, TowerColor } from './types';
|
import { IFloorInfo, ITowerInfo, TowerColor } from './types';
|
||||||
import { buildTopologicalGraph } from 'src/topology/graph';
|
import { buildTopologicalGraph } from '../topology/graph';
|
||||||
import {
|
import {
|
||||||
commonDoorTiles,
|
commonDoorTiles,
|
||||||
doorTiles,
|
doorTiles,
|
||||||
@ -14,8 +14,8 @@ import {
|
|||||||
resourceTiles,
|
resourceTiles,
|
||||||
specialDoorTiles,
|
specialDoorTiles,
|
||||||
wallTiles
|
wallTiles
|
||||||
} from 'src/shared';
|
} from '../shared';
|
||||||
import { NodeType } from 'src/topology/interface';
|
import { NodeType } from '../topology/interface';
|
||||||
|
|
||||||
interface IRawTowerInfo {
|
interface IRawTowerInfo {
|
||||||
/** 作者 id */
|
/** 作者 id */
|
||||||
|
|||||||
@ -1,4 +1,9 @@
|
|||||||
import { ICodeRunResult, IConvertedMap, INeededFloorData } from './types';
|
import {
|
||||||
|
IAutoLabelConfig,
|
||||||
|
ICodeRunResult,
|
||||||
|
IConvertedMap,
|
||||||
|
INeededFloorData
|
||||||
|
} from './types';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 运行塔的代码
|
* 运行塔的代码
|
||||||
@ -39,7 +44,8 @@ function edge(x: number, y: number, width: number, height: number) {
|
|||||||
|
|
||||||
export function convertTowerMap(
|
export function convertTowerMap(
|
||||||
result: ICodeRunResult,
|
result: ICodeRunResult,
|
||||||
floor: INeededFloorData
|
floor: INeededFloorData,
|
||||||
|
config: IAutoLabelConfig
|
||||||
): IConvertedMap {
|
): IConvertedMap {
|
||||||
const width = floor.map[0].length;
|
const width = floor.map[0].length;
|
||||||
const height = floor.map.length;
|
const height = floor.map.length;
|
||||||
@ -109,33 +115,31 @@ export function convertTowerMap(
|
|||||||
core.status.hero.def = 0;
|
core.status.hero.def = 0;
|
||||||
core.status.hero.mdef = 0;
|
core.status.hero.mdef = 0;
|
||||||
|
|
||||||
|
const tiles = config.classes;
|
||||||
|
|
||||||
for (let nx = 0; nx < width; nx++) {
|
for (let nx = 0; nx < width; nx++) {
|
||||||
for (let ny = 0; ny < height; ny++) {
|
for (let ny = 0; ny < height; ny++) {
|
||||||
const num = floor.map[ny][nx];
|
const num = floor.map[ny][nx];
|
||||||
if (num === 0) {
|
if (num === 0 || num === 17) {
|
||||||
converted[ny][nx] = 0;
|
converted[ny][nx] = tiles.empty;
|
||||||
continue;
|
|
||||||
} else if (num === 17) {
|
|
||||||
hasCannotInOut = true;
|
|
||||||
converted[ny][nx] = 0;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const loc = `${nx},${ny}`;
|
const loc = `${nx},${ny}`;
|
||||||
if (floor.changeFloor[loc]) {
|
if (floor.changeFloor[loc]) {
|
||||||
converted[ny][nx] = 29;
|
converted[ny][nx] = tiles.entry;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const block = result.map[num];
|
const block = result.map[num];
|
||||||
if (!block) {
|
if (!block) {
|
||||||
// 图块不存在说明是额外素材中的内容,默认不可通行,视为墙壁
|
// 图块不存在说明是额外素材中的内容,默认不可通行,视为墙壁
|
||||||
converted[ny][nx] = 1;
|
converted[ny][nx] = tiles.wall;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// 怪物处理
|
// 怪物处理
|
||||||
if (block.cls === 'enemys' || block.cls === 'enemy48') {
|
if (block.cls === 'enemys' || block.cls === 'enemy48') {
|
||||||
const enemy = result.enemy[block.id];
|
const enemy = result.enemy[block.id];
|
||||||
if (!enemy) {
|
if (!enemy) {
|
||||||
converted[ny][nx] = 0;
|
converted[ny][nx] = tiles.empty;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const value = enemy.hp * (enemy.atk + enemy.def);
|
const value = enemy.hp * (enemy.atk + enemy.def);
|
||||||
@ -146,7 +150,7 @@ export function convertTowerMap(
|
|||||||
if (block.cls === 'items') {
|
if (block.cls === 'items') {
|
||||||
const item = result.item[block.id];
|
const item = result.item[block.id];
|
||||||
if (!item) {
|
if (!item) {
|
||||||
converted[ny][nx] = 0;
|
converted[ny][nx] = tiles.empty;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// 先清空内容
|
// 先清空内容
|
||||||
@ -155,22 +159,32 @@ export function convertTowerMap(
|
|||||||
heroStatus.def = 0;
|
heroStatus.def = 0;
|
||||||
heroStatus.mdef = 0;
|
heroStatus.mdef = 0;
|
||||||
if (block.id === 'pickaxe') {
|
if (block.id === 'pickaxe') {
|
||||||
converted[ny][nx] = 24;
|
const idx = Math.min(tiles.items.length - 1, 0);
|
||||||
|
converted[ny][nx] = tiles.items[idx];
|
||||||
continue;
|
continue;
|
||||||
} else if (block.id === 'bomb') {
|
} else if (block.id === 'bomb') {
|
||||||
converted[ny][nx] = 24;
|
const idx = Math.min(tiles.items.length - 1, 1);
|
||||||
|
converted[ny][nx] = tiles.items[idx];
|
||||||
continue;
|
continue;
|
||||||
} else if (block.id === 'centerFly') {
|
} else if (block.id === 'centerFly') {
|
||||||
converted[ny][nx] = 23;
|
const idx = Math.min(tiles.items.length - 1, 2);
|
||||||
|
converted[ny][nx] = tiles.items[idx];
|
||||||
continue;
|
continue;
|
||||||
} else if (block.id === 'yellowKey') {
|
} else if (block.id === 'yellowKey') {
|
||||||
converted[ny][nx] = 7;
|
const idx = Math.min(tiles.items.length - 1, 0);
|
||||||
|
converted[ny][nx] = tiles.keys[idx];
|
||||||
continue;
|
continue;
|
||||||
} else if (block.id === 'blueKey') {
|
} else if (block.id === 'blueKey') {
|
||||||
converted[ny][nx] = 8;
|
const idx = Math.min(tiles.items.length - 1, 1);
|
||||||
|
converted[ny][nx] = tiles.keys[idx];
|
||||||
continue;
|
continue;
|
||||||
} else if (block.id === 'redKey') {
|
} else if (block.id === 'redKey') {
|
||||||
converted[ny][nx] = 9;
|
const idx = Math.min(tiles.items.length - 1, 2);
|
||||||
|
converted[ny][nx] = tiles.keys[idx];
|
||||||
|
continue;
|
||||||
|
} else if (block.id === 'greenKey') {
|
||||||
|
const idx = Math.min(tiles.items.length - 1, 3);
|
||||||
|
converted[ny][nx] = tiles.keys[idx];
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// 执行道具效果
|
// 执行道具效果
|
||||||
@ -213,30 +227,34 @@ export function convertTowerMap(
|
|||||||
itemMap.set(ny * width + nx, arr);
|
itemMap.set(ny * width + nx, arr);
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
converted[ny][nx] = 0;
|
converted[ny][nx] = tiles.empty;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 门信息,这种处理方式只能处理 2.7+ 的塔,老塔估计处理不了,不过老塔占比也不大,忽略就好了
|
// 门信息,这种处理方式只能处理 2.7+ 的塔,老塔估计处理不了,不过老塔占比也不大,忽略就好了
|
||||||
if (block.doorInfo && Object.keys(block.doorInfo.keys).length > 0) {
|
if (block.doorInfo && Object.keys(block.doorInfo.keys).length > 0) {
|
||||||
if (block.id === 'specialDoor') {
|
if (block.id === 'specialDoor') {
|
||||||
converted[ny][nx] = 6;
|
converted[ny][nx] = tiles.specialDoors[0];
|
||||||
continue;
|
continue;
|
||||||
} else if (
|
} else if ('greenKey' in block.doorInfo.keys) {
|
||||||
'redKey' in block.doorInfo.keys ||
|
const idx = Math.min(tiles.commonDoors.length - 1, 3);
|
||||||
'greenKey' in block.doorInfo.keys
|
converted[ny][nx] = tiles.commonDoors[idx];
|
||||||
) {
|
} else if ('redKey' in block.doorInfo.keys) {
|
||||||
converted[ny][nx] = 5;
|
const idx = Math.min(tiles.commonDoors.length - 1, 2);
|
||||||
|
converted[ny][nx] = tiles.commonDoors[idx];
|
||||||
continue;
|
continue;
|
||||||
} else if ('blueKey' in block.doorInfo.keys) {
|
} else if ('blueKey' in block.doorInfo.keys) {
|
||||||
converted[ny][nx] = 4;
|
const idx = Math.min(tiles.commonDoors.length - 1, 1);
|
||||||
|
converted[ny][nx] = tiles.commonDoors[idx];
|
||||||
continue;
|
continue;
|
||||||
} else if ('yellowKey' in block.doorInfo.keys) {
|
} else if ('yellowKey' in block.doorInfo.keys) {
|
||||||
converted[ny][nx] = 3;
|
const idx = Math.min(tiles.commonDoors.length - 1, 0);
|
||||||
|
converted[ny][nx] = tiles.commonDoors[idx];
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
// 其他门一律视为黄门
|
// 其余视为绿门
|
||||||
converted[ny][nx] = 3;
|
const idx = Math.min(tiles.commonDoors.length - 1, 3);
|
||||||
|
converted[ny][nx] = tiles.commonDoors[idx];
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -261,16 +279,16 @@ export function convertTowerMap(
|
|||||||
fg2Block?.cannotIn ||
|
fg2Block?.cannotIn ||
|
||||||
fg2Block?.cannotOut
|
fg2Block?.cannotOut
|
||||||
) {
|
) {
|
||||||
converted[ny][nx] = 0;
|
converted[ny][nx] = tiles.empty;
|
||||||
hasCannotInOut = true;
|
hasCannotInOut = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// 墙壁处理
|
// 墙壁处理
|
||||||
if (block.canPass) {
|
if (block.canPass) {
|
||||||
converted[ny][nx] = 0;
|
converted[ny][nx] = tiles.empty;
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
converted[ny][nx] = 1;
|
converted[ny][nx] = tiles.wall;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -285,15 +303,18 @@ export function convertTowerMap(
|
|||||||
enemyMap.forEach((value, pos) => {
|
enemyMap.forEach((value, pos) => {
|
||||||
const nx = pos % width;
|
const nx = pos % width;
|
||||||
const ny = Math.floor(pos / width);
|
const ny = Math.floor(pos / width);
|
||||||
converted[ny][nx] = 26;
|
converted[ny][nx] = tiles.enemies[0];
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
enemyMap.forEach((value, pos) => {
|
enemyMap.forEach((value, pos) => {
|
||||||
const nx = pos % width;
|
const nx = pos % width;
|
||||||
const ny = Math.floor(pos / width);
|
const ny = Math.floor(pos / width);
|
||||||
const ratio = (value - minEnemyValue) / enemyValueDelta;
|
const ratio = (value - minEnemyValue) / enemyValueDelta;
|
||||||
const n = Math.min(Math.floor(ratio * 3), 2);
|
const idx = Math.min(
|
||||||
converted[ny][nx] = 26 + n;
|
Math.floor(ratio * tiles.enemies.length),
|
||||||
|
tiles.enemies.length - 1
|
||||||
|
);
|
||||||
|
converted[ny][nx] = tiles.enemies[idx];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -317,19 +338,19 @@ export function convertTowerMap(
|
|||||||
// 资源判定为占比最大的那个
|
// 资源判定为占比最大的那个
|
||||||
// 如果只有一种资源且道具包含这种属性,全部使用最低的资源种类
|
// 如果只有一种资源且道具包含这种属性,全部使用最低的资源种类
|
||||||
if (minHpValue === maxHpValue && hp > 0) {
|
if (minHpValue === maxHpValue && hp > 0) {
|
||||||
converted[ny][nx] = 19;
|
converted[ny][nx] = tiles.potions[0];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (minAtkValue === maxAtkValue && atk > 0) {
|
if (minAtkValue === maxAtkValue && atk > 0) {
|
||||||
converted[ny][nx] = 10;
|
converted[ny][nx] = tiles.redGems[0];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (minDefValue === maxDefValue && def > 0) {
|
if (minDefValue === maxDefValue && def > 0) {
|
||||||
converted[ny][nx] = 13;
|
converted[ny][nx] = tiles.blueGems[0];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (minMdefValue === maxMdefValue && mdef > 0) {
|
if (minMdefValue === maxMdefValue && mdef > 0) {
|
||||||
converted[ny][nx] = 16;
|
converted[ny][nx] = tiles.greenGems[0];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const hpRatio = (hp - minHpValue) / hpValueDelta;
|
const hpRatio = (hp - minHpValue) / hpValueDelta;
|
||||||
@ -353,68 +374,38 @@ export function convertTowerMap(
|
|||||||
switch (maxIndex) {
|
switch (maxIndex) {
|
||||||
case 0: {
|
case 0: {
|
||||||
// 血瓶
|
// 血瓶
|
||||||
const n = Math.min(Math.floor(hpRatio * 4), 3);
|
const idx = Math.min(
|
||||||
converted[ny][nx] = 19 + n;
|
Math.floor(hpRatio * tiles.potions.length),
|
||||||
|
tiles.potions.length - 1
|
||||||
|
);
|
||||||
|
converted[ny][nx] = tiles.potions[idx];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 1: {
|
case 1: {
|
||||||
// 红宝石,这里不可能只有一种数值了,不需要判断
|
// 红宝石,这里不可能只有一种数值了,不需要判断
|
||||||
if (itemAtkSet.size === 2) {
|
const idx = Math.min(
|
||||||
if (atkRatio <= 0.5) {
|
Math.floor(atkRatio * tiles.redGems.length),
|
||||||
// 小宝石
|
tiles.redGems.length - 1
|
||||||
converted[ny][nx] = 10;
|
);
|
||||||
} else {
|
converted[ny][nx] = tiles.redGems[idx];
|
||||||
// 大宝石
|
|
||||||
if (maxAtkValue / minAtkValue > 3) {
|
|
||||||
converted[nx][nx] = 12;
|
|
||||||
} else {
|
|
||||||
converted[ny][nx] = 11;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const n = Math.min(Math.floor(atkRatio * 3), 2);
|
|
||||||
converted[ny][nx] = 10 + n;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 2: {
|
case 2: {
|
||||||
// 蓝宝石,这里不可能只有一种数值了,不需要判断
|
// 蓝宝石,这里不可能只有一种数值了,不需要判断
|
||||||
if (itemDefSet.size === 2) {
|
const idx = Math.min(
|
||||||
if (defRatio <= 0.5) {
|
Math.floor(defRatio * tiles.blueGems.length),
|
||||||
// 小宝石
|
tiles.blueGems.length - 1
|
||||||
converted[ny][nx] = 13;
|
);
|
||||||
} else {
|
converted[ny][nx] = tiles.blueGems[idx];
|
||||||
// 大宝石
|
|
||||||
if (maxDefValue / minDefValue > 3) {
|
|
||||||
converted[nx][nx] = 15;
|
|
||||||
} else {
|
|
||||||
converted[ny][nx] = 14;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const n = Math.min(Math.floor(defRatio * 3), 2);
|
|
||||||
converted[ny][nx] = 13 + n;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 2: {
|
case 2: {
|
||||||
// 绿宝石,这里不可能只有一种数值了,不需要判断
|
// 绿宝石,这里不可能只有一种数值了,不需要判断
|
||||||
if (itemMdefSet.size === 2) {
|
const idx = Math.min(
|
||||||
if (mdefRatio <= 0.5) {
|
Math.floor(mdefRatio * tiles.greenGems.length),
|
||||||
// 小宝石
|
tiles.greenGems.length - 1
|
||||||
converted[ny][nx] = 16;
|
);
|
||||||
} else {
|
converted[ny][nx] = tiles.greenGems[idx];
|
||||||
// 大宝石
|
|
||||||
if (maxMdefValue / minMdefValue > 3) {
|
|
||||||
converted[nx][nx] = 18;
|
|
||||||
} else {
|
|
||||||
converted[ny][nx] = 17;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const n = Math.min(Math.floor(mdefRatio * 3), 2);
|
|
||||||
converted[ny][nx] = 16 + n;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -428,7 +419,7 @@ export function convertTowerMap(
|
|||||||
!isFinite(converted[ny][nx]) ||
|
!isFinite(converted[ny][nx]) ||
|
||||||
converted[ny][nx] < 0
|
converted[ny][nx] < 0
|
||||||
) {
|
) {
|
||||||
converted[ny][nx] = 0;
|
converted[ny][nx] = tiles.empty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -95,7 +95,44 @@ export interface IFloorInfo {
|
|||||||
readonly wallDensityStd: number;
|
readonly wallDensityStd: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface IMapBlockConfig {
|
||||||
|
/** 空地的图块数字 */
|
||||||
|
readonly empty: number;
|
||||||
|
/** 墙的图块数字 */
|
||||||
|
readonly wall: number;
|
||||||
|
/** 装饰图块 */
|
||||||
|
readonly decoration: number;
|
||||||
|
/**
|
||||||
|
* 普通门,黄、蓝、红、绿等级依次增加,如果数组长度不够,会取最高级的那个,
|
||||||
|
* 对于四种基础门之外的门,会进入 `specialDoors` 判断
|
||||||
|
*/
|
||||||
|
readonly commonDoors: number[];
|
||||||
|
/** 机关门,普通机关门使用第一项作为结果,对于四种基础门及机关门之外的门,会选用第二项作为结果 */
|
||||||
|
readonly specialDoors: [number, number];
|
||||||
|
/**
|
||||||
|
* 钥匙,黄、蓝、红、绿等级依次增加,如果数组长度不够,会取最高级的那个,
|
||||||
|
* 特殊钥匙视为最高级
|
||||||
|
*/
|
||||||
|
readonly keys: number[];
|
||||||
|
/** 红宝石图块,平均分为若干档 */
|
||||||
|
readonly redGems: number[];
|
||||||
|
/** 蓝宝石图块,平均分为若干档 */
|
||||||
|
readonly blueGems: number[];
|
||||||
|
/** 绿宝石图块,平均分为若干档 */
|
||||||
|
readonly greenGems: number[];
|
||||||
|
/** 血瓶图块,平均分为若干档 */
|
||||||
|
readonly potions: number[];
|
||||||
|
/** 道具图块,依次为破炸飞,如果长度不够则取最后一个 */
|
||||||
|
readonly items: number[];
|
||||||
|
/** 怪物图块,按怪物强度分为若干当,强度为血量乘攻防和 */
|
||||||
|
readonly enemies: number[];
|
||||||
|
/** 入口图块 */
|
||||||
|
readonly entry: number;
|
||||||
|
}
|
||||||
|
|
||||||
export interface IAutoLabelConfig {
|
export interface IAutoLabelConfig {
|
||||||
|
/** 地图图块分类 */
|
||||||
|
readonly classes: Readonly<IMapBlockConfig>;
|
||||||
/** 地图允许大小 */
|
/** 地图允许大小 */
|
||||||
readonly allowedSize: [number, number][];
|
readonly allowedSize: [number, number][];
|
||||||
/** 是否允许无用节点 */
|
/** 是否允许无用节点 */
|
||||||
|
|||||||
@ -2,15 +2,15 @@
|
|||||||
export const emptyTiles = new Set([0]);
|
export const emptyTiles = new Set([0]);
|
||||||
export const wallTiles = new Set([1]);
|
export const wallTiles = new Set([1]);
|
||||||
export const decorationTiles = new Set([2]);
|
export const decorationTiles = new Set([2]);
|
||||||
export const commonDoorTiles = new Set([3, 4, 5]);
|
export const commonDoorTiles = new Set([3]);
|
||||||
export const specialDoorTiles = new Set([6]);
|
export const specialDoorTiles = new Set([6]);
|
||||||
export const keyTiles = new Set([7, 8, 9]);
|
export const keyTiles = new Set([7]);
|
||||||
export const redGemTiles = new Set([10, 11, 12]);
|
export const redGemTiles = new Set([10]);
|
||||||
export const blueGemTiles = new Set([13, 14, 15]);
|
export const blueGemTiles = new Set([13]);
|
||||||
export const greenGemTiles = new Set([16, 17, 18]);
|
export const greenGemTiles = new Set([16]);
|
||||||
export const potionTiles = new Set([19, 20, 21, 22]);
|
export const potionTiles = new Set([19]);
|
||||||
export const itemTiles = new Set([23, 24, 25]);
|
export const itemTiles = new Set([23]);
|
||||||
export const enemyTiles = new Set([26, 27, 28]);
|
export const enemyTiles = new Set([26]);
|
||||||
export const entryTiles = new Set([29]);
|
export const entryTiles = new Set([29]);
|
||||||
|
|
||||||
// 组合图块定义
|
// 组合图块定义
|
||||||
|
|||||||
@ -67,13 +67,18 @@ class EncoderFusion(nn.Module):
|
|||||||
num_layers=2
|
num_layers=2
|
||||||
)
|
)
|
||||||
self.norm = nn.LayerNorm(d_model)
|
self.norm = nn.LayerNorm(d_model)
|
||||||
|
self.fc = nn.Sequential(
|
||||||
|
nn.Linear(d_model * 2, d_model * 2),
|
||||||
|
nn.LayerNorm(d_model * 2),
|
||||||
|
nn.GELU()
|
||||||
|
)
|
||||||
|
|
||||||
def forward(self, logits):
|
def forward(self, logits):
|
||||||
x = self.norm(self.transformer(logits))
|
x = self.norm(self.transformer(logits))
|
||||||
h_mean = torch.mean(x, dim=1)
|
h_mean = torch.mean(x, dim=1)
|
||||||
h_max = torch.max(x, dim=1).values
|
h_max = torch.max(x, dim=1).values
|
||||||
h = torch.cat([h_mean, h_max], dim=1)
|
h = torch.cat([h_mean, h_max], dim=1)
|
||||||
return h
|
return self.fc(h)
|
||||||
|
|
||||||
class VAEEncoder(nn.Module):
|
class VAEEncoder(nn.Module):
|
||||||
def __init__(self, device, tile_classes=32, latent_dim=32, width=13, height=13):
|
def __init__(self, device, tile_classes=32, latent_dim=32, width=13, height=13):
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user