diff --git a/logic/GameClass/GameObj/Map/MapStruct.cs b/logic/GameClass/GameObj/Map/MapStruct.cs
index 39c96325..8c7e2d5e 100644
--- a/logic/GameClass/GameObj/Map/MapStruct.cs
+++ b/logic/GameClass/GameObj/Map/MapStruct.cs
@@ -1,16 +1,30 @@
using Preparation.Utility;
+using System;
using System.IO;
namespace GameClass.MapGenerator;
+#region 异常
+public class MapFileError(string filename) : Exception
+{
+ public override string Message => $"{filename} is illegal map file";
+}
+
+public class MapStreamError(Stream str) : Exception
+{
+ public override string Message => $"{str.ToString} is illegal stream of map";
+}
+#endregion
+
///
/// 地图结构体
///
-public struct MapStruct
+public readonly struct MapStruct
{
- public uint height;
- public uint width;
- public PlaceType[,] map;
+ public readonly uint height;
+ public readonly uint width;
+ public readonly PlaceType[,] map;
+
#region ctor
public MapStruct(uint height, uint width)
{
@@ -34,30 +48,40 @@ public MapStruct(uint height, uint width, uint[,] map)
}
}
#endregion
+
+ #region 文件读写
///
/// 地图文件读取
///
- /// 地图文件
- ///
+ /// 待读取地图文件
+ /// 读取得到的地图
+ ///
public static MapStruct FromFile(string filename)
{
using BinaryReader br = new(File.OpenRead(filename));
- var height = br.ReadUInt32(); var width = br.ReadUInt32();
- MapStruct ret = new(height, width);
- for (uint i = 0; i < height; i++)
+ try
{
- for (uint j = 0; j < width; j++)
+ var height = br.ReadUInt32(); var width = br.ReadUInt32();
+ MapStruct ret = new(height, width);
+ for (uint i = 0; i < height; i++)
{
- ret.map[i, j] = (PlaceType)br.ReadUInt32();
+ for (uint j = 0; j < width; j++)
+ {
+ ret[i, j] = (PlaceType)br.ReadUInt32();
+ }
}
+ return ret;
+ }
+ catch
+ {
+ throw new MapFileError(filename);
}
- return ret;
}
///
/// 地图文件存储
///
- /// 地图文件
- /// 地图
+ /// 待写入地图文件
+ /// 待写入地图
public static void ToFile(string filename, MapStruct src)
{
using BinaryWriter bw = new(File.OpenWrite(filename));
@@ -67,18 +91,75 @@ public static void ToFile(string filename, MapStruct src)
{
for (uint j = 0; j < src.width; j++)
{
- bw.Write((uint)src.map[i, j]);
+ bw.Write((uint)src[i, j]);
}
}
}
- public void Clear()
+ #endregion
+
+ #region 流读写
+ ///
+ /// 字节提取
+ ///
+ /// 字节输出流
+ /// 提取得到的地图
+ ///
+ public static MapStruct FromBytes(Stream str)
+ {
+ if (!str.CanRead) throw new MapStreamError(str);
+ try
+ {
+ BinaryReader br = new(str);
+ var height = br.ReadUInt32(); var width = br.ReadUInt32();
+ MapStruct ret = new(height, width);
+ for (uint i = 0; i < height; i++)
+ {
+ for (uint j = 0; j < width; j++)
+ {
+ ret[i, j] = (PlaceType)br.ReadUInt32();
+ }
+ }
+ return ret;
+ }
+ catch
+ {
+ throw new MapStreamError(str);
+ }
+ }
+ ///
+ /// 字节解析
+ ///
+ /// 字节输入流
+ /// 待解析地图
+ ///
+ public static void ToBytes(Stream str, MapStruct src)
+ {
+ if (!str.CanWrite) throw new MapStreamError(str);
+ BinaryWriter bw = new(str);
+ bw.Write(src.height);
+ bw.Write(src.width);
+ for (uint i = 0; i < src.height; i++)
+ {
+ for (uint j = 0; j < src.width; j++)
+ {
+ bw.Write((uint)src[i, j]);
+ }
+ }
+ }
+ #endregion
+
+ ///
+ /// 地图清空
+ ///
+ public readonly void Clear()
{
for (uint i = 0; i < height; i++)
{
for (uint j = 0; j < width; j++) map[i, j] = PlaceType.Null;
}
}
- public PlaceType this[uint i, uint j]
+
+ public readonly PlaceType this[uint i, uint j]
{
get => map[i, j];
set => map[i, j] = value;
diff --git a/dependency/MapGenerator/README.md b/map-generator/JavaScript/README.md
old mode 100755
new mode 100644
similarity index 100%
rename from dependency/MapGenerator/README.md
rename to map-generator/JavaScript/README.md
diff --git a/dependency/MapGenerator/assets/css/map.css b/map-generator/JavaScript/assets/css/map.css
old mode 100755
new mode 100644
similarity index 100%
rename from dependency/MapGenerator/assets/css/map.css
rename to map-generator/JavaScript/assets/css/map.css
diff --git a/dependency/MapGenerator/assets/css/style.css b/map-generator/JavaScript/assets/css/style.css
old mode 100755
new mode 100644
similarity index 100%
rename from dependency/MapGenerator/assets/css/style.css
rename to map-generator/JavaScript/assets/css/style.css
diff --git a/dependency/MapGenerator-Python/favicon.ico b/map-generator/JavaScript/assets/img/favicon.ico
old mode 100755
new mode 100644
similarity index 100%
rename from dependency/MapGenerator-Python/favicon.ico
rename to map-generator/JavaScript/assets/img/favicon.ico
diff --git a/dependency/MapGenerator/assets/js/map.js b/map-generator/JavaScript/assets/js/map.js
old mode 100755
new mode 100644
similarity index 100%
rename from dependency/MapGenerator/assets/js/map.js
rename to map-generator/JavaScript/assets/js/map.js
diff --git a/dependency/MapGenerator/index.html b/map-generator/JavaScript/index.html
old mode 100755
new mode 100644
similarity index 100%
rename from dependency/MapGenerator/index.html
rename to map-generator/JavaScript/index.html
diff --git a/dependency/MapGenerator-Python/.gitignore b/map-generator/Python/.gitignore
old mode 100755
new mode 100644
similarity index 55%
rename from dependency/MapGenerator-Python/.gitignore
rename to map-generator/Python/.gitignore
index e6650953..64af04a6
--- a/dependency/MapGenerator-Python/.gitignore
+++ b/map-generator/Python/.gitignore
@@ -1,4 +1,5 @@
.vscode/
*.map
build/
-dist/
\ No newline at end of file
+dist/
+*__pycache__
\ No newline at end of file
diff --git a/dependency/MapGenerator-Python/CLR_IMPORT.py b/map-generator/Python/CLR_IMPORT.py
similarity index 88%
rename from dependency/MapGenerator-Python/CLR_IMPORT.py
rename to map-generator/Python/CLR_IMPORT.py
index a49493f4..48ceb735 100644
--- a/dependency/MapGenerator-Python/CLR_IMPORT.py
+++ b/map-generator/Python/CLR_IMPORT.py
@@ -6,13 +6,15 @@
r'../../logic/Preparation/bin/Release/net8.0/',
r'../../../logic/Preparation/bin/Debug/net8.0/',
r'../../../logic/Preparation/bin/Release/net8.0/',
- r'_internal/']
+ r'./',
+ r'./_internal/']
PREPARATION = 'Preparation'
GAMECLASS_IMPORT = [r'../../logic/GameClass/bin/Debug/net8.0/',
r'../../logic/GameClass/bin/Release/net8.0/',
r'../../../logic/GameClass/bin/Debug/net8.0/',
r'../../../logic/GameClass/bin/Release/net8.0/',
- r'_internal/']
+ r'./',
+ r'./_internal/']
GAMECLASS = 'GameClass'
diff --git a/dependency/MapGenerator-Python/CLR_START.py b/map-generator/Python/CLR_START.py
similarity index 100%
rename from dependency/MapGenerator-Python/CLR_START.py
rename to map-generator/Python/CLR_START.py
diff --git a/dependency/MapGenerator-Python/Classes/MapRenderer.py b/map-generator/Python/Classes/MapRenderer.py
old mode 100755
new mode 100644
similarity index 100%
rename from dependency/MapGenerator-Python/Classes/MapRenderer.py
rename to map-generator/Python/Classes/MapRenderer.py
diff --git a/dependency/MapGenerator-Python/Classes/RandomCore.py b/map-generator/Python/Classes/RandomCore.py
old mode 100755
new mode 100644
similarity index 100%
rename from dependency/MapGenerator-Python/Classes/RandomCore.py
rename to map-generator/Python/Classes/RandomCore.py
diff --git a/dependency/MapGenerator-Python/Classes/RandomCores/PerlinRandomCore.py b/map-generator/Python/Classes/RandomCores/PerlinRandomCore.py
old mode 100755
new mode 100644
similarity index 100%
rename from dependency/MapGenerator-Python/Classes/RandomCores/PerlinRandomCore.py
rename to map-generator/Python/Classes/RandomCores/PerlinRandomCore.py
diff --git "a/dependency/MapGenerator-Python/Classes/RandomCores/\320\241\321\216\320\271\320\247\321\215\320\275RandomCore.py" b/map-generator/Python/Classes/RandomCores/XuchengRandomCore.py
old mode 100755
new mode 100644
similarity index 71%
rename from "dependency/MapGenerator-Python/Classes/RandomCores/\320\241\321\216\320\271\320\247\321\215\320\275RandomCore.py"
rename to map-generator/Python/Classes/RandomCores/XuchengRandomCore.py
index 09401dd8..af8ef53f
--- "a/dependency/MapGenerator-Python/Classes/RandomCores/\320\241\321\216\320\271\320\247\321\215\320\275RandomCore.py"
+++ b/map-generator/Python/Classes/RandomCores/XuchengRandomCore.py
@@ -9,7 +9,7 @@
from Classes.RandomCore import RandomCore
-class DefaultСюйЧэнRandomSettings:
+class DefaultXuchengRandomSettings:
asteroidWidth = 2
resourceNum = 7
constructionNum = 5
@@ -19,7 +19,7 @@ class DefaultСюйЧэнRandomSettings:
ruinCrossBonus = 40
-class СюйЧэнRandomCore(RandomCore):
+class XuchengRandomCore(RandomCore):
title: str
asteroidWidth: int
resourceNum: int
@@ -36,7 +36,7 @@ def AsteroidWidth(self) -> int:
@AsteroidWidth.setter
def AsteroidWidth(self, value: int) -> None:
if value < 1 or value > 4:
- self.asteroidWidth = DefaultСюйЧэнRandomSettings.asteroidWidth
+ self.asteroidWidth = DefaultXuchengRandomSettings.asteroidWidth
else:
self.asteroidWidth = value
@@ -47,7 +47,7 @@ def ResourceNum(self) -> int:
@ResourceNum.setter
def ResourceNum(self, value: int) -> None:
if value < 1 or value > 10:
- self.resourceNum = DefaultСюйЧэнRandomSettings.resourceNum
+ self.resourceNum = DefaultXuchengRandomSettings.resourceNum
else:
self.resourceNum = value
@@ -58,7 +58,7 @@ def ConstructionNum(self) -> int:
@ConstructionNum.setter
def ConstructionNum(self, value: int) -> None:
if value < 1 or value > 10:
- self.constructionNum = DefaultСюйЧэнRandomSettings.constructionNum
+ self.constructionNum = DefaultXuchengRandomSettings.constructionNum
else:
self.constructionNum = value
@@ -69,7 +69,7 @@ def ShadowProb(self) -> float:
@ShadowProb.setter
def ShadowProb(self, value: float) -> None:
if value < 0 or value > 0.1:
- self.shadowProb = DefaultСюйЧэнRandomSettings.shadowProb
+ self.shadowProb = DefaultXuchengRandomSettings.shadowProb
else:
self.shadowProb = value
@@ -80,7 +80,7 @@ def ShadowCrossBonus(self) -> int:
@ShadowCrossBonus.setter
def ShadowCrossBonus(self, value: int) -> None:
if value < 1 or value > 50:
- self.shadowCrossBonus = DefaultСюйЧэнRandomSettings.shadowCrossBonus
+ self.shadowCrossBonus = DefaultXuchengRandomSettings.shadowCrossBonus
else:
self.shadowCrossBonus = value
@@ -91,7 +91,7 @@ def RuinProb(self) -> float:
@RuinProb.setter
def RuinProb(self, value: float) -> None:
if value < 0 or value > 0.1:
- self.ruinProb = DefaultСюйЧэнRandomSettings.ruinProb
+ self.ruinProb = DefaultXuchengRandomSettings.ruinProb
else:
self.ruinProb = value
@@ -102,19 +102,19 @@ def RuinCrossBonus(self) -> int:
@RuinCrossBonus.setter
def RuinCrossBonus(self, value: int) -> None:
if value < 1 or value > 50:
- self.ruinCrossBonus = DefaultСюйЧэнRandomSettings.ruinCrossBonus
+ self.ruinCrossBonus = DefaultXuchengRandomSettings.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:
+ asteroidWidth: int = DefaultXuchengRandomSettings.asteroidWidth,
+ resourceNum: int = DefaultXuchengRandomSettings.resourceNum,
+ constructionNum: int = DefaultXuchengRandomSettings.constructionNum,
+ shadowProb: float = DefaultXuchengRandomSettings.shadowProb,
+ shadowCrossBonus: int = DefaultXuchengRandomSettings.shadowCrossBonus,
+ ruinProb: float = DefaultXuchengRandomSettings.ruinProb,
+ ruinCrossBonus: int = DefaultXuchengRandomSettings.ruinCrossBonus) -> None:
self.title = title
self.AsteroidWidth = asteroidWidth
self.ResourceNum = resourceNum
@@ -126,7 +126,7 @@ def __init__(self,
@property
def Name(self) -> str:
- return 'СюйЧэн'
+ return 'Xucheng'
def Menu(self) -> bool:
try:
@@ -163,14 +163,14 @@ def Menu(self) -> bool:
def Random(self, mp: MapStruct) -> None:
mp.Clear()
- СюйЧэн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)
+ XuchengRandomCore.generateBorderRuin(mp)
+ XuchengRandomCore.generateHome(mp)
+ XuchengRandomCore.generateAsteroid(mp, self.asteroidWidth)
+ XuchengRandomCore.generateResource(mp, self.resourceNum)
+ XuchengRandomCore.generateConstruction(mp, self.constructionNum)
+ XuchengRandomCore.generateShadow(mp, self.shadowProb, self.shadowCrossBonus)
+ XuchengRandomCore.generateRuin(mp, self.ruinProb, self.ruinCrossBonus)
+ XuchengRandomCore.generateWormhole(mp)
@staticmethod
def isEmptyNearby(mp: MapStruct, x: int, y: int, r: int) -> bool:
@@ -214,7 +214,7 @@ def generateHome(mp: MapStruct) -> None:
mp[46, 3] = PT.Home
@staticmethod
- def generateAsteroid(mp: MapStruct, width: int = DefaultСюйЧэнRandomSettings.asteroidWidth) -> None:
+ def generateAsteroid(mp: MapStruct, width: int = DefaultXuchengRandomSettings.asteroidWidth) -> None:
for i in range(1, 49):
for j in range(24, 24 - width, -1):
mp[i, j] = PT.Asteroid
@@ -227,12 +227,12 @@ def generateAsteroid(mp: MapStruct, width: int = DefaultСюйЧэнRandomSettin
mp[49 - i, 25 - width] = PT.Null
@staticmethod
- def generateResource(mp: MapStruct, num: int = DefaultСюйЧэнRandomSettings.resourceNum) -> None:
+ def generateResource(mp: MapStruct, num: int = DefaultXuchengRandomSettings.resourceNum) -> None:
i = 0
while i < num:
x = floor(random() * 48) + 1
y = floor(random() * 23) + 1
- if СюйЧэнRandomCore.isEmptyNearby(mp, x, y, 2):
+ if XuchengRandomCore.isEmptyNearby(mp, x, y, 2):
mp[x, y] = PT.Resource
mp[49 - x, 49 - y] = PT.Resource
else:
@@ -240,12 +240,12 @@ def generateResource(mp: MapStruct, num: int = DefaultСюйЧэнRandomSettings
i += 1
@staticmethod
- def generateConstruction(mp: MapStruct, num: int = DefaultСюйЧэнRandomSettings.constructionNum) -> None:
+ def generateConstruction(mp: MapStruct, num: int = DefaultXuchengRandomSettings.constructionNum) -> None:
i = 0
while i < num:
x = floor(random() * 48) + 1
y = floor(random() * 23) + 1
- if СюйЧэнRandomCore.isEmptyNearby(mp, x, y, 1):
+ if XuchengRandomCore.isEmptyNearby(mp, x, y, 1):
mp[x, y] = PT.Construction
mp[49 - x, 49 - y] = PT.Construction
else:
@@ -253,26 +253,26 @@ def generateConstruction(mp: MapStruct, num: int = DefaultСюйЧэнRandomSett
i += 1
@staticmethod
- def generateShadow(mp: MapStruct, prob: float = DefaultСюйЧэнRandomSettings.shadowProb,
- crossBonus: int = DefaultСюйЧэнRandomSettings.shadowCrossBonus) -> None:
+ def generateShadow(mp: MapStruct, prob: float = DefaultXuchengRandomSettings.shadowProb,
+ crossBonus: int = DefaultXuchengRandomSettings.shadowCrossBonus) -> None:
for i in range(50):
for j in range(50):
if (mp[i, j] == PT.Null and
- random() < prob * (СюйЧэнRandomCore.haveSthCross(mp, i, j, 1, PT.Shadow) * crossBonus + 1)):
+ random() < prob * (XuchengRandomCore.haveSthCross(mp, i, j, 1, PT.Shadow) * crossBonus + 1)):
mp[i, j] = PT.Shadow
mp[49 - i, 49 - j] = PT.Shadow
@staticmethod
- def generateRuin(mp: MapStruct, prob: float = DefaultСюйЧэнRandomSettings.ruinProb,
- crossBonus: int = DefaultСюйЧэнRandomSettings.ruinCrossBonus) -> None:
+ def generateRuin(mp: MapStruct, prob: float = DefaultXuchengRandomSettings.ruinProb,
+ crossBonus: int = DefaultXuchengRandomSettings.ruinCrossBonus) -> None:
for i in range(2, 48):
for j in range(2, 48):
if ((mp[i, j] == PT.Null or mp[i, j] == PT.Shadow) and
- not СюйЧэнRandomCore.haveSthNearby(mp, i, j, 1, PT.Asteroid) and
- not СюйЧэнRandomCore.haveSthNearby(mp, i, j, 1, PT.Home) and
+ not XuchengRandomCore.haveSthNearby(mp, i, j, 1, PT.Asteroid) and
+ not XuchengRandomCore.haveSthNearby(mp, i, j, 1, PT.Home) and
random() < prob
- * (СюйЧэнRandomCore.haveSthCross(mp, i, j, 1, PT.Ruin)
- * (0 if СюйЧэнRandomCore.haveSthCross(mp, i, j, 1, PT.Ruin) > 1
+ * (XuchengRandomCore.haveSthCross(mp, i, j, 1, PT.Ruin)
+ * (0 if XuchengRandomCore.haveSthCross(mp, i, j, 1, PT.Ruin) > 1
else crossBonus) + 1)):
mp[i, j] = PT.Ruin
mp[49 - i, 49 - j] = PT.Ruin
diff --git a/dependency/MapGenerator-Python/GameClass/MapGenerator.pyi b/map-generator/Python/GameClass/MapGenerator.pyi
similarity index 100%
rename from dependency/MapGenerator-Python/GameClass/MapGenerator.pyi
rename to map-generator/Python/GameClass/MapGenerator.pyi
diff --git a/dependency/MapGenerator-Python/MapGenerator.spec b/map-generator/Python/MapGenerator.spec
old mode 100755
new mode 100644
similarity index 82%
rename from dependency/MapGenerator-Python/MapGenerator.spec
rename to map-generator/Python/MapGenerator.spec
index 333e8673..84986753
--- a/dependency/MapGenerator-Python/MapGenerator.spec
+++ b/map-generator/Python/MapGenerator.spec
@@ -5,8 +5,8 @@ a = Analysis(
['main.py'],
pathex=[],
binaries=[],
- datas=[('../../logic/Preparation/bin/Debug/net8.0/Preparation.dll', '.'),
- ('../../logic/GameClass/bin/Debug/net8.0/GameClass.dll', '.')
+ datas=[('../../logic/Preparation/bin/Release/net8.0/Preparation.dll', '.'),
+ ('../../logic/GameClass/bin/Release/net8.0/GameClass.dll', '.')
],
hiddenimports=[],
hookspath=[],
diff --git a/dependency/MapGenerator-Python/Pipfile b/map-generator/Python/Pipfile
old mode 100755
new mode 100644
similarity index 100%
rename from dependency/MapGenerator-Python/Pipfile
rename to map-generator/Python/Pipfile
diff --git a/dependency/MapGenerator-Python/Pipfile.lock b/map-generator/Python/Pipfile.lock
old mode 100755
new mode 100644
similarity index 86%
rename from dependency/MapGenerator-Python/Pipfile.lock
rename to map-generator/Python/Pipfile.lock
index e33cef7f..4379ec69
--- a/dependency/MapGenerator-Python/Pipfile.lock
+++ b/map-generator/Python/Pipfile.lock
@@ -254,51 +254,51 @@
},
"fonttools": {
"hashes": [
- "sha256:0452fcbfbce752ba596737a7c5ec5cf76bc5f83847ce1781f4f90eab14ece252",
- "sha256:0a2417547462e468edf35b32e3dd06a6215ac26aa6316b41e03b8eeaf9f079ea",
- "sha256:0d2b01428f7da26f229a5656defc824427b741e454b4e210ad2b25ed6ea2aed4",
- "sha256:0d533f89819f9b3ee2dbedf0fed3825c425850e32bdda24c558563c71be0064e",
- "sha256:12ee86abca46193359ea69216b3a724e90c66ab05ab220d39e3fc068c1eb72ac",
- "sha256:18b35fd1a850ed7233a99bbd6774485271756f717dac8b594958224b54118b61",
- "sha256:292922dc356d7f11f5063b4111a8b719efb8faea92a2a88ed296408d449d8c2e",
- "sha256:2eb4167bde04e172a93cf22c875d8b0cff76a2491f67f5eb069566215302d45d",
- "sha256:3cdb9a92521b81bf717ebccf592bd0292e853244d84115bfb4db0c426de58348",
- "sha256:4108b1d247953dd7c90ec8f457a2dec5fceb373485973cc852b14200118a51ee",
- "sha256:4709c5bf123ba10eac210d2d5c9027d3f472591d9f1a04262122710fa3d23199",
- "sha256:5057ade278e67923000041e2b195c9ea53e87f227690d499b6a4edd3702f7f01",
- "sha256:56339ec557f0c342bddd7c175f5e41c45fc21282bee58a86bd9aa322bec715f2",
- "sha256:578c00f93868f64a4102ecc5aa600a03b49162c654676c3fadc33de2ddb88a81",
- "sha256:594206b31c95fcfa65f484385171fabb4ec69f7d2d7f56d27f17db26b7a31814",
- "sha256:63c73b9dd56a94a3cbd2f90544b5fca83666948a9e03370888994143b8d7c070",
- "sha256:63dc592a16cd08388d8c4c7502b59ac74190b23e16dfc863c69fe1ea74605b68",
- "sha256:6978bade7b6c0335095bdd0bd97f8f3d590d2877b370f17e03e0865241694eb5",
- "sha256:6f30e605c7565d0da6f0aec75a30ec372072d016957cd8fc4469721a36ea59b7",
- "sha256:702ae93058c81f46461dc4b2c79f11d3c3d8fd7296eaf8f75b4ba5bbf813cd5f",
- "sha256:8b8a45254218679c7f1127812761e7854ed5c8e34349aebf581e8c9204e7495a",
- "sha256:902e9c4e9928301912f34a6638741b8ae0b64824112b42aaf240e06b735774b1",
- "sha256:97f0a49fa6aa2d6205c6f72f4f98b74ef4b9bfdcb06fd78e6fe6c7af4989b63e",
- "sha256:9b4ec6d42a7555f5ae35f3b805482f0aad0f1baeeef54859492ea3b782959d4a",
- "sha256:9b58638d8a85e3a1b32ec0a91d9f8171a877b4b81c408d4cb3257d0dee63e092",
- "sha256:a8c8b54bd1420c184a995f980f1a8076f87363e2bb24239ef8c171a369d85a31",
- "sha256:aee76fd81a8571c68841d6ef0da750d5ff08ff2c5f025576473016f16ac3bcf7",
- "sha256:b10633aafc5932995a391ec07eba5e79f52af0003a1735b2306b3dab8a056d48",
- "sha256:bcd77f89fc1a6b18428e7a55dde8ef56dae95640293bfb8f4e929929eba5e2a2",
- "sha256:bff5b38d0e76eb18e0b8abbf35d384e60b3371be92f7be36128ee3e67483b3ec",
- "sha256:c900508c46274d32d308ae8e82335117f11aaee1f7d369ac16502c9a78930b0a",
- "sha256:cad5cfd044ea2e306fda44482b3dd32ee47830fa82dfa4679374b41baa294f5f",
- "sha256:cdfd7557d1bd294a200bd211aa665ca3b02998dcc18f8211a5532da5b8fad5c5",
- "sha256:cf5a0cd974f85a80b74785db2d5c3c1fd6cc09a2ba3c837359b2b5da629ee1b0",
- "sha256:d10979ef14a8beaaa32f613bb698743f7241d92f437a3b5e32356dfb9769c65d",
- "sha256:d20588466367f05025bb1efdf4e5d498ca6d14bde07b6928b79199c588800f0a",
- "sha256:d3260db55f1843e57115256e91247ad9f68cb02a434b51262fe0019e95a98738",
- "sha256:df48798f9a4fc4c315ab46e17873436c8746f5df6eddd02fad91299b2af7af95",
- "sha256:e3e33862fc5261d46d9aae3544acb36203b1a337d00bdb5d3753aae50dac860e",
- "sha256:e740a7602c2bb71e1091269b5dbe89549749a8817dc294b34628ffd8b2bf7124",
- "sha256:f40441437b039930428e04fb05ac3a132e77458fb57666c808d74a556779e784",
- "sha256:f7449493886da6a17472004d3818cc050ba3f4a0aa03fb47972e4fa5578e6703"
+ "sha256:0404faea044577a01bb82d47a8fa4bc7a54067fa7e324785dd65d200d6dd1133",
+ "sha256:07bc5ea02bb7bc3aa40a1eb0481ce20e8d9b9642a9536cde0218290dd6085828",
+ "sha256:08877e355d3dde1c11973bb58d4acad1981e6d1140711230a4bfb40b2b937ccc",
+ "sha256:0af65c720520710cc01c293f9c70bd69684365c6015cc3671db2b7d807fe51f2",
+ "sha256:0ba0e00620ca28d4ca11fc700806fd69144b463aa3275e1b36e56c7c09915559",
+ "sha256:1f255ce8ed7556658f6d23f6afd22a6d9bbc3edb9b96c96682124dc487e1bf42",
+ "sha256:1fac1b7eebfce75ea663e860e7c5b4a8831b858c17acd68263bc156125201abf",
+ "sha256:263832fae27481d48dfafcc43174644b6706639661e242902ceb30553557e16c",
+ "sha256:29e89d0e1a7f18bc30f197cfadcbef5a13d99806447c7e245f5667579a808036",
+ "sha256:33037d9e56e2562c710c8954d0f20d25b8386b397250d65581e544edc9d6b942",
+ "sha256:33c584c0ef7dc54f5dd4f84082eabd8d09d1871a3d8ca2986b0c0c98165f8e86",
+ "sha256:36c8865bdb5cfeec88f5028e7e592370a0657b676c6f1d84a2108e0564f90e22",
+ "sha256:4145f91531fd43c50f9eb893faa08399816bb0b13c425667c48475c9f3a2b9b5",
+ "sha256:4d418b1fee41a1d14931f7ab4b92dc0bc323b490e41d7a333eec82c9f1780c75",
+ "sha256:768947008b4dc552d02772e5ebd49e71430a466e2373008ce905f953afea755a",
+ "sha256:7c7125068e04a70739dad11857a4d47626f2b0bd54de39e8622e89701836eabd",
+ "sha256:83a0d9336de2cba86d886507dd6e0153df333ac787377325a39a2797ec529814",
+ "sha256:86eef6aab7fd7c6c8545f3ebd00fd1d6729ca1f63b0cb4d621bccb7d1d1c852b",
+ "sha256:8fb022d799b96df3eaa27263e9eea306bd3d437cc9aa981820850281a02b6c9a",
+ "sha256:9d95fa0d22bf4f12d2fb7b07a46070cdfc19ef5a7b1c98bc172bfab5bf0d6844",
+ "sha256:a974c49a981e187381b9cc2c07c6b902d0079b88ff01aed34695ec5360767034",
+ "sha256:ac9a745b7609f489faa65e1dc842168c18530874a5f5b742ac3dd79e26bca8bc",
+ "sha256:af20acbe198a8a790618ee42db192eb128afcdcc4e96d99993aca0b60d1faeb4",
+ "sha256:af281525e5dd7fa0b39fb1667b8d5ca0e2a9079967e14c4bfe90fd1cd13e0f18",
+ "sha256:b050d362df50fc6e38ae3954d8c29bf2da52be384649ee8245fdb5186b620836",
+ "sha256:b44a52b8e6244b6548851b03b2b377a9702b88ddc21dcaf56a15a0393d425cb9",
+ "sha256:b607ea1e96768d13be26d2b400d10d3ebd1456343eb5eaddd2f47d1c4bd00880",
+ "sha256:b85ec0bdd7bdaa5c1946398cbb541e90a6dfc51df76dfa88e0aaa41b335940cb",
+ "sha256:bebd91041dda0d511b0d303180ed36e31f4f54b106b1259b69fade68413aa7ff",
+ "sha256:c076a9e548521ecc13d944b1d261ff3d7825048c338722a4bd126d22316087b7",
+ "sha256:cbe61b158deb09cffdd8540dc4a948d6e8f4d5b4f3bf5cd7db09bd6a61fee64e",
+ "sha256:cdee3ab220283057e7840d5fb768ad4c2ebe65bdba6f75d5d7bf47f4e0ed7d29",
+ "sha256:ce7033cb61f2bb65d8849658d3786188afd80f53dad8366a7232654804529532",
+ "sha256:d00af0884c0e65f60dfaf9340e26658836b935052fdd0439952ae42e44fdd2be",
+ "sha256:d647a0e697e5daa98c87993726da8281c7233d9d4ffe410812a4896c7c57c075",
+ "sha256:d970ecca0aac90d399e458f0b7a8a597e08f95de021f17785fb68e2dc0b99717",
+ "sha256:ea329dafb9670ffbdf4dbc3b0e5c264104abcd8441d56de77f06967f032943cb",
+ "sha256:ebf46e7f01b7af7861310417d7c49591a85d99146fc23a5ba82fdb28af156321",
+ "sha256:edc0cce355984bb3c1d1e89d6a661934d39586bb32191ebff98c600f8957c63e",
+ "sha256:f3bbe672df03563d1f3a691ae531f2e31f84061724c319652039e5a70927167e",
+ "sha256:fc11e5114f3f978d0cea7e9853627935b30d451742eeb4239a81a677bdee6bf6",
+ "sha256:fdb54b076f25d6b0f0298dc706acee5052de20c83530fa165b60d1f2e9cbe3cb"
],
"markers": "python_version >= '3.8'",
- "version": "==4.48.1"
+ "version": "==4.49.0"
},
"kiwisolver": {
"hashes": [
@@ -412,38 +412,38 @@
},
"matplotlib": {
"hashes": [
- "sha256:01a978b871b881ee76017152f1f1a0cbf6bd5f7b8ff8c96df0df1bd57d8755a1",
- "sha256:03f9d160a29e0b65c0790bb07f4f45d6a181b1ac33eb1bb0dd225986450148f0",
- "sha256:091275d18d942cf1ee9609c830a1bc36610607d8223b1b981c37d5c9fc3e46a4",
- "sha256:09796f89fb71a0c0e1e2f4bdaf63fb2cefc84446bb963ecdeb40dfee7dfa98c7",
- "sha256:0f4fc5d72b75e2c18e55eb32292659cf731d9d5b312a6eb036506304f4675630",
- "sha256:172f4d0fbac3383d39164c6caafd3255ce6fa58f08fc392513a0b1d3b89c4f89",
- "sha256:1b0f3b8ea0e99e233a4bcc44590f01604840d833c280ebb8fe5554fd3e6cfe8d",
- "sha256:3773002da767f0a9323ba1a9b9b5d00d6257dbd2a93107233167cfb581f64717",
- "sha256:46a569130ff53798ea5f50afce7406e91fdc471ca1e0e26ba976a8c734c9427a",
- "sha256:4c318c1e95e2f5926fba326f68177dee364aa791d6df022ceb91b8221bd0a627",
- "sha256:4e208f46cf6576a7624195aa047cb344a7f802e113bb1a06cfd4bee431de5e31",
- "sha256:533b0e3b0c6768eef8cbe4b583731ce25a91ab54a22f830db2b031e83cca9213",
- "sha256:5864bdd7da445e4e5e011b199bb67168cdad10b501750367c496420f2ad00843",
- "sha256:5ba9cbd8ac6cf422f3102622b20f8552d601bf8837e49a3afed188d560152788",
- "sha256:6f9c6976748a25e8b9be51ea028df49b8e561eed7809146da7a47dbecebab367",
- "sha256:7c48d9e221b637c017232e3760ed30b4e8d5dfd081daf327e829bf2a72c731b4",
- "sha256:830f00640c965c5b7f6bc32f0d4ce0c36dfe0379f7dd65b07a00c801713ec40a",
- "sha256:9a5430836811b7652991939012f43d2808a2db9b64ee240387e8c43e2e5578c8",
- "sha256:aa11b3c6928a1e496c1a79917d51d4cd5d04f8a2e75f21df4949eeefdf697f4b",
- "sha256:b78e4f2cedf303869b782071b55fdde5987fda3038e9d09e58c91cc261b5ad18",
- "sha256:b9576723858a78751d5aacd2497b8aef29ffea6d1c95981505877f7ac28215c6",
- "sha256:bddfb1db89bfaa855912261c805bd0e10218923cc262b9159a49c29a7a1c1afa",
- "sha256:c7d36c2209d9136cd8e02fab1c0ddc185ce79bc914c45054a9f514e44c787917",
- "sha256:d1095fecf99eeb7384dabad4bf44b965f929a5f6079654b681193edf7169ec20",
- "sha256:d7b1704a530395aaf73912be741c04d181f82ca78084fbd80bc737be04848331",
- "sha256:d86593ccf546223eb75a39b44c32788e6f6440d13cfc4750c1c15d0fcb850b63",
- "sha256:deaed9ad4da0b1aea77fe0aa0cebb9ef611c70b3177be936a95e5d01fa05094f",
- "sha256:ef8345b48e95cee45ff25192ed1f4857273117917a4dcd48e3905619bcd9c9b8"
+ "sha256:04b36ad07eac9740fc76c2aa16edf94e50b297d6eb4c081e3add863de4bb19a7",
+ "sha256:09074f8057917d17ab52c242fdf4916f30e99959c1908958b1fc6032e2d0f6d4",
+ "sha256:1c5c8290074ba31a41db1dc332dc2b62def469ff33766cbe325d32a3ee291aea",
+ "sha256:242489efdb75b690c9c2e70bb5c6550727058c8a614e4c7716f363c27e10bba1",
+ "sha256:40321634e3a05ed02abf7c7b47a50be50b53ef3eaa3a573847431a545585b407",
+ "sha256:4c6e00a65d017d26009bac6808f637b75ceade3e1ff91a138576f6b3065eeeba",
+ "sha256:5184e07c7e1d6d1481862ee361905b7059f7fe065fc837f7c3dc11eeb3f2f900",
+ "sha256:5745f6d0fb5acfabbb2790318db03809a253096e98c91b9a31969df28ee604aa",
+ "sha256:5e431a09e6fab4012b01fc155db0ce6dccacdbabe8198197f523a4ef4805eb26",
+ "sha256:5f557156f7116be3340cdeef7f128fa99b0d5d287d5f41a16e169819dcf22357",
+ "sha256:6728dde0a3997396b053602dbd907a9bd64ec7d5cf99e728b404083698d3ca01",
+ "sha256:7b416239e9ae38be54b028abbf9048aff5054a9aba5416bef0bd17f9162ce161",
+ "sha256:7c42dae72a62f14982f1474f7e5c9959fc4bc70c9de11cc5244c6e766200ba65",
+ "sha256:813925d08fb86aba139f2d31864928d67511f64e5945ca909ad5bc09a96189bb",
+ "sha256:83c0653c64b73926730bd9ea14aa0f50f202ba187c307a881673bad4985967b7",
+ "sha256:83e0f72e2c116ca7e571c57aa29b0fe697d4c6425c4e87c6e994159e0c008635",
+ "sha256:b3c5f96f57b0369c288bf6f9b5274ba45787f7e0589a34d24bdbaf6d3344632f",
+ "sha256:b97653d869a71721b639714b42d87cda4cfee0ee74b47c569e4874c7590c55c5",
+ "sha256:bf5932eee0d428192c40b7eac1399d608f5d995f975cdb9d1e6b48539a5ad8d0",
+ "sha256:c4af3f7317f8a1009bbb2d0bf23dfaba859eb7dd4ccbd604eba146dccaaaf0a4",
+ "sha256:cd3a0c2be76f4e7be03d34a14d49ded6acf22ef61f88da600a18a5cd8b3c5f3c",
+ "sha256:cf60138ccc8004f117ab2a2bad513cc4d122e55864b4fe7adf4db20ca68a078f",
+ "sha256:d7e7e0993d0758933b1a241a432b42c2db22dfa37d4108342ab4afb9557cbe3e",
+ "sha256:e7b49ab49a3bea17802df6872f8d44f664ba8f9be0632a60c99b20b6db2165b7",
+ "sha256:e9764df0e8778f06414b9d281a75235c1e85071f64bb5d71564b97c1306a2afc",
+ "sha256:ef6c1025a570354297d6c15f7d0f296d95f88bd3850066b7f1e7b4f2f4c13a39",
+ "sha256:f386cf162b059809ecfac3bcc491a9ea17da69fa35c8ded8ad154cd4b933d5ec",
+ "sha256:fa93695d5c08544f4a0dfd0965f378e7afc410d8672816aff1e81be1f45dbf2e"
],
"index": "pip_conf_index_global",
"markers": "python_version >= '3.9'",
- "version": "==3.8.2"
+ "version": "==3.8.3"
},
"numpy": {
"hashes": [
@@ -594,11 +594,11 @@
},
"python-dateutil": {
"hashes": [
- "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86",
- "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"
+ "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3",
+ "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
- "version": "==2.8.2"
+ "version": "==2.9.0.post0"
},
"pythonnet": {
"hashes": [
diff --git a/dependency/MapGenerator-Python/Preparation/Utility.pyi b/map-generator/Python/Preparation/Utility.pyi
similarity index 100%
rename from dependency/MapGenerator-Python/Preparation/Utility.pyi
rename to map-generator/Python/Preparation/Utility.pyi
diff --git a/map-generator/Python/README.md b/map-generator/Python/README.md
new file mode 100644
index 00000000..f3e79030
--- /dev/null
+++ b/map-generator/Python/README.md
@@ -0,0 +1,88 @@
+# MapGenerator开发指南
+
+- [MapGenerator开发指南](#mapgenerator开发指南)
+ - [虚拟环境](#虚拟环境)
+ - [代码说明](#代码说明)
+ - [构建项目](#构建项目)
+ - [其他](#其他)
+
+## 虚拟环境
+
+本项目使用 `pipenv`[^1] 管理虚拟环境.
+
+`Pipfile` 是关于虚拟环境的信息, 包括 `pip` 的信息、项目使用的第三方库和项目的 Python 版本.
+
+`Pipfile.lock` 类似于传统的 `requirements.txt`, 用于确保依赖版本的适配. 使用如下指令可以按照 `Pipfile.lock` 安装依赖:
+
+```shell
+pipenv install # 从Pipfile安装
+pipenv install --dev # 安装为仅开发
+pipenv sync # 从Pipfile.lock安装
+```
+
+向环境中加入依赖, 使用:
+
+```shell
+pipenv install package # 安装依赖
+pipenv install --dev dev_package # 仅开发安装
+```
+
+删除依赖, 需要使用:
+
+```shell
+pipenv uninstall your_package
+```
+
+在虚拟环境中运行脚本, 使用如下指令:
+
+```shell
+pipenv run python3 main.py
+```
+
+## 代码说明
+
+`./CLR_START.py`、`./CLR_IMPORT.py` 为使用 PythonNet 加载 CLR 的脚本. 在 `./CLR_IMPORT.py` 中有一串 `GameClass` 和 `Preparation` 路径, 是所需的 C# DLL 的位置. 如果出现找不到 DLL 的问题, 请检查 C# 是否编译以及编译产物的路径.
+
+`./GameClass/MapGenerator.pyi`、`./Preparation/Utility.pyi` 和 `./System.pyi` 为 C# DLL 的调用存根, 用于语法高亮; 不需要语法高亮请无视或删除.
+
+> 本项目使用了 C# 的 `GameClass.MapGenerator.MapStruct` 和 `Preparation.Utility.PlaceType`, 以及 C# 的基础类型 `UInt32`、`string` 和 `Array`.
+> PythonNet 可以自动将数字和字符串类型在 Python 和 Dotnet 之间转换.
+
+`./SETTINGS.py` 为设置脚本, 分别为程序窗口标题、地图文件后缀名和地图区域类型所对应的颜色.
+
+`./Classes/MapRenderer.py` 为程序主体, 负责提供 UI 界面和地图渲染及编辑. 其中存在 `on_click()`(鼠标事件侦测) 和 `on_press()`(键盘事件侦测), 可按需修改.
+
+`./Classes/RandomCore.py` 为 `RandomCore` 虚基类的所在.
+
+`./Classes/RandomCores/` 为 `RandomCore` 的实现.
+
+> 注意: `RandomCore` 的实现具有强的项目依赖性, 请根据项目实际情况重写.
+
+`./main.py` 为启动脚本. 其中需要留意的是 `RandomCore` 的注册——将其改为重写后的实现.
+
+## 构建项目
+
+在代码根据项目实际修改完成后, 先编译依赖 C# DLL.
+
+C# DLL 编译完成后, 再次检查 DLL 的路径, 包括 `./CLR_IMPORT.py` 的路径和 `./MapGenerator.spec` 里 `datas` 参数的路径.
+
+检查完成后, 运行下列命令即可:
+
+```shell
+# 首次编译
+pipenv run pyinstaller ./MapGenerator.spec
+# 如果项目编译过一次了, 用这个跳过文件夹清除询问
+pipenv run pyinstaller ./MapGenerator.spec -y
+```
+
+项目编译在 `./dist/`下.
+
+## 其他
+
+`./pyproject.toml` 目前用于规定 autopep8 代码格式化参数. 想要格式化代码, 只需:
+
+```shell
+autopep8 .
+```
+
+[^1]: https://pipenv.pypa.io/en/latest/cli.html
\ No newline at end of file
diff --git a/dependency/MapGenerator-Python/SETTINGS.py b/map-generator/Python/SETTINGS.py
similarity index 100%
rename from dependency/MapGenerator-Python/SETTINGS.py
rename to map-generator/Python/SETTINGS.py
diff --git a/dependency/MapGenerator-Python/System.pyi b/map-generator/Python/System.pyi
similarity index 72%
rename from dependency/MapGenerator-Python/System.pyi
rename to map-generator/Python/System.pyi
index 2e34aeda..0b351596 100644
--- a/dependency/MapGenerator-Python/System.pyi
+++ b/map-generator/Python/System.pyi
@@ -7,11 +7,11 @@ from __future__ import annotations
class UInt32:
- def __init__(self, i: int) -> None: ...
+ def __init__(self, _: int) -> None: ...
class String:
- def __init__(self, s: str) -> None: ...
+ def __init__(self, _: str) -> None: ...
class Array[T]:
diff --git a/dependency/MapGenerator/assets/img/favicon.ico b/map-generator/Python/favicon.ico
old mode 100755
new mode 100644
similarity index 100%
rename from dependency/MapGenerator/assets/img/favicon.ico
rename to map-generator/Python/favicon.ico
diff --git a/dependency/MapGenerator-Python/main.py b/map-generator/Python/main.py
old mode 100755
new mode 100644
similarity index 52%
rename from dependency/MapGenerator-Python/main.py
rename to map-generator/Python/main.py
index 94842829..db90c938
--- a/dependency/MapGenerator-Python/main.py
+++ b/map-generator/Python/main.py
@@ -1,17 +1,30 @@
from __future__ import annotations
-from io import TextIOWrapper
import os
import os.path
+import sys
from easygui import multenterbox
import CLR_IMPORT
import SETTINGS
-from System import UInt32, String
from GameClass.MapGenerator import MapStruct
from Classes.MapRenderer import MapRenderer
from Classes.RandomCores.PerlinRandomCore import PerlinRandomCore
-from Classes.RandomCores.СюйЧэнRandomCore import СюйЧэнRandomCore
+from Classes.RandomCores.XuchengRandomCore import XuchengRandomCore
+
+# 命令行接口
+if (argc := len(sys.argv)) != 1:
+ match sys.argv[1]:
+ # 生成器最小化
+ case "--min":
+ randomCore = XuchengRandomCore(SETTINGS.title)
+ mapStruct = MapStruct(50, 50)
+ randomCore.Random(mapStruct)
+ if argc >= 3:
+ MapStruct.ToFile(sys.argv[2], mapStruct)
+ else:
+ MapStruct.ToFile(f"demo{SETTINGS.file_suffix}", mapStruct)
+ exit(0)
# 获取路径
path: str = multenterbox(msg='', title=SETTINGS.title, fields=[f'Path(*{SETTINGS.file_suffix})'])[0]
@@ -19,14 +32,14 @@
path += SETTINGS.file_suffix
# 地图加载
if not os.path.exists(path):
- height, width = [UInt32(int(x))
+ height, width = [int(x)
for x in multenterbox(msg='Create new map', title=SETTINGS.title, fields=['Height', 'Width'])]
mapStruct = MapStruct(height, width)
- MapStruct.ToFile(String(path), mapStruct)
+ MapStruct.ToFile(path, mapStruct)
else:
- mapStruct = MapStruct.FromFile(String(path))
+ mapStruct = MapStruct.FromFile(path)
# 随机核加载
-randomCores = [СюйЧэнRandomCore(SETTINGS.title), PerlinRandomCore(SETTINGS.title)]
+randomCores = [XuchengRandomCore(SETTINGS.title), PerlinRandomCore(SETTINGS.title)]
# 地图渲染
-mapRenderer = MapRenderer(SETTINGS.title, mapStruct, SETTINGS.areas, String(path), randomCores)
+mapRenderer = MapRenderer(SETTINGS.title, mapStruct, SETTINGS.areas, path, randomCores)
mapRenderer.MainFrame()
diff --git a/dependency/MapGenerator-Python/pyproject.toml b/map-generator/Python/pyproject.toml
similarity index 100%
rename from dependency/MapGenerator-Python/pyproject.toml
rename to map-generator/Python/pyproject.toml