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_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_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)
"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,
+}
+
+option_years = {
+ OPTION_PLANETS: 1979,
+ OPTION_PROBE: 1980,
+ OPTION_SHOWME: 2005,
+ OPTION_RAMMING: 1979,
+ OPTION_MVBADDY: 1979,
+ OPTION_AUTOPASS: 1997,
+ OPTION_BLKHOLE: 2005,
+ OPTION_BASE: 2005,
+ OPTION_WORLDS: 2996,
+ OPTION_AUTOSCAN: 2006,
+ OPTION_CAPTURE: 2013,
+ OPTION_CLOAK: 2013,
+ OPTION_ALMY: 1997,
+ OPTION_COLOR: 2010,
+ OPTION_DOTFILL: 2019,
+ OPTION_ALPHAMERIC: 2023,
+}
# Define devices
DSRSENS = 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."))
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
# 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
return
def warp(wcourse, involuntary):
- "ove under warp drive."
+ "Move under warp drive."
blooey = False; twarp = False
if not involuntary: # Not WARPX entry
game.ididit = False
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.\""))
def choose():
"Choose your game type."
- while True:
- game.tourn = None
- game.length = 0
- game.thawed = False
- game.skill = SKILL_NONE
- # Do not chew here, we want to use command-line tokens
- if not scanner.inqueue: # Can start with command line options
- proutn(_("Would you like a regular, tournament, or saved game? "))
+ game.tourn = None
+ game.length = 0
+ game.thawed = False
+ game.skill = SKILL_NONE
+ gametype = None
+ wayback = 0
+ while gametype is None or game.length == 0 or game.skill == SKILL_NONE or wayback == 0:
+ eol_is_fancy = False
+ if not scanner.inqueue or scanner.token == "IHEOL": # Can start with command line options
+ if gametype is None:
+ proutn(_("Would you like a regular, tournament, or saved game? "))
+ elif game.length==0:
+ proutn(_("Would you like a Short, Medium, or Long game? "))
+ elif game.skill == SKILL_NONE:
+ proutn(_("Are you a Novice, Fair, Good, Expert, or Emeritus player? "))
+ elif wayback == 0:
+ proutn(_("Wayback setting (press enter for current year): "))
+ eol_is_fancy = True
scanner.nexttok()
- if scanner.sees("tournament"):
+ if game.idebug:
+ prout("-- Token: %s=%s" % (scanner.type, repr(scanner.token)))
+ if scanner.token == "":
+ raise SystemExit(0) # Early end of replay
+ if scanner.token.startswith("r"): # regular
+ gametype = "regular"
+ elif scanner.token.startswith("t"):
+ gametype = "tournament"
+ proutn(_("Type in tournament number-"))
game.tourn = 0
while scanner.nexttok() == "IHEOL":
- proutn(_("Type in tournament number-"))
- if scanner.real == 0:
- scanner.chew()
- continue # We don't want a blank entry
+ if scanner.real == 0:
+ scanner.chew()
+ continue # We don't want a blank entry
game.tourn = int(round(scanner.real))
rnd.seed(scanner.real)
if logfp:
logfp.write("# rnd.seed(%d)\n" % scanner.real)
- break
- if scanner.sees("saved") or scanner.sees("frozen"):
+ elif scanner.token.startswith("sa") or scanner.token.startswith("fr"): # saved or frozen
+ gametype = "saved"
if thaw():
continue
scanner.chew()
report()
waitfor()
return True
- if scanner.sees("regular"):
- break
- proutn(_("What is \"%s\"? ") % scanner.token)
- scanner.chew()
- while game.length==0 or game.skill==SKILL_NONE:
- if scanner.nexttok() == "IHALPHA":
- if scanner.sees("short"):
- game.length = 1
- elif scanner.sees("medium"):
- game.length = 2
- elif scanner.sees("long"):
- game.length = 4
- elif scanner.sees("novice"):
- game.skill = SKILL_NOVICE
- elif scanner.sees("fair"):
- game.skill = SKILL_FAIR
- elif scanner.sees("good"):
- game.skill = SKILL_GOOD
- elif scanner.sees("expert"):
- game.skill = SKILL_EXPERT
- elif scanner.sees("emeritus"):
- game.skill = SKILL_EMERITUS
- else:
- proutn(_("What is \""))
- proutn(scanner.token)
- prout("\"?")
+ elif scanner.token.startswith("s"): # short
+ game.length = 1
+ elif scanner.token.startswith("m"): # medium
+ game.length = 2
+ elif scanner.token.startswith("l"): # long
+ game.length = 4
+ elif scanner.token.startswith("n"): # novice
+ game.skill = SKILL_NOVICE
+ elif (game.skill is None) and scanner.token.startswith("f"): # fair
+ game.skill = SKILL_FAIR
+ elif scanner.token.startswith("g"): # good
+ game.skill = SKILL_GOOD
+ elif scanner.token.startswith("e"): # expert
+ game.skill = SKILL_EXPERT
+ elif scanner.token.startswith("em"): # emeritus
+ game.skill = SKILL_EMERITUS
+ elif scanner.type == "IHREAL":
+ wayback = scanner.int()
+ if wayback <= 1973:
+ # Approximates the UT FORTRAN version.
+ 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.int() < 1980:
+ # Approximates Tom Almy's 1979 version.
+ game.options &=~ (OPTION_BLKHOLE | OPTION_BASE | OPTION_WORLDS | OPTION_COLOR | OPTION_DOTFILL | OPTION_ALPHAMERIC)
+ elif (eol_is_fancy and scanner.token.startswith("\n")):
+ wayback = time.localtime().tm_year
+ elif scanner.token.startswith("\n"):
+ continue
+ elif scanner.token.startswith("idebug"):
+ game.idebug = True
else:
- scanner.chew()
- if game.length==0:
- proutn(_("Would you like a Short, Medium, or Long game? "))
- elif game.skill == SKILL_NONE:
- proutn(_("Are you a Novice, Fair, Good, Expert, or Emeritus player? "))
- # Choose game options -- added by ESR for SST2K
- if scanner.nexttok() != "IHALPHA":
- scanner.chew()
- proutn(_("Choose your game style (plain, almy, fancy or just press enter): "))
- scanner.nexttok()
- if scanner.sees("plain"):
- # Approximates the UT FORTRAN version.
- 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_DOTFILL | OPTION_ALPHAMERIC)
- game.options |= OPTION_PLAIN
- elif scanner.sees("almy"):
- # Approximates Tom Almy's version.
- 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)
+ # Unrecognized token
+ prout(_("Can't interpret %s") % repr(scanner.token))
setpassword()
if game.passwd == "debug": # pragma: no cover
game.idebug = True
prout("=== Debug mode enabled.")
+ if game.idebug:
+ prout("--- Setup: type=%s length=%s skill=%s wayback=%s" % (gametype, game.length, game.skill, wayback))
# Use parameters to generate initial values of things
game.damfac = 0.5 * game.skill
game.inbase = rnd.integer(BASEMIN, BASEMAX+1)
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
game = Gamestate()
rnd = randomizer()
logfp = None
- game.options = OPTION_ALL &~ (OPTION_IOMODES | OPTION_PLAIN)
+ game.options = OPTION_ALL &~ OPTION_IOMODES
if os.getenv("TERM"):
game.options |= OPTION_CURSES # pragma: no cover
else:
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:]
+ while True:
+ line = replayfp.readline().strip()
+ print(line)
+ if line == "#":
+ break
+ if line.startswith("# seed"):
+ (__, __, seed) = line.split()
+ # pylint: disable=eval-used
+ seed = eval(seed)
+ elif line.startswith("# arguments"):
+ arguments += line.split()[2:]
except ValueError: # pragma: no cover
sys.stderr.write("sst: replay file %s is ill-formed\n"% val)
raise SystemExit(1)
logfp.write("# SST2K version %s\n" % version)
logfp.write("# recorded by %s@%s on %s\n" % \
(getpass.getuser(),socket.getfqdn(),time.ctime()))
+ logfp.write("#\n")
rnd.seed(seed)
scanner = sstscanner()
for arg in arguments: