"Do not anger the Space Thingy!"
def __init__(self):
self.location = Coord()
- self.angered = False
- def angry(self):
- self.angered = True
def at(self, q):
return (q.i, q.j) == (self.location.i, self.location.j)
OPTION_TTY = 0x00000001 # old interface
OPTION_CURSES = 0x00000002 # new interface
OPTION_IOMODES = 0x00000003 # cover both interfaces
-OPTION_PLANETS = 0x00000004 # planets and mining
+OPTION_PLANETS = 0x00000004 # planets and mining (> 1974)
OPTION_THOLIAN = 0x00000008 # Tholians and their webs (UT 1979 version)
-OPTION_THINGY = 0x00000010 # Space Thingy can shoot back (Stas, 2005)
OPTION_PROBE = 0x00000020 # deep-space probes (DECUS version, 1980)
-OPTION_SHOWME = 0x00000040 # bracket Enterprise in chart
-OPTION_RAMMING = 0x00000080 # enemies may ram Enterprise (Almy)
-OPTION_MVBADDY = 0x00000100 # more enemies can move (Almy)
-OPTION_BLKHOLE = 0x00000200 # black hole may timewarp you (Stas, 2005)
-OPTION_BASE = 0x00000400 # bases have good shields (Stas, 2005)
-OPTION_WORLDS = 0x00000800 # logic for inhabited worlds (ESR, 2006)
-OPTION_AUTOSCAN = 0x00001000 # automatic LRSCAN before CHART (ESR, 2006)
-OPTION_CAPTURE = 0x00002000 # Enable BSD-Trek capture (Almy, 2013).
-OPTION_CLOAK = 0x80004000 # Enable BSD-Trek capture (Almy, 2013).
-OPTION_PLAIN = 0x01000000 # user chose plain game
-OPTION_ALMY = 0x02000000 # user chose Almy variant
+OPTION_SHOWME = 0x00000040 # bracket Enterprise in chart (ESR, 2005)
+OPTION_RAMMING = 0x00000080 # enemies may ram Enterprise (Almy, 1979)
+OPTION_MVBADDY = 0x00000100 # more enemies can move (Almy, 1979?)
+OPTION_AUTOPASS = 0x00000200 # Autogenerate password (Almy, 1997?)
+OPTION_BLKHOLE = 0x00000400 # black hole may timewarp you (Stas, 2005)
+OPTION_BASE = 0x00000800 # bases have good shields (Stas, 2005)
+OPTION_WORLDS = 0x00001000 # logic for inhabited worlds (ESR, 2006)
+OPTION_AUTOSCAN = 0x00002000 # automatic LRSCAN before CHART (ESR, 2006)
+OPTION_CAPTURE = 0x00004000 # Enable BSD-Trek capture (Almy, 2013).
+OPTION_CLOAK = 0x80008000 # Enable BSD-Trek capture (Almy, 2013).
+OPTION_ALMY = 0x01000000 # Almy's death ray upgrade (1997?)
OPTION_COLOR = 0x04000000 # enable color display (ESR, 2010)
OPTION_DOTFILL = 0x08000000 # fix dotfill glitch in chart (ESR, 2019)
OPTION_ALPHAMERIC = 0x10000000 # Alpha Y coordinates (ESR, 2023)
"TTY": OPTION_TTY,
"IOMODES": OPTION_IOMODES,
"PLANETS": OPTION_PLANETS,
- "THOLIAN": OPTION_THOLIAN,
- "THINGY": OPTION_THINGY,
"PROBE": OPTION_PROBE,
"SHOWME": OPTION_SHOWME,
"RAMMING": OPTION_RAMMING,
"MVBADDY": OPTION_MVBADDY,
+ "AUTOPASS": OPTION_AUTOPASS,
"BLKHOLE": OPTION_BLKHOLE,
"BASE": OPTION_BASE,
"WORLDS": OPTION_WORLDS,
"AUTOSCAN": OPTION_AUTOSCAN,
"CAPTURE": OPTION_CAPTURE,
"CLOAK": OPTION_CLOAK,
- "PLAIN": OPTION_PLAIN,
"ALMY": OPTION_ALMY,
"COLOR": OPTION_COLOR,
"DOTFILL": OPTION_DOTFILL,
+ "ALPHAMERIC": OPTION_ALPHAMERIC,
}
# Define devices
if game.condition == "docked" and (game.options & OPTION_BASE): # protected by base -- back off !
motion -= game.skill*(2.0-rnd.real()**2)
if game.idebug:
- proutn("=== MOTION = %d, FORCES = %1.2f, " % (motion, forces))
+ proutn("=== MOTION = %d, FORCES = %1.2f, " % (motion, forces)) # pragma: no cover
# don't move if no motion
if motion == 0:
return []
nsteps = min(nsteps, QUADSIZE) # This shouldn't be necessary
nsteps = max(nsteps, 1) # This shouldn't be necessary
if game.idebug:
- proutn("NSTEPS = %d:" % nsteps)
+ proutn("NSTEPS = %d:" % nsteps) # pragma: no cover
# Compute preferred values of delta X and Y
m = game.sector - enemy.location
if 2.0 * abs(m.i) < abs(m.j):
# main move loop
for ll in range(nsteps):
if game.idebug:
- proutn(" %d" % (ll+1))
+ proutn(" %d" % (ll+1)) # pragma: no cover
# Check if preferred position available
look = goto + m
if m.i < 0:
if success:
goto = look
if game.idebug:
- proutn(repr(goto))
+ proutn(repr(goto)) # pragma: no cover
else:
break # done early
if game.idebug:
- skip(1)
+ skip(1) # pragma: no cover
# Enemy moved, but is still in sector
return [(False, enemy, old_dist, goto)]
idelta = Coord()
basetbl = []
if game.idebug:
- prout("== SUPERCOMMANDER")
+ prout("== SUPERCOMMANDER") # pragma: no cover
# Decide on being active or passive
avoid = ((game.incom - len(game.state.kcmdr) + game.inkling - game.remkl())/(game.state.date+0.01-game.indate) < 0.1*game.skill*(game.skill+1.0) or \
(game.state.date-game.indate) < 3.0)
# Loop to move a single torpedo
setwnd(message_window)
for step in range(1, QUADSIZE*2):
- if not track.nexttok():
+ if not track.nextstep():
break
w = track.sector()
if not w.valid_sector():
# In the C/FORTRAN version, dispersion was 2.5 radians, which
# is 143 degrees, which is almost exactly 4.8 clockface units
displacement = course(track.bearing+rnd.real(-2.4, 2.4), distance=2**0.5)
- displacement.nexttok()
+ displacement.nextstep()
bumpto = displacement.sector()
if not bumpto.valid_sector():
return hit
return None
proutn(crmena(True, iquad, "sector", w))
displacement = course(track.bearing+rnd.real(-2.4, 2.4), distance=2**0.5, origin=w)
- displacement.nexttok()
+ displacement.nextstep()
bumpto = displacement.sector()
if game.quad[bumpto.i][bumpto.j] == ' ':
prout(_(" buffeted into black hole."))
prout(crmena(True, '*', "sector", w) + _(" unaffected by photon blast."))
return None
elif iquad == '?': # Hit a thingy
- if not (game.options & OPTION_THINGY) or rnd.withprob(0.3):
- skip(1)
- prouts(_("AAAAIIIIEEEEEEEEAAAAAAAAUUUUUGGGGGHHHHHHHHHHHH!!!"))
- skip(1)
- prouts(_(" HACK! HACK! HACK! *CHOKE!* "))
- skip(1)
- proutn(_("Mr. Spock-"))
- prouts(_(" \"Fascinating!\""))
- skip(1)
- deadkl(w, iquad, w)
- else:
- # Stas Sergeev added the possibility that
- # you can shove the Thingy and piss it off.
- # It then becomes an enemy and may fire at you.
- thing.angry()
+ skip(1)
+ prouts(_("AAAAIIIIEEEEEEEEAAAAAAAAUUUUUGGGGGHHHHHHHHHHHH!!!"))
+ skip(1)
+ prouts(_(" HACK! HACK! HACK! *CHOKE!* "))
+ skip(1)
+ proutn(_("Mr. Spock-"))
+ prouts(_(" \"Fascinating!\""))
+ skip(1)
+ deadkl(w, iquad, w)
return None
elif iquad == ' ': # Black hole
skip(1)
prout("Sector %s." % goto)
sortenemies()
# if no enemies remain after movement, we're done
- if len(game.enemies) == 0 or (len(game.enemies) == 1 and thing.at(game.quadrant) and not thing.angered):
+ if len(game.enemies) == 0 or (len(game.enemies) == 1 and thing.at(game.quadrant)):
return
# set up partial hits if attack happens during shield status change
pfac = 1.0/game.inshld
r *= 0.25
if enemy.power < 500:
r *= 0.25
- if enemy.type == 'T' or (enemy.type == '?' and not thing.angered):
+ if enemy.type in ('T', '?'):
continue
# different enemies have different probabilities of throwing a torp
usephasers = not torps_ok or \
else:
proutn(_("Very small hit on "))
ienm = game.quad[w.i][w.j]
- if ienm == '?':
- thing.angry()
proutn(crmena(False, ienm, "sector", w))
skip(1)
if kpow == 0:
supercommander()
elif evcode == FDSPROB: # Move deep space probe
schedule(FDSPROB, 0.01)
- if not game.probe.nexttok():
+ if not game.probe.nextstep():
if not game.probe.quadrant().valid_quadrant() or \
game.state.galaxy[game.probe.quadrant().i][game.probe.quadrant().j].supernova:
# Left galaxy or ran into supernova
break
else:
# can't seem to find one; ignore this call
- if game.idebug: # pragma: no cover
- prout("=== Couldn't find location for distress event.")
+ if game.idebug:
+ prout("=== Couldn't find location for distress event.") # pragma: no cover
continue
# got one!! Schedule its enslavement
ev = schedule(FENSLV, expran(game.intime))
# Move out
game.quad[game.sector.i][game.sector.j] = '.'
for _m in range(icourse.moves):
- icourse.nexttok()
+ icourse.nextstep()
w = icourse.sector()
if icourse.origin.quadrant() != icourse.location.quadrant():
newquadrant(noattack)
self.step = 0
def arrived(self):
return self.location.roundtogrid() == self.final
- def nexttok(self):
+ def nextstep(self):
"Next step on course."
self.step += 1
self.nextlocation = self.location + self.increment
# Decide if time warp will occur
if 0.5*wcourse.distance*math.pow(7.0,game.warpfac-10.0) > rnd.real():
twarp = True
- if game.idebug and game.warpfac==10 and not twarp:
+ if game.idebug and game.warpfac==10 and not twarp: # pragma: no cover
blooey = False
proutn("=== Force time warp? ")
if ja():
look = wcourse.moves
while look > 0:
look -= 1
- wcourse.nexttok()
+ wcourse.nextstep()
w = wcourse.sector()
if not w.valid_sector():
break
if not ja():
scanner.chew()
return
- if not (game.options & OPTION_PLAIN):
+ if (game.options & OPTION_ALMY):
nrgneed = 50 * game.skill + game.height / 100.0
if nrgneed > game.energy:
prout(_("Engineering to bridge--"))
prouts(_("WHIRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR"))
skip(1)
dprob = 0.30
- if game.options & OPTION_PLAIN:
+ # Ugh. This test (For Tom Almy's death-ray upgrade) was inverted for a long time.
+ # Furthermore, somebody (ESR or Stas?) changed Tom Almy's 0.7 upgraded chance of
+ # working to 0.5.
+ if game.options & OPTION_ALMY:
dprob = 0.5
r = rnd.real()
if r > dprob:
prout(_("Ensign Chekov- \"Congratulations, Captain!\""))
if game.unwon() == 0:
finish(FWON)
- if (game.options & OPTION_PLAIN) == 0:
+ if (game.options & OPTION_ALMY):
prout(_("Spock- \"Captain, I believe the `Experimental Death Ray'"))
if rnd.withprob(0.05):
prout(_(" is still operational.\""))
game.state.galaxy[i][j].stars = k
# Locate star bases in galaxy
if game.idebug:
- prout("=== Allocating %d bases" % game.inbase)
+ prout("=== Allocating %d bases" % game.inbase) # pragma: no cover
for i in range(game.inbase):
while True:
while True:
if distq < 6.0*(BASEMAX+1-game.inbase) and rnd.withprob(0.75):
contflag = True
if game.idebug:
- prout("=== Abandoning base #%d at %s" % (i, w))
+ prout("=== Abandoning base #%d at %s" % (i, w)) # pragma: no cover
break
elif distq < 6.0 * (BASEMAX+1-game.inbase):
if game.idebug:
- prout("=== Saving base #%d, close to #%d" % (i, j))
+ prout("=== Saving base #%d, close to #%d" % (i, j)) # pragma: no cover
if not contflag:
break
if game.idebug:
- prout("=== Placing base #%d in quadrant %s" % (i, w))
+ prout("=== Placing base #%d in quadrant %s" % (i, w)) # pragma: no cover
game.state.baseq.append(w)
game.state.galaxy[w.i][w.j].starbase = game.state.chart[w.i][w.j].starbase = True
# Position ordinary Klingon Battle Cruisers
return True
if scanner.sees("regular"):
break
- proutn(_("What is \"%s\"? ") % scanner.token)
+ proutn(_("What game type is \"%s\"? ") % scanner.token)
scanner.chew()
while game.length==0 or game.skill==SKILL_NONE:
if scanner.nexttok() == "IHALPHA":
elif scanner.sees("emeritus"):
game.skill = SKILL_EMERITUS
else:
- proutn(_("What is \""))
+ proutn(_("What skill level is is \""))
proutn(scanner.token)
prout("\"?")
else:
scanner.nexttok()
if scanner.sees("plain"):
# Approximates the UT FORTRAN version.
- game.options &=~ (OPTION_THOLIAN | OPTION_PLANETS | OPTION_THINGY | OPTION_PROBE | OPTION_RAMMING | OPTION_MVBADDY | OPTION_BLKHOLE | OPTION_BASE | OPTION_WORLDS | OPTION_COLOR | OPTION_CAPTURE | OPTION_CLOAK | OPTION_DOTFILL | OPTION_ALPHAMERIC)
- game.options |= OPTION_PLAIN
+ game.options &=~ (OPTION_THOLIAN | OPTION_PLANETS | OPTION_PROBE | OPTION_RAMMING | OPTION_MVBADDY | OPTION_BLKHOLE | OPTION_BASE | OPTION_WORLDS | OPTION_COLOR | OPTION_CAPTURE | OPTION_CLOAK | OPTION_ALMY | OPTION_AUTOPASS | OPTION_DOTFILL | OPTION_ALPHAMERIC)
elif scanner.sees("almy"):
# Approximates Tom Almy's version.
- game.options &=~ (OPTION_THINGY | OPTION_BLKHOLE | OPTION_BASE | OPTION_WORLDS | OPTION_COLOR | OPTION_DOTFILL | OPTION_ALPHAMERIC)
- game.options |= OPTION_ALMY
+ game.options &=~ (OPTION_BLKHOLE | OPTION_BASE | OPTION_WORLDS | OPTION_COLOR | OPTION_DOTFILL | OPTION_ALPHAMERIC)
elif scanner.sees("fancy") or scanner.sees("\n"):
pass
elif len(scanner.token):
- proutn(_("What is \"%s\"?") % scanner.token)
+ proutn(_("What game style is \"%s\"?") % scanner.token)
setpassword()
if game.passwd == "debug": # pragma: no cover
game.idebug = True
def setpassword():
"Set the self-destruct password."
- if game.options & OPTION_PLAIN:
+ if game.options & OPTION_AUTOPASS:
+ game.passwd = ""
+ game.passwd += chr(ord('a')+rnd.integer(26))
+ game.passwd += chr(ord('a')+rnd.integer(26))
+ game.passwd += chr(ord('a')+rnd.integer(26))
+ else:
while True:
scanner.chew()
proutn(_("Please type in a secret password- "))
#game.passwd = getpass.getpass("Please type in a secret password- ")
if game.passwd is not None:
break
- else:
- game.passwd = ""
- game.passwd += chr(ord('a')+rnd.integer(26))
- game.passwd += chr(ord('a')+rnd.integer(26))
- game.passwd += chr(ord('a')+rnd.integer(26))
# Code from sst.c begins here
if game.alldone:
break
if game.idebug:
- prout("=== Ending")
+ prout("=== Ending") # pragma: no cover
def cramen(ch):
"Emit the name of an enemy or feature."
proutn("Toggle debug flag? ")
if ja():
game.idebug = not game.idebug
- if game.idebug:
+ if game.idebug: # pragma: no cover
prout("Debug output ON")
else:
prout("Debug output OFF")
game = Gamestate()
rnd = randomizer()
logfp = None
- game.options = OPTION_ALL &~ (OPTION_IOMODES | OPTION_PLAIN | OPTION_ALMY)
+ game.options = OPTION_ALL &~ OPTION_IOMODES
if os.getenv("TERM"):
game.options |= OPTION_CURSES # pragma: no cover
else:
game.options |= OPTION_TTY
seed = int(time.time())
- (options, arguments) = getopt.getopt(sys.argv[1:], "cr:s:txV")
- for (switch, val) in options:
- if switch == '-r':
- # pylint: disable=raise-missing-from
- try:
- replayfp = open(val, "r")
- except IOError:
- sys.stderr.write("sst: can't open replay file %s\n" % val)
- raise SystemExit(1)
- # pylint: disable=raise-missing-from
- try:
- line = replayfp.readline().strip()
- (leader, __, seed) = line.split()
- # pylint: disable=eval-used
- seed = eval(seed)
- line = replayfp.readline().strip()
- arguments += line.split()[2:]
- except ValueError: # pragma: no cover
- sys.stderr.write("sst: replay file %s is ill-formed\n"% val)
+ try:
+ (options, arguments) = getopt.getopt(sys.argv[1:], "cr:s:txV")
+ for (switch, val) in options:
+ if switch == '-r':
+ # pylint: disable=raise-missing-from
+ try:
+ replayfp = open(val, "r")
+ except IOError:
+ sys.stderr.write("sst: can't open replay file %s\n" % val)
+ raise SystemExit(1)
+ # pylint: disable=raise-missing-from
+ try:
+ line = replayfp.readline().strip()
+ (leader, __, seed) = line.split()
+ # pylint: disable=eval-used
+ seed = eval(seed)
+ line = replayfp.readline().strip()
+ arguments += line.split()[2:]
+ except ValueError: # pragma: no cover
+ sys.stderr.write("sst: replay file %s is ill-formed\n"% val)
+ raise SystemExit(1)
+ game.options |= OPTION_TTY
+ game.options &=~ OPTION_CURSES
+ elif switch == '-s': # pragma: no cover
+ seed = int(val)
+ elif switch == '-t': # pragma: no cover
+ game.options |= OPTION_TTY
+ game.options &=~ OPTION_CURSES
+ elif switch == '-x': # pragma: no cover
+ game.idebug = True
+ elif switch == '-c': # Enable curses debugging - undocumented
+ game.cdebug = True
+ elif switch == '-V': # pragma: no cover
+ print("SST2K", version)
+ raise SystemExit(0)
+ else: # pragma: no cover
+ sys.stderr.write("usage: sst [-t] [-x] [startcommand...].\n")
raise SystemExit(1)
- game.options |= OPTION_TTY
- game.options &=~ OPTION_CURSES
- elif switch == '-s': # pragma: no cover
- seed = int(val)
- elif switch == '-t': # pragma: no cover
- game.options |= OPTION_TTY
- game.options &=~ OPTION_CURSES
- elif switch == '-x': # pragma: no cover
- game.idebug = True
- elif switch == '-c': # Enable curses debugging - undocumented
- game.cdebug = True
- elif switch == '-V': # pragma: no cover
- print("SST2K", version)
- raise SystemExit(0)
- else: # pragma: no cover
- sys.stderr.write("usage: sst [-t] [-x] [startcommand...].\n")
- raise SystemExit(1)
+ except getopt.GetoptError as err:
+ print(err)
+ raise SystemExit(1) from err
# where to save the input in case of bugs
if "TMPDIR" in os.environ: # pragma: no cover
tmpdir = os.environ['TMPDIR']