BitBlizzard

Tastes sorta like tea...

User Tools

Site Tools


universe_tree

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

universe_tree [2019/08/13 07:33] (current)
admin created
Line 1: Line 1:
 +<code python>
 +# GLOBAL ###############################################################​
 +rootSeed = "​0123456789abcdef"​
  
 +class Unit(float):​
 +    def __new__(cls,​ base, value=1, name="​baseUnit"​):​
 +        return super().__new__(cls,​ value)
 +
 +    def __init__(self,​ base, value=1, name="​m"​):​
 +        self.base = base
 +        self.name = name
 +
 +    def test(self):
 +        return "One %s is %s %s" % (self.name, super().__str__(),​ self.base.name)
 +
 +baseUnit = Unit(1,1)
 +
 +## Constants
 +### Mass in grams
 +g = Unit(baseUnit,​ name="​Gram"​)
 +solarMass = Unit(g, 1988920001144580000000000000000,​ "Solar Mass")
 +ug = Unit(g, 1e-6, "​Microgram"​) # Microgram
 +mg = Unit(g, 0.001, "​Milligram"​) # Milligram
 +kg = Unit(g, 1000, "​Kilogram"​)
 +
 +### Distance in meters
 +m   = Unit(baseUnit,​ name="​m"​)
 +gpc = Unit(m, 3.086e+25, "​gpc"​)
 +mpc = Unit(m, 3.086e+22, "​mpc"​)
 +kpc = Unit(m, 3.086e+19, "​kpc"​)
 +pc  = Unit(m, 3.086e+16, "​pc"​)
 +ly  = Unit(m, 9.461e+15, "​ly"​)
 +au  = Unit(m, 1.496e+11, "​au"​)
 +km  = Unit(m, 1000, "​km"​)
 +cm  = Unit(m, 0.01, "​cm"​)
 +mm  = Unit(m, 0.001, "​mm"​)
 +
 +print("​Unit class test: %s" % gpc.test())
 +
 +### Velocity in m/s
 +c = 2.998e+8
 +
 +# GENNY ################################################################​
 +from vectors import Vector
 +from string import ascii_uppercase,​ digits
 +import math, curses
 +import random
 +
 +rand = random.random
 +set_seed = random.seed
 +choice = random.choice
 +randrange = random.randrange
 +randint = random.randint
 +set_seed(rootSeed)
 +Random = random.Random
 +
 +set_seed(rootSeed)
 +
 +name_chars = ascii_uppercase+digits
 +
 +class Vector(Vector):​
 +    scale = m
 +
 +    """​Extends the Vector object with some more methods."""​
 +    def __init__(self,​ x = 0, y = 0, z = 0, scale = m):
 +        self.scale = scale
 +        super(Vector,​ self).__init__(x,​ y, z)
 +
 +    def midpoint(self,​ other):
 +        """​Center between two vectors"""​
 +
 +        return Vector(
 +            (self.x + other.x) / 2,
 +            (self.y + other.y) / 2,
 +            (self.z + other.z) / 2,
 +        )
 +
 +    def distanceTo(self,​ other):
 +        """​Distance between two vectors."""​
 +
 +        return math.sqrt(
 +            (
 +                self.x - other.x
 +            ) ** 2 + (
 +                self.y - other.y
 +            ) ** 2 + (
 +                self.z - other.z
 +            ) ** 2
 +        ) * other.scale
 +
 +    def invert(self):​
 +        """​Returns exact opposite of this vector, e.g. -x, -y, -z."""​
 +
 +        return Vector(-self.x,​ -self.y, -self.z)
 +
 +    def __iter__(self):​
 +        """​Iterate over vector'​s coordinates."""​
 +
 +        yield self.x
 +        yield self.y
 +        yield self.z
 +
 +
 +class Player(Vector):​
 +    def __init__(self,​ x = 0, y = 0, z = 0, name = ""​):​
 +        self.name = name
 +        super(Player,​ self).__init__(x,​ y, z)
 +
 +
 +class CelestialSeed(Vector):​
 +    minChildren = 1000
 +    maxChildren = 2000
 +    ecliptic = False # Whether children are spread out in a fuzzy
 +    # blob (False) or in a flat-ish disk (True)
 +
 +    def __init__(self,​ x, y, z, childTypes, scale = mpc):
 +        self.childTypes = childTypes
 +
 +        self.scale = scale # Since we instantiate this class naked later, scale should be optionally passed
 +        self.seed = "​%s%s%s%s"​ % (x,​y,​z,​rootSeed)
 +
 +        super(CelestialSeed,​ self).__init__(x,​ y, z, self.scale)
 +
 +    @property
 +    def pos(self):
 +        return self.x, self.y, self.z
 +
 +    @pos.setter
 +    def pos(self, pos):
 +        self.x, self.y, self.z = pos
 +
 +    @property
 +    def numChildren(self):​
 +        if self.maxChildren:​
 +            rnd = Random(self.seed)
 +
 +            numChildren = rnd.randrange(
 +                self.minChildren,​ self.maxChildren+1
 +            )
 +        else:
 +            numChildren = 0
 +
 +        return numChildren
 +
 +    @property
 +    def children(self):​
 +        types = self.childTypes
 +        rnd = Random(self.seed)
 +
 +        for i in range(self.numChildren):​
 +            yield rnd.choice(types)(
 +                rnd.random() + self.x,
 +                rnd.random() + self.y,
 +                rnd.random() + self.z
 +            )
 +
 +    def nearestChildTo(self,​ other):
 +        """​WARNING:​ Keep calls to a minimum"""​
 +
 +        nearest = None
 +        nearestDistance = None
 +
 +        for child in self.children:​
 +            if (nearest is None
 +            or child.distanceTo(other) < nearest.distanceTo(other)):​
 +                nearest = child
 +
 +        return nearest
 +
 +    def __getitem__(self,​ item):
 +        """​WARNING:​ Keep calls to a minimum"""​
 +
 +        if item <= self.numChildren:​
 +            for i, child in enumerate(self.children):​
 +                if i == item:
 +                    return child
 +
 +        raise(IndexError("​Index out of range"​))
 +
 +    @property
 +    def name(self):
 +        rnd = Random(self.seed)
 +
 +        name = '​-'​.join(
 +            ''​.join(rnd.choice(name_chars) for i in range(3))
 +            for i in range(3)
 +        )
 +
 +
 +        return name
 +
 +def duplicate_name_check(parent):​
 +    names = []
 +    nappend = names.append
 +
 +    for i in parent.children:​
 +        for c in i.children:
 +            n = c.name
 +
 +            if n in names:
 +                print(n)
 +            else:
 +                nappend(n)
 +
 +
 +class Asteroid(CelestialSeed):​
 +    scale = m
 +    childMassScale = kg
 +    minChildren = 0
 +    maxChildren = 0
 +
 +    massScale = kg
 +
 +    def __init__(self,​ x, y, z):
 +        super(Asteroid,​ self).__init__(x,​ y, z, (Asteroid,​),​ self.scale)
 +
 +
 +class Moon(CelestialSeed):​
 +    scale = km
 +    childMassScale = kg
 +    minChildren = 0
 +    maxChildren = 5
 +
 +    massScale = solarMass
 +
 +    def __init__(self,​ x, y, z):
 +        super(Moon, self).__init__(x,​ y, z, (Asteroid,​),​ self.scale)
 +
 +
 +class Planet(CelestialSeed):​
 +    scale = km
 +    childMassScale = solarMass
 +    childType = Moon
 +    minChildren = 0
 +    maxChildren = 100
 +
 +    massScale = solarMass
 +
 +    def __init__(self,​ x, y, z):
 +        super(Planet,​ self).__init__(x,​ y, z, (Moon,), self.scale)
 +
 +
 +class Star(CelestialSeed):​
 +    scale = au
 +    childMassScale = solarMass
 +    minChildren = 1
 +    maxChildren = 100
 +
 +    massScale = solarMass
 +
 +    def __init__(self,​ x, y, z):
 +        super(Star, self).__init__(x,​ y, z, (Planet,), self.scale)
 +
 +
 +class StarSeed(CelestialSeed):​
 +    scale = pc
 +    childMassScale = solarMass
 +    minChildren = 1000
 +    maxChildren = 2000
 +
 +    massScale = solarMass
 +
 +    def __init__(self,​ x, y, z):
 +        super(StarSeed,​ self).__init__(x,​ y, z, (Star,), self.scale)
 +
 +
 +class Galaxy(CelestialSeed):​
 +    scale = kpc
 +    childMassScale = solarMass
 +    minChildren = 1000
 +    maxChildren = 2000
 +
 +    massScale = solarMass
 +
 +    def __init__(self,​ x, y, z):
 +        super(Galaxy,​ self).__init__(x,​ y, z, (StarSeed,​),​ self.scale)
 +
 +
 +class SeedGrid(CelestialSeed):​ # THIS SHOULD PLANT SEEDS NOT INHERIT
 +    # AKA SHOULD HAVE IT'S OWN __iter__
 +    scale = gpc
 +
 +    def __init__(self,​ snapTo = None):
 +        super(SeedGrid,​ self).__init__(0,​ 0, 0, (Galaxy,), self.scale)
 +
 +        if snapTo:
 +            self.snap(snapTo)
 +
 +    @property
 +    def numChildren(self):​
 +        return 8
 +
 +    @property
 +    def children(self):​
 +        """​Orient base universeTree on the corners of a 1-unit cube.
 +        My brain is in conflict about whether or not a base grid is
 +        ncessary."""​
 +
 +        childTypes = self.childTypes
 +        #~ scale = self.scale)
 +
 +        for z in range(-2,​2,​2):​
 +            for y in range(-2, 2,2):
 +                for x in range(-2,​2,​2):​
 +                    yield CelestialSeed(
 +                        (x + 1),
 +                        (y + 1),
 +                        (z + 1),
 +                        childTypes
 +                    )
 +
 +    def snap(self, pos):
 +        """​Move grid to the nearest self.scale relative to pos"""​
 +        base = self.scale
 +
 +        self.x = int( base * round(float(pos.x) / base) )
 +        self.y = int( base * round(float(pos.y) / base) )
 +        self.z = int( base * round(float(pos.z) / base) )
 +
 +
 +
 +if __name__ == "​__main__":​
 +    player = Player()
 +
 +    universeTree = SeedGrid()
 +    universeTree.snap(player)
 +
 +    print(universeTree.nearestChildTo(player).nearestChildTo(player))
 +
 +    for c in universeTree.children:​
 +        print("​Parent has num children: %s" % c.numChildren)
 +
 +    # ~ duplicate_name_check(universeTree)
 +
 +    nearestSeed = universeTree.nearestChildTo(player)
 +    nearestGalaxy = nearestSeed.nearestChildTo(player)
 +    nearestStarSeed = nearestGalaxy.nearestChildTo(player)
 +    nearestStar = nearestStarSeed.nearestChildTo(player)
 +    ​
 +    print(
 +        "​Nearest seed: %s, Distance to: %s" % (
 +            nearestSeed, ​
 +            player.distanceTo(nearestSeed)
 +        )
 +    )
 +    ​
 +    print(
 +        "​Nearest galaxy: %s, Distance to: %s" % (
 +            nearestGalaxy,​
 +            player.distanceTo(nearestGalaxy)
 +        )
 +    )
 +    ​
 +    print(
 +        "​Nearest star seed: %s, Distance to: %s" % (
 +            nearestStarSeed,​
 +            player.distanceTo(nearestStarSeed)
 +        )
 +    )
 +
 +    print(
 +        "​Nearest star: %s, Distance to: %s" % (
 +            nearestStar,​
 +            player.distanceTo(nearestStar)
 +        )
 +    )
 +
 +    branchChildrenCount = nearestSeed.numChildren + nearestGalaxy.numChildren + nearestStarSeed.numChildren + nearestStar.numChildren
 +    print("​Num children in nearest branch: %s" % branchChildrenCount)
 +
 +    print("​Distance to nearest star: %s" % player.distanceTo(nearestStar))
 +
 +    print("​This should be False: %s" % str(1+mpc == 1.5+mpc))
 +
 +</​code>​
universe_tree.txt ยท Last modified: 2019/08/13 07:33 by admin