2 sst.py =-- Super Star Trek in Python
5 import os, sys, math, curses
7 SSTDOC = "/usr/share/doc/sst/sst.doc"
10 def _(str): return str
14 NINHAB = (GALSIZE * GALSIZE / 2)
16 PLNETMAX = (NINHAB + MAXUNINHAB)
18 BASEMAX = (GALSIZE * GALSIZE / 12)
21 FULLCREW = 428 # BSD Trek was 387, that's wrong
24 # These functions hide the difference between 0-origin and 1-origin addressing.
25 def VALID_QUADRANT(x, y): return ((x)>=1 and (x)<=GALSIZE and (y)>=1 and (y)<=GALSIZE)
26 def VALID_SECTOR(x, y): return ((x)>=1 and (x)<=QUADSIZE and (y)>=1 and (y)<=QUADSIZE)
28 def square(i): return ((i)*(i))
29 def distance(c1, c2): return math.sqrt(square(c1.x - c2.x) + square(c1.y - c2.y))
30 def invalidate(w): w.x = w.y = 0
31 def is_valid(w): return (w.x != 0 and w.y != 0)
34 def __init(self, x=None, y=None):
38 self.x = self.y = None
40 return self.x != None and self.y != None
41 def __eq__(self, other):
42 return self.x == other.y and self.x == other.y
43 def __add__(self, other):
44 return coord(self.x+self.x, self.y+self.y)
45 def __sub__(self, other):
46 return coord(self.x-self.x, self.y-self.y)
47 def distance(self, other):
48 return math.sqrt((self.x - other.x)**2 + (self.y - other.y)**2)
50 return coord(self.x / abs(x), self.y / abs(y));
54 return "%d - %d" % (self.x, self.y)
58 self.name = None # string-valued if inhabited
59 self.w = coord() # quadrant located
60 self.pclass = None # could be ""M", "N", "O", or "destroyed"
61 self.crystals = None # could be "mined", "present", "absent"
62 self.known = None # could be "unknown", "known", "shuttle_down"
64 # How to represent features
94 self.status = None # Could be "secure", "distressed", "enslaved"
104 self.snap = False # snapshot taken
105 self.crew = None # crew complement
106 self.remkl = None # remaining klingons
107 self.remcom = None # remaining commanders
108 self.nscrem = None # remaining super commanders
109 self.rembase = None # remaining bases
110 self.starkl = None # destroyed stars
111 self.basekl = None # destroyed bases
112 self.nromrem = None # Romulans remaining
113 self.nplankl = None # destroyed uninhabited planets
114 self.nworldkl = None # destroyed inhabited planets
115 self.planets = [] # Planet information
116 for i in range(PLNETMAX):
117 self.planets.append(planet())
118 self.date = None # stardate
119 self.remres = None # remaining resources
120 self.remtime = None # remaining time
121 self.baseq = [] # Base quadrant coordinates
122 for i in range(BASEMAX+1):
123 self.baseq.append(coord())
124 self.kcmdr = [] # Commander quadrant coordinates
125 for i in range(QUADSIZE+1):
126 self.kcmdr.append(coord())
127 self.kscmdr = coord() # Supercommander quadrant coordinates
128 self.galaxy = [] # The Galaxy (subscript 0 not used)
129 for i in range(GALSIZE+1):
130 self.chart.append([])
131 for j in range(GALSIZE+1):
132 self.galaxy[i].append(quadrant())
133 self.chart = [] # the starchart (subscript 0 not used)
134 for i in range(GALSIZE+1):
135 self.chart.append([])
136 for j in range(GALSIZE+1):
137 self.chart[i].append(page())
141 self.date = None # A real number
142 self.quadrant = None # A coord structure
145 OPTION_ALL = 0xffffffff
146 OPTION_TTY = 0x00000001 # old interface
147 OPTION_CURSES = 0x00000002 # new interface
148 OPTION_IOMODES = 0x00000003 # cover both interfaces
149 OPTION_PLANETS = 0x00000004 # planets and mining
150 OPTION_THOLIAN = 0x00000008 # Tholians and their webs
151 OPTION_THINGY = 0x00000010 # Space Thingy can shoot back
152 OPTION_PROBE = 0x00000020 # deep-space probes
153 OPTION_SHOWME = 0x00000040 # bracket Enterprise in chart
154 OPTION_RAMMING = 0x00000080 # enemies may ram Enterprise
155 OPTION_MVBADDY = 0x00000100 # more enemies can move
156 OPTION_BLKHOLE = 0x00000200 # black hole may timewarp you
157 OPTION_BASE = 0x00000400 # bases have good shields
158 OPTION_WORLDS = 0x00000800 # logic for inhabited worlds
159 OPTION_PLAIN = 0x01000000 # user chose plain game
160 OPTION_ALMY = 0x02000000 # user chose Almy variant
179 NDEVICES= 16 # Number of devices
181 def damaged(dev): return (game.damage[dev] != 0.0)
183 # Define future events
184 FSPY = 0 # Spy event happens always (no future[] entry)
185 # can cause SC to tractor beam Enterprise
186 FSNOVA = 1 # Supernova
187 FTBEAM = 2 # Commander tractor beams Enterprise
188 FSNAP = 3 # Snapshot for time warp
189 FBATTAK = 4 # Commander attacks base
190 FCDBAS = 5 # Commander destroys base
191 FSCMOVE = 6 # Supercommander moves (might attack base)
192 FSCDBAS = 7 # Supercommander destroys base
193 FDSPROB = 8 # Move deep space probe
194 FDISTR = 9 # Emit distress call from an inhabited world
195 FENSLV = 10 # Inhabited word is enslaved */
196 FREPRO = 11 # Klingons build a ship in an enslaved system
200 # abstract out the event handling -- underlying data structures will change
201 # when we implement stateful events
203 def findevent(evtype): return game.future[evtype]
207 self.options = None # Game options
208 self.state = None # A snapshot structure
209 self.snapsht = None # Last snapshot taken for time-travel purposes
210 self.quad = [[IHDOT * (QUADSIZE+1)] * (QUADSIZE+1)] # contents of our quadrant
211 self.kpower = [[0 * (QUADSIZE+1)] * (QUADSIZE+1)] # enemy energy levels
212 self.kdist = [[0 * (QUADSIZE+1)] * (QUADSIZE+1)] # enemy distances
213 self.kavgd = [[0 * (QUADSIZE+1)] * (QUADSIZE+1)] # average distances
214 self.damage = [0] * NDEVICES # damage encountered
215 self.future = [0.0] * NEVENTS # future events
216 for i in range(NEVENTS):
217 self.future.append(event())
218 self.passwd = None; # Self Destruct password
219 self.ks = [[None * (QUADSIZE+1)] * (QUADSIZE+1)] # enemy sector locations
220 self.quadrant = None # where we are in the large
221 self.sector = None # where we are in the small
222 self.tholian = None # coordinates of Tholian
223 self.base = None # position of base in current quadrant
224 self.battle = None # base coordinates being attacked
225 self.plnet = None # location of planet in quadrant
226 self.probec = None # current probe quadrant
227 self.gamewon = False # Finished!
228 self.ididit = False # action taken -- allows enemy to attack
229 self.alive = False # we are alive (not killed)
230 self.justin = False # just entered quadrant
231 self.shldup = False # shields are up
232 self.shldchg = False # shield is changing (affects efficiency)
233 self.comhere = False # commander here
234 self.ishere = False # super-commander in quadrant
235 self.iscate = False # super commander is here
236 self.ientesc = False # attempted escape from supercommander
237 self.ithere = False # Tholian is here
238 self.resting = False # rest time
239 self.icraft = False # Kirk in Galileo
240 self.landed = False # party on planet (true), on ship (false)
241 self.alldone = False # game is now finished
242 self.neutz = False # Romulan Neutral Zone
243 self.isarmed = False # probe is armed
244 self.inorbit = False # orbiting a planet
245 self.imine = False # mining
246 self.icrystl = False # dilithium crystals aboard
247 self.iseenit = False # seen base attack report
248 self.thawed = False # thawed game
249 self.condition = None # "green", "yellow", "red", "docked", "dead"
250 self.iscraft = None # "onship", "offship", "removed"
251 self.skill = None # Player skill level
252 self.inkling = 0 # initial number of klingons
253 self.inbase = 0 # initial number of bases
254 self.incom = 0 # initial number of commanders
255 self.inscom = 0 # initial number of commanders
256 self.inrom = 0 # initial number of commanders
257 self.instar = 0 # initial stars
258 self.intorps = 0 # initial/max torpedoes
259 self.torps = 0 # number of torpedoes
260 self.ship = 0 # ship type -- 'E' is Enterprise
261 self.abandoned = 0 # count of crew abandoned in space
262 self.length = 0 # length of game
263 self.klhere = 0 # klingons here
264 self.casual = 0 # causalties
265 self.nhelp = 0 # calls for help
266 self.nkinks = 0 # count of energy-barrier crossings
267 self.iplnet = 0 # planet # in quadrant
268 self.inplan = 0 # initial planets
269 self.nenhere = 0 # number of enemies in quadrant
270 self.irhere = 0 # Romulans in quadrant
271 self.isatb = 0 # =1 if super commander is attacking base
272 self.tourn = 0 # tournament number
273 self.proben = 0 # number of moves for probe
274 self.nprobes = 0 # number of probes available
275 self.inresor = 0.0 # initial resources
276 self.intime = 0.0 # initial time
277 self.inenrg = 0.0 # initial/max energy
278 self.inshld = 0.0 # initial/max shield
279 self.inlsr = 0.0 # initial life support resources
280 self.indate = 0.0 # initial date
281 self.energy = 0.0 # energy level
282 self.shield = 0.0 # shield level
283 self.warpfac = 0.0 # warp speed
284 self.wfacsq = 0.0 # squared warp factor
285 self.lsupres = 0.0 # life support reserves
286 self.dist = 0.0 # movement distance
287 self.direc = 0.0 # movement direction
288 self.optime = 0.0 # time taken by current operation
289 self.docfac = 0.0 # repair factor when docking (constant?)
290 self.damfac = 0.0 # damage factor
291 self.lastchart = 0.0 # time star chart was last updated
292 self.cryprob = 0.0 # probability that crystal will work
293 self.probex = 0.0 # location of probe
295 self.probeinx = 0.0 # probe x,y increment
296 self.probeiny = 0.0 #
297 self.height = 0.0 # height of orbit around planet