Reset the translation, we're going to redo it with ctopy.
[super-star-trek.git] / src / sst.py
index 4d98a47953ac9bae432e05f13c233a093acfb002..c082b3b4df7ed83bf73ba3980cb509ffdcbb4161 100644 (file)
@@ -1,5 +1,15 @@
 """
 sst.py =-- Super Star Trek in Python
+
+Control flow of this translation is pretty much identical to the C version
+(and thus like the ancestral FORTRAN) but the data structures are
+radically different -- the Python code makes heavy use of objects.
+
+Note that the game.quad, game.snap.galaxy and game.snap.chart members
+are not actually arrays but dictioaries indixed by coord tuples.  Be setting
+the hash of a coord equal to the hash of a literal tuple containing its
+coordinate data, we ensure these can be indexed both ways.
+
 """
 import math
 
@@ -15,21 +25,13 @@ MAXKLGAME   = 127
 MAXKLQUAD      = 9
 FOREVER        = 1e30
 
-# Feature vakues
-IHR = 'R',
-IHK = 'K',
-IHC = 'C',
-IHS = 'S',
-IHSTAR = '*',
-IHP = 'P',
-IHW = '@',
-IHB = 'B',
-IHBLANK = ' ',
-IHDOT = '.',
+# These macros hide the difference between 0-origin and 1-origin addressing.
+# They're a step towards de-FORTRANizing the code.
+def VALID_QUADRANT(x,y): ((x)>=1 and (x)<=GALSIZE and (y)>=1 and (y)<=GALSIZE)
+def VALID_SECTOR(x, y):        ((x)>=1 and (x)<=QUADSIZE and (y)>=1 and (y)<=QUADSIZE)
+
+# These types have not been dealt with yet 
 IHQUEST = '?',
-IHE = 'E',
-IHF = 'F',
-IHT = 'T',
 IHWEB = '#',
 IHMATER0 = '-',
 IHMATER1 = 'o',
@@ -45,15 +47,101 @@ class coord:
         return self.x != None and self.y != None
     def __eq__(self, other):
         return self.x == other.y and self.x == other.y
+    def __add__(self, other):
+        return coord(self.x+self.x, self.y+self.y)
+    def __sub__(self, other):
+        return coord(self.x-self.x, self.y-self.y)
     def distance(self, other):
         return math.sqrt((self.x - other.x)**2 + (self.y - other.y)**2)
+    def sgn(self):
+        return coord(self.x / abs(x), self.y / abs(y));
+    def __hash__(self):
+        return hash((x, y))
+    def __str__(self):
+        return "%d - %d" % (self.x, self.y)
+
+class feature:
+    "A feature in the current quadrant (ship, star, black hole, base, etc)." 
+    def __init__(self):
+        self.type = None       # name of feature type
+        self.sector = None     # sector location
+    def distance(self):
+        return self.sector.distance(game.sector)
+    def __str__(self):
+        "This will be overridden by subclasses."
+        return self.name[0]
+    def sectormove(self, dest):
+        "Move this feature within the current quadrant." 
+        if self.sector:
+            game.quad[self.sector] = None
+        game.quad[dest] = self
+        self.sector = dest
 
-class planet:
+class ship(feature):
+    "A starship, frindly or enemy." 
+    def __init__(self, type, power):
+        feature.__init__(self)
+        self.type = type       # klingon, romulan, commander,
+                               # supercommander, tholian,
+                                # enterprise, faerie queene.
+        self.power = power     # power
+        if self.type in ("Klingon", "Commander", "Super-Commander"):
+            game.remkl += 1
+        elif self.type == "Romulan":
+            game.romrem += 1
+    def __del__(self):
+        if self.type in ("Klingon", "Commander", "Super-Commander"):
+            game.remkl -= 1
+        elif self.type == "Romulan":
+            game.romrem -= 1
+
+class space(feature):
+    "Empty space.  Has no state, just knows how to identify iself."
+    def __str__(self):
+        return '*'
+
+class star(feature):
+    "A star.  Has no state, just knows how to identify iself."
+    def __str__(self):
+        return '*'
+
+class planet(feature):
+    "A planet.  May be inhabited or not, may hold dilithium crystals or not."
     def __init(self):
-        self.w = coord()
+        feature.__init__(self)
         self.name = None
         self.crystals = None   # "absent", "present", or "mined"
+        self.inhabited = False
         self.known = "unknown" # Other values: "known" and "shuttle down"
+        game.state.planets.append(self)
+    def __del__(self):
+        game.state.planets.remove(self)
+    def __str__(self):
+        if self.inhabited:
+            return '@'
+        else:
+            return 'P'
+
+class web(feature):
+    "A bit of Tholian web.  Has no state, just knows how to identify iself."
+    def __str__(self):
+        return '*'
+
+class blackhole(feature):
+    "A black hole.  Has no hair, just knows how to identify iself."
+    def __str__(self):
+        return ' '
+
+class starbase(feature):
+    "Starbases also have no features, just a location."
+    def __init(self, quadrant):
+        feature.__init__(self)
+        self.quadrant = quadrant
+        game.state.bases.append(self)
+    def __del__(self):
+        game.state.bases.remove(self)
+    def __str__(self):
+        return 'B'
 
 class quadrant:
     def __init__(self):
@@ -65,6 +153,15 @@ class quadrant:
         self.supernova = None
         self.charted = None
         self.status = "secure" # Other valuues: "distressed", "enslaved"
+    def enemies(self):
+        "List enemies in this quadrant."
+        lst = []
+        for feature in self.quad.values:
+            if not isinstance(feature, ship):
+                continue
+            if feature.name not in ("Enterprise", "Faerie Queene"):
+                lst.append(feature)
+        return lst
 
 class page:
     "A chart page.  The starchart is a 2D array of these."
@@ -80,13 +177,11 @@ class snapshot:
        self.remkl = None       # remaining klingons
        self.remcom = None      # remaining commanders
        self.nscrem = None      # remaining super commanders
-       self.rembase = None     # remaining bases
        self.starkl = None      # destroyed stars
        self.basekl = None      # destroyed bases
        self.nromrem = None     # Romulans remaining
-       self.nplankl = None     # destroyed uninhabited planets
-       self.nworldkl = None    # destroyed inhabited planets
-        self.plnets = [];      # List of planets known
+       self.nplankl = None     # destroyed uninhabited planets self.nworldkl = None    # destroyed inhabited planets
+        self.planets = [];     # List of planets known
         self.date = None       # stardate
        self.remres = None      # remaining resources
        self. remtime = None    # remaining time
@@ -116,7 +211,7 @@ class game:
         self.future = []               # future events
         self.passwd = None             # Self Destruct password
         # Coordinate members start here
-       self.ks = {}                    # enemy sector locations
+       self.enemies = {}                       # enemy sector locations
        self.quadrant = None            # where we are
         self.sector = None
        self.tholian = None             # coordinates of Tholian
@@ -153,7 +248,7 @@ class game:
         self.skill = None              # levels: none, novice, fair, good,
                                        # expert, emeritus
         # Integer nembers sart here
-       self.inkling = None             # initial number of klingons
+x      self.inkling = None             # initial number of klingons
        self.inbase = None              # initial number of bases
        self.incom = None               # initial number of commanders
        self.inscom = None              # initial number of commanders
@@ -170,7 +265,6 @@ class game:
        self.nkinks = None              # count of energy-barrier crossings
        self.iplnet = None              # planet # in quadrant
        self.inplan = None              # initial planets
-       self.nenhere = None             # number of enemies in quadrant
        self.irhere = None              # Romulans in quadrant
        self.isatb = None               # =1 if super commander is attacking base
        self.tourn = None               # tournament number