X-Git-Url: https://jxself.org/git/?a=blobdiff_plain;f=sst;h=cebcad1af65111eafa439357db791339bd1212a8;hb=8530f073f790a012b79facf6d02d943add67d933;hp=c11e661b431bcaa467dd2554fb5674cc5beda2bb;hpb=fc8da2f955459e49dfa48ff42354243ef0d5d429;p=super-star-trek.git diff --git a/sst b/sst index c11e661..cebcad1 100755 --- a/sst +++ b/sst @@ -18,7 +18,7 @@ on how to modify (and how not to modify!) this code. # pylint: disable=multiple-imports import os, sys, math, curses, time, pickle, copy, gettext, getpass -import getopt, socket, locale +import getopt, socket import codecs # This import only works on Unixes. The intention is to enable @@ -88,6 +88,14 @@ class randomizer: # logfp.write("#seed(%d)\n" % n) game.lcg_x = n % randomizer.LCG_M + @staticmethod + def getrngstate(): + return game.lcg_x + + @staticmethod + def setrngstate(n): + game.lcg_x = n + GALSIZE = 8 # Galaxy size in quadrants NINHAB = (GALSIZE * GALSIZE // 2) # Number of inhabited worlds MAXUNINHAB = 10 # Maximum uninhabited worlds @@ -163,9 +171,9 @@ class Coord: return Coord(self.i//other, self.j//other) def __mod__(self, other): return Coord(self.i % other, self.j % other) - def __rtruediv__(self, other): + def __rtruediv__(self, other): # pragma: no cover return Coord(self.i/other, self.j/other) - def __rfloordiv__(self, other): + def __rfloordiv__(self, other): # pragma: no cover return Coord(self.i//other, self.j//other) def roundtogrid(self): return Coord(int(round(self.i)), int(round(self.j))) @@ -195,11 +203,6 @@ class Coord: return self.roundtogrid() // QUADSIZE def sector(self): return self.roundtogrid() % QUADSIZE - def scatter(self): - s = Coord() - s.i = self.i + rnd.integer(-1, 2) - s.j = self.j + rnd.integer(-1, 2) - return s def __str__(self): if self.i is None or self.j is None: return "Nowhere" # pragma: no cover @@ -208,15 +211,12 @@ class Coord: return "%s - %s" % (self.i+1, self.j+1) __repr__ = __str__ -class Thingy(Coord): +class Thingy(): "Do not anger the Space Thingy!" def __init__(self): - Coord.__init__(self) - self.angered = False - def angry(self): - self.angered = True + self.location = Coord() def at(self, q): - return (q.i, q.j) == (self.i, self.j) + return (q.i, q.j) == (self.location.i, self.location.j) class Planet: def __init__(self): @@ -240,7 +240,7 @@ class Quadrant: self.charted = False self.status = "secure" # Could be "secure", "distressed", "enslaved" def __str__(self): - return "" % self.__dict__ + return "" % self.__dict__ # pragma: no cover __repr__ = __str__ class Page: @@ -296,21 +296,20 @@ OPTION_ALL = 0xffffffff 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_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_PLAIN = 0x01000000 # user chose plain game -OPTION_ALMY = 0x02000000 # user chose Almy variant 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) @@ -320,12 +319,11 @@ option_names = { "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, @@ -333,9 +331,9 @@ option_names = { "CAPTURE": OPTION_CAPTURE, "CLOAK": OPTION_CLOAK, "PLAIN": OPTION_PLAIN, - "ALMY": OPTION_ALMY, "COLOR": OPTION_COLOR, "DOTFILL": OPTION_DOTFILL, + "ALPHAMERIC": OPTION_ALPHAMERIC, } # Define devices @@ -421,7 +419,7 @@ class Enemy: game.enemies.remove(self) return motion def __repr__(self): - return "<%s,%s.%f>" % (self.type, self.location, self.power) # pragma: no cover + return "<%s,%s,%f>" % (self.type, self.location, self.power) # pragma: no cover class Gamestate: def __init__(self): @@ -685,7 +683,7 @@ def movebaddy(enemy): 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 [] @@ -702,7 +700,7 @@ def movebaddy(enemy): 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): @@ -714,7 +712,7 @@ def movebaddy(enemy): # 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: @@ -762,11 +760,11 @@ def movebaddy(enemy): 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)] @@ -842,7 +840,7 @@ def supercommander(): 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) @@ -973,7 +971,7 @@ def movetholian(): elif game.tholian.location.i == QUADSIZE-1 and game.tholian.location.j == 0: tid.i = 0 tid.j = 0 - else: + else: # pragma: no cover # something is wrong! game.tholian.move(None) prout("***Internal error: Tholian in a bad spot.") @@ -1246,7 +1244,7 @@ def collision(rammed, enemy): proutn(_(" (original position)")) skip(1) deadkl(enemy.location, enemy.type, game.sector) - proutn("***" + crmshp() + " heavily damaged.") + prout("***" + crmshp() + " heavily damaged.") icas = rnd.integer(10, 30) prout(_("***Sickbay reports %d casualties") % icas) game.casual += icas @@ -1417,21 +1415,15 @@ def torpedo(origin, bearing, dispersion, number, nburst): 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) @@ -1550,7 +1542,7 @@ def attack(torps_ok): 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 @@ -1570,7 +1562,7 @@ def attack(torps_ok): 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 \ @@ -1913,8 +1905,6 @@ def hittem(hits): 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: @@ -2607,8 +2597,8 @@ def events(): 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)) @@ -3412,11 +3402,6 @@ curwnd = None def iostart(): global stdscr, rows - # for some recent versions of python2, the following enables UTF8 - # for the older ones we probably need to set C locale, and python3 - # has no problems at all - if sys.version_info[0] < 3: - locale.setlocale(locale.LC_ALL, "") gettext.bindtextdomain("sst", "/usr/local/share/locale") gettext.textdomain("sst") if not (game.options & OPTION_CURSES): @@ -3425,7 +3410,7 @@ def iostart(): rows = ln_env else: rows = 25 - else: + else: # pragma: no cover stdscr = curses.initscr() stdscr.keypad(True) curses.nonl() @@ -3456,7 +3441,7 @@ def iostart(): def ioend(): "Wrap up I/O." - if game.options & OPTION_CURSES: + if game.options & OPTION_CURSES: # pragma: no cover stdscr.keypad(False) curses.echo() curses.nocbreak() @@ -3464,7 +3449,7 @@ def ioend(): def waitfor(): "Wait for user action -- OK to do nothing if on a TTY" - if game.options & OPTION_CURSES: + if game.options & OPTION_CURSES: # pragma: no cover stdscr.getch() def announce(): @@ -3478,7 +3463,7 @@ def pause_game(): else: prompt = _("[PRESS ENTER TO CONTINUE]") - if game.options & OPTION_CURSES: + if game.options & OPTION_CURSES: # pragma: no cover drawmaps(0) setwnd(prompt_window) prompt_window.clear() @@ -3499,7 +3484,7 @@ def pause_game(): def skip(i): "Skip i lines. Pause game if this would cause a scrolling event." for _dummy in range(i): - if game.options & OPTION_CURSES: + if game.options & OPTION_CURSES: # pragma: no cover (y, _x) = curwnd.getyx() try: curwnd.move(y+1, 0) @@ -3515,7 +3500,7 @@ def skip(i): def proutn(proutntline): "Utter a line with no following line feed." - if game.options & OPTION_CURSES: + if game.options & OPTION_CURSES: # pragma: no cover (y, x) = curwnd.getyx() (my, _mx) = curwnd.getmaxyx() if curwnd == message_window and y >= my - 2: @@ -3539,7 +3524,7 @@ def prouts(proutsline): if not replayfp or replayfp.closed: # Don't slow down replays time.sleep(0.03) proutn(c) - if game.options & OPTION_CURSES: + if game.options & OPTION_CURSES: # pragma: no cover curwnd.refresh() else: sys.stdout.flush() @@ -3548,7 +3533,7 @@ def prouts(proutsline): def cgetline(): "Get a line of input." - if game.options & OPTION_CURSES: + if game.options & OPTION_CURSES: # pragma: no cover linein = codecs.decode(curwnd.getstr()) + "\n" curwnd.refresh() else: @@ -3556,7 +3541,7 @@ def cgetline(): while True: linein = replayfp.readline() proutn(linein) - if linein == '': + if linein == '': # pragma: no cover prout("*** Replay finished") replayfp.close() break @@ -3575,7 +3560,7 @@ def cgetline(): def setwnd(wnd): "Change windows -- OK for this to be a no-op in tty mode." global curwnd - if game.options & OPTION_CURSES: + if game.options & OPTION_CURSES: # pragma: no cover if game.cdebug and logfp: if wnd == fullscreen_window: legend = "fullscreen" @@ -3603,21 +3588,21 @@ def setwnd(wnd): def clreol(): "Clear to end of line -- can be a no-op in tty mode" - if game.options & OPTION_CURSES: + if game.options & OPTION_CURSES: # pragma: no cover curwnd.clrtoeol() curwnd.refresh() def clrscr(): "Clear screen -- can be a no-op in tty mode." global linecount - if game.options & OPTION_CURSES: + if game.options & OPTION_CURSES: # pragma: no cover curwnd.clear() curwnd.move(0, 0) curwnd.refresh() linecount = 0 def textcolor(color=DEFAULT): - if (game.options & OPTION_COLOR) and (game.options & OPTION_CURSES): + if (game.options & OPTION_COLOR) and (game.options & OPTION_CURSES): # pragma: no cover if color == DEFAULT: curwnd.attrset(0) elif color == BLACK: @@ -3654,7 +3639,7 @@ def textcolor(color=DEFAULT): curwnd.attron(curses.color_pair(curses.COLOR_WHITE) | curses.A_BOLD) def highvideo(): - if (game.options & OPTION_COLOR) and (game.options & OPTION_CURSES): + if (game.options & OPTION_COLOR) and (game.options & OPTION_CURSES): # pragma: no cover curwnd.attron(curses.A_REVERSE) # @@ -3663,7 +3648,7 @@ def highvideo(): def drawmaps(mode): "Hook to be called after moving to redraw maps." - if game.options & OPTION_CURSES: + if game.options & OPTION_CURSES: # pragma: no cover if mode == 1: sensor() setwnd(srscan_window) @@ -3682,7 +3667,7 @@ def drawmaps(mode): lrscan_window.move(0, 0) lrscan(silent=False) -def put_srscan_sym(w, sym): +def put_srscan_sym(w, sym): # pragma: no cover "Emit symbol for short-range scan." srscan_window.move(w.i+1, w.j*2+2) srscan_window.addch(sym) @@ -3690,7 +3675,7 @@ def put_srscan_sym(w, sym): def boom(w): "Enemy fall down, go boom." - if game.options & OPTION_CURSES: + if game.options & OPTION_CURSES: # pragma: no cover drawmaps(0) setwnd(srscan_window) srscan_window.attron(curses.A_REVERSE) @@ -3705,12 +3690,12 @@ def boom(w): def warble(): "Sound and visual effects for teleportation." - if game.options & OPTION_CURSES: + if game.options & OPTION_CURSES: # pragma: no cover drawmaps(2) setwnd(message_window) #sound(50) prouts(" . . . . . ") - if game.options & OPTION_CURSES: + if game.options & OPTION_CURSES: # pragma: no cover #curses.delay_output(1000) #nosound() pass @@ -3728,7 +3713,7 @@ def tracktorpedo(w, step, i, n, iquad): elif step in {4, 9}: skip(1) proutn("%s " % w) - else: + else: # pragma: no cover if not damaged(DSRSENS) or game.condition=="docked": if i != 0 and step == 1: drawmaps(2) @@ -3752,7 +3737,7 @@ def tracktorpedo(w, step, i, n, iquad): def makechart(): "Display the current galaxy chart." - if game.options & OPTION_CURSES: + if game.options & OPTION_CURSES: # pragma: no cover setwnd(message_window) message_window.clear() chart() @@ -3763,14 +3748,14 @@ NSYM = 14 def prstat(txt, data): proutn(txt) - if game.options & OPTION_CURSES: + if game.options & OPTION_CURSES: # pragma: no cover skip(1) setwnd(status_window) else: proutn(" " * (NSYM - len(txt))) proutn(data) skip(1) - if game.options & OPTION_CURSES: + if game.options & OPTION_CURSES: # pragma: no cover setwnd(report_window) # Code from moving.c begins here @@ -3843,12 +3828,12 @@ def imove(icourse=None, noattack=False): stopegy = 50.0*icourse.distance/game.optime if iquad in ('T', 'K', 'C', 'S', 'R', '?'): for enemy in game.enemies: - if enemy.location == game.sector: + if enemy.location == h: collision(rammed=False, enemy=enemy) return True # This should not happen - prout(_("Which way did he go?")) - return False + prout(_("Which way did he go?")) # pragma: no cover + return False # pragma: no cover elif iquad == ' ': skip(1) prouts(_("***RED ALERT! RED ALERT!")) @@ -4271,7 +4256,7 @@ def warp(wcourse, involuntary): # 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(): @@ -4590,7 +4575,7 @@ def mayday(): break prout(_("fails.")) textcolor(DEFAULT) - if game.options & OPTION_CURSES: + if game.options & OPTION_CURSES: # pragma: no cover curses.delay_output(500) if m > 3: game.quad[game.sector.i][game.sector.j]='?' @@ -5306,8 +5291,8 @@ def damagereport(): for i in range(NDEVICES): if damaged(i): if not jdam: - prout(_("\tDEVICE\t\t\t-REPAIR TIMES-")) - prout(_("\t\t\tIN FLIGHT\t\tDOCKED")) + prout(_("DEVICE REPAIR TIMES")) + prout(_(" IN FLIGHT DOCKED")) jdam = True prout(" %-26s\t%8.2f\t\t%8.2f" % (device[i], game.damage[i]+0.05, @@ -5373,7 +5358,7 @@ def sectscan(goodScan, i, j): if goodScan or (abs(i-game.sector.i)<= 1 and abs(j-game.sector.j) <= 1): if game.quad[i][j] in ('E', 'F'): if game.iscloaked: - highvideo() + highvideo() # pragma: no cover textcolor({"green":GREEN, "yellow":YELLOW, "red":RED, @@ -5634,11 +5619,11 @@ def goptions(): else: prout(_("No such option as ") + scanner.token) if mode == "set": - if (not (game.options & OPTION_CURSES)) and (changemask & OPTION_CURSES): + if (not (game.options & OPTION_CURSES)) and (changemask & OPTION_CURSES): # pragma: no cover iostart() game.options |= changemask elif mode == "clear": - if (game.options & OPTION_CURSES) and (not (changemask & OPTION_CURSES)): + if (game.options & OPTION_CURSES) and (not (changemask & OPTION_CURSES)): # pragma: no cover ioend() game.options &=~ changemask prout(_("Acknowledged, Captain.")) @@ -5830,7 +5815,7 @@ def setup(): 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: @@ -5846,15 +5831,15 @@ def setup(): 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 @@ -5940,12 +5925,17 @@ def setup(): # Place thing (in tournament game, we don't want one!) # New in SST2K: never place the Thing near a starbase. # This makes sense and avoids a special case in the old code. - global thing if game.tourn is None: + # Avoid distrubing the RNG chain. This code + # was a late fix and we don't want to mess up + # all the regression tests. + state = randomizer.getrngstate() while True: - thing = randplace(GALSIZE) - if thing not in game.state.baseq: + thing.location = randplace(GALSIZE) + # Put it somewhere a starbase is not + if thing.location not in game.state.baseq: break + randomizer.setrngstate(state) skip(2) game.state.snap = False if game.skill == SKILL_NOVICE: @@ -5981,7 +5971,7 @@ def setup(): clrscr() setwnd(message_window) newqad() - if len(game.enemies) - (thing == game.quadrant) - (game.tholian is not None): + if len(game.enemies) - (thing.location == game.quadrant) - (game.tholian is not None): game.shldup = True if game.neutz: # bad luck to start in a Romulan Neutral Zone attack(torps_ok=False) @@ -5989,7 +5979,8 @@ def setup(): def choose(): "Choose your game type." while True: - game.tourn = game.length = 0 + game.tourn = None + game.length = 0 game.thawed = False game.skill = SKILL_NONE # Do not chew here, we want to use command-line tokens @@ -5997,6 +5988,7 @@ def choose(): proutn(_("Would you like a regular, tournament, or saved game? ")) scanner.nexttok() if scanner.sees("tournament"): + game.tourn = 0 while scanner.nexttok() == "IHEOL": proutn(_("Type in tournament number-")) if scanner.real == 0: @@ -6057,12 +6049,11 @@ def choose(): 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_THOLIAN | OPTION_PLANETS | OPTION_PROBE | OPTION_RAMMING | OPTION_MVBADDY | OPTION_BLKHOLE | OPTION_BASE | OPTION_WORLDS | OPTION_COLOR | OPTION_CAPTURE | OPTION_CLOAK | OPTION_AUTOPASS | OPTION_DOTFILL | OPTION_ALPHAMERIC) game.options |= OPTION_PLAIN 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): @@ -6184,7 +6175,7 @@ def newqad(): prout(_("INTRUDER! YOU HAVE VIOLATED THE ROMULAN NEUTRAL ZONE.")) prout(_("LEAVE AT ONCE, OR YOU WILL BE DESTROYED!")) # Put in THING if needed - if thing == game.quadrant: + if thing.location == game.quadrant: Enemy(etype='?', loc=dropin(), power=rnd.real(6000,6500.0)+250.0*game.skill) if not damaged(DSRSENS): @@ -6237,7 +6228,12 @@ def newqad(): 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- ")) @@ -6246,11 +6242,6 @@ def setpassword(): #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 @@ -6387,7 +6378,7 @@ def makemoves(): clrscr() proutn("COMMAND> ") if scanner.nexttok() == "IHEOL": - if game.options & OPTION_CURSES: + if game.options & OPTION_CURSES: # pragma: no cover makechart() continue elif scanner.token == "": @@ -6413,7 +6404,7 @@ def makemoves(): huh() else: break - if game.options & OPTION_CURSES: + if game.options & OPTION_CURSES: # pragma: no cover prout("COMMAND> %s" % cmd) if cmd == "SRSCAN": # srscan srscan() @@ -6521,7 +6512,7 @@ def makemoves(): helpme() # get help elif cmd == "SCORE": score() # see current score - elif cmd == "CURSES": + elif cmd == "CURSES": # pragma: no cover game.options |= (OPTION_CURSES | OPTION_COLOR) iostart() elif cmd == "OPTIONS": @@ -6548,7 +6539,7 @@ def makemoves(): 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." @@ -6713,7 +6704,7 @@ def debugme(): # pragma: no cover 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") @@ -6791,49 +6782,53 @@ if __name__ == '__main__': game = Gamestate() rnd = randomizer() logfp = None - game.options = OPTION_ALL &~ (OPTION_IOMODES | OPTION_PLAIN | OPTION_ALMY) + game.options = OPTION_ALL &~ (OPTION_IOMODES | OPTION_PLAIN) if os.getenv("TERM"): - game.options |= OPTION_CURSES + 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': - 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']