diff --git a/dependency/MapGenerator-Python/.gitignore b/dependency/MapGenerator-Python/.gitignore
new file mode 100644
index 00000000..e6650953
--- /dev/null
+++ b/dependency/MapGenerator-Python/.gitignore
@@ -0,0 +1,4 @@
+.vscode/
+*.map
+build/
+dist/
\ No newline at end of file
diff --git a/dependency/MapGenerator-Python/Classes/AreaRenderDict.py b/dependency/MapGenerator-Python/Classes/AreaRenderDict.py
new file mode 100644
index 00000000..8672813d
--- /dev/null
+++ b/dependency/MapGenerator-Python/Classes/AreaRenderDict.py
@@ -0,0 +1,34 @@
+from __future__ import annotations
+from functools import cached_property
+
+
+class AreaRenderDict:
+ class Unit:
+ name: str
+ value: int
+ color: str
+
+ def __init__(self, _name: str, _value: int, _color: str) -> None:
+ self.name, self.value, self.color = _name, _value, _color
+
+ areas: list[Unit]
+
+ @cached_property
+ def Name2Unit(self) -> dict[str, Unit]:
+ return {x.name: x for x in self.areas}
+
+ @cached_property
+ def Value2Unit(self) -> dict[int, Unit]:
+ return {x.value: x for x in self.areas}
+
+ @cached_property
+ def Color2Unit(self) -> dict[str, Unit]:
+ return {x.color: x for x in self.areas}
+
+ @cached_property
+ def Value2Color(self) -> dict[int, str]:
+ return {x: self.Value2Unit[x].color for x in self.Value2Unit}
+
+ def __init__(self, _areas: list[list[str, int, str]]) -> None:
+ self.areas = [AreaRenderDict.Unit(_name, _value, _color)
+ for _name, _value, _color in _areas]
diff --git a/dependency/MapGenerator-Python/Classes/MapRenderer.py b/dependency/MapGenerator-Python/Classes/MapRenderer.py
new file mode 100644
index 00000000..c11b20dc
--- /dev/null
+++ b/dependency/MapGenerator-Python/Classes/MapRenderer.py
@@ -0,0 +1,155 @@
+from __future__ import annotations
+from queue import Queue
+
+from easygui import choicebox
+import matplotlib.pyplot as plt
+from matplotlib.figure import Figure
+from matplotlib.axes import Axes
+from matplotlib.patches import Rectangle
+from matplotlib.ticker import MultipleLocator
+from matplotlib.backend_bases import MouseEvent, KeyEvent
+
+from Classes.AreaRenderDict import AreaRenderDict
+from Classes.MapStruct import MapStruct
+from Classes.RandomCore import RandomCore
+
+
+class MapRenderer:
+ class RenderUnit:
+ r: int
+ c: int
+ tp: str
+
+ def __init__(self, _r: int, _c: int, _tp: str) -> None:
+ self.r = _r
+ self.c = _c
+ self.tp = _tp
+
+ title: str
+ map: MapStruct
+ areaRender: AreaRenderDict
+ mapf: str
+ fig: Figure
+ ax: Axes
+ rects: list[list[Rectangle]]
+ queue_render: Queue[RenderUnit]
+ randomCores: list[RandomCore]
+
+ isCursorLift: int # 0: 未提起; 1: 提起未选定; 2: 提起并选定
+ cursorLift: tuple[int] # 提起坐标
+
+ __curMax: int
+ __cur: int
+
+ @property
+ def Cur(self) -> str:
+ return self.areaRender.areas[self.__cur].color
+
+ @Cur.setter
+ def Cur(self, _) -> None:
+ self.__cur += 1
+ self.__cur %= self.__curMax
+
+ @property
+ def Queue_Render(self) -> RenderUnit:
+ return self.queue_render.get(timeout=0.1)
+
+ @Queue_Render.setter
+ def Queue_Render(self, value: RenderUnit) -> None:
+ self.queue_render.put(value, timeout=0.1)
+
+ def __init__(self, _title, _mapStruct: MapStruct, _areas: AreaRenderDict,
+ _mapf: str, _randoms: list[RandomCore]) -> None:
+ self.title = _title
+ self.map = _mapStruct
+ self.areaRender = _areas
+ self.mapf = _mapf
+ self.randomCores = _randoms
+ self.fig, self.ax = plt.subplots()
+ self.rects = [[Rectangle((j, i), 1, 1, facecolor=self.areaRender.areas[self.map[i, j]].color)
+ for j in range(self.map.width)]
+ for i in range(self.map.height)]
+ self.queue_render = Queue()
+ self.isCursorLift = 0
+ self.cursorLift = None
+ self.__curMax = len(self.areaRender.areas)
+ self.__cur = 0
+
+ def MainFrame(self) -> None:
+ self.fig.set_size_inches(self.map.width, self.map.height)
+ self.ax.set_xlim(0, self.map.width)
+ self.ax.set_ylim(self.map.height, 0)
+ self.ax.xaxis.set_major_locator(MultipleLocator(1))
+ self.ax.yaxis.set_major_locator(MultipleLocator(1))
+ self.ax.set_aspect(1)
+ for i in range(self.map.height):
+ for j in range(self.map.width):
+ self.ax.add_patch(self.rects[i][j])
+ plt.hlines(range(self.map.height + 1), 0, self.map.width)
+ plt.vlines(range(self.map.width + 1), 0, self.map.height)
+ self.fig.canvas.mpl_connect('button_press_event', self.on_click)
+ self.fig.canvas.mpl_connect('key_press_event', self.on_press)
+ plt.show()
+
+ def on_click(self, event: MouseEvent) -> None:
+ if not event.button:
+ return
+ match event.button:
+ case 1:
+ r, c = int(event.ydata), int(event.xdata)
+ match self.isCursorLift:
+ case 0:
+ self.map[r, c] = self.areaRender.Color2Unit[self.Cur].value
+ self.Queue_Render = MapRenderer.RenderUnit(r, c, self.Cur)
+ self.Render()
+ case 1:
+ self.cursorLift = (r, c)
+ self.isCursorLift = 2
+ case 2:
+ liftr, liftc = self.cursorLift
+ dir_r, dir_c = (1 if liftr <= r else -1), (1 if liftc <= c else -1)
+ for i in range(liftr, r + dir_r, dir_r):
+ for j in range(liftc, c + dir_c, dir_c):
+ self.map[i, j] = self.areaRender.Color2Unit[self.Cur].value
+ self.Queue_Render = MapRenderer.RenderUnit(i, j, self.Cur)
+ self.Render()
+ self.isCursorLift = 0
+ case 3:
+ self.Cur = 0
+ case _:
+ return
+
+ def on_press(self, event: KeyEvent) -> None:
+ if not event.key:
+ return
+ match event.key:
+ case 'z':
+ self.isCursorLift = 1
+ case 'c':
+ self.map.ToFile(self.mapf)
+ case 'p':
+ opt = choicebox(msg='Choose random', title=self.title, choices=[x.Name for x in self.randomCores])
+ if opt is None:
+ return
+ for x in self.randomCores:
+ if x.Name == opt:
+ if x.Menu():
+ x.Random(self.map)
+ for r in range(self.map.height):
+ for c in range(self.map.width):
+ self.Queue_Render = MapRenderer.RenderUnit(
+ r, c, self.areaRender.Value2Color[self.map[r, c]])
+ self.Render()
+ plt.show(block=False)
+ case _:
+ return
+
+ def Render(self) -> None:
+ while not self.queue_render.empty():
+ cur = self.Queue_Render
+ self._render(cur.r, cur.c, cur.tp)
+
+ def _render(self, r: int, c: int, tp: str) -> None:
+ self.rects[r][c].set_color(tp)
+ self.ax.draw_artist(self.rects[r][c])
+ plt.show(block=False)
diff --git a/dependency/MapGenerator-Python/Classes/MapStruct.py b/dependency/MapGenerator-Python/Classes/MapStruct.py
new file mode 100644
index 00000000..e3ecf2d8
--- /dev/null
+++ b/dependency/MapGenerator-Python/Classes/MapStruct.py
@@ -0,0 +1,52 @@
+from __future__ import annotations
+from functools import cached_property
+from io import TextIOWrapper
+from typing import Literal, overload
+from array import array
+
+
+class MapStruct:
+ __arrAlloc: array[int]
+
+ @cached_property
+ def width(self) -> int:
+ return self.__arrAlloc[1]
+
+ @cached_property
+ def height(self) -> int:
+ return self.__arrAlloc[0]
+
+ @property
+ def ArrayView(self) -> list[list[int]]:
+ return [[self[i, j] for j in range(self.width)] for i in range(self.height)]
+
+ def __getitem__(self, rowcol: tuple[int, int]) -> int:
+ return self.__arrAlloc[2 + rowcol[1] + rowcol[0] * self.width]
+
+ def __setitem__(self, rowcol: tuple[int, int], val: int) -> None:
+ self.__arrAlloc[2 + rowcol[1] + rowcol[0] * self.width] = val
+
+ @overload
+ def __init__(self, dtype: Literal['b', 'B', 'u', 'h', 'H', 'i', 'I', 'l', 'L', 'q', 'Q', 'f', 'd'],
+ height: int, width: int) -> None: ...
+
+ @overload
+ def __init__(self, dtype: Literal['b', 'B', 'u', 'h', 'H', 'i', 'I', 'l', 'L', 'q', 'Q', 'f', 'd'],
+ mapFile: TextIOWrapper) -> None: ...
+
+ def __init__(self, dtype: Literal['b', 'B', 'u', 'h', 'H', 'i', 'I', 'l', 'L', 'q', 'Q', 'f', 'd'],
+ *args) -> None:
+ self.__arrAlloc = array(dtype)
+ if len(args) == 1:
+ mapFile = args[0]
+ self.__arrAlloc.fromfile(mapFile, 2)
+ self.__arrAlloc.fromfile(mapFile, self.width * self.height)
+ else:
+ self.__arrAlloc.append(args[0])
+ self.__arrAlloc.append(args[1])
+ self.__arrAlloc.fromlist(
+ [0 for _ in range(self.width * self.height)])
+
+ def ToFile(self, path: str) -> None:
+ with open(path, 'wb') as fp:
+ self.__arrAlloc.tofile(fp)
diff --git a/dependency/MapGenerator-Python/Classes/RandomCore.py b/dependency/MapGenerator-Python/Classes/RandomCore.py
new file mode 100644
index 00000000..a783d49e
--- /dev/null
+++ b/dependency/MapGenerator-Python/Classes/RandomCore.py
@@ -0,0 +1,15 @@
+from __future__ import annotations
+from abc import abstractmethod, abstractproperty
+
+from Classes.MapStruct import MapStruct
+
+
+class RandomCore:
+ @abstractproperty
+ def Name(self) -> str: ...
+
+ @abstractmethod
+ def Menu(self) -> bool: ...
+
+ @abstractmethod
+ def Random(self, mp: MapStruct) -> None: ...
diff --git a/dependency/MapGenerator-Python/Classes/RandomCores/PerlinRandomCore.py b/dependency/MapGenerator-Python/Classes/RandomCores/PerlinRandomCore.py
new file mode 100644
index 00000000..aa9b3e91
--- /dev/null
+++ b/dependency/MapGenerator-Python/Classes/RandomCores/PerlinRandomCore.py
@@ -0,0 +1,101 @@
+from __future__ import annotations
+from typing import Any
+
+from easygui import multenterbox
+from perlin_noise import PerlinNoise
+
+from Classes.MapStruct import MapStruct
+from Classes.RandomCore import RandomCore
+
+dict_place2num = {
+ 'Space': 0,
+ 'Ruin': 1,
+ 'Shadow': 2
+}
+
+
+class PerlinRandomCore(RandomCore):
+ title: str
+ octaves: float
+ seed: int | None
+
+ @property
+ def Octaves(self) -> float:
+ return self.octaves
+
+ @Octaves.setter
+ def Octaves(self, value: float) -> None:
+ if value > 0:
+ self.octaves = value
+ else:
+ self.octaves = 10
+
+ @property
+ def Seed(self) -> int | None:
+ return self.seed
+
+ @Seed.setter
+ def Seed(self, value: int | Any) -> None:
+ if isinstance(value, int) and value > 0:
+ self.seed = value
+ else:
+ self.seed = None
+
+ def __init__(self, title: str, octaves: float = 10) -> None:
+ self.title = title
+ self.Octaves = octaves
+ self.Seed = None
+
+ @property
+ def Name(self) -> str:
+ return 'Perlin'
+
+ def Menu(self) -> bool:
+ try:
+ (self.Octaves,
+ self.Seed) = (lambda f1, i2: (float(f1), int(i2) if i2 else i2))(*multenterbox(
+ msg='Random settings',
+ title=self.title,
+ fields=[
+ 'Octaves',
+ 'Seed'
+ ],
+ values=[
+ self.Octaves,
+ self.Seed
+ ]
+ ))
+ except TypeError:
+ return False
+ return True
+
+ def Random(self, mp: MapStruct) -> None:
+ noise = PerlinNoise(self.Octaves, self.Seed)
+ arr: list[list[float]] = []
+ arrMax: float = float('-inf')
+ arrMin: float = float('inf')
+ for i in range(mp.height):
+ arr.append([])
+ for j in range(mp.width):
+ cur = noise([j / mp.width, i / mp.height])
+ arr[i].append(cur)
+ if cur > arrMax:
+ arrMax = cur
+ elif cur < arrMin:
+ arrMin = cur
+ arr0, arr1, arr2 = arrMin, (2 * arrMin + arrMax) / 3, (arrMin + 2 * arrMax) / 3
+ for i in range(mp.height):
+ for j in range(mp.width):
+ if i == 0 or i == mp.height - 1:
+ mp[i, j] = dict_place2num['Ruin']
+ continue
+ elif j == 0 or j == mp.width - 1:
+ mp[i, j] = dict_place2num['Ruin']
+ continue
+ cur = arr[i][j]
+ if arr0 < cur < arr1:
+ mp[i, j] = dict_place2num['Shadow']
+ elif arr1 < cur < arr2:
+ mp[i, j] = dict_place2num['Space']
+ else:
+ mp[i, j] = dict_place2num['Ruin']
diff --git "a/dependency/MapGenerator-Python/Classes/RandomCores/\320\241\321\216\320\271\320\247\321\215\320\275RandomCore.py" "b/dependency/MapGenerator-Python/Classes/RandomCores/\320\241\321\216\320\271\320\247\321\215\320\275RandomCore.py"
new file mode 100644
index 00000000..36b8e590
--- /dev/null
+++ "b/dependency/MapGenerator-Python/Classes/RandomCores/\320\241\321\216\320\271\320\247\321\215\320\275RandomCore.py"
@@ -0,0 +1,289 @@
+from __future__ import annotations
+from math import floor
+from random import random
+
+from easygui import multenterbox
+
+from Classes.MapStruct import MapStruct
+from Classes.RandomCore import RandomCore
+
+
+class DefaultСюйЧэнRandomSettings:
+ asteroidWidth = 2
+ resourceNum = 7
+ constructionNum = 5
+ shadowProb = 0.015
+ shadowCrossBonus = 23
+ ruinProb = 0.01
+ ruinCrossBonus = 40
+
+
+class СюйЧэнRandomCore(RandomCore):
+ title: str
+ asteroidWidth: int
+ resourceNum: int
+ constructionNum: int
+ shadowProb: float
+ shadowCrossBonus: int
+ ruinProb: float
+ ruinCrossBonus: int
+
+ @property
+ def AsteroidWidth(self) -> int:
+ return self.asteroidWidth
+
+ @AsteroidWidth.setter
+ def AsteroidWidth(self, value: int) -> None:
+ if value < 1 or value > 4:
+ self.asteroidWidth = DefaultСюйЧэнRandomSettings.asteroidWidth
+ else:
+ self.asteroidWidth = value
+
+ @property
+ def ResourceNum(self) -> int:
+ return self.resourceNum
+
+ @ResourceNum.setter
+ def ResourceNum(self, value: int) -> None:
+ if value < 1 or value > 10:
+ self.resourceNum = DefaultСюйЧэнRandomSettings.resourceNum
+ else:
+ self.resourceNum = value
+
+ @property
+ def ConstructionNum(self) -> int:
+ return self.constructionNum
+
+ @ConstructionNum.setter
+ def ConstructionNum(self, value: int) -> None:
+ if value < 1 or value > 10:
+ self.constructionNum = DefaultСюйЧэнRandomSettings.constructionNum
+ else:
+ self.constructionNum = value
+
+ @property
+ def ShadowProb(self) -> float:
+ return self.shadowProb
+
+ @ShadowProb.setter
+ def ShadowProb(self, value: float) -> None:
+ if value < 0 or value > 0.1:
+ self.shadowProb = DefaultСюйЧэнRandomSettings.shadowProb
+ else:
+ self.shadowProb = value
+
+ @property
+ def ShadowCrossBonus(self) -> int:
+ return self.shadowCrossBonus
+
+ @ShadowCrossBonus.setter
+ def ShadowCrossBonus(self, value: int) -> None:
+ if value < 1 or value > 50:
+ self.shadowCrossBonus = DefaultСюйЧэнRandomSettings.shadowCrossBonus
+ else:
+ self.shadowCrossBonus = value
+
+ @property
+ def RuinProb(self) -> float:
+ return self.ruinProb
+
+ @RuinProb.setter
+ def RuinProb(self, value: float) -> None:
+ if value < 0 or value > 0.1:
+ self.ruinProb = DefaultСюйЧэнRandomSettings.ruinProb
+ else:
+ self.ruinProb = value
+
+ @property
+ def RuinCrossBonus(self) -> int:
+ return self.ruinCrossBonus
+
+ @RuinCrossBonus.setter
+ def RuinCrossBonus(self, value: int) -> None:
+ if value < 1 or value > 50:
+ self.ruinCrossBonus = DefaultСюйЧэнRandomSettings.ruinCrossBonus
+ else:
+ self.ruinCrossBonus = value
+
+ def __init__(self,
+ title,
+ asteroidWidth: int = DefaultСюйЧэнRandomSettings.asteroidWidth,
+ resourceNum: int = DefaultСюйЧэнRandomSettings.resourceNum,
+ constructionNum: int = DefaultСюйЧэнRandomSettings.constructionNum,
+ shadowProb: float = DefaultСюйЧэнRandomSettings.shadowProb,
+ shadowCrossBonus: int = DefaultСюйЧэнRandomSettings.shadowCrossBonus,
+ ruinProb: float = DefaultСюйЧэнRandomSettings.ruinProb,
+ ruinCrossBonus: int = DefaultСюйЧэнRandomSettings.ruinCrossBonus) -> None:
+ self.title = title
+ self.AsteroidWidth = asteroidWidth
+ self.ResourceNum = resourceNum
+ self.ConstructionNum = constructionNum
+ self.ShadowProb = shadowProb
+ self.ShadowCrossBonus = shadowCrossBonus
+ self.RuinProb = ruinProb
+ self.RuinCrossBonus = ruinCrossBonus
+
+ @property
+ def Name(self) -> str:
+ return 'СюйЧэн'
+
+ def Menu(self) -> bool:
+ try:
+ (self.AsteroidWidth,
+ self.ResourceNum,
+ self.ConstructionNum,
+ self.ShadowProb,
+ self.ShadowCrossBonus,
+ self.RuinProb,
+ self.RuinCrossBonus) = (lambda i1, i2, i3, f4, i5, f6, i7:
+ (int(i1), int(i2), int(i3), float(f4), int(i5), float(f6), int(i7)))(*multenterbox(
+ msg='Random settings',
+ title=self.title,
+ fields=[
+ 'Asteroid 宽度',
+ 'Resource 数量',
+ 'Construction 数量',
+ 'Shadow 生成概率',
+ 'Shadow 蔓延加成',
+ 'Ruin 生成概率',
+ 'Ruin 蔓延加成'
+ ],
+ values=[self.AsteroidWidth,
+ self.ResourceNum,
+ self.ConstructionNum,
+ self.ShadowProb,
+ self.ShadowCrossBonus,
+ self.RuinProb,
+ self.RuinCrossBonus]
+ ))
+ except TypeError:
+ return False
+ return True
+
+ def Random(self, mp: MapStruct) -> None:
+ СюйЧэнRandomCore.generateBorderRuin(mp)
+ СюйЧэнRandomCore.generateHome(mp)
+ СюйЧэнRandomCore.generateAsteroid(mp, self.asteroidWidth)
+ СюйЧэнRandomCore.generateResource(mp, self.resourceNum)
+ СюйЧэнRandomCore.generateConstruction(mp, self.constructionNum)
+ СюйЧэнRandomCore.generateShadow(mp, self.shadowProb, self.shadowCrossBonus)
+ СюйЧэнRandomCore.generateRuin(mp, self.ruinProb, self.ruinCrossBonus)
+ СюйЧэнRandomCore.generateWormhole(mp)
+
+ @staticmethod
+ def isEmptyNearby(mp: MapStruct, x: int, y: int, r: int) -> bool:
+ for i in range(x - r if x - r >= 0 else 0, (x + r if x + r <= 49 else 49) + 1):
+ for j in range(y - r if y - r >= 0 else 0, (y - r if y + r <= 9 else 49) + 1):
+ if mp[i, j] != 0:
+ return False
+ return True
+
+ @staticmethod
+ def haveSthNearby(mp: MapStruct, x: int, y: int, r: int, tp: int) -> int:
+ ret = 0
+ for i in range(x - r if x - r >= 0 else 0, (x + r if x + r <= 49 else 49) + 1):
+ for j in range(y - r if y - r >= 0 else 0, (y - r if y + r <= 9 else 49) + 1):
+ if mp[i, j] == tp:
+ ret += 1
+ return ret
+
+ @staticmethod
+ def haveSthCross(mp: MapStruct, x: int, y: int, r: int, tp: int) -> int:
+ ret = 0
+ for i in range(x - r if x - r >= 0 else 0, (x + r if x + r <= 49 else 49) + 1):
+ if mp[i, y] == tp:
+ ret += 1
+ for j in range(y - r if y - r >= 0 else 0, (y - r if y + r <= 9 else 49) + 1):
+ if mp[x, j] == tp:
+ ret += 1
+ return ret
+
+ @staticmethod
+ def generateBorderRuin(mp: MapStruct) -> None:
+ for i in range(50):
+ mp[i, 0] = 1
+ mp[i, 49] = 1
+ mp[0, i] = 1
+ mp[49, i] = 1
+
+ @staticmethod
+ def generateHome(mp: MapStruct) -> None:
+ mp[3, 46] = 7
+ mp[46, 3] = 7
+
+ @staticmethod
+ def generateAsteroid(mp: MapStruct, width: int = DefaultСюйЧэнRandomSettings.asteroidWidth) -> None:
+ for i in range(1, 49):
+ for j in range(24, 24 - width, -1):
+ mp[i, j] = 3
+ mp[49 - i, 49 - j] = 3
+ for i in range(1, 23):
+ if random() < 0.5 and i != 9 and i != 10 and i != 11 and i != 12:
+ mp[i, 24 - width] = 3
+ mp[i, 24 + width] = 0
+ mp[49 - i, 25 + width] = 3
+ mp[49 - i, 25 - width] = 0
+
+ @staticmethod
+ def generateResource(mp: MapStruct, num: int = DefaultСюйЧэнRandomSettings.resourceNum) -> None:
+ i = 0
+ while i < num:
+ x = floor(random() * 48) + 1
+ y = floor(random() * 23) + 1
+ if СюйЧэнRandomCore.isEmptyNearby(mp, x, y, 2):
+ mp[x, y] = 4
+ mp[49 - x, 49 - y] = 4
+ else:
+ i -= 1
+ i += 1
+
+ @staticmethod
+ def generateConstruction(mp: MapStruct, num: int = DefaultСюйЧэнRandomSettings.constructionNum) -> None:
+ i = 0
+ while i < num:
+ x = floor(random() * 48) + 1
+ y = floor(random() * 23) + 1
+ if СюйЧэнRandomCore.isEmptyNearby(mp, x, y, 1):
+ mp[x, y] = 5
+ mp[49 - x, 49 - y] = 5
+ else:
+ i -= 1
+ i += 1
+
+ @staticmethod
+ def generateShadow(mp: MapStruct, prob: float = DefaultСюйЧэнRandomSettings.shadowProb,
+ crossBonus: int = DefaultСюйЧэнRandomSettings.shadowCrossBonus) -> None:
+ for i in range(50):
+ for j in range(50):
+ if (mp[i, j] == 0 and
+ random() < prob * (СюйЧэнRandomCore.haveSthCross(mp, i, j, 1, 2) * crossBonus + 1)):
+ mp[i, j] = 2
+ mp[49 - i, 49 - j] = 2
+
+ @staticmethod
+ def generateRuin(mp: MapStruct, prob: float = DefaultСюйЧэнRandomSettings.ruinProb,
+ crossBonus: int = DefaultСюйЧэнRandomSettings.ruinCrossBonus) -> None:
+ for i in range(2, 48):
+ for j in range(2, 48):
+ if ((mp[i, j] == 0 or mp[i, j] == 2) and
+ not СюйЧэнRandomCore.haveSthNearby(mp, i, j, 1, 3) and
+ not СюйЧэнRandomCore.haveSthNearby(mp, i, j, 1, 7) and
+ random() < prob
+ * (СюйЧэнRandomCore.haveSthCross(mp, i, j, 1, 1)
+ * (0 if СюйЧэнRandomCore.haveSthCross(mp, i, j, 1, 1) > 1
+ else crossBonus) + 1)):
+ mp[i, j] = 1
+ mp[49 - i, 49 - j] = 1
+
+ @staticmethod
+ def generateWormhole(mp: MapStruct) -> None:
+ for i in range(1, 49):
+ if mp[10, i] == 3:
+ mp[10, i] = 6
+ mp[39, 49 - i] = 6
+ if mp[11, i] == 3:
+ mp[11, i] = 6
+ mp[38, 49 - i] = 6
+ if mp[24, i] == 3:
+ mp[24, i] = 6
+ mp[25, 49 - i] = 6
diff --git a/dependency/MapGenerator-Python/MapGenerator.spec b/dependency/MapGenerator-Python/MapGenerator.spec
new file mode 100644
index 00000000..124c419b
--- /dev/null
+++ b/dependency/MapGenerator-Python/MapGenerator.spec
@@ -0,0 +1,44 @@
+# -*- mode: python ; coding: utf-8 -*-
+
+
+a = Analysis(
+ ['main.py'],
+ pathex=[],
+ binaries=[],
+ datas=[('Settings.json', '.')],
+ hiddenimports=[],
+ hookspath=[],
+ hooksconfig={},
+ runtime_hooks=[],
+ excludes=[],
+ noarchive=False,
+)
+pyz = PYZ(a.pure)
+
+exe = EXE(
+ pyz,
+ a.scripts,
+ [],
+ exclude_binaries=True,
+ name='MapGenerator',
+ debug=False,
+ bootloader_ignore_signals=False,
+ strip=False,
+ upx=True,
+ console=False,
+ disable_windowed_traceback=False,
+ argv_emulation=False,
+ target_arch=None,
+ codesign_identity=None,
+ entitlements_file=None,
+ icon=['favicon.ico'],
+)
+coll = COLLECT(
+ exe,
+ a.binaries,
+ a.datas,
+ strip=False,
+ upx=True,
+ upx_exclude=[],
+ name='MapGenerator',
+)
diff --git a/dependency/MapGenerator-Python/Pipfile b/dependency/MapGenerator-Python/Pipfile
new file mode 100644
index 00000000..d4834fb7
--- /dev/null
+++ b/dependency/MapGenerator-Python/Pipfile
@@ -0,0 +1,14 @@
+[[source]]
+url = "https://pypi.tuna.tsinghua.edu.cn/simple"
+verify_ssl = true
+name = "pip_conf_index_global"
+
+[packages]
+easygui = "*"
+matplotlib = "*"
+perlin-noise = "*"
+
+[dev-packages]
+
+[requires]
+python_version = "3.10"
diff --git a/dependency/MapGenerator-Python/Pipfile.lock b/dependency/MapGenerator-Python/Pipfile.lock
new file mode 100644
index 00000000..5413d322
--- /dev/null
+++ b/dependency/MapGenerator-Python/Pipfile.lock
@@ -0,0 +1,422 @@
+{
+ "_meta": {
+ "hash": {
+ "sha256": "2ef3fb26544825937dfea936d5374c5981f7b007a6c6c42357a12add146dc967"
+ },
+ "pipfile-spec": 6,
+ "requires": {
+ "python_version": "3.10"
+ },
+ "sources": [
+ {
+ "name": "pip_conf_index_global",
+ "url": "https://pypi.tuna.tsinghua.edu.cn/simple",
+ "verify_ssl": true
+ }
+ ]
+ },
+ "default": {
+ "contourpy": {
+ "hashes": [
+ "sha256:0274c1cb63625972c0c007ab14dd9ba9e199c36ae1a231ce45d725cbcbfd10a8",
+ "sha256:0d7e03c0f9a4f90dc18d4e77e9ef4ec7b7bbb437f7f675be8e530d65ae6ef956",
+ "sha256:11f8d2554e52f459918f7b8e6aa20ec2a3bce35ce95c1f0ef4ba36fbda306df5",
+ "sha256:139d8d2e1c1dd52d78682f505e980f592ba53c9f73bd6be102233e358b401063",
+ "sha256:16a7380e943a6d52472096cb7ad5264ecee36ed60888e2a3d3814991a0107286",
+ "sha256:171f311cb758de7da13fc53af221ae47a5877be5a0843a9fe150818c51ed276a",
+ "sha256:18fc2b4ed8e4a8fe849d18dce4bd3c7ea637758c6343a1f2bae1e9bd4c9f4686",
+ "sha256:1c203f617abc0dde5792beb586f827021069fb6d403d7f4d5c2b543d87edceb9",
+ "sha256:1c2559d6cffc94890b0529ea7eeecc20d6fadc1539273aa27faf503eb4656d8f",
+ "sha256:1c88dfb9e0c77612febebb6ac69d44a8d81e3dc60f993215425b62c1161353f4",
+ "sha256:1e9dc350fb4c58adc64df3e0703ab076f60aac06e67d48b3848c23647ae4310e",
+ "sha256:247b9d16535acaa766d03037d8e8fb20866d054d3c7fbf6fd1f993f11fc60ca0",
+ "sha256:266270c6f6608340f6c9836a0fb9b367be61dde0c9a9a18d5ece97774105ff3e",
+ "sha256:34b9071c040d6fe45d9826cbbe3727d20d83f1b6110d219b83eb0e2a01d79488",
+ "sha256:3d7d1f8871998cdff5d2ff6a087e5e1780139abe2838e85b0b46b7ae6cc25399",
+ "sha256:461e3ae84cd90b30f8d533f07d87c00379644205b1d33a5ea03381edc4b69431",
+ "sha256:464b423bc2a009088f19bdf1f232299e8b6917963e2b7e1d277da5041f33a779",
+ "sha256:491b1917afdd8638a05b611a56d46587d5a632cabead889a5440f7c638bc6ed9",
+ "sha256:4a1b1208102be6e851f20066bf0e7a96b7d48a07c9b0cfe6d0d4545c2f6cadab",
+ "sha256:575bcaf957a25d1194903a10bc9f316c136c19f24e0985a2b9b5608bdf5dbfe0",
+ "sha256:5c6b28956b7b232ae801406e529ad7b350d3f09a4fde958dfdf3c0520cdde0dd",
+ "sha256:5d16edfc3fc09968e09ddffada434b3bf989bf4911535e04eada58469873e28e",
+ "sha256:5fd1810973a375ca0e097dee059c407913ba35723b111df75671a1976efa04bc",
+ "sha256:67b7f17679fa62ec82b7e3e611c43a016b887bd64fb933b3ae8638583006c6d6",
+ "sha256:68ce4788b7d93e47f84edd3f1f95acdcd142ae60bc0e5493bfd120683d2d4316",
+ "sha256:6d3364b999c62f539cd403f8123ae426da946e142312a514162adb2addd8d808",
+ "sha256:6e739530c662a8d6d42c37c2ed52a6f0932c2d4a3e8c1f90692ad0ce1274abe0",
+ "sha256:6fdd887f17c2f4572ce548461e4f96396681212d858cae7bd52ba3310bc6f00f",
+ "sha256:78e6ad33cf2e2e80c5dfaaa0beec3d61face0fb650557100ee36db808bfa6843",
+ "sha256:884c3f9d42d7218304bc74a8a7693d172685c84bd7ab2bab1ee567b769696df9",
+ "sha256:8d8faf05be5ec8e02a4d86f616fc2a0322ff4a4ce26c0f09d9f7fb5330a35c95",
+ "sha256:999c71939aad2780f003979b25ac5b8f2df651dac7b38fb8ce6c46ba5abe6ae9",
+ "sha256:99ad97258985328b4f207a5e777c1b44a83bfe7cf1f87b99f9c11d4ee477c4de",
+ "sha256:9e6c93b5b2dbcedad20a2f18ec22cae47da0d705d454308063421a3b290d9ea4",
+ "sha256:ab459a1cbbf18e8698399c595a01f6dcc5c138220ca3ea9e7e6126232d102bb4",
+ "sha256:b69303ceb2e4d4f146bf82fda78891ef7bcd80c41bf16bfca3d0d7eb545448aa",
+ "sha256:b7caf9b241464c404613512d5594a6e2ff0cc9cb5615c9475cc1d9b514218ae8",
+ "sha256:b95a225d4948b26a28c08307a60ac00fb8671b14f2047fc5476613252a129776",
+ "sha256:bd2f1ae63998da104f16a8b788f685e55d65760cd1929518fd94cd682bf03e41",
+ "sha256:be16975d94c320432657ad2402f6760990cb640c161ae6da1363051805fa8108",
+ "sha256:ce96dd400486e80ac7d195b2d800b03e3e6a787e2a522bfb83755938465a819e",
+ "sha256:dbd50d0a0539ae2e96e537553aff6d02c10ed165ef40c65b0e27e744a0f10af8",
+ "sha256:dd10c26b4eadae44783c45ad6655220426f971c61d9b239e6f7b16d5cdaaa727",
+ "sha256:ebeac59e9e1eb4b84940d076d9f9a6cec0064e241818bcb6e32124cc5c3e377a"
+ ],
+ "markers": "python_version >= '3.9'",
+ "version": "==1.2.0"
+ },
+ "cycler": {
+ "hashes": [
+ "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30",
+ "sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c"
+ ],
+ "markers": "python_version >= '3.8'",
+ "version": "==0.12.1"
+ },
+ "easygui": {
+ "hashes": [
+ "sha256:33498710c68b5376b459cd3fc48d1d1f33822139eb3ed01defbc0528326da3ba",
+ "sha256:d653ff79ee1f42f63b5a090f2f98ce02335d86ad8963b3ce2661805cafe99a04"
+ ],
+ "index": "pip_conf_index_global",
+ "version": "==0.98.3"
+ },
+ "fonttools": {
+ "hashes": [
+ "sha256:05d7c4d2c95b9490e669f3cb83918799bf1c838619ac6d3bad9ea017cfc63f2e",
+ "sha256:0f412954275e594f7a51c16f3b3edd850acb0d842fefc33856b63a17e18499a5",
+ "sha256:22ea8aa7b3712450b42b044702bd3a64fd118006bad09a6f94bd1b227088492e",
+ "sha256:2db63941fee3122e31a21dd0f5b2138ce9906b661a85b63622421d3654a74ae2",
+ "sha256:2e91e19b583961979e2e5a701269d3cfc07418963bee717f8160b0a24332826b",
+ "sha256:31b38528f25bc662401e6ffae14b3eb7f1e820892fd80369a37155e3b636a2f4",
+ "sha256:3d29509f6e05e8d725db59c2d8c076223d793e4e35773040be6632a0349f2f97",
+ "sha256:46c79af80a835410874683b5779b6c1ec1d5a285e11c45b5193e79dd691eb111",
+ "sha256:4e90dd81b6e0d97ebfe52c0d12a17a9ef7f305d6bfbb93081265057d6092f252",
+ "sha256:50d25893885e80a5955186791eed5579f1e75921751539cc1dc3ffd1160b48cf",
+ "sha256:518a945dbfe337744bfff31423c1430303b8813c5275dffb0f2577f0734a1189",
+ "sha256:54efed22b2799a85475e6840e907c402ba49892c614565dc770aa97a53621b2b",
+ "sha256:58af428746fa73a2edcbf26aff33ac4ef3c11c8d75bb200eaea2f7e888d2de4e",
+ "sha256:59b6ad83cce067d10f4790c037a5904424f45bebb5e7be2eb2db90402f288267",
+ "sha256:63a3112f753baef8c6ac2f5f574bb9ac8001b86c8c0c0380039db47a7f512d20",
+ "sha256:66bc6efd829382f7a7e6cf33c2fb32b13edc8a239eb15f32acbf197dce7a0165",
+ "sha256:6999e80a125b0cd8e068d0210b63323f17338038c2ecd2e11b9209ec430fe7f2",
+ "sha256:6d16d9634ff1e5cea2cf4a8cbda9026f766e4b5f30b48f8180f0e99133d3abfc",
+ "sha256:84f308b7a8d28208d54315d11d35f9888d6d607673dd4d42d60b463682ee0400",
+ "sha256:9ee8692e23028564c13d924004495f284df8ac016a19f17a87251210e1f1f928",
+ "sha256:a3da036b016c975c2d8c69005bdc4d5d16266f948a7fab950244e0f58301996a",
+ "sha256:a7aec7f5d14dfcd71fb3ebc299b3f000c21fdc4043079101777ed2042ba5b7c5",
+ "sha256:a8a1fa9a718de0bc026979c93e1e9b55c5efde60d76f91561fd713387573817d",
+ "sha256:a8b99713d3a0d0e876b6aecfaada5e7dc9fe979fcd90ef9fa0ba1d9b9aed03f2",
+ "sha256:b63da598d9cbc52e2381f922da0e94d60c0429f92207bd3fb04d112fc82ea7cb",
+ "sha256:b6e6aa2d066f8dafd06d8d0799b4944b5d5a1f015dd52ac01bdf2895ebe169a0",
+ "sha256:b99fe8ef4093f672d00841569d2d05691e50334d79f4d9c15c1265d76d5580d2",
+ "sha256:b9beb0fa6ff3ea808ad4a6962d68ac0f140ddab080957b20d9e268e4d67fb335",
+ "sha256:b9eab7f9837fdaa2a10a524fbcc2ec24bf60637c044b6e4a59c3f835b90f0fae",
+ "sha256:bca49da868e8bde569ef36f0cc1b6de21d56bf9c3be185c503b629c19a185287",
+ "sha256:c05064f95aacdfc06f21e55096c964b2228d942b8675fa26995a2551f6329d2d",
+ "sha256:c2de1fb18198acd400c45ffe2aef5420c8d55fde903e91cba705596099550f3b",
+ "sha256:c794de4086f06ae609b71ac944ec7deb09f34ecf73316fddc041087dd24bba39",
+ "sha256:d4fa4f4bc8fd86579b8cdbe5e948f35d82c0eda0091c399d009b2a5a6b61c040",
+ "sha256:dab3d00d27b1a79ae4d4a240e8ceea8af0ff049fd45f05adb4f860d93744110d",
+ "sha256:dbac86d83d96099890e731cc2af97976ff2c98f4ba432fccde657c5653a32f1c",
+ "sha256:df40daa6c03b98652ffe8110ae014fe695437f6e1cb5a07e16ea37f40e73ac86",
+ "sha256:e1cd1c6bb097e774d68402499ff66185190baaa2629ae2f18515a2c50b93db0c",
+ "sha256:e8ff7d19a6804bfd561cfcec9b4200dd1788e28f7de4be70189801530c47c1b3",
+ "sha256:eb01c49c8aa035d5346f46630209923d4927ed15c2493db38d31da9f811eb70d",
+ "sha256:f53526668beccdb3409c6055a4ffe50987a7f05af6436fa55d61f5e7bd450219",
+ "sha256:f611c97678604e302b725f71626edea113a5745a7fb557c958b39edb6add87d5"
+ ],
+ "markers": "python_version >= '3.8'",
+ "version": "==4.44.0"
+ },
+ "kiwisolver": {
+ "hashes": [
+ "sha256:00bd361b903dc4bbf4eb165f24d1acbee754fce22ded24c3d56eec268658a5cf",
+ "sha256:040c1aebeda72197ef477a906782b5ab0d387642e93bda547336b8957c61022e",
+ "sha256:05703cf211d585109fcd72207a31bb170a0f22144d68298dc5e61b3c946518af",
+ "sha256:06f54715b7737c2fecdbf140d1afb11a33d59508a47bf11bb38ecf21dc9ab79f",
+ "sha256:0dc9db8e79f0036e8173c466d21ef18e1befc02de8bf8aa8dc0813a6dc8a7046",
+ "sha256:0f114aa76dc1b8f636d077979c0ac22e7cd8f3493abbab152f20eb8d3cda71f3",
+ "sha256:11863aa14a51fd6ec28688d76f1735f8f69ab1fabf388851a595d0721af042f5",
+ "sha256:11c7de8f692fc99816e8ac50d1d1aef4f75126eefc33ac79aac02c099fd3db71",
+ "sha256:11d011a7574eb3b82bcc9c1a1d35c1d7075677fdd15de527d91b46bd35e935ee",
+ "sha256:146d14bebb7f1dc4d5fbf74f8a6cb15ac42baadee8912eb84ac0b3b2a3dc6ac3",
+ "sha256:15568384086b6df3c65353820a4473575dbad192e35010f622c6ce3eebd57af9",
+ "sha256:19df6e621f6d8b4b9c4d45f40a66839294ff2bb235e64d2178f7522d9170ac5b",
+ "sha256:1b04139c4236a0f3aff534479b58f6f849a8b351e1314826c2d230849ed48985",
+ "sha256:210ef2c3a1f03272649aff1ef992df2e724748918c4bc2d5a90352849eb40bea",
+ "sha256:2270953c0d8cdab5d422bee7d2007f043473f9d2999631c86a223c9db56cbd16",
+ "sha256:2400873bccc260b6ae184b2b8a4fec0e4082d30648eadb7c3d9a13405d861e89",
+ "sha256:2a40773c71d7ccdd3798f6489aaac9eee213d566850a9533f8d26332d626b82c",
+ "sha256:2c5674c4e74d939b9d91dda0fae10597ac7521768fec9e399c70a1f27e2ea2d9",
+ "sha256:3195782b26fc03aa9c6913d5bad5aeb864bdc372924c093b0f1cebad603dd712",
+ "sha256:31a82d498054cac9f6d0b53d02bb85811185bcb477d4b60144f915f3b3126342",
+ "sha256:32d5cf40c4f7c7b3ca500f8985eb3fb3a7dfc023215e876f207956b5ea26632a",
+ "sha256:346f5343b9e3f00b8db8ba359350eb124b98c99efd0b408728ac6ebf38173958",
+ "sha256:378a214a1e3bbf5ac4a8708304318b4f890da88c9e6a07699c4ae7174c09a68d",
+ "sha256:39b42c68602539407884cf70d6a480a469b93b81b7701378ba5e2328660c847a",
+ "sha256:3a2b053a0ab7a3960c98725cfb0bf5b48ba82f64ec95fe06f1d06c99b552e130",
+ "sha256:3aba7311af82e335dd1e36ffff68aaca609ca6290c2cb6d821a39aa075d8e3ff",
+ "sha256:3cd32d6c13807e5c66a7cbb79f90b553642f296ae4518a60d8d76243b0ad2898",
+ "sha256:3edd2fa14e68c9be82c5b16689e8d63d89fe927e56debd6e1dbce7a26a17f81b",
+ "sha256:4c380469bd3f970ef677bf2bcba2b6b0b4d5c75e7a020fb863ef75084efad66f",
+ "sha256:4e66e81a5779b65ac21764c295087de82235597a2293d18d943f8e9e32746265",
+ "sha256:53abb58632235cd154176ced1ae8f0d29a6657aa1aa9decf50b899b755bc2b93",
+ "sha256:5794cf59533bc3f1b1c821f7206a3617999db9fbefc345360aafe2e067514929",
+ "sha256:59415f46a37f7f2efeec758353dd2eae1b07640d8ca0f0c42548ec4125492635",
+ "sha256:59ec7b7c7e1a61061850d53aaf8e93db63dce0c936db1fda2658b70e4a1be709",
+ "sha256:59edc41b24031bc25108e210c0def6f6c2191210492a972d585a06ff246bb79b",
+ "sha256:5a580c91d686376f0f7c295357595c5a026e6cbc3d77b7c36e290201e7c11ecb",
+ "sha256:5b94529f9b2591b7af5f3e0e730a4e0a41ea174af35a4fd067775f9bdfeee01a",
+ "sha256:5c7b3b3a728dc6faf3fc372ef24f21d1e3cee2ac3e9596691d746e5a536de920",
+ "sha256:5c90ae8c8d32e472be041e76f9d2f2dbff4d0b0be8bd4041770eddb18cf49a4e",
+ "sha256:5e7139af55d1688f8b960ee9ad5adafc4ac17c1c473fe07133ac092310d76544",
+ "sha256:5ff5cf3571589b6d13bfbfd6bcd7a3f659e42f96b5fd1c4830c4cf21d4f5ef45",
+ "sha256:620ced262a86244e2be10a676b646f29c34537d0d9cc8eb26c08f53d98013390",
+ "sha256:6512cb89e334e4700febbffaaa52761b65b4f5a3cf33f960213d5656cea36a77",
+ "sha256:6c08e1312a9cf1074d17b17728d3dfce2a5125b2d791527f33ffbe805200a355",
+ "sha256:6c3bd3cde54cafb87d74d8db50b909705c62b17c2099b8f2e25b461882e544ff",
+ "sha256:6ef7afcd2d281494c0a9101d5c571970708ad911d028137cd558f02b851c08b4",
+ "sha256:7269d9e5f1084a653d575c7ec012ff57f0c042258bf5db0954bf551c158466e7",
+ "sha256:72d40b33e834371fd330fb1472ca19d9b8327acb79a5821d4008391db8e29f20",
+ "sha256:74d1b44c6cfc897df648cc9fdaa09bc3e7679926e6f96df05775d4fb3946571c",
+ "sha256:74db36e14a7d1ce0986fa104f7d5637aea5c82ca6326ed0ec5694280942d1162",
+ "sha256:763773d53f07244148ccac5b084da5adb90bfaee39c197554f01b286cf869228",
+ "sha256:76c6a5964640638cdeaa0c359382e5703e9293030fe730018ca06bc2010c4437",
+ "sha256:76d9289ed3f7501012e05abb8358bbb129149dbd173f1f57a1bf1c22d19ab7cc",
+ "sha256:7931d8f1f67c4be9ba1dd9c451fb0eeca1a25b89e4d3f89e828fe12a519b782a",
+ "sha256:7b8b454bac16428b22560d0a1cf0a09875339cab69df61d7805bf48919415901",
+ "sha256:7e5bab140c309cb3a6ce373a9e71eb7e4873c70c2dda01df6820474f9889d6d4",
+ "sha256:83d78376d0d4fd884e2c114d0621624b73d2aba4e2788182d286309ebdeed770",
+ "sha256:852542f9481f4a62dbb5dd99e8ab7aedfeb8fb6342349a181d4036877410f525",
+ "sha256:85267bd1aa8880a9c88a8cb71e18d3d64d2751a790e6ca6c27b8ccc724bcd5ad",
+ "sha256:88a2df29d4724b9237fc0c6eaf2a1adae0cdc0b3e9f4d8e7dc54b16812d2d81a",
+ "sha256:88b9f257ca61b838b6f8094a62418421f87ac2a1069f7e896c36a7d86b5d4c29",
+ "sha256:8ab3919a9997ab7ef2fbbed0cc99bb28d3c13e6d4b1ad36e97e482558a91be90",
+ "sha256:92dea1ffe3714fa8eb6a314d2b3c773208d865a0e0d35e713ec54eea08a66250",
+ "sha256:9407b6a5f0d675e8a827ad8742e1d6b49d9c1a1da5d952a67d50ef5f4170b18d",
+ "sha256:9408acf3270c4b6baad483865191e3e582b638b1654a007c62e3efe96f09a9a3",
+ "sha256:955e8513d07a283056b1396e9a57ceddbd272d9252c14f154d450d227606eb54",
+ "sha256:9db8ea4c388fdb0f780fe91346fd438657ea602d58348753d9fb265ce1bca67f",
+ "sha256:9eaa8b117dc8337728e834b9c6e2611f10c79e38f65157c4c38e9400286f5cb1",
+ "sha256:a51a263952b1429e429ff236d2f5a21c5125437861baeed77f5e1cc2d2c7c6da",
+ "sha256:a6aa6315319a052b4ee378aa171959c898a6183f15c1e541821c5c59beaa0238",
+ "sha256:aa12042de0171fad672b6c59df69106d20d5596e4f87b5e8f76df757a7c399aa",
+ "sha256:aaf7be1207676ac608a50cd08f102f6742dbfc70e8d60c4db1c6897f62f71523",
+ "sha256:b0157420efcb803e71d1b28e2c287518b8808b7cf1ab8af36718fd0a2c453eb0",
+ "sha256:b3f7e75f3015df442238cca659f8baa5f42ce2a8582727981cbfa15fee0ee205",
+ "sha256:b9098e0049e88c6a24ff64545cdfc50807818ba6c1b739cae221bbbcbc58aad3",
+ "sha256:ba55dce0a9b8ff59495ddd050a0225d58bd0983d09f87cfe2b6aec4f2c1234e4",
+ "sha256:bb86433b1cfe686da83ce32a9d3a8dd308e85c76b60896d58f082136f10bffac",
+ "sha256:bbea0db94288e29afcc4c28afbf3a7ccaf2d7e027489c449cf7e8f83c6346eb9",
+ "sha256:bbf1d63eef84b2e8c89011b7f2235b1e0bf7dacc11cac9431fc6468e99ac77fb",
+ "sha256:c7940c1dc63eb37a67721b10d703247552416f719c4188c54e04334321351ced",
+ "sha256:c9bf3325c47b11b2e51bca0824ea217c7cd84491d8ac4eefd1e409705ef092bd",
+ "sha256:cdc8a402aaee9a798b50d8b827d7ecf75edc5fb35ea0f91f213ff927c15f4ff0",
+ "sha256:ceec1a6bc6cab1d6ff5d06592a91a692f90ec7505d6463a88a52cc0eb58545da",
+ "sha256:cfe6ab8da05c01ba6fbea630377b5da2cd9bcbc6338510116b01c1bc939a2c18",
+ "sha256:d099e745a512f7e3bbe7249ca835f4d357c586d78d79ae8f1dcd4d8adeb9bda9",
+ "sha256:d0ef46024e6a3d79c01ff13801cb19d0cad7fd859b15037aec74315540acc276",
+ "sha256:d2e5a98f0ec99beb3c10e13b387f8db39106d53993f498b295f0c914328b1333",
+ "sha256:da4cfb373035def307905d05041c1d06d8936452fe89d464743ae7fb8371078b",
+ "sha256:da802a19d6e15dffe4b0c24b38b3af68e6c1a68e6e1d8f30148c83864f3881db",
+ "sha256:dced8146011d2bc2e883f9bd68618b8247387f4bbec46d7392b3c3b032640126",
+ "sha256:dfdd7c0b105af050eb3d64997809dc21da247cf44e63dc73ff0fd20b96be55a9",
+ "sha256:e368f200bbc2e4f905b8e71eb38b3c04333bddaa6a2464a6355487b02bb7fb09",
+ "sha256:e391b1f0a8a5a10ab3b9bb6afcfd74f2175f24f8975fb87ecae700d1503cdee0",
+ "sha256:e57e563a57fb22a142da34f38acc2fc1a5c864bc29ca1517a88abc963e60d6ec",
+ "sha256:e5d706eba36b4c4d5bc6c6377bb6568098765e990cfc21ee16d13963fab7b3e7",
+ "sha256:ec20916e7b4cbfb1f12380e46486ec4bcbaa91a9c448b97023fde0d5bbf9e4ff",
+ "sha256:f1d072c2eb0ad60d4c183f3fb44ac6f73fb7a8f16a2694a91f988275cbf352f9",
+ "sha256:f846c260f483d1fd217fe5ed7c173fb109efa6b1fc8381c8b7552c5781756192",
+ "sha256:f91de7223d4c7b793867797bacd1ee53bfe7359bd70d27b7b58a04efbb9436c8",
+ "sha256:faae4860798c31530dd184046a900e652c95513796ef51a12bc086710c2eec4d",
+ "sha256:fc579bf0f502e54926519451b920e875f433aceb4624a3646b3252b5caa9e0b6",
+ "sha256:fcc700eadbbccbf6bc1bcb9dbe0786b4b1cb91ca0dcda336eef5c2beed37b797",
+ "sha256:fd32ea360bcbb92d28933fc05ed09bffcb1704ba3fc7942e81db0fd4f81a7892",
+ "sha256:fdb7adb641a0d13bdcd4ef48e062363d8a9ad4a182ac7647ec88f695e719ae9f"
+ ],
+ "markers": "python_version >= '3.7'",
+ "version": "==1.4.5"
+ },
+ "matplotlib": {
+ "hashes": [
+ "sha256:044df81c1f6f3a8e52d70c4cfcb44e77ea9632a10929932870dfaa90de94365d",
+ "sha256:0d24c47a1bb47e392fbcd26fe322e4ff3431653ac1e8718e4e147d450ae97a44",
+ "sha256:1fcb49b6baf0375281979cbf26695ec10bd1cada1e311893e89533b3b70143e7",
+ "sha256:20a0fdfd3ee836179047f3782be060057b878ad37f5abe29edf006a1ff3ecd73",
+ "sha256:27502d2452208ae784c19504644f09f83742809143bbeae147617640930aa344",
+ "sha256:2afe7d2f8c9e35e94fbcfcfd9b28f29cb32f0a9068cba469cf907428379c8db9",
+ "sha256:43a9d40feb63c9e31a0b8b069dcbd74a912f59bdc0095d187126694cd26977e4",
+ "sha256:43cf368a4a1d8cbc426944806e5e183cead746647a64d2cdb786441546235967",
+ "sha256:608ea2951838d391e45dec2e644888db6899c752d3c29e157af9dcefb3d7d8d5",
+ "sha256:7658b7073c1d6a2922ecc0ed41602410fae88586cb8a54f7a2063d537b6beaf7",
+ "sha256:7f99d07c0e753717775be7be39ab383453b4d8b629c9fa174596b970c6555890",
+ "sha256:82ec95b02e894561c21e066bd0c716e4b410df141ce9441aa5af6cd937e4ade2",
+ "sha256:afb72822ae410d62aa1a2920c6563cb5680de9078358f0e9474396c6c3e06be2",
+ "sha256:bf6889643d4560fcc56f9f0941f078e4df0d72a6c3e4ca548841fc13c5642664",
+ "sha256:c1b0ecaa0d1f4fe1e30f625a2347f0034a89a7d17c39efbb502e554d92ee2f61",
+ "sha256:c54c55457c7f5ea4dfdba0020004fc7667f5c10c8d9b8010d735345acc06c9b8",
+ "sha256:ca84deaa38cb64b7dd160ca2046b45f7b5dbff2b0179642e1339fadc337446c9",
+ "sha256:cd54bbf089953140905768ed4626d7223e1ad1d7e2a138410a9c4d3b865ccd80",
+ "sha256:d921c0270647ab11c3ef283efaaa3d46fd005ba233bfb3aea75231cdf3656de8",
+ "sha256:e11ab864323fa73ac1b7849688d9671c47a2665242e899785b4db1a375b547e1",
+ "sha256:e17674ee127f78f26fea237e7f4d5cf910a8be82beb6260fedf358b88075b823",
+ "sha256:e3ad1759ad4a5245172c6d32b8ada603a6020d03211524c39d78d25c9a7dc0d2",
+ "sha256:e3bb809b743653b5aab5d72ee45c8c937c28e147b0846b0826a54bece898608c",
+ "sha256:e5a504ff40f81d6233603475a45497a6dca37a873393fa20ae6f7dd6596ef72b",
+ "sha256:ed3b29f54f6bbf3eaca4cbd23bc260155153ace63b7f597c474fa6fc6f386530",
+ "sha256:f34b46dbb1db1f09bfa937cd5853e5f2af232caeeff509c3ab6e43fd33780eae",
+ "sha256:f55fb5ff02d999a100be28bf6ffe826e1867a54c7b465409685332c9dd48ffa5",
+ "sha256:ff842e27bc6a80de08c40e0bfdce460bd08080e8a94af131162b6a1b8948f2cc"
+ ],
+ "index": "pip_conf_index_global",
+ "markers": "python_version >= '3.9'",
+ "version": "==3.8.1"
+ },
+ "numpy": {
+ "hashes": [
+ "sha256:06fa1ed84aa60ea6ef9f91ba57b5ed963c3729534e6e54055fc151fad0423f0a",
+ "sha256:174a8880739c16c925799c018f3f55b8130c1f7c8e75ab0a6fa9d41cab092fd6",
+ "sha256:1a13860fdcd95de7cf58bd6f8bc5a5ef81c0b0625eb2c9a783948847abbef2c2",
+ "sha256:1cc3d5029a30fb5f06704ad6b23b35e11309491c999838c31f124fee32107c79",
+ "sha256:22f8fc02fdbc829e7a8c578dd8d2e15a9074b630d4da29cda483337e300e3ee9",
+ "sha256:26c9d33f8e8b846d5a65dd068c14e04018d05533b348d9eaeef6c1bd787f9919",
+ "sha256:2b3fca8a5b00184828d12b073af4d0fc5fdd94b1632c2477526f6bd7842d700d",
+ "sha256:2beef57fb031dcc0dc8fa4fe297a742027b954949cabb52a2a376c144e5e6060",
+ "sha256:36340109af8da8805d8851ef1d74761b3b88e81a9bd80b290bbfed61bd2b4f75",
+ "sha256:3703fc9258a4a122d17043e57b35e5ef1c5a5837c3db8be396c82e04c1cf9b0f",
+ "sha256:3ced40d4e9e18242f70dd02d739e44698df3dcb010d31f495ff00a31ef6014fe",
+ "sha256:4a06263321dfd3598cacb252f51e521a8cb4b6df471bb12a7ee5cbab20ea9167",
+ "sha256:4eb8df4bf8d3d90d091e0146f6c28492b0be84da3e409ebef54349f71ed271ef",
+ "sha256:5d5244aabd6ed7f312268b9247be47343a654ebea52a60f002dc70c769048e75",
+ "sha256:64308ebc366a8ed63fd0bf426b6a9468060962f1a4339ab1074c228fa6ade8e3",
+ "sha256:6a3cdb4d9c70e6b8c0814239ead47da00934666f668426fc6e94cce869e13fd7",
+ "sha256:854ab91a2906ef29dc3925a064fcd365c7b4da743f84b123002f6139bcb3f8a7",
+ "sha256:94cc3c222bb9fb5a12e334d0479b97bb2df446fbe622b470928f5284ffca3f8d",
+ "sha256:96ca5482c3dbdd051bcd1fce8034603d6ebfc125a7bd59f55b40d8f5d246832b",
+ "sha256:a2bbc29fcb1771cd7b7425f98b05307776a6baf43035d3b80c4b0f29e9545186",
+ "sha256:a4cd6ed4a339c21f1d1b0fdf13426cb3b284555c27ac2f156dfdaaa7e16bfab0",
+ "sha256:aa18428111fb9a591d7a9cc1b48150097ba6a7e8299fb56bdf574df650e7d1f1",
+ "sha256:aa317b2325f7aa0a9471663e6093c210cb2ae9c0ad824732b307d2c51983d5b6",
+ "sha256:b04f5dc6b3efdaab541f7857351aac359e6ae3c126e2edb376929bd3b7f92d7e",
+ "sha256:b272d4cecc32c9e19911891446b72e986157e6a1809b7b56518b4f3755267523",
+ "sha256:b361d369fc7e5e1714cf827b731ca32bff8d411212fccd29ad98ad622449cc36",
+ "sha256:b96e7b9c624ef3ae2ae0e04fa9b460f6b9f17ad8b4bec6d7756510f1f6c0c841",
+ "sha256:baf8aab04a2c0e859da118f0b38617e5ee65d75b83795055fb66c0d5e9e9b818",
+ "sha256:bcc008217145b3d77abd3e4d5ef586e3bdfba8fe17940769f8aa09b99e856c00",
+ "sha256:bd3f0091e845164a20bd5a326860c840fe2af79fa12e0469a12768a3ec578d80",
+ "sha256:cc392fdcbd21d4be6ae1bb4475a03ce3b025cd49a9be5345d76d7585aea69440",
+ "sha256:d73a3abcac238250091b11caef9ad12413dab01669511779bc9b29261dd50210",
+ "sha256:f43740ab089277d403aa07567be138fc2a89d4d9892d113b76153e0e412409f8",
+ "sha256:f65738447676ab5777f11e6bbbdb8ce11b785e105f690bc45966574816b6d3ea",
+ "sha256:f79b231bf5c16b1f39c7f4875e1ded36abee1591e98742b05d8a0fb55d8a3eec",
+ "sha256:fe6b44fb8fcdf7eda4ef4461b97b3f63c466b27ab151bec2366db8b197387841"
+ ],
+ "markers": "python_version >= '3.9'",
+ "version": "==1.26.2"
+ },
+ "packaging": {
+ "hashes": [
+ "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5",
+ "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"
+ ],
+ "markers": "python_version >= '3.7'",
+ "version": "==23.2"
+ },
+ "perlin-noise": {
+ "hashes": [
+ "sha256:01ec42d9f2bc338ae52edbb069b375fb83fec51784e17479366ced1f7063957c",
+ "sha256:7c65b6671ce06d93cf467e2b59041878e3d5dc40208a8c089de581d3f9d47701"
+ ],
+ "index": "pip_conf_index_global",
+ "version": "==1.12"
+ },
+ "pillow": {
+ "hashes": [
+ "sha256:00f438bb841382b15d7deb9a05cc946ee0f2c352653c7aa659e75e592f6fa17d",
+ "sha256:0248f86b3ea061e67817c47ecbe82c23f9dd5d5226200eb9090b3873d3ca32de",
+ "sha256:04f6f6149f266a100374ca3cc368b67fb27c4af9f1cc8cb6306d849dcdf12616",
+ "sha256:062a1610e3bc258bff2328ec43f34244fcec972ee0717200cb1425214fe5b839",
+ "sha256:0a026c188be3b443916179f5d04548092e253beb0c3e2ee0a4e2cdad72f66099",
+ "sha256:0f7c276c05a9767e877a0b4c5050c8bee6a6d960d7f0c11ebda6b99746068c2a",
+ "sha256:1a8413794b4ad9719346cd9306118450b7b00d9a15846451549314a58ac42219",
+ "sha256:1ab05f3db77e98f93964697c8efc49c7954b08dd61cff526b7f2531a22410106",
+ "sha256:1c3ac5423c8c1da5928aa12c6e258921956757d976405e9467c5f39d1d577a4b",
+ "sha256:1c41d960babf951e01a49c9746f92c5a7e0d939d1652d7ba30f6b3090f27e412",
+ "sha256:1fafabe50a6977ac70dfe829b2d5735fd54e190ab55259ec8aea4aaea412fa0b",
+ "sha256:1fb29c07478e6c06a46b867e43b0bcdb241b44cc52be9bc25ce5944eed4648e7",
+ "sha256:24fadc71218ad2b8ffe437b54876c9382b4a29e030a05a9879f615091f42ffc2",
+ "sha256:2cdc65a46e74514ce742c2013cd4a2d12e8553e3a2563c64879f7c7e4d28bce7",
+ "sha256:2ef6721c97894a7aa77723740a09547197533146fba8355e86d6d9a4a1056b14",
+ "sha256:3b834f4b16173e5b92ab6566f0473bfb09f939ba14b23b8da1f54fa63e4b623f",
+ "sha256:3d929a19f5469b3f4df33a3df2983db070ebb2088a1e145e18facbc28cae5b27",
+ "sha256:41f67248d92a5e0a2076d3517d8d4b1e41a97e2df10eb8f93106c89107f38b57",
+ "sha256:47e5bf85b80abc03be7455c95b6d6e4896a62f6541c1f2ce77a7d2bb832af262",
+ "sha256:4d0152565c6aa6ebbfb1e5d8624140a440f2b99bf7afaafbdbf6430426497f28",
+ "sha256:50d08cd0a2ecd2a8657bd3d82c71efd5a58edb04d9308185d66c3a5a5bed9610",
+ "sha256:61f1a9d247317fa08a308daaa8ee7b3f760ab1809ca2da14ecc88ae4257d6172",
+ "sha256:6932a7652464746fcb484f7fc3618e6503d2066d853f68a4bd97193a3996e273",
+ "sha256:7a7e3daa202beb61821c06d2517428e8e7c1aab08943e92ec9e5755c2fc9ba5e",
+ "sha256:7dbaa3c7de82ef37e7708521be41db5565004258ca76945ad74a8e998c30af8d",
+ "sha256:7df5608bc38bd37ef585ae9c38c9cd46d7c81498f086915b0f97255ea60c2818",
+ "sha256:806abdd8249ba3953c33742506fe414880bad78ac25cc9a9b1c6ae97bedd573f",
+ "sha256:883f216eac8712b83a63f41b76ddfb7b2afab1b74abbb413c5df6680f071a6b9",
+ "sha256:912e3812a1dbbc834da2b32299b124b5ddcb664ed354916fd1ed6f193f0e2d01",
+ "sha256:937bdc5a7f5343d1c97dc98149a0be7eb9704e937fe3dc7140e229ae4fc572a7",
+ "sha256:9882a7451c680c12f232a422730f986a1fcd808da0fd428f08b671237237d651",
+ "sha256:9a92109192b360634a4489c0c756364c0c3a2992906752165ecb50544c251312",
+ "sha256:9d7bc666bd8c5a4225e7ac71f2f9d12466ec555e89092728ea0f5c0c2422ea80",
+ "sha256:a5f63b5a68daedc54c7c3464508d8c12075e56dcfbd42f8c1bf40169061ae666",
+ "sha256:a646e48de237d860c36e0db37ecaecaa3619e6f3e9d5319e527ccbc8151df061",
+ "sha256:a89b8312d51715b510a4fe9fc13686283f376cfd5abca8cd1c65e4c76e21081b",
+ "sha256:a92386125e9ee90381c3369f57a2a50fa9e6aa8b1cf1d9c4b200d41a7dd8e992",
+ "sha256:ae88931f93214777c7a3aa0a8f92a683f83ecde27f65a45f95f22d289a69e593",
+ "sha256:afc8eef765d948543a4775f00b7b8c079b3321d6b675dde0d02afa2ee23000b4",
+ "sha256:b0eb01ca85b2361b09480784a7931fc648ed8b7836f01fb9241141b968feb1db",
+ "sha256:b1c25762197144e211efb5f4e8ad656f36c8d214d390585d1d21281f46d556ba",
+ "sha256:b4005fee46ed9be0b8fb42be0c20e79411533d1fd58edabebc0dd24626882cfd",
+ "sha256:b920e4d028f6442bea9a75b7491c063f0b9a3972520731ed26c83e254302eb1e",
+ "sha256:baada14941c83079bf84c037e2d8b7506ce201e92e3d2fa0d1303507a8538212",
+ "sha256:bb40c011447712d2e19cc261c82655f75f32cb724788df315ed992a4d65696bb",
+ "sha256:c0949b55eb607898e28eaccb525ab104b2d86542a85c74baf3a6dc24002edec2",
+ "sha256:c9aeea7b63edb7884b031a35305629a7593272b54f429a9869a4f63a1bf04c34",
+ "sha256:cfe96560c6ce2f4c07d6647af2d0f3c54cc33289894ebd88cfbb3bcd5391e256",
+ "sha256:d27b5997bdd2eb9fb199982bb7eb6164db0426904020dc38c10203187ae2ff2f",
+ "sha256:d921bc90b1defa55c9917ca6b6b71430e4286fc9e44c55ead78ca1a9f9eba5f2",
+ "sha256:e6bf8de6c36ed96c86ea3b6e1d5273c53f46ef518a062464cd7ef5dd2cf92e38",
+ "sha256:eaed6977fa73408b7b8a24e8b14e59e1668cfc0f4c40193ea7ced8e210adf996",
+ "sha256:fa1d323703cfdac2036af05191b969b910d8f115cf53093125e4058f62012c9a",
+ "sha256:fe1e26e1ffc38be097f0ba1d0d07fcade2bcfd1d023cda5b29935ae8052bd793"
+ ],
+ "markers": "python_version >= '3.8'",
+ "version": "==10.1.0"
+ },
+ "pyparsing": {
+ "hashes": [
+ "sha256:32c7c0b711493c72ff18a981d24f28aaf9c1fb7ed5e9667c9e84e3db623bdbfb",
+ "sha256:ede28a1a32462f5a9705e07aea48001a08f7cf81a021585011deba701581a0db"
+ ],
+ "markers": "python_full_version >= '3.6.8'",
+ "version": "==3.1.1"
+ },
+ "python-dateutil": {
+ "hashes": [
+ "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86",
+ "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"
+ ],
+ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
+ "version": "==2.8.2"
+ },
+ "six": {
+ "hashes": [
+ "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926",
+ "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"
+ ],
+ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
+ "version": "==1.16.0"
+ }
+ },
+ "develop": {}
+}
diff --git a/dependency/MapGenerator-Python/Settings.json b/dependency/MapGenerator-Python/Settings.json
new file mode 100644
index 00000000..db949be3
--- /dev/null
+++ b/dependency/MapGenerator-Python/Settings.json
@@ -0,0 +1,47 @@
+{
+ "title": "THUAI7-MapGenerator",
+ "file_suffix": ".thuai7.map",
+ "dtype": "B",
+ "areas": [
+ [
+ "Space",
+ 0,
+ "#FFFFFF"
+ ],
+ [
+ "Ruin",
+ 1,
+ "#B97A57"
+ ],
+ [
+ "Shadow",
+ 2,
+ "#22B14C"
+ ],
+ [
+ "Asteroid",
+ 3,
+ "#99D9EA"
+ ],
+ [
+ "Resource",
+ 4,
+ "#A349A4"
+ ],
+ [
+ "Construction",
+ 5,
+ "#FF7F27"
+ ],
+ [
+ "Wormhole",
+ 6,
+ "#880015"
+ ],
+ [
+ "Home",
+ 7,
+ "#ED1C24"
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/dependency/MapGenerator-Python/favicon.ico b/dependency/MapGenerator-Python/favicon.ico
new file mode 100644
index 00000000..75325016
Binary files /dev/null and b/dependency/MapGenerator-Python/favicon.ico differ
diff --git a/dependency/MapGenerator-Python/main.py b/dependency/MapGenerator-Python/main.py
new file mode 100644
index 00000000..2c48ab1e
--- /dev/null
+++ b/dependency/MapGenerator-Python/main.py
@@ -0,0 +1,50 @@
+from __future__ import annotations
+from io import TextIOWrapper
+import json
+import os
+import os.path
+
+from easygui import multenterbox
+
+from Classes.AreaRenderDict import AreaRenderDict
+from Classes.MapStruct import MapStruct
+from Classes.MapRenderer import MapRenderer
+from Classes.RandomCores.PerlinRandomCore import PerlinRandomCore
+from Classes.RandomCores.СюйЧэнRandomCore import СюйЧэнRandomCore
+
+
+# 查找设置
+SETTINGS_PATH = ''
+TARGET_SETTINGS_PATH = 'Settings.json'
+for root, _, files in os.walk('.'):
+ if TARGET_SETTINGS_PATH in files:
+ SETTINGS_PATH = os.path.join(root, TARGET_SETTINGS_PATH)
+if SETTINGS_PATH == '':
+ raise FileNotFoundError('未找到设置文件')
+# 加载设置
+with open(SETTINGS_PATH, 'r', encoding='utf-8') as jsonfp:
+ SETTINGS = json.load(jsonfp)
+ TITLE: str = SETTINGS['title']
+ FILE_SUFFIX: str = SETTINGS['file_suffix']
+ DTYPE: str = SETTINGS['dtype']
+ AREAS: AreaRenderDict = AreaRenderDict(SETTINGS['areas'])
+# 获取路径
+path: str = multenterbox(msg='', title=TITLE, fields=[f'Path(*{FILE_SUFFIX})'])[0]
+if path[-len(FILE_SUFFIX):] != FILE_SUFFIX:
+ path += FILE_SUFFIX
+# 地图加载
+mapfile: TextIOWrapper
+mapStruct: MapStruct
+if not os.path.exists(path):
+ height, width = [int(x) for x in multenterbox(msg='Create new map', title=TITLE, fields=['Height', 'Width'])]
+ mapStruct = MapStruct(DTYPE, height, width)
+ mapStruct.ToFile(path)
+else:
+ mapfile = open(path, 'r+b')
+ mapStruct = MapStruct(DTYPE, mapfile)
+ mapfile.close()
+# 随机核加载
+randomCores = [СюйЧэнRandomCore(TITLE), PerlinRandomCore(TITLE)]
+# 地图渲染
+mapRenderer = MapRenderer(TITLE, mapStruct, AREAS, path, randomCores)
+mapRenderer.MainFrame()
diff --git a/logic/GameClass/GameObj/Map/MapReader.cs b/logic/GameClass/GameObj/Map/MapReader.cs
new file mode 100644
index 00000000..cb475916
--- /dev/null
+++ b/logic/GameClass/GameObj/Map/MapReader.cs
@@ -0,0 +1,233 @@
+using System.IO;
+
+namespace MapGenerator;
+
+///
+/// ͼṹ
+///
+public struct MapStruct
+{
+ public MapStruct(uint height, uint width, uint[,] map)
+ {
+ this.height = height;
+ this.width = width;
+ this.map = map;
+ }
+ public uint height;
+ public uint width;
+ public uint[,] map;
+}
+
+public static class MapReader
+{
+ ///
+ /// ȡƵͼļ
+ ///
+ /// ͼļ·
+ /// ͼļȡ
+ ///
+ public static MapStruct MapRead(string mapFile, char dtype = 'B')
+ {
+ var fp = File.OpenRead(mapFile);
+ BinaryReader br = new(fp);
+ switch (dtype)
+ {
+ #region ֧
+
+ case 'b':
+ {
+ uint height = (uint)br.ReadSByte(), width = (uint)br.ReadSByte();
+ uint[,] ret = new uint[height, width];
+ for (int i = 0; i < height; i++)
+ {
+ for (int j = 0; j < width; j++)
+ {
+ ret[i, j] = (uint)br.ReadSByte();
+ }
+ }
+ return new MapStruct(height, width, ret);
+ }
+ case 'B':
+ {
+ uint height = br.ReadByte(), width = br.ReadByte();
+ uint[,] ret = new uint[height, width];
+ for (int i = 0; i < height; i++)
+ {
+ for (int j = 0; j < width; j++)
+ {
+ ret[i, j] = br.ReadByte();
+ }
+ }
+ return new MapStruct(height, width, ret);
+ }
+ case 'u':
+ {
+ uint height = br.ReadChar(), width = br.ReadChar();
+ uint[,] ret = new uint[height, width];
+ for (int i = 0; i < height; i++)
+ {
+ for (int j = 0; j < width; j++)
+ {
+ ret[i, j] = br.ReadChar();
+ }
+ }
+ return new MapStruct(height, width, ret);
+ }
+ case 'h':
+ {
+ uint height = (uint)br.ReadInt16(), width = (uint)br.ReadInt16();
+ uint[,] ret = new uint[height, width];
+ for (int i = 0; i < height; i++)
+ {
+ for (int j = 0; j < width; j++)
+ {
+ ret[i, j] = (uint)br.ReadInt16();
+ }
+ }
+ return new MapStruct(height, width, ret);
+ }
+ case 'H':
+ {
+ uint height = br.ReadUInt16(), width = br.ReadUInt16();
+ uint[,] ret = new uint[height, width];
+ for (int i = 0; i < height; i++)
+ {
+ for (int j = 0; j < width; j++)
+ {
+ ret[i, j] = br.ReadUInt16();
+ }
+ }
+ return new MapStruct(height, width, ret);
+ }
+ case 'i':
+ {
+ uint height = (uint)br.ReadInt32(), width = (uint)br.ReadInt32();
+ uint[,] ret = new uint[height, width];
+ for (int i = 0; i < height; i++)
+ {
+ for (int j = 0; j < width; j++)
+ {
+ ret[i, j] = (uint)br.ReadInt32();
+ }
+ }
+ return new MapStruct(height, width, ret);
+ }
+ case 'I':
+ {
+ uint height = br.ReadUInt32(), width = br.ReadUInt32();
+ uint[,] ret = new uint[height, width];
+ for (int i = 0; i < height; i++)
+ {
+ for (int j = 0; j < width; j++)
+ {
+ ret[i, j] = br.ReadUInt32();
+ }
+ }
+ return new MapStruct(height, width, ret);
+ }
+
+ #endregion
+
+ #region ֵ֧Ч
+
+ case 'l':
+ {
+ uint height = (uint)br.ReadInt64(), width = (uint)br.ReadInt64();
+ uint[,] ret = new uint[height, width];
+ for (int i = 0; i < height; i++)
+ {
+ for (int j = 0; j < width; j++)
+ {
+ ret[i, j] = (uint)br.ReadInt64();
+ }
+ }
+ return new MapStruct(height, width, ret);
+ }
+ case 'L':
+ {
+ uint height = (uint)br.ReadUInt64(), width = (uint)br.ReadUInt64();
+ uint[,] ret = new uint[height, width];
+ for (int i = 0; i < height; i++)
+ {
+ for (int j = 0; j < width; j++)
+ {
+ ret[i, j] = (uint)br.ReadUInt64();
+ }
+ }
+ return new MapStruct(height, width, ret);
+ }
+ case 'f':
+ {
+ uint height = (uint)br.ReadSingle(), width = (uint)br.ReadSingle();
+ uint[,] ret = new uint[height, width];
+ for (int i = 0; i < height; i++)
+ {
+ for (int j = 0; j < width; j++)
+ {
+ ret[i, j] = (uint)br.ReadSingle();
+ }
+ }
+ return new MapStruct(height, width, ret);
+ }
+ case 'd':
+ {
+ uint height = (uint)br.ReadDouble(), width = (uint)br.ReadDouble();
+ uint[,] ret = new uint[height, width];
+ for (int i = 0; i < height; i++)
+ {
+ for (int j = 0; j < width; j++)
+ {
+ ret[i, j] = (uint)br.ReadDouble();
+ }
+ }
+ return new MapStruct(height, width, ret);
+ }
+
+ #endregion
+
+ #region ²֧
+
+ case 'q':
+ {
+ uint height = br.ReadByte(), width = br.ReadByte();
+ uint[,] ret = new uint[height, width];
+ for (int i = 0; i < height; i++)
+ {
+ for (int j = 0; j < width; j++)
+ {
+ ret[i, j] = br.ReadByte();
+ }
+ }
+ return new MapStruct(height, width, ret);
+ }
+ case 'Q':
+ {
+ uint height = br.ReadByte(), width = br.ReadByte();
+ uint[,] ret = new uint[height, width];
+ for (int i = 0; i < height; i++)
+ {
+ for (int j = 0; j < width; j++)
+ {
+ ret[i, j] = br.ReadByte();
+ }
+ }
+ return new MapStruct(height, width, ret);
+ }
+ default:
+ {
+ uint height = br.ReadByte(), width = br.ReadByte();
+ uint[,] ret = new uint[height, width];
+ for (int i = 0; i < height; i++)
+ {
+ for (int j = 0; j < width; j++)
+ {
+ ret[i, j] = br.ReadByte();
+ }
+ }
+ return new MapStruct(height, width, ret);
+ }
+
+ #endregion
+ };
+ }
+}
\ No newline at end of file
diff --git a/logic/GameClass/GameObj/Ship.cs b/logic/GameClass/GameObj/Ship.cs
index 50234da9..0a640fa3 100644
--- a/logic/GameClass/GameObj/Ship.cs
+++ b/logic/GameClass/GameObj/Ship.cs
@@ -48,7 +48,7 @@ public override bool IgnoreCollideExecutor(IGameObj targetObj)
private ArmorType armorType = ArmorType.Null;
public ArmorType ArmorModuleType => armorType;
private IArmor armor;
- public IArmor ArmorModule;
+ public IArmor ArmorModule => armor;
#endregion
#region Shield