"""
sst.py =-- Super Star Trek in Python
-This code is a Python translation of a C translation of a FORTRAN original.
-The FORTRANness still shows in many ways, notably the use of a lot of
-parallel arrays where a more modern language would use structures
-or objects. (However, 1-origin array indexing was fixed.)
+This code is a Python translation of a C translation of a FORTRAN
+original dating back to 1973. Beautiful Python it is not. But it
+works.
Dave Matuszek says:
features that I liked. I also took a peek at the DECUS version (a
port, less sources, to the PDP-10), and some other variations.
-1, Compared to the original UT version, I've changed the "help" command to
-"call" and the "terminate" command to "quit" to better match
-user expectations. The DECUS version apparently made those changes
-as well as changing "freeze" to "save". However I like "freeze".
-(Both "freeze" and "save" work in SST2K.)
+1, Compared to the original UT version, I've changed the "help"
+command to "call" and the "terminate" command to "quit" to better
+match user expectations. The DECUS version apparently made those
+changes as well as changing "freeze" to "save". However I like
+"freeze". (Both "freeze" and "save" work in SST2K.)
2. The experimental deathray originally had only a 5% chance of
success, but could be used repeatedly. I guess after a couple
self.baseq = [] # Base quadrant coordinates
self.kcmdr = [] # Commander quadrant coordinates
self.kscmdr = coord() # Supercommander quadrant coordinates
- # the galaxy (subscript 0 not used)
+ # the galaxy
self.galaxy = fill2d(GALSIZE, lambda i, j: quadrant())
- # the starchart (subscript 0 not used)
+ # the starchart
self.chart = fill2d(GALSIZE, lambda i, j: page())
class event:
self.damfac = 0.0 # damage factor
self.lastchart = 0.0 # time star chart was last updated
self.cryprob = 0.0 # probability that crystal will work
- self.probex = 0.0 # location of probe
- self.probey = 0.0 #
- self.probeinx = 0.0 # probe x,y increment
- self.probeiny = 0.0 #
+ self.probe = None # location of probe
+ self.probein = None # probe i,j increment
self.height = 0.0 # height of orbit around planet
def recompute(self):
# Stas thinks this should be (C expression):
# after killing the last klingon when score is shown -- perhaps also
# if the only remaining klingon is SCOM.
game.state.remtime = game.state.remres/(game.state.remkl + 4*len(game.state.kcmdr))
-# From enumerated type 'feature'
+
IHR = 'R'
IHK = 'K'
IHC = 'C'
IHMATER1 = 'o'
IHMATER2 = '0'
-
-# From enumerated type 'FINTYPE'
FWON = 0
FDEPLETE = 1
FLIFESUP = 2
FHOLE = 20
FCREW = 21
-# Log the results of pulling random numbers so we can check determinism.
-
-import traceback
-
def withprob(p):
v = random.random()
#logfp.write("# withprob(%s) -> %f (%s) at %s\n" % (p, v, v<p, traceback.extract_stack()[-2][1:]))
supercommander()
elif evcode == FDSPROB: # Move deep space probe
schedule(FDSPROB, 0.01)
- game.probex += game.probeinx
- game.probey += game.probeiny
- i = (int)(game.probex/QUADSIZE +0.05)
- j = (int)(game.probey/QUADSIZE + 0.05)
+ game.probe += game.probein
+ i = int(round(game.probe.i/float(QUADSIZE)))
+ j = int(round(game.probe.j/float(QUADSIZE)))
if game.probec.i != i or game.probec.j != j:
game.probec.i = i
game.probec.j = j
if not VALID_QUADRANT(i, j) or \
game.state.galaxy[game.probec.i][game.probec.j].supernova:
# Left galaxy or ran into supernova
- if comunicating():
+ if communicating():
announce()
skip(1)
proutn(_("Lt. Uhura- \"The deep space probe "))
- if not VALID_QUADRANT(j, i):
+ if not VALID_QUADRANT(i, j):
proutn(_("has left the galaxy"))
else:
proutn(_("is no longer transmitting"))
pdest.charted = True
game.proben -= 1 # One less to travel
if game.proben == 0 and game.isarmed and pdest.stars:
- # lets blow the sucker!
- supernova(game.probec)
+ supernova(game.probec) # fire in the hole!
unschedule(FDSPROB)
if game.state.galaxy[game.quadrant.i][game.quadrant.j].supernova:
return
game.resting = False
game.optime = 0
-# A nova occurs. It is the result of having a star hit with a
-# photon torpedo, or possibly of a probe warhead going off.
-# Stars that go nova cause stars which surround them to undergo
-# the same probabilistic process. Klingons next to them are
-# destroyed. And if the starship is next to it, it gets zapped.
-# If the zap is too much, it gets destroyed.
-
def nova(nov):
"Star goes nova."
course = (0.0, 10.5, 12.0, 1.5, 9.0, 0.0, 3.0, 7.5, 6.0, 4.5)
setwnd(fullscreen_window)
def ioend():
- "Wrap up I/O. Presently a stub."
- stdscr.keypad(False)
- curses.echo()
- curses.nocbreak()
- curses.endwin()
+ "Wrap up I/O."
+ if game.options & OPTION_CURSES:
+ stdscr.keypad(False)
+ curses.echo()
+ curses.nocbreak()
+ curses.endwin()
def waitfor():
"Wait for user action -- OK to do nothing if on a TTY"
# because it involves giving x and y motions, yet the coordinates
# are always displayed y - x, where +y is downward!
-def getcourse(isprobe, akey):
+def getcourse(isprobe):
"Get a course and distance from the user."
key = 0
dquad = copy.copy(game.quadrant)
navmode = "manual"
key = "IHEOL"
break
- if isprobe and akey != -1:
- # For probe launch, use pre-scanned value first time
- key = akey
- akey = -1
- else:
- key = scanner.next()
+ key = scanner.next()
if key == "IHEOL":
proutn(_("Manual or automatic- "))
iprompt = True
prout(_("Engineer Scott- \"The impulse engines are damaged, Sir.\""))
return
if game.energy > 30.0:
- if not getcourse(isprobe=False, akey=0):
+ if not getcourse(isprobe=False):
return
power = 20.0 + 100.0*game.dist
else:
prout(_(" is repaired, I can only give you warp 4.\""))
return
# Read in course and distance
- if not getcourse(isprobe=False, akey=0):
+ if not getcourse(isprobe=False):
return
# Make sure starship has enough energy for the trip
power = (game.dist+0.05)*game.warpfac*game.warpfac*game.warpfac*(game.shldup+1)
proutn(_("The %s has stopped in a quadrant containing") % crmshp())
prouts(_(" a supernova."))
skip(2)
- prout(_("***Emergency automatic override attempts to hurl ")+crmshp())
- skip(1)
+ proutn(_("***Emergency automatic override attempts to hurl ")+crmshp())
prout(_("safely out of quadrant."))
if not damaged(DRADIO):
game.state.galaxy[game.quadrant.i][game.quadrant.j].charted = True
return
key = scanner.next()
if key == "IHEOL":
- # slow mode, so let Kirk know how many probes there are left
if game.nprobes == 1:
prout(_("1 probe left."))
else:
elif key == "IHEOL":
proutn(_("Arm NOVAMAX warhead? "))
game.isarmed = ja()
- if not getcourse(isprobe=True, akey=key):
+ elif key == "IHREAL": # first element of course
+ scanner.push(scanner.token)
+ if not getcourse(isprobe=True):
return
game.nprobes -= 1
angle = ((15.0 - game.direc) * 0.5235988)
- game.probeinx = -math.sin(angle)
- game.probeiny = math.cos(angle)
- if math.fabs(game.probeinx) > math.fabs(game.probeiny):
- bigger = math.fabs(game.probeinx)
- else:
- bigger = math.fabs(game.probeiny)
- game.probeiny /= bigger
- game.probeinx /= bigger
+ game.probein = coord(-math.sin(angle), math.cos(angle))
+ bigger = max(abs(game.probein.i), abs(game.probein.j))
+ game.probein /= bigger
game.proben = 10.0*game.dist*bigger +0.5
- game.probex = game.quadrant.i*QUADSIZE + game.sector.i - 1 # We will use better packing than original
- game.probey = game.quadrant.j*QUADSIZE + game.sector.j - 1
- game.probec = game.quadrant
+ game.probe = coord(game.quadrant.i*QUADSIZE + game.sector.i,
+ game.quadrant.j*QUADSIZE + game.sector.j)
+ game.probec = copy.copy(game.quadrant)
schedule(FDSPROB, 0.01) # Time to move one sector
prout(_("Ensign Chekov- \"The deep space probe is launched, Captain.\""))
game.ididit = True
return
-# Here's how the mayday code works:
-#
-# First, the closest starbase is selected. If there is a a starbase
-# in your own quadrant, you are in good shape. This distance takes
-# quadrant distances into account only.
-#
-# A magic number is computed based on the distance which acts as the
-# probability that you will be rematerialized. You get three tries.
-#
-# When it is determined that you should be able to be rematerialized
-# (i.e., when the probability thing mentioned above comes up
-# positive), you are put into that quadrant (anywhere). Then, we try
-# to see if there is a spot adjacent to the star- base. If not, you
-# can't be rematerialized!!! Otherwise, it drops you there. It only
-# tries five times to find a spot to drop you. After that, it's your
-# problem.
-
def mayday():
"Yell for help from nearest starbase."
# There's more than one way to move in this game!
skip(1)
prout(_("Lt. Uhura- \"Captain, we made it!\""))
-# Abandon Ship (the BSD-Trek description)
-#
-# The ship is abandoned. If your current ship is the Faire
-# Queene, or if your shuttlecraft is dead, you're out of
-# luck. You need the shuttlecraft in order for the captain
-# (that's you!!) to escape.
-#
-# Your crew can beam to an inhabited starsystem in the
-# quadrant, if there is one and if the transporter is working.
-# If there is no inhabited starsystem, or if the transporter
-# is out, they are left to die in outer space.
-#
-# If there are no starbases left, you are captured by the
-# Klingons, who torture you mercilessly. However, if there
-# is at least one starbase, you are returned to the
-# Federation in a prisoner of war exchange. Of course, this
-# can't happen unless you have taken some prisoners.
-
def abandon():
"Abandon ship."
scanner.chew()