"""
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
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',
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):
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."
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
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
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
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