mirror of
https://github.com/unanmed/ginka-generator.git
synced 2026-05-14 04:41:12 +08:00
feat: 数据集密度占比
This commit is contained in:
parent
8add448195
commit
44d6c7410e
42
README.md
42
README.md
@ -8,28 +8,34 @@ GINKA Model 内部集成了 Minamo Model 用做判别器,与 Ginka Model 对
|
||||
|
||||
对于 HTML5 魔塔,如果你想要贡献数据集,需要对你的魔塔进行手动数据处理,流程如下:
|
||||
|
||||
1. 选择楼层,可以是剧情层、战斗层等,但是需要满足下述条件
|
||||
2. 楼层中不应该有闲置怪,不应该在直线上有无间隔连续 3 个以上的怪物,不应该有无法到达的区域,不宜有过多的入口
|
||||
3. 最外面一层围上一圈墙壁(箭头楼层切换除外)
|
||||
4. 所有箭头换成样板原版箭头(数字 91 至 94),所有上下楼梯换成样板原版楼梯(数字 87 和 88)
|
||||
5. (可选,不改的话会自动按攻防和计算)怪物分为三个强度,弱怪,中怪,强怪,弱怪换为绿头怪(数字 201),中怪换成红头怪(数字 202),强怪换成青头怪(数字 203)
|
||||
6. 在 `project` 文件夹下创建 `ginka-config.json` 文件,双击进入编辑,粘贴如下模板:
|
||||
1. 在 `project` 文件夹下创建 `ginka-config.json` 文件,双击进入编辑,粘贴如下模板:
|
||||
|
||||
```json
|
||||
{
|
||||
"clip": {
|
||||
"defaults": [0, 0, 13, 13],
|
||||
"special": {
|
||||
"MT11": [3, 3, 7, 7]
|
||||
}
|
||||
"special": {}
|
||||
},
|
||||
"mapping": {
|
||||
"redGem": [27],
|
||||
"blueGem": [28],
|
||||
"greenGem": [29],
|
||||
"yellowGem": [30],
|
||||
"redGem": {
|
||||
"27": 1
|
||||
},
|
||||
"blueGem": {
|
||||
"28": 1
|
||||
},
|
||||
"greenGem": {
|
||||
"29": 1
|
||||
},
|
||||
"yellowGem": {
|
||||
"30": 1
|
||||
},
|
||||
"item": [47, 49, 50, 51, 52, 53],
|
||||
"potion": [31, 32, 33, 34],
|
||||
"potion": {
|
||||
"31": 100,
|
||||
"32": 200,
|
||||
"33": 400,
|
||||
"34": 800
|
||||
},
|
||||
"key": [21, 22, 23],
|
||||
"door": [81, 82, 83, 85],
|
||||
"wall": [1, 17]
|
||||
@ -38,9 +44,7 @@ GINKA Model 内部集成了 Minamo Model 用做判别器,与 Ginka Model 对
|
||||
}
|
||||
```
|
||||
|
||||
其中,`clip` 属性表示你的每张地图的那一部分会被当成数据集,例如填写 `[0, 0, 13, 13]` 就会让坐标为 `(0, 0)`,长宽为 `(13, 13)` 的矩形内容作为数据集。`special` 属性允许你针对单独的某几层设置不同的裁剪方式,例如设置 `MT11` 为 `[3, 3, 7, 7]` 等,如果没有设置默认使用 `defaults` 的裁剪方式。最好保证每个楼层大小一致,不然我还要手动分类。
|
||||
其中,`clip` 属性表示你的每张地图的那一部分会被当成数据集,例如填写 `[0, 0, 13, 13]` 就会让坐标为 `(0, 0)`,长宽为 `(13, 13)` 的矩形内容作为数据集。`special` 不用管。
|
||||
|
||||
`mapping` 中表示每种图块的图块数字,如果自己添加了一些新的宝石、门、道具等,需要在里面填写
|
||||
|
||||
7. 在全塔属性中的楼层列表中去除不在数据集内的楼层
|
||||
8. 将 `project` 文件夹打包发给我即可
|
||||
2. 使用 [在线工具](https://unanmed.github.io/ginka-process) 处理数据,需要给每个地图添加标签,为每个图块分配种类,有一些图块包含多种等级,需要填写正确。
|
||||
3. 将 `project` 文件夹打包发给我
|
||||
|
||||
@ -4,12 +4,12 @@ const numMap: Record<number, number> = {
|
||||
0: 0,
|
||||
1: 1,
|
||||
2: 2,
|
||||
91: 29,
|
||||
92: 29,
|
||||
93: 29,
|
||||
94: 29,
|
||||
87: 28,
|
||||
88: 28
|
||||
91: 30,
|
||||
92: 30,
|
||||
93: 30,
|
||||
94: 30,
|
||||
87: 29,
|
||||
88: 29
|
||||
};
|
||||
|
||||
export interface Enemy {
|
||||
@ -55,8 +55,8 @@ function convert(
|
||||
const dict = config.mapping;
|
||||
dict.wall.forEach(v => (mapping[v] = 1));
|
||||
dict.decoration.forEach(v => (mapping[v] = 2));
|
||||
dict.floor.forEach(v => (mapping[v] = 28));
|
||||
dict.arrow.forEach(v => (mapping[v] = 29));
|
||||
dict.floor.forEach(v => (mapping[v] = 29));
|
||||
dict.arrow.forEach(v => (mapping[v] = 30));
|
||||
for (let nx = 0; nx < w; nx++) {
|
||||
for (let ny = 0; ny < h; ny++) {
|
||||
const tile = clipped[ny][nx];
|
||||
@ -101,32 +101,43 @@ function convert(
|
||||
const tile = clipped[ny][nx];
|
||||
if (dict.redGem[tile] !== void 0) {
|
||||
const value = dict.redGem[tile];
|
||||
if (maxRedGem === minRedGem) {
|
||||
if (maxRedGem - minRedGem < 1e-8) {
|
||||
res[ny][nx] = 10;
|
||||
} else {
|
||||
const level = Math.floor(
|
||||
((value - minRedGem) / (maxRedGem - minRedGem)) * 3
|
||||
const level = Math.min(
|
||||
Math.floor(
|
||||
((value - minRedGem) / (maxRedGem - minRedGem)) * 3
|
||||
),
|
||||
2
|
||||
);
|
||||
res[ny][nx] = 10 + level;
|
||||
}
|
||||
} else if (dict.blueGem[tile] !== void 0) {
|
||||
const value = dict.blueGem[tile];
|
||||
if (maxBlueGem === minBlueGem) {
|
||||
if (maxBlueGem - minBlueGem < 1e-8) {
|
||||
res[ny][nx] = 13;
|
||||
} else {
|
||||
const level = Math.floor(
|
||||
((value - minBlueGem) / (maxBlueGem - minBlueGem)) * 3
|
||||
const level = Math.min(
|
||||
Math.floor(
|
||||
((value - minBlueGem) / (maxBlueGem - minBlueGem)) *
|
||||
3
|
||||
),
|
||||
2
|
||||
);
|
||||
res[ny][nx] = 13 + level;
|
||||
}
|
||||
} else if (dict.greenGem[tile] !== void 0) {
|
||||
const value = dict.greenGem[tile];
|
||||
if (maxGreenGem === minGreenGem) {
|
||||
if (maxGreenGem - minGreenGem < 1e-8) {
|
||||
res[ny][nx] = 16;
|
||||
} else {
|
||||
const level = Math.floor(
|
||||
((value - minGreenGem) / (maxGreenGem - minGreenGem)) *
|
||||
3
|
||||
const level = Math.min(
|
||||
Math.floor(
|
||||
((value - minGreenGem) /
|
||||
(maxGreenGem - minGreenGem)) *
|
||||
3
|
||||
),
|
||||
2
|
||||
);
|
||||
res[ny][nx] = 16 + level;
|
||||
}
|
||||
@ -134,43 +145,58 @@ function convert(
|
||||
const rand = Math.random();
|
||||
const value = dict.yellowGem[tile];
|
||||
if (rand < 2 / 5) {
|
||||
if (maxRedGem === minRedGem) {
|
||||
if (maxRedGem - minRedGem < 1e-8) {
|
||||
res[ny][nx] = 10;
|
||||
} else {
|
||||
const level = Math.floor(
|
||||
((value - minRedGem) / (maxRedGem - minRedGem)) * 3
|
||||
const level = Math.min(
|
||||
Math.floor(
|
||||
((value - minRedGem) /
|
||||
(maxRedGem - minRedGem)) *
|
||||
3
|
||||
),
|
||||
2
|
||||
);
|
||||
res[ny][nx] = 10 + level;
|
||||
}
|
||||
} else if (rand < 4 / 5) {
|
||||
if (maxBlueGem === minBlueGem) {
|
||||
if (maxBlueGem - minBlueGem < 1e-8) {
|
||||
res[ny][nx] = 13;
|
||||
} else {
|
||||
const level = Math.floor(
|
||||
((value - minBlueGem) / (maxBlueGem - minBlueGem)) *
|
||||
3
|
||||
const level = Math.min(
|
||||
Math.floor(
|
||||
((value - minBlueGem) /
|
||||
(maxBlueGem - minBlueGem)) *
|
||||
3
|
||||
),
|
||||
2
|
||||
);
|
||||
res[ny][nx] = 13 + level;
|
||||
}
|
||||
} else {
|
||||
if (maxGreenGem === minGreenGem) {
|
||||
if (maxGreenGem - minGreenGem < 1e-8) {
|
||||
res[ny][nx] = 16;
|
||||
} else {
|
||||
const level = Math.floor(
|
||||
((value - minGreenGem) /
|
||||
(maxGreenGem - minGreenGem)) *
|
||||
3
|
||||
const level = Math.min(
|
||||
Math.floor(
|
||||
((value - minGreenGem) /
|
||||
(maxGreenGem - minGreenGem)) *
|
||||
3
|
||||
),
|
||||
2
|
||||
);
|
||||
res[ny][nx] = 16 + level;
|
||||
}
|
||||
}
|
||||
} else if (dict.potion[tile] !== void 0) {
|
||||
const value = dict.potion[tile];
|
||||
if (maxGreenGem === minGreenGem) {
|
||||
if (maxGreenGem - minGreenGem < 1e-8) {
|
||||
res[ny][nx] = 19;
|
||||
} else {
|
||||
const level = Math.floor(
|
||||
((value - minPotion) / (maxPotion - minPotion)) * 3
|
||||
const level = Math.min(
|
||||
Math.floor(
|
||||
((value - minPotion) / (maxPotion - minPotion)) * 4
|
||||
),
|
||||
3
|
||||
);
|
||||
res[ny][nx] = 19 + level;
|
||||
}
|
||||
@ -233,3 +259,31 @@ export function convertFloor(
|
||||
) {
|
||||
return convert(map, clip, config, enemyMap);
|
||||
}
|
||||
|
||||
export function getCount(map: number[][], tiles: number[]) {
|
||||
let n = 0;
|
||||
map.flat().forEach(v => {
|
||||
if (tiles.includes(v)) n++;
|
||||
});
|
||||
return n;
|
||||
}
|
||||
|
||||
export function getRatio(map: number[][], tiles: number[]) {
|
||||
const area = map.length * map[0].length;
|
||||
return getCount(map, tiles) / area;
|
||||
}
|
||||
|
||||
function range(from: number, to: number) {
|
||||
const length = to - from;
|
||||
return Array.from({ length }, (_, i) => i + from);
|
||||
}
|
||||
|
||||
export function getGinkaRatio(map: number[][]) {
|
||||
return [
|
||||
getRatio(map, [1, ...range(3, 32)]),
|
||||
getRatio(map, [26, 27, 28]),
|
||||
getRatio(map, range(7, 26)),
|
||||
getRatio(map, [3, 4, 5, 6]),
|
||||
getCount(map, [29, 30])
|
||||
];
|
||||
}
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import { SingleBar, Presets } from 'cli-progress';
|
||||
import { getGinkaRatio } from 'src/floor';
|
||||
import { GinkaTrainData, GinkaConfig, GinkaDataset } from 'src/types';
|
||||
import { FloorData } from 'src/utils';
|
||||
|
||||
@ -12,14 +13,13 @@ export function parseGinka(data: Map<string, FloorData>) {
|
||||
data.forEach((floor, key) => {
|
||||
const config = floor.config as GinkaConfig;
|
||||
const data = config.data[floor.id] ?? {
|
||||
tag: Array(64).fill(0),
|
||||
val: Array(16).fill(0)
|
||||
tag: Array(64).fill(0)
|
||||
};
|
||||
resolved[key] = {
|
||||
map: floor.map,
|
||||
size: [floor.map[0].length, floor.map.length],
|
||||
tag: data.tag,
|
||||
val: data.val
|
||||
val: getGinkaRatio(floor.map)
|
||||
};
|
||||
i++;
|
||||
progress.update(i);
|
||||
|
||||
@ -14,7 +14,6 @@ export interface TowerInfo {
|
||||
|
||||
export interface GinkaData {
|
||||
tag: number[];
|
||||
val: number[];
|
||||
}
|
||||
|
||||
export interface GinkaConfig extends BaseConfig {
|
||||
|
||||
@ -33,11 +33,11 @@ from shared.image import matrix_to_image_cv
|
||||
# 10-12. 三种等级的红宝石
|
||||
# 13-15. 三种等级的蓝宝石
|
||||
# 16-18. 三种等级的绿宝石
|
||||
# 19-21. 三种等级的血瓶
|
||||
# 22-24. 三种等级的道具
|
||||
# 25-27. 三种等级的怪物
|
||||
# 28. 楼梯入口
|
||||
# 29. 箭头入口
|
||||
# 19-22. 四种等级的血瓶
|
||||
# 23-25. 三种等级的道具
|
||||
# 26-28. 三种等级的怪物
|
||||
# 29. 楼梯入口
|
||||
# 30. 箭头入口
|
||||
|
||||
BATCH_SIZE = 16
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user