Checkpoint initial implementation

This commit is contained in:
Andrew Miner
2025-10-06 17:41:18 -06:00
parent 773e0a3d85
commit a8b6e6b15e
106 changed files with 3012 additions and 0 deletions
View File
+33
View File
@@ -0,0 +1,33 @@
import math
# Class ############################################################################################
class Bulk:
def __init__(self, name:str, smallest:int, largest:int):
self.name = name
self.smallest = smallest
self.largest = largest
def __str__(self) -> str:
return self.name
def __repr__(self) -> str:
return f"Bulk<{self.name}>{{smallest: {self.smallest}, largest: {self.largest}}}"
def scale(self, factor) -> "Bulk":
return Bulk(
self.name,
math.floor(self.smallest * factor),
math.floor(self.largest * factor)
)
# Constants ########################################################################################
SMALL = Bulk("tiny", 250, 500)
MEDIUM = Bulk("small", 500, 1000)
LARGE = Bulk("small", 1000, 2000)
ALL = [SMALL, MEDIUM, LARGE]
+20
View File
@@ -0,0 +1,20 @@
from pytest import fixture
from tungston.core.geology.bulk import Bulk
# Fixture ##########################################################################################
@fixture(name="bulk")
def createBulk():
return Bulk("chunk", 64, 128)
@fixture(name="scaledBulk")
def scaleBulk(bulk):
yield bulk.scale(2.0)
# Fixture ##########################################################################################
def test_repr(bulk, scaledBulk):
assert repr(bulk) == "Bulk<chunk>{smallest: 64, largest: 128}"
assert repr(scaledBulk) == "Bulk<chunk>{smallest: 128, largest: 256}"
+22
View File
@@ -0,0 +1,22 @@
from tungston.core.ecology.biomefilter import BiomeFilter
from tungston.core.geology.bulk import Bulk
from tungston.core.geology.mineral import Mineral
from tungston.core.scarcity import Scarcity
import tungston.core.scarcity as scarcity
# Class ############################################################################################
class Deposit:
def __init__(
self,
name:str,
scarcity:Scarcity=scarcity.SPARSE,
biomeFilter:BiomeFilter|None=None,
):
self.name = name
self.biomeFilter = biomeFilter or BiomeFilter()
self.scarcity = scarcity
@@ -0,0 +1,43 @@
from tungston.core.ecology.biomefilter import BiomeFilter
from tungston.core.geology.bulk import Bulk
from tungston.core.geology.deposit import Deposit
from tungston.core.geology.inclusion import Inclusion
from tungston.core.geology.proportion import Proportion
from tungston.core.scarcity import Scarcity
import tungston.core.geology.bulk as BU
import tungston.core.geology.proportion as PR
import tungston.core.scarcity as SC
# Class ############################################################################################
class MetalDeposit(Deposit):
def __init__(
self,
name:str,
inclusions:tuple[Inclusion],
bulk:Bulk=BU.MEDIUM,
proportion:Proportion=PR.BODY,
biomeFilter:BiomeFilter=None,
scarcity:Scarcity=SC.SPARSE,
):
super().__init__(name, scarcity, biomeFilter)
self.inclusions = inclusions
self.bulk = bulk
self.proportion = proportion
def __str__(self) -> str:
return self.name
def __repr__(self) -> str:
return "".join([str(p) for p in [
"MetalDeposit<", self.name, ">{",
"scarcity: ", repr(self.scarcity), ", ",
"biomeFilter: ", self.biomeFilter, ", ",
"inclusions: [", ", ".join([repr(m) for m in self.inclusions]), "], ",
"bulk: ", repr(self.bulk), ", ",
"proportion: ", repr(self.proportion),
"}"
]])
@@ -0,0 +1,55 @@
from pytest import fixture
from tungston.core.ecology.biomefilter import BiomeFilter
from tungston.core.geology.deposit.metaldeposit import MetalDeposit
from tungston.core.geology.inclusion import Inclusion
from tungston.core.geology.mineral import Mineral
from tungston.core.geology.replacement import Replacement
import tungston.core.ecology.flora as FL
import tungston.core.geology.bulk as BU
import tungston.core.geology.proportion as PR
import tungston.core.scarcity as SC
# Fixtures #########################################################################################
@fixture(name="quartz")
def createQuartz():
yield Mineral("quartz", [
Replacement("#minecraft:stone_replaceables", "minecraft:quartz_ore"),
Replacement("#minecraft:deepslate_replaceables", "minecraft:deepslate_quartz_ore")
])
@fixture(name="iron")
def createIron():
yield Mineral("iron", [
Replacement("#minecraft:stone_replaceables", "minecraft:iron_ore"),
Replacement("#minecraft:deepslate_replaceables", "minecraft:deepslate_iron_ore")
])
@fixture(name="bifIron")
def createBifIron(iron, quartz):
yield MetalDeposit(
name = "bifiron",
biomeFilter = BiomeFilter([FL.FOREST]),
bulk = BU.LARGE,
inclusions = [Inclusion(iron, 60), Inclusion(quartz, 40)],
proportion = PR.LENS,
scarcity = SC.COMMON,
)
# Tests ############################################################################################
def test_repr(bifIron):
assert repr(bifIron) == (
"MetalDeposit<bifiron>{" +
"scarcity: Scarcity<common>, " +
"biomeFilter: BiomeFilter([[Flora<forest>]], [[]]), " +
"inclusions: [" +
"Inclusion{mineral: iron, weight: 60}, " +
"Inclusion{mineral: quartz, weight: 40}" +
"], " +
"bulk: Bulk<small>{smallest: 1000, largest: 2000}, " +
"proportion: Proportion<lens>{ratio: 0.4}" +
"}"
)
+27
View File
@@ -0,0 +1,27 @@
from tungston.core.geology.mineralcatalog import MineralCatalog
from tungston.core.geology.deposit import Deposit
from typing import Iterator
# Class ############################################################################################
class DepositCatalog:
def __init__(self, deposits:None|tuple[Deposit]=None):
self._deposits = {}
for deposit in (deposits or []):
self.add(deposit)
def add(self, deposit:Deposit) -> "DepositCatalog":
if deposit.name in self._deposits:
raise Exception("Catalog already has an entry for {deposit.name}")
self._deposits[deposit.name] = deposit
def all(self) -> Iterator[Deposit]:
for deposit in self._deposits.values():
yield deposit
def get(self, name:str) -> Deposit|None:
return self._deposits.get(name, None)
@@ -0,0 +1,53 @@
from pytest import fixture
from tungston.core.ecology.biomefilter import BiomeFilter
from tungston.core.geology.deposit import Deposit
from tungston.core.geology.deposit.metaldeposit import MetalDeposit
from tungston.core.geology.depositcatalog import DepositCatalog
from tungston.core.geology.inclusion import Inclusion
from tungston.core.geology.mineral import Mineral
from tungston.core.geology.replacement import Replacement
import tungston.core.ecology.flora as FL
import tungston.core.geology.bulk as BU
import tungston.core.scarcity as SC
# Fixtures #########################################################################################
@fixture(name="quartz")
def createQuartz():
yield Mineral("quartz", [
Replacement("#minecraft:stone_replaceables", "minecraft:quartz_ore"),
Replacement("#minecraft:deepslate_replaceables", "minecraft:deepslate_quartz_ore")
])
@fixture(name="iron")
def createIron():
yield Mineral("iron", [
Replacement("#minecraft:stone_replaceables", "minecraft:iron_ore"),
Replacement("#minecraft:deepslate_replaceables", "minecraft:deepslate_iron_ore")
])
@fixture(name="bifiron")
def createBifIron(iron, quartz):
yield MetalDeposit(
name = "bif_iron",
scarcity = SC.COMMON,
biomeFilter = BiomeFilter([FL.FOREST]),
inclusions = [Inclusion(iron, 60), Inclusion(quartz, 40)],
bulk = BU.LARGE,
proportion = 0.5,
)
@fixture(name="catalog")
def createCatalog(bifiron):
yield DepositCatalog([bifiron])
# Tests ############################################################################################
def test_all(catalog):
assert [m.name for m in catalog.all()] == ["bif_iron"]
def test_get(catalog):
assert catalog.get("bif_iron").name == "bif_iron"
+24
View File
@@ -0,0 +1,24 @@
from tungston.core.geology.mineral import Mineral
# Class ############################################################################################
class Inclusion:
def __init__(self, mineral:Mineral, weight:int=100):
self.mineral = mineral
self.weight = weight
def __str__(self) -> str:
if self.weight == 100:
return self.mineral.name
return f"{self.mineral.name} ({self.weight}%)"
def __repr__(self) -> str:
return "".join([str(p) for p in [
"Inclusion{",
"mineral: ", self.mineral.name, ", ",
"weight: ", self.weight,
"}"
]])
+24
View File
@@ -0,0 +1,24 @@
from pytest import fixture
from tungston.core.geology.inclusion import Inclusion
from tungston.core.geology.mineral import Mineral
from tungston.core.geology.replacement import Replacement
# Fixtures #########################################################################################I
@fixture(name="iron")
def createIron():
yield Mineral("iron", [
Replacement("#minecraft:stone_replaceables", "minecraft:iron_ore"),
Replacement("#minecraft:deepslate_replaceables", "minecraft:deepslate_iron_ore")
])
@fixture(name="inclusion")
def createInclusion(iron):
yield Inclusion(iron, 75)
# Tests ############################################################################################I
def test_repr(inclusion):
assert repr(inclusion) == "Inclusion{mineral: iron, weight: 75}"
+32
View File
@@ -0,0 +1,32 @@
from tungston.core.geology.replacement import Replacement
from tungston.core.resourceid import ResourceId
# Class ############################################################################################
class Mineral:
def __init__(self, name:str, replacements:None|tuple[Replacement]=None):
self.name = name
self.replacements = replacements or []
def __str__(self) -> str:
return self.name
def __repr__(self) -> str:
return "".join([str(p) for p in [
f"Mineral<{self.name}>", "{",
"replacements: [",
", ".join([str(r) for r in self.replacements]),
"]",
"}"
]])
def addStoneReplacement(self, blockId:str) -> "Mineral":
blockId = ResourceId.canonical(blockId)
self.replacements.append(Replacement(STONE_REPLACEABLES, blockId))
return self
def addDeepslateReplacement(self, blockId:str) -> "Mineral":
blockId = ResourceId.canonical(blockId)
self.replacements.append(Replacement(DEEPSLATE_REPLACEABLES, blockId))
+28
View File
@@ -0,0 +1,28 @@
from tungston.core.geology.mineral import Mineral
from tungston.core.geology.replacement import Replacement
from pytest import fixture
import tungston.core.geology.mineral as mineral
# Fixtures #########################################################################################
@fixture(name="iron")
def createIron():
yield Mineral("iron", [
Replacement.inStone("iron_ore"),
Replacement.inDeepslate("deepslate_iron_ore"),
])
# Tests ############################################################################################
def test_repr(iron):
assert repr(iron) == (
"Mineral<iron>{" +
"replacements: [" +
"#minecraft:stone_ore_replaceables => minecraft:iron_ore, " +
"#minecraft:deepslate_ore_replaceables => minecraft:deepslate_iron_ore" +
"]" +
"}"
)
+26
View File
@@ -0,0 +1,26 @@
from tungston.core.geology.mineral import Mineral
from typing import Iterator
# Class ############################################################################################
class MineralCatalog:
def __init__(self, minerals:tuple[Mineral]=None):
self._minerals = {}
for mineral in (minerals or []):
self.add(mineral)
def add(self, mineral:Mineral) -> "MineralCatalog":
if mineral.name in self._minerals:
raise Exception(f"Catalog already contains an entry for {mineral.name}")
self._minerals[mineral.name] = mineral
def all(self) -> Iterator[Mineral]:
for mineral in self._minerals.values():
yield mineral
def get(self, name:str) -> Mineral|None:
return self._minerals.get(name, None)
@@ -0,0 +1,34 @@
from tungston.core.geology.mineral import Mineral
from tungston.core.geology.mineralcatalog import MineralCatalog
from tungston.core.geology.replacement import Replacement
from pytest import fixture
# Fixtures #########################################################################################
@fixture(name="copper")
def createCopper():
yield Mineral("copper", [
Replacement("#minecraft:stone_replaceables", "minecraft:copper_ore"),
Replacement("#minecraft:deepslate_replaceables", "minecraft:deepslate_copper_ore")
])
@fixture(name="iron")
def createIron():
yield Mineral("iron", [
Replacement("#minecraft:stone_replaceables", "minecraft:iron_ore"),
Replacement("#minecraft:deepslate_replaceables", "minecraft:deepslate_iron_ore")
])
@fixture(name="catalog")
def createCatalog(copper, iron):
yield MineralCatalog([copper, iron])
# Tests ############################################################################################
def test_all(catalog):
assert [m.name for m in catalog.all()] == ["copper", "iron"]
def test_get(catalog):
assert catalog.get("iron").name == "iron"
+34
View File
@@ -0,0 +1,34 @@
# Class ############################################################################################
class Proportion:
def __init__(self, name:str, ratio:float):
self.name = name
self.ratio = ratio
def __eq__(self, other) -> bool:
if type(self) != type(other): return False
if self.name != other.name: return False
return True
def __hash__(self) -> int:
return hash(self.name)
def __str__(self) -> str:
return self.name
def __repr__(self) -> str:
return f"Proportion<{self.name}>{{ratio: {self.ratio}}}"
# Constants ########################################################################################
BED = Proportion("bed", 0.1) # salt, nitrate, redbed, loam, bif iron, peat coal
LENS = Proportion("lens", 0.4) # bit.coal, aluminum, lapis, quartzite
LODE = Proportion("lode", 0.7) # au.quartz, mvt lead
BODY = Proportion("body", 1.0) # sed.iron
STOCK = Proportion("stock", 1.3) # tin
VENT = Proportion("vent", 1.6) # sulfur
PIPE = Proportion("pipe", 1.9) # por.copper
ALL = [BED, LENS, LODE, BODY, STOCK, VENT, PIPE]
+12
View File
@@ -0,0 +1,12 @@
from pytest import fixture
import tungston.core.geology.proportion as proportion
# Tests ############################################################################################
def test_str():
assert str(proportion.LENS) == "lens"
def test_repr():
assert repr(proportion.LENS) == "Proportion<lens>{ratio: 0.4}"
+40
View File
@@ -0,0 +1,40 @@
from tungston.core.resourceid import ResourceId
# Constants ########################################################################################
STONE_REPLACEABLES = "#minecraft:stone_ore_replaceables"
DEEPSLATE_REPLACEABLES = "#minecraft:deepslate_ore_replaceables"
# Class ############################################################################################
class Replacement:
@staticmethod
def inStone(target:str, weight:int=100):
return Replacement(STONE_REPLACEABLES, target, weight)
@staticmethod
def inDeepslate(target:str, weight:int=100):
return Replacement(DEEPSLATE_REPLACEABLES, target, weight)
def __init__(self, source:str, target:str, weight:int=100):
self.source = ResourceId.canonical(source)
self.target = ResourceId.canonical(target)
self.weight = weight
def __str__(self) -> str:
if self.weight == 100:
return f"{self.source} => {self.target}"
return f"{self.source} => {self.target} ({self.weight}%)"
def __repr__(self) -> str:
return "".join([str(p) for p in [
"Replacement{" +
"source: ", self.source, ", ",
"target: ", self.target, ", ",
"weight: ", self.weight,
"}"
]])
+28
View File
@@ -0,0 +1,28 @@
from pytest import fixture
from tungston.core.geology.replacement import Replacement
# Fixtures #########################################################################################
@fixture(name="replacement")
def createReplacement():
yield Replacement("#minecraft:stone", "minecraft:iron_ore")
@fixture(name="weightedReplacement")
def createWeightedReplacement():
yield Replacement("#minecraft:dirt", "minecraft:gravel", 25)
# Tests ############################################################################################
def test_repr(replacement, weightedReplacement):
assert repr(replacement) == (
"Replacement{source: #minecraft:stone, target: minecraft:iron_ore, weight: 100}"
)
assert repr(weightedReplacement) == (
"Replacement{source: #minecraft:dirt, target: minecraft:gravel, weight: 25}"
)
def test_str(replacement, weightedReplacement):
assert str(replacement) == "#minecraft:stone => minecraft:iron_ore"
assert str(weightedReplacement) == "#minecraft:dirt => minecraft:gravel (25%)"