first masked hover

This commit is contained in:
2019-06-07 20:08:35 -07:00
parent dd0495a2f1
commit df3bb39515
14 changed files with 651 additions and 43 deletions
@@ -160,6 +160,7 @@
<Compile Include="Assets\Terrain Hexes\Example Scene\BasicHexArranger.cs" />
<Compile Include="Assets\TouchHandler.cs" />
<None Include="Assets\Hex Mesh Shader.shader" />
<None Include="Assets\Eagle\maskShader.shader" />
<None Include="Assets\Shardok\Medieval-Fantasy Hex Locations\Samples\samples readme.txt" />
<None Include="Assets\Shardok\Cold Terrain Hexes\readme_cold.txt" />
<None Include="Assets\Shardok\Cold Terrain Hexes\Samples\samples readme.txt" />
-1
View File
@@ -5,5 +5,4 @@ curl "https://docs.google.com/spreadsheets/d/1pNWiyxIks2wJ1v7jRLFD24zrKHG2AfhC-n
curl "https://docs.google.com/spreadsheets/d/1DHEsiv4cY4gE6AX3sVH82K__mpBD1aznIYCQwQxA_F0/export?gid=0&format=tsv" > installdata/usr/local/share/eagle0/names.tsv
curl "https://docs.google.com/spreadsheets/d/1pv-WMXReccddPwev_YG9IXEGznuGHrYjNNEZ0Rb-ZhM/export?gid=0&format=tsv" > installdata/usr/local/share/eagle0/shardok/settings.tsv
curl "https://docs.google.com/spreadsheets/d/1p6I5nUMcoAPHIcqikVgbBCFVnqN9dpOEVClbS_wOI7M/export?gid=0&format=tsv" > installdata/usr/local/share/eagle0/eagle/settings.tsv
curl "https://docs.google.com/spreadsheets/d/1ctgkki-UlP1irf695cHcKZtMVNGE31s21o4RsN04fQ8/export?gid=0&format=tsv" > installdata/usr/local/share/eagle0/eagle/province_map.tsv
@@ -21,12 +21,6 @@ import "eagle0/eagle/common/unaffiliated_hero.proto";
message ProvinceView {
int32 id = 1;
string name = 19;
message HeightmapColor {
int32 r = 1;
int32 g = 2;
int32 b = 3;
}
HeightmapColor heightmap_color = 20;
.google.protobuf.Int32Value ruling_player = 2;
.google.protobuf.Int32Value ruling_hero = 3;
@@ -20,12 +20,6 @@ import "eagle0/eagle/common/unaffiliated_hero.proto";
message Province {
int32 id = 1;
string name = 19;
message HeightmapColor {
int32 r = 1;
int32 g = 2;
int32 b = 3;
}
HeightmapColor heightmap_color = 20;
repeated int32 neighbors = 14;
@@ -19,7 +19,6 @@ import com.eagle0.eagle.internal.hero.Hero
import com.eagle0.eagle.internal.imminent_battle.ImminentBattle
import com.eagle0.eagle.internal.moving_army.MovingArmy
import com.eagle0.eagle.internal.province.Province
import com.eagle0.eagle.internal.province.Province.HeightmapColor
import com.eagle0.eagle.internal.shardok_battle.ShardokBattle
import com.eagle0.eagle.library.util.ProvinceUtils
@@ -141,26 +140,12 @@ object ActionResultFilter {
)),
foodConsumption = ProvinceUtils.foodConsumption(province.id, gameState),
unaffiliatedHeroCount = province.unaffiliatedHeroes.size,
name = province.name,
heightmapColor = province.heightmapColor.map(hc =>
ProvinceView.HeightmapColor(
r = hc.r,
g = hc.g,
b = hc.b
)
)
name = province.name
))
else
Some(
ProvinceView(
rulingPlayer = province.rulingPlayer,
heightmapColor = province.heightmapColor.map(hc =>
ProvinceView.HeightmapColor(
r = hc.r,
g = hc.g,
b = hc.b
)
)
rulingPlayer = province.rulingPlayer
)
.withId(province.id)
.withName(province.name)
@@ -1,7 +1,6 @@
package com.eagle0.eagle.library.util
import com.eagle0.eagle.internal.province.Province
import com.eagle0.eagle.internal.province.Province.HeightmapColor
import scala.io.Source
@@ -10,11 +9,6 @@ object MapGenerator {
Province()
.withId(map("id").toInt)
.withName(map("name"))
.withHeightmapColor(HeightmapColor()
.withR(map("r").toInt)
.withG(map("g").toInt)
.withB(map("b").toInt)
)
.withNeighbors(
map("neighbors")
.split(",")
@@ -114,8 +114,12 @@ object TempGameMaker {
.map(p => p.id -> p)
.toMap
private val provincesMap = Map(
1 -> downloadedProvinces(1)
private val provincesMap = downloadedProvinces.mapValues(_
.withEconomy(20)
.withAgriculture(20)
.withInfrastructure(20)
) ++ Map(
4 -> downloadedProvinces(4)
.withRulingPlayer(player1Leader.playerId.get)
.withRulingHero(player1Leader.id)
.withRulingPlayerHeroes(Seq(1, 2))
@@ -127,8 +131,7 @@ object TempGameMaker {
.withAgriculture(45)
.withInfrastructure(45)
.withSupport(26),
2 -> downloadedProvinces(2)
.withId(2)
6 -> downloadedProvinces(6)
.withRulingPlayer(player2Leader.playerId.get)
.withRulingHero(player2Leader.id)
.withRulingPlayerHeroes(Seq(3, 4))
@@ -1,3 +1,17 @@
id name r g b neighbors
1 Jeong 214 235 189 2
2 Kirk 198 231 231 1
id name neighbors neighborNames
3 Schom 5,13,12 Ouneuf,Mel,Didir
7 Nams 2,15 Mingia,Aesium
10 Tana 5,13 Ouneuf,Mel
12 Didir 5,3,6 Ouneuf,Schom,Kirk
9 Botnes 16,8,1,4,14 Ahfieldia,Cho,Cre,Jeong,Tsatia
1 Cre 16,9 Ahfieldia,Botnes
11 Ama 6,8 Kirk,Cho
13 Mel 10,5,3 Tana,Ouneuf,Schom
14 Tsatia 15,2,9 Aesium,Mingia,Botnes
15 Aesium 4,7,14 Jeong,Nams,Tsatia
8 Cho 9,4,16,11,6 Botnes,Jeong,Ahfieldia,Ama,Kirk
16 Ahfieldia 1,8,9 Cre,Cho,Botnes
6 Kirk 5,4,8,12,11 Ouneuf,Jeong,Cho,Didir,Ama
4 Jeong 9,8,15,6 Botnes,Cho,Aesium,Kirk
2 Mingia 14,7 Tsatia,Nams
5 Ouneuf 3,6,10,12,13 Schom,Kirk,Tana,Didir,Mel
1 id name r neighbors g neighborNames b
2 1 3 Jeong Schom 214 2 5,13,12 235 Ouneuf,Mel,Didir 189
3 2 7 Kirk Nams 198 1 2,15 231 Mingia,Aesium 231
4 10 Tana 5,13 Ouneuf,Mel
5 12 Didir 5,3,6 Ouneuf,Schom,Kirk
6 9 Botnes 16,8,1,4,14 Ahfieldia,Cho,Cre,Jeong,Tsatia
7 1 Cre 16,9 Ahfieldia,Botnes
8 11 Ama 6,8 Kirk,Cho
9 13 Mel 10,5,3 Tana,Ouneuf,Schom
10 14 Tsatia 15,2,9 Aesium,Mingia,Botnes
11 15 Aesium 4,7,14 Jeong,Nams,Tsatia
12 8 Cho 9,4,16,11,6 Botnes,Jeong,Ahfieldia,Ama,Kirk
13 16 Ahfieldia 1,8,9 Cre,Cho,Botnes
14 6 Kirk 5,4,8,12,11 Ouneuf,Jeong,Cho,Didir,Ama
15 4 Jeong 9,8,15,6 Botnes,Cho,Aesium,Kirk
16 2 Mingia 14,7 Tsatia,Nams
17 5 Ouneuf 3,6,10,12,13 Schom,Kirk,Tana,Didir,Mel
@@ -0,0 +1,296 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 50;
objects = {
/* Begin PBXBuildFile section */
AF6723FC22A7472D0022C16E /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF6723FB22A7472D0022C16E /* main.swift */; };
AF67240322AA9FD40022C16E /* MapBitmap.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF67240222AA9FD40022C16E /* MapBitmap.swift */; };
AF67240522AB45130022C16E /* MaskMaker.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF67240422AB45130022C16E /* MaskMaker.swift */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
AF6723F622A7472D0022C16E /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = /usr/share/man/man1/;
dstSubfolderSpec = 0;
files = (
);
runOnlyForDeploymentPostprocessing = 1;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
AF6723F822A7472D0022C16E /* map_preprocessor */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = map_preprocessor; sourceTree = BUILT_PRODUCTS_DIR; };
AF6723FB22A7472D0022C16E /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = "<group>"; };
AF67240222AA9FD40022C16E /* MapBitmap.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapBitmap.swift; sourceTree = "<group>"; };
AF67240422AB45130022C16E /* MaskMaker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MaskMaker.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
AF6723F522A7472D0022C16E /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
AF6723EF22A7472D0022C16E = {
isa = PBXGroup;
children = (
AF6723FA22A7472D0022C16E /* map_preprocessor */,
AF6723F922A7472D0022C16E /* Products */,
);
sourceTree = "<group>";
};
AF6723F922A7472D0022C16E /* Products */ = {
isa = PBXGroup;
children = (
AF6723F822A7472D0022C16E /* map_preprocessor */,
);
name = Products;
sourceTree = "<group>";
};
AF6723FA22A7472D0022C16E /* map_preprocessor */ = {
isa = PBXGroup;
children = (
AF6723FB22A7472D0022C16E /* main.swift */,
AF67240222AA9FD40022C16E /* MapBitmap.swift */,
AF67240422AB45130022C16E /* MaskMaker.swift */,
);
path = map_preprocessor;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
AF6723F722A7472D0022C16E /* map_preprocessor */ = {
isa = PBXNativeTarget;
buildConfigurationList = AF6723FF22A7472D0022C16E /* Build configuration list for PBXNativeTarget "map_preprocessor" */;
buildPhases = (
AF6723F422A7472D0022C16E /* Sources */,
AF6723F522A7472D0022C16E /* Frameworks */,
AF6723F622A7472D0022C16E /* CopyFiles */,
);
buildRules = (
);
dependencies = (
);
name = map_preprocessor;
productName = map_preprocessor;
productReference = AF6723F822A7472D0022C16E /* map_preprocessor */;
productType = "com.apple.product-type.tool";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
AF6723F022A7472D0022C16E /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 1020;
LastUpgradeCheck = 1020;
ORGANIZATIONNAME = "Dan Crosby";
TargetAttributes = {
AF6723F722A7472D0022C16E = {
CreatedOnToolsVersion = 10.2.1;
};
};
};
buildConfigurationList = AF6723F322A7472D0022C16E /* Build configuration list for PBXProject "map_preprocessor" */;
compatibilityVersion = "Xcode 9.3";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
);
mainGroup = AF6723EF22A7472D0022C16E;
productRefGroup = AF6723F922A7472D0022C16E /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
AF6723F722A7472D0022C16E /* map_preprocessor */,
);
};
/* End PBXProject section */
/* Begin PBXSourcesBuildPhase section */
AF6723F422A7472D0022C16E /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
AF67240522AB45130022C16E /* MaskMaker.swift in Sources */,
AF6723FC22A7472D0022C16E /* main.swift in Sources */,
AF67240322AA9FD40022C16E /* MapBitmap.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
AF6723FD22A7472D0022C16E /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "Mac Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.14;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
};
name = Debug;
};
AF6723FE22A7472D0022C16E /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "Mac Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.14;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
SDKROOT = macosx;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
};
name = Release;
};
AF67240022A7472D0022C16E /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = UWJ88DX8WQ;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
};
name = Debug;
};
AF67240122A7472D0022C16E /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = UWJ88DX8WQ;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
AF6723F322A7472D0022C16E /* Build configuration list for PBXProject "map_preprocessor" */ = {
isa = XCConfigurationList;
buildConfigurations = (
AF6723FD22A7472D0022C16E /* Debug */,
AF6723FE22A7472D0022C16E /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
AF6723FF22A7472D0022C16E /* Build configuration list for PBXNativeTarget "map_preprocessor" */ = {
isa = XCConfigurationList;
buildConfigurations = (
AF67240022A7472D0022C16E /* Debug */,
AF67240122A7472D0022C16E /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = AF6723F022A7472D0022C16E /* Project object */;
}
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:map_preprocessor.xcodeproj">
</FileRef>
</Workspace>
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
@@ -0,0 +1,107 @@
//
// MapBitmap.swift
// map_preprocessor
//
// Created by Dan Crosby on 6/7/19.
// Copyright © 2019 Dan Crosby. All rights reserved.
//
import Foundation
import Cocoa
func MapBitmap(bitmap: NSBitmapImageRep, provincesByColor: Dictionary<Int, Province>) -> [UInt8] {
var idMap = [UInt8](repeating: 0, count: width * height)
let width = Int(bitmap.size.width)
let height = Int(bitmap.size.height)
let totalSize = width * height
func processSet(_ idxs: [Int]) -> [Int] {
var indices = idxs.shuffled()
while !indices.isEmpty {
let remainingCount = indices.count
print("Remaining: \(remainingCount)")
var newRemainingSet = [Int]()
for index in indices {
// rotate or randomize order
if index % width != width-1 && idMap[index+1] != 0xFE && idMap[index+1] != 0xFF && idMap[index+1] != 0 {
idMap[index] = idMap[index+1]
} else if index % width != 0 && idMap[index-1] != 0xFE && idMap[index-1] != 0xFF && idMap[index-1] != 0 {
idMap[index] = idMap[index-1]
} else if index + width < totalSize && idMap[index + width] != 0xFE && idMap[index+width] != 0xFF && idMap[index+width] != 0 {
idMap[index] = idMap[index + width]
} else if index > width && idMap[index - width] != 0xFE && idMap[index - width] != 0xFF && idMap[index-width] != 0 {
idMap[index] = idMap[index - width]
} else {
newRemainingSet.append(index)
}
}
indices = newRemainingSet
if newRemainingSet.count == remainingCount {
return newRemainingSet
}
}
return indices
}
var remainingSet = [Int]()
var borderSet = [Int]()
let group = DispatchGroup()
let batchSize = 256
let syncQ = DispatchQueue(label: "sync")
for baseY in stride(from: 0, to: height, by: batchSize) {
DispatchQueue.global().async(group: group) {
var localRemaining = [Int]()
var localBorder = [Int]()
for y in baseY..<min((baseY + batchSize), totalSize) {
for x in 0..<width {
// do this flipping at the end
let index = y * width + x
let colorInt = bitmap.colorAt(x: x, y: y)!.asInt
if let province = provincesByColor[colorInt] {
idMap[index] = province.id
} else if colorInt == 0xFF {
localBorder.append(index)
/* } else if (colorInt >> 24) != 0xFF && (colorInt >> 24) != 0 {
idMap[index] = 0*/
} else if colorInt != 0 {
localRemaining.append(index)
idMap[index] = 0xFE
}
}
}
syncQ.sync {
remainingSet.append(contentsOf: localRemaining)
borderSet.append(contentsOf: localBorder)
}
}
}
group.wait()
let newRemaining = processSet(remainingSet)
print("Finished remainingSet")
borderSet.append(contentsOf: newRemaining)
let unfinished = processSet(borderSet)
print("Finished borders with \(unfinished.count) remaining")
return idMap
}
func FlipArray<T>(array: [T], stride: Int) -> [T] {
var newArray = [T]()
let rows = (array.count - 1) / stride + 1
for y in 0..<rows {
for x in 0..<stride {
newArray.append(array[(rows - y - 1) * stride + x])
}
}
return newArray
}
@@ -0,0 +1,55 @@
//
// MaskMaker.swift
// map_preprocessor
//
// Created by Dan Crosby on 6/7/19.
// Copyright © 2019 Dan Crosby. All rights reserved.
//
import Foundation
import Cocoa
func MasksForProvinces(idMap: [UInt8], provinceIds: [UInt8]) -> Dictionary<UInt8, CGImage> {
var maskArrays = Dictionary<UInt8, [UInt8]>()
let group = DispatchGroup()
let syncQ = DispatchQueue(label: "sync")
for id in provinceIds {
DispatchQueue.global().async(group: group) {
print("starting for province \(id)")
var arr = [UInt8](repeating: 0, count: idMap.count)
for index in 0..<idMap.count {
if idMap[index] == id {
arr[index] = 0xFF
}
}
syncQ.sync {
maskArrays[id] = arr
}
}
}
group.wait()
var images = Dictionary<UInt8, CGImage>()
for (id, arr) in maskArrays {
images[id] = CGImage(
width: width,
height: height,
bitsPerComponent: 8,
bitsPerPixel: 8,
bytesPerRow: width,
space: CGColorSpace(name: CGColorSpace.linearGray)!,
bitmapInfo: CGBitmapInfo(),
provider: CGDataProvider(data: NSData(bytes: arr, length: arr.count))!,
decode: nil,
shouldInterpolate: false,
intent: CGColorRenderingIntent.defaultIntent
)!
}
return images
}
@@ -0,0 +1,151 @@
//
// main.swift
// map_preprocessor
//
// Created by Dan Crosby on 6/4/19.
// Copyright © 2019 Dan Crosby. All rights reserved.
//
import Foundation
import Cocoa
let provinces = """
[{"i":1,"color":"#fccde5","name":"Cre","expansionism":1.3,"capital":1,"type":"River","center":540,"culture":8},{"i":2,"color":"#ccebc5","name":"Mingia","expansionism":1.3,"capital":2,"type":"Naval","center":2017,"culture":5},{"i":3,"color":"#fb8072","name":"Schom","expansionism":1.5,"capital":3,"type":"Naval","center":3556,"culture":2},{"i":4,"color":"#b3de69","name":"Jeong","expansionism":1.3,"capital":4,"type":"Hunting","center":5142,"culture":13},{"i":5,"color":"#fdb462","name":"Ouneuf","expansionism":1.3,"capital":5,"type":"Naval","center":1401,"culture":4},{"i":6,"color":"#8dd3c7","name":"Kirk","expansionism":1.8,"capital":6,"type":"River","center":2576,"culture":10},{"i":7,"color":"#aff05b","name":"Nams","expansionism":1.4,"capital":7,"type":"Naval","center":2871,"culture":5},{"i":8,"color":"#bc80bd","name":"Cho","expansionism":1.6,"capital":8,"type":"Generic","center":924,"culture":12},{"i":9,"color":"#ffffb3","name":"Botnes","expansionism":1.6,"capital":9,"type":"River","center":1471,"culture":8},{"i":10,"color":"#bebada","name":"Tana","expansionism":1.6,"capital":10,"type":"Naval","center":263,"culture":9},{"i":11,"color":"#6e40aa","name":"Ama","expansionism":2,"capital":11,"type":"Generic","center":934,"culture":12},{"i":12,"color":"#ff5e63","name":"Didir","expansionism":1.3,"capital":12,"type":"River","center":3644,"culture":10},{"i":13,"color":"#ffed6f","name":"Mel","expansionism":1.3,"capital":13,"type":"Naval","center":743,"culture":9},{"i":14,"color":"#80b1d3","name":"Tsatia","expansionism":1.6,"capital":14,"type":"Naval","center":2038,"culture":5},{"i":15,"color":"#d9d9d9","name":"Aesium","expansionism":1.3,"capital":15,"type":"Naval","center":4666,"culture":1},{"i":16,"color":"#1ac7c2","name":"Ahfieldia","expansionism":1.1,"capital":16,"type":"River","center":549,"culture":8}]
"""
extension NSColor {
var rgbColor: NSColor {
return self.usingColorSpace(NSColorSpace.genericRGB) ?? self
}
var hexString: String {
let rgbc = rgbColor
let red = Int(round(rgbc.redComponent * 0xFF))
let green = Int(round(rgbc.greenComponent * 0xFF))
let blue = Int(round(rgbc.blueComponent * 0xFF))
let hexString = NSString(format: "#%02X%02X%02X", red, green, blue)
return hexString as String
}
var asInt: Int {
let rgbc = rgbColor
let red = Int(round(rgbc.redComponent * 0xFF))
let green = Int(round(rgbc.greenComponent * 0xFF))
let blue = Int(round(rgbc.blueComponent * 0xFF))
return red << 16 | green << 8 | blue
}
}
struct RawMapProvince: Decodable {
let i: Int
let color: String
let name: String
}
public struct Province {
let id: UInt8
let color: Int
let name: String
var neighbors: Set<UInt8>
}
guard let provincesData = provinces.data(using: String.Encoding.ascii) else {
print("Unable to get data from provinces string")
abort()
}
guard let rawProvinces = try? JSONDecoder().decode([RawMapProvince].self, from: provincesData) else {
print("Unable to decode")
abort()
}
var provincesByColor = Dictionary<Int, Province>()
for province in rawProvinces {
let colorInt = Int(province.color.dropFirst(), radix: 16)!
provincesByColor[colorInt] = Province(id: UInt8(province.i), color: colorInt, name: province.name, neighbors: Set<UInt8>())
}
let imageURL = URL(fileURLWithPath: "/Users/dancrosby/Downloads/map_color_nolabels_borders.png")
let imageData = try! Data(contentsOf: imageURL)
let bitmap = NSBitmapImageRep(data: imageData)!
let width = Int(bitmap.size.width)
let height = Int(bitmap.size.height)
let idMap = MapBitmap(bitmap: bitmap, provincesByColor: provincesByColor)
let flippedIdMap = FlipArray(array: idMap, stride: width)
let rawData = Data(bytes: flippedIdMap, count: flippedIdMap.count)
try! rawData.write(to: URL(fileURLWithPath: "/Users/dancrosby/Downloads/rawGray.bytes"))
var provincesById = provincesByColor
.values
.reduce([UInt8 : Province]()) { (dict, province) -> [UInt8 : Province] in
var dict = dict
dict[province.id] = province
return dict
}
// find neighbors
for y in 0..<height {
for x in 0..<width {
let currentValue = idMap[y * width + x]
if currentValue != 0 && currentValue != 0xFF {
let rightPosition = y * width + x + 1
let rightValue = idMap[rightPosition]
if x < width - 1 {
if rightValue != 0xFF && rightValue != 0 && rightValue != currentValue {
provincesById[currentValue]!.neighbors.insert(rightValue)
provincesById[rightValue]!.neighbors.insert(currentValue)
}
}
let downPosition = (y+1) * width + x
let downValue = idMap[downPosition]
if y < height - 1 {
if downValue != 0xFF && downValue != 0 && downValue != currentValue {
provincesById[currentValue]!.neighbors.insert(downValue)
provincesById[downValue]!.neighbors.insert(currentValue)
}
}
}
}
}
var tsv = "id\tname\tneighbors\tneighborNames\n"
for province in provincesById.values {
tsv += "\(province.id)\t\(province.name)\t"
for n in province.neighbors {
tsv += "\(n),"
}
tsv.remove(at: tsv.index(before: tsv.endIndex))
tsv += "\t"
for n in province.neighbors {
tsv += "\(provincesById[n]!.name),"
}
tsv.remove(at: tsv.index(before: tsv.endIndex))
tsv += "\n"
}
print(tsv)
try! tsv.write(to: URL(fileURLWithPath: "/Users/dancrosby/Downloads/province_map.tsv"), atomically: true, encoding: String.Encoding.ascii)
let images = MasksForProvinces(idMap: idMap, provinceIds: Array(provincesById.keys))
for (id, cgImage) in images {
let bitmap = NSBitmapImageRep(cgImage: cgImage)
guard let pngData = bitmap.representation(using: .png, properties: [:]) else {
print("unable to make png")
break
}
try! pngData.write(to: URL(fileURLWithPath: "/Users/dancrosby/Downloads/\(id).png"))
}