diff --git a/README.md b/README.md index e4a4f0c..a7766fb 100644 --- a/README.md +++ b/README.md @@ -29,22 +29,45 @@ GINKA Model 内部集成了 Minamo Model 用做判别器,与 Ginka Model 对 "yellowGem": { "30": 1 }, - "item": [47, 49, 50, 51, 52, 53], + "item": { + "47": 1, + "49": 1, + "50": 0, + "51": 1, + "52": 1, + "53": 2 + }, "potion": { "31": 100, "32": 200, "33": 400, "34": 800 }, - "key": [21, 22, 23], - "door": [81, 82, 83, 85], - "wall": [1, 17] + "key": { + "21": 0, + "22": 1, + "23": 2, + "24": 2, + "25": 2 + }, + "door": { + "81": 0, + "82": 1, + "83": 2, + "84": 2, + "85": 3, + "86": 2 + }, + "wall": [1, 17], + "decoration": [], + "floor": [87, 88], + "arrow": [91, 92, 93, 94] }, "data": {} } ``` -其中,`clip` 属性表示你的每张地图的那一部分会被当成数据集,例如填写 `[0, 0, 13, 13]` 就会让坐标为 `(0, 0)`,长宽为 `(13, 13)` 的矩形内容作为数据集。`special` 不用管。 +其中,`clip` 属性表示你的每张地图的那一部分会被当成数据集,例如填写 `[0, 0, 13, 13]` 就会让坐标为 `(0, 0)`,长宽为 `(13, 13)` 的矩形内容作为数据集。`special` 不用管。注意装饰所使用的贴图是白墙,如果白墙是墙壁的话,需要将白墙设置为墙壁。注意不要忘记保存 2. 使用 [在线工具](https://unanmed.github.io/ginka-process) 处理数据,需要给每个地图添加标签,为每个图块分配种类,有一些图块包含多种等级,需要填写正确。 3. 将 `project` 文件夹打包发给我 diff --git a/data/src/floor.ts b/data/src/floor.ts index e308bfa..572bc97 100644 --- a/data/src/floor.ts +++ b/data/src/floor.ts @@ -28,16 +28,16 @@ function convert( const clipped: number[][] = []; // 1. 裁剪 - for (let nx = x; nx < x + w; nx++) { + for (let ny = y; ny < y + w; ny++) { const row: number[] = []; - for (let ny = y; ny < y + h; ny++) { + for (let nx = y; nx < x + h; nx++) { row.push(map[ny][nx]); } clipped.push(row); } const res: number[][] = Array.from({ length: clipped.length }, () => - Array.from({ length: clipped[0].length }) + Array.from({ length: clipped[0].length }, () => 0) ); // 2. 初步映射 @@ -278,12 +278,18 @@ function range(from: number, to: number) { 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]) - ]; +export function getGinkaRatio(map: number[][]): number[] { + const arr: number[] = Array(16).fill(0); + arr[0] = getRatio(map, [1, ...range(3, 32)]); + arr[1] = getRatio(map, [1]); + arr[2] = getRatio(map, [2]); + arr[3] = getRatio(map, [3, 4, 5, 6]); + arr[4] = getRatio(map, [26, 27, 28]); + arr[5] = getRatio(map, range(7, 26)); + arr[6] = getRatio(map, range(10, 19)); + arr[7] = getRatio(map, range(19, 23)); + arr[8] = getRatio(map, [7, 8, 9]); + arr[9] = getCount(map, [23, 24, 25]); + arr[10] = getCount(map, [29, 30]); + return arr; } diff --git a/ginka/critic/vision.py b/ginka/critic/vision.py index 465760c..de317b3 100644 --- a/ginka/critic/vision.py +++ b/ginka/critic/vision.py @@ -13,7 +13,10 @@ class MinamoVisionModel(nn.Module): spectral_norm(nn.Conv2d(in_ch*2, in_ch*4, 3)), #9*9 nn.LeakyReLU(0.2), - spectral_norm(nn.Conv2d(in_ch*4, out_ch, 3)), # 7*7 + spectral_norm(nn.Conv2d(in_ch*4, in_ch*8, 3)), # 7*7 + nn.LeakyReLU(0.2), + + spectral_norm(nn.Conv2d(in_ch*8, out_ch, 3)), # 5*5 nn.LeakyReLU(0.2), ) diff --git a/ginka/dataset.py b/ginka/dataset.py index cbbe4c2..c701c19 100644 --- a/ginka/dataset.py +++ b/ginka/dataset.py @@ -6,13 +6,12 @@ from torch.utils.data import Dataset import torch import torch.nn.functional as F from typing import List -from shared.utils import random_smooth_onehot -STAGE1_MASK = [0, 1, 10, 11] -STAGE1_REMOVE = [2, 3, 4, 5, 6, 7, 8, 9, 12, 13] -STAGE2_MASK = [6, 7, 8, 9] -STAGE2_REMOVE = [2, 3, 4, 5, 12, 13] -STAGE3_MASK = [2, 3, 4, 5, 12, 13] +STAGE1_MASK = [0, 1, 2, 29, 30] +STAGE1_REMOVE = list(range(3, 29)) +STAGE2_MASK = [3, 4, 5, 6, 26, 27, 28] +STAGE2_REMOVE = list(range(7, 26)) +STAGE3_MASK = list(range(7, 26)) STAGE3_REMOVE = [] def load_data(path: str): diff --git a/ginka/generator/loss.py b/ginka/generator/loss.py index 11bd813..211bbf8 100644 --- a/ginka/generator/loss.py +++ b/ginka/generator/loss.py @@ -9,13 +9,13 @@ from shared.constant import VISION_WEIGHT, TOPO_WEIGHT from ..critic.model import MinamoModel CLASS_NUM = 32 -ILLEGAL_MAX_NUM = 13 +ILLEGAL_MAX_NUM = 30 STAGE_ALLOWED = [ [], - [0, 1, 10, 11], - [6, 7, 8, 9], - [2, 3, 4, 5, 12, 13] + [0, 1, 2, 29, 30], + [3, 4, 5, 6, 26, 27, 28], + list(range(7, 26)) ] def get_not_allowed(classes: list[int], include_illegal=False): @@ -30,14 +30,13 @@ def get_not_allowed(classes: list[int], include_illegal=False): return res -def outer_border_constraint_loss(pred: torch.Tensor, allowed_classes=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13]): +def outer_border_constraint_loss(pred: torch.Tensor, allowed_classes=[*list(range(0, 29)), 30]): """ 强制地图最外圈像素必须为指定类别(墙或箭头) 参数: pred: 模型输出的概率分布,形状 [B, C, H, W] - allowed_classes: 允许出现在外圈的类别列表(默认[1,11]) - penalty_scale: 惩罚强度系数 + allowed_classes: 允许出现在外圈的类别列表 返回: loss: 标量损失值 @@ -62,12 +61,12 @@ def outer_border_constraint_loss(pred: torch.Tensor, allowed_classes=[0, 1, 2, 3 return loss_unallowed -def inner_constraint_loss(pred: torch.Tensor, allowed=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 13]): +def inner_constraint_loss(pred: torch.Tensor, allowed=list(range(0, 30))): """限定内部允许出现的图块种类 Args: pred (torch.Tensor): 模型输出的概率分布 [B, C, H, W] - unallowed (list, optional): 在地图中部(处最外圈)允许出现的图块种类. Defaults to [11]. + allowed (list, optional): 在地图中部(除最外圈)允许出现的图块种类 """ B, C, H, W = pred.shape @@ -100,7 +99,7 @@ def _create_distance_kernel(size): def entrance_constraint_loss( pred: torch.Tensor, - entrance_classes=[10, 11], # 假设10是楼梯,11是箭头 + entrance_classes=[29, 30], min_distance=9, presence_threshold=0.8, lambda_presence=1.0, diff --git a/ginka/train_wgan.py b/ginka/train_wgan.py index 02ce124..1f7ecc7 100644 --- a/ginka/train_wgan.py +++ b/ginka/train_wgan.py @@ -17,14 +17,22 @@ from shared.image import matrix_to_image_cv # 标签定义: # 0. 蓝海, 1. 红海, 2: 室内, 3. 野外, 4. 左右对称, 5. 上下对称, 6. 伪对称, 7. 咸鱼层, -# 8. 剧情层, 9. 水层, 10. 爽塔, 11. Boss层, 12. 纯Boss层, 13. 多房间, 14. 多走廊, 15. 道具塔 +# 8. 剧情层, 9. 水层, 10. 爽塔, 11. Boss层, 12. 纯Boss层, 13. 多房间, 14. 多走廊, 15. 道具风 +# 16. 区域入口, 17. 区域连接, 18. 有机关门, 19. 道具层, 20. 斜向对称, 21. 左右通道, 22. 上下通道, 23. 多机关门 +# 24. 中心对称, 25. 部分对称, 26. 鱼骨 # 标量值定义: # 0. 整体密度,非空白图块/地图面积,空白图块还包括装饰图块 -# 1. 怪物密度,怪物数量/地图面积 -# 2. 资源密度,资源数量/地图面积 +# 1. 墙体密度,墙壁/地图面积 +# 2. 装饰密度,装饰数量/地图面积 # 3. 门密度,门数量/地图面积 -# 4. 入口数量 +# 4. 怪物密度,怪物数量/地图面积 +# 5. 资源密度,资源数量/地图面积 +# 6. 宝石密度,宝石数量/地图面积 +# 7. 血瓶密度,血瓶数量/地图面积 +# 8. 钥匙密度,钥匙数量/地图面积 +# 9. 道具数量 +# 10. 入口数量 # 图块定义: # 0. 空地, 1. 墙壁, 2. 装饰(用于野外装饰,视为空地), diff --git a/ginka/validate.py b/ginka/validate.py index c82e6d0..2e61bd6 100644 --- a/ginka/validate.py +++ b/ginka/validate.py @@ -6,10 +6,10 @@ import torch import torch.nn.functional as F from torch_geometric.loader import DataLoader from tqdm import tqdm -from minamo.model.model import MinamoModel +from .critic.model import MinamoModel from .dataset import GinkaDataset -from .model.loss import GinkaLoss -from .model.model import GinkaModel +from .generator.loss import GinkaLoss +from .generator.model import GinkaModel from shared.image import matrix_to_image_cv device = torch.device("cuda" if torch.cuda.is_available() else "cpu") diff --git a/shared/image.py b/shared/image.py index 364e6ae..039d1d0 100644 --- a/shared/image.py +++ b/shared/image.py @@ -26,15 +26,15 @@ def matrix_to_image_cv(map_matrix, tile_set, tile_size=32): if '0' in tile_set: canvas[y:y+tile_size, x:x+tile_size] = tile_set['0'][:, :, :3] # 仅填充 RGB - if tile_index == '11': + if tile_index == '30': if row == 0: - tile_index = '11_1' + tile_index = '30_1' elif row == W - 1: - tile_index = '11_3' + tile_index = '30_3' elif col == 0: - tile_index = '11_2' + tile_index = '30_2' elif col == H - 1: - tile_index = '11_4' + tile_index = '30_4' # 叠加其他透明图块 if tile_index in tile_set and tile_index != 0: diff --git a/tiles/10.png b/tiles/10.png index d2eb533..08409ab 100644 Binary files a/tiles/10.png and b/tiles/10.png differ diff --git a/tiles/11.png b/tiles/11.png new file mode 100644 index 0000000..378a738 Binary files /dev/null and b/tiles/11.png differ diff --git a/tiles/12.png b/tiles/12.png index 7f6a74b..c2330ec 100644 Binary files a/tiles/12.png and b/tiles/12.png differ diff --git a/tiles/13.png b/tiles/13.png index 4b8d3a6..792ed88 100644 Binary files a/tiles/13.png and b/tiles/13.png differ diff --git a/tiles/14.png b/tiles/14.png new file mode 100644 index 0000000..a3a33e1 Binary files /dev/null and b/tiles/14.png differ diff --git a/tiles/15.png b/tiles/15.png new file mode 100644 index 0000000..56ecb3f Binary files /dev/null and b/tiles/15.png differ diff --git a/tiles/16.png b/tiles/16.png new file mode 100644 index 0000000..4b8d3a6 Binary files /dev/null and b/tiles/16.png differ diff --git a/tiles/17.png b/tiles/17.png new file mode 100644 index 0000000..835cbde Binary files /dev/null and b/tiles/17.png differ diff --git a/tiles/18.png b/tiles/18.png new file mode 100644 index 0000000..b092cb4 Binary files /dev/null and b/tiles/18.png differ diff --git a/tiles/19.png b/tiles/19.png new file mode 100644 index 0000000..b121323 Binary files /dev/null and b/tiles/19.png differ diff --git a/tiles/2.png b/tiles/2.png index 339c1c3..64e8e53 100644 Binary files a/tiles/2.png and b/tiles/2.png differ diff --git a/tiles/20.png b/tiles/20.png new file mode 100644 index 0000000..dd9a8c5 Binary files /dev/null and b/tiles/20.png differ diff --git a/tiles/21.png b/tiles/21.png new file mode 100644 index 0000000..d9fe4bf Binary files /dev/null and b/tiles/21.png differ diff --git a/tiles/22.png b/tiles/22.png new file mode 100644 index 0000000..62626ab Binary files /dev/null and b/tiles/22.png differ diff --git a/tiles/23.png b/tiles/23.png new file mode 100644 index 0000000..38d7a35 Binary files /dev/null and b/tiles/23.png differ diff --git a/tiles/24.png b/tiles/24.png new file mode 100644 index 0000000..255a39b Binary files /dev/null and b/tiles/24.png differ diff --git a/tiles/25.png b/tiles/25.png new file mode 100644 index 0000000..aee20bf Binary files /dev/null and b/tiles/25.png differ diff --git a/tiles/26.png b/tiles/26.png new file mode 100644 index 0000000..1329097 Binary files /dev/null and b/tiles/26.png differ diff --git a/tiles/27.png b/tiles/27.png new file mode 100644 index 0000000..2e564fd Binary files /dev/null and b/tiles/27.png differ diff --git a/tiles/28.png b/tiles/28.png new file mode 100644 index 0000000..9404de6 Binary files /dev/null and b/tiles/28.png differ diff --git a/tiles/29.png b/tiles/29.png new file mode 100644 index 0000000..d2eb533 Binary files /dev/null and b/tiles/29.png differ diff --git a/tiles/3.png b/tiles/3.png index 08409ab..83de73a 100644 Binary files a/tiles/3.png and b/tiles/3.png differ diff --git a/tiles/11_1.png b/tiles/30_1.png similarity index 100% rename from tiles/11_1.png rename to tiles/30_1.png diff --git a/tiles/11_2.png b/tiles/30_2.png similarity index 100% rename from tiles/11_2.png rename to tiles/30_2.png diff --git a/tiles/11_3.png b/tiles/30_3.png similarity index 100% rename from tiles/11_3.png rename to tiles/30_3.png diff --git a/tiles/11_4.png b/tiles/30_4.png similarity index 100% rename from tiles/11_4.png rename to tiles/30_4.png diff --git a/tiles/4.png b/tiles/4.png index 792ed88..bd23e07 100644 Binary files a/tiles/4.png and b/tiles/4.png differ diff --git a/tiles/5.png b/tiles/5.png index b121323..0556fb9 100644 Binary files a/tiles/5.png and b/tiles/5.png differ diff --git a/tiles/6.png b/tiles/6.png index 83de73a..efce63b 100644 Binary files a/tiles/6.png and b/tiles/6.png differ diff --git a/tiles/7.png b/tiles/7.png index 1329097..339c1c3 100644 Binary files a/tiles/7.png and b/tiles/7.png differ diff --git a/tiles/8.png b/tiles/8.png index 2e564fd..9e5888f 100644 Binary files a/tiles/8.png and b/tiles/8.png differ diff --git a/tiles/9.png b/tiles/9.png index 9404de6..d106e37 100644 Binary files a/tiles/9.png and b/tiles/9.png differ diff --git a/tiles/999.png b/tiles/999.png new file mode 100644 index 0000000..eb62785 Binary files /dev/null and b/tiles/999.png differ