Add color. Turns out SCORE was implemented already.
[super-star-trek.git] / sst.py
diff --git a/sst.py b/sst.py
index cf32126f814a658cd22307d48f188e35636b2809..df431649e1c0a0579f0f336a4d4b6ce1aa819130 100755 (executable)
--- a/sst.py
+++ b/sst.py
@@ -11,7 +11,8 @@ Stas Sergeev, and Eric S. Raymond.
 See the doc/HACKING file in the distribution for designers notes and advice
 on how to modify (and how not to modify!) this code.
 """
-import os, sys, math, curses, time, readline, pickle, random, copy, gettext, getpass
+import os, sys, math, curses, time, pickle, random, copy, gettext, getpass
+import getopt, socket, locale
 
 # This import only works on Unixes.  The intention is to enable
 # Ctrl-P, Ctrl-N, and friends in Cmd.
@@ -22,7 +23,7 @@ except ImportError:
 
 version = "2.1"
 
-docpath        = (".", "../doc", "/usr/share/doc/sst")
+docpath        = (".", "doc/", "/usr/share/doc/sst/")
 
 def _(st):
     return gettext.gettext(st)
@@ -211,22 +212,22 @@ class Event:
 # game options
 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_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_PLAIN        = 0x01000000        # user chose plain game
-OPTION_ALMY        = 0x02000000        # user chose Almy variant
-OPTION_COLOR    = 0x04000000        # enable color display (experimental, ESR, 2010)
+OPTION_CURSES     = 0x00000002        # new interface
+OPTION_IOMODES    = 0x00000003        # cover both interfaces
+OPTION_PLANETS    = 0x00000004        # planets and mining
+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_PLAIN      = 0x01000000        # user chose plain game
+OPTION_ALMY       = 0x02000000        # user chose Almy variant
+OPTION_COLOR      = 0x04000000        # enable color display (ESR, 2010)
 
 # Define devices
 DSRSENS         = 0
@@ -489,7 +490,7 @@ def tryexit(enemy, look, irun):
                 game.state.kcmdr.append(iq)
                 break
     # report move out of quadrant.
-    return [(True, enemy, oldloc, ibq)]
+    return [(True, enemy, oldloc, iq)]
 
 # The bad-guy movement algorithm:
 #
@@ -1741,9 +1742,9 @@ def phasers():
     no = False
     itarg = True
     msgflag = True
-    rpow = 0
+    rpow = 0.0
     automode = "NOTSET"
-    key = 0
+    key = ""
     skip(1)
     # SR sensors and Computer are needed for automode
     if damaged(DSRSENS) or damaged(DCOMPTR):
@@ -2234,16 +2235,16 @@ def events():
                 unschedule(FBATTAK)
                 unschedule(FCDBAS)
                 continue
+            ibq = None # Force battle location to persist past loop
             try:
                 for ibq in game.state.baseq:
                     for cmdr in game.state.kcmdr:
                         if ibq == cmdr and ibq != game.quadrant and ibq != game.state.kscmdr:
                             raise JumpOut
-                else:
-                    # no match found -- try later
-                    schedule(FBATTAK, expran(0.3*game.intime))
-                    unschedule(FCDBAS)
-                    continue
+                # no match found -- try later
+                schedule(FBATTAK, expran(0.3*game.intime))
+                unschedule(FCDBAS)
+                continue
             except JumpOut:
                 pass
             # commander + starbase combination found -- launch attack
@@ -2398,8 +2399,8 @@ def events():
                             if q.klingons >= MAXKLQUAD or q.supernova:
                                 continue
                             raise JumpOut
-                    else:
-                        continue        # search for eligible quadrant failed
+                    # search for eligible quadrant failed
+                    continue
                 except JumpOut:
                     w = m
             # deliver the child
@@ -2469,7 +2470,7 @@ def wait():
         if game.state.galaxy[game.quadrant.i][game.quadrant.j].supernova:
             break
     game.resting = False
-    game.optime = 0
+    game.optime = 0.0
 
 def nova(nov):
     "Star goes nova."
@@ -2558,33 +2559,37 @@ def nova(nov):
                 elif iquad == 'K': # kill klingon
                     deadkl(neighbor, iquad, neighbor)
                 elif iquad in ('C','S','R'): # Damage/destroy big enemies
+                    target = None
                     for ll in range(len(game.enemies)):
                         if game.enemies[ll].location == neighbor:
+                            target = game.enemies[ll]
                             break
-                    game.enemies[ll].power -= 800.0 # If firepower is lost, die
-                    if game.enemies[ll].power <= 0.0:
-                        deadkl(neighbor, iquad, neighbor)
-                        break
-                    newc = neighbor + neighbor - hits[-1]
-                    proutn(crmena(True, iquad, "sector", neighbor) + _(" damaged"))
-                    if not newc.valid_sector():
-                        # can't leave quadrant
-                        skip(1)
-                        break
-                    iquad1 = game.quad[newc.i][newc.j]
-                    if iquad1 == ' ':
-                        proutn(_(", blasted into ") + crmena(False, ' ', "sector", newc))
-                        skip(1)
-                        deadkl(neighbor, iquad, newc)
-                        break
-                    if iquad1 != '.':
-                        # can't move into something else
-                        skip(1)
-                        break
-                    proutn(_(", buffeted to Sector %s") % newc)
-                    game.quad[neighbor.i][neighbor.j] = '.'
-                    game.quad[newc.i][newc.j] = iquad
-                    game.enemies[ll].move(newc)
+                    if target is not None:
+                        target.power -= 800.0 # If firepower is lost, die
+                        if target.power <= 0.0:
+                            deadkl(neighbor, iquad, neighbor)
+                            continue   # neighbor loop
+                        # Else enemy gets flung by the blast wave
+                        newc = neighbor + neighbor - hits[-1]
+                        proutn(crmena(True, iquad, "sector", neighbor) + _(" damaged"))
+                        if not newc.valid_sector():
+                            # can't leave quadrant
+                            skip(1)
+                            continue
+                        iquad1 = game.quad[newc.i][newc.j]
+                        if iquad1 == ' ':
+                            proutn(_(", blasted into ") + crmena(False, ' ', "sector", newc))
+                            skip(1)
+                            deadkl(neighbor, iquad, newc)
+                            continue
+                        if iquad1 != '.':
+                            # can't move into something else
+                            skip(1)
+                            continue
+                        proutn(_(", buffeted to Sector %s") % newc)
+                        game.quad[neighbor.i][neighbor.j] = '.'
+                        game.quad[newc.i][newc.j] = iquad
+                        target.move(newc)
     # Starship affected by nova -- kick it away.
     dist = kount*0.1
     direc = ncourse[3*(bump.i+1)+bump.j+2]
@@ -2593,11 +2598,11 @@ def nova(nov):
     if dist == 0.0:
         return
     scourse = course(bearing=direc, distance=dist)
-    game.optime = scourse.time(warp=4)
+    game.optime = scourse.time(w=4)
     skip(1)
     prout(_("Force of nova displaces starship."))
     imove(scourse, noattack=True)
-    game.optime = scourse.time(warp=4)
+    game.optime = scourse.time(w=4)
     return
 
 def supernova(w):
@@ -2607,14 +2612,14 @@ def supernova(w):
         nq = copy.copy(w)
     else:
         # Scheduled supernova -- select star at random.
-        stars = 0
+        nstars = 0
         nq = Coord()
         for nq.i in range(GALSIZE):
             for nq.j in range(GALSIZE):
-                stars += game.state.galaxy[nq.i][nq.j].stars
+                nstars += game.state.galaxy[nq.i][nq.j].stars
         if stars == 0:
             return # nothing to supernova exists
-        num = randrange(stars) + 1
+        num = randrange(nstars) + 1
         for nq.i in range(GALSIZE):
             for nq.j in range(GALSIZE):
                 num -= game.state.galaxy[nq.i][nq.j].stars
@@ -3131,11 +3136,10 @@ 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 the python3"
-    "has no problems at all"
+    # 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:
-        import locale
         locale.setlocale(locale.LC_ALL, "")
     gettext.bindtextdomain("sst", "/usr/local/share/locale")
     gettext.textdomain("sst")
@@ -3163,7 +3167,7 @@ def iostart():
             curses.init_pair(curses.COLOR_YELLOW,  curses.COLOR_YELLOW, -1)
         global fullscreen_window, srscan_window, report_window, status_window
         global lrscan_window, message_window, prompt_window
-        (rows, columns)   = stdscr.getmaxyx()
+        (rows, _columns)   = stdscr.getmaxyx()
         fullscreen_window = stdscr
         srscan_window     = curses.newwin(12, 25, 0,       0)
         report_window     = curses.newwin(11, 0,  1,       25)
@@ -3218,9 +3222,9 @@ def pause_game():
 
 def skip(i):
     "Skip i lines.  Pause game if this would cause a scrolling event."
-    for dummy in range(i):
+    for _dummy in range(i):
         if game.options & OPTION_CURSES:
-            (y, x) = curwnd.getyx()
+            (y, _x) = curwnd.getyx()
             try:
                 curwnd.move(y+1, 0)
             except curses.error:
@@ -3233,30 +3237,30 @@ def skip(i):
             else:
                 sys.stdout.write('\n')
 
-def proutn(line):
+def proutn(proutntline):
     "Utter a line with no following line feed."
     if game.options & OPTION_CURSES:
         (y, x) = curwnd.getyx()
-        (my, mx) = curwnd.getmaxyx()
+        (my, _mx) = curwnd.getmaxyx()
         if curwnd == message_window and y >= my - 2:
             pause_game()
             clrscr()
         # Uncomment this to debug curses problems
         if logfp:
-            logfp.write("#curses: at %s proutn(%s)\n" % ((y, x), repr(line)))
-        curwnd.addstr(line)
+            logfp.write("#curses: at %s proutn(%s)\n" % ((y, x), repr(proutntline)))
+        curwnd.addstr(proutntline)
         curwnd.refresh()
     else:
-        sys.stdout.write(line)
+        sys.stdout.write(proutntline)
         sys.stdout.flush()
 
-def prout(line):
-    proutn(line)
+def prout(proutline):
+    proutn(proutline)
     skip(1)
 
-def prouts(line):
+def prouts(proutsline):
     "Emit slowly!"
-    for c in line:
+    for c in proutsline:
         if not replayfp or replayfp.closed:        # Don't slow down replays
             time.sleep(0.03)
         proutn(c)
@@ -3270,24 +3274,24 @@ def prouts(line):
 def cgetline():
     "Get a line of input."
     if game.options & OPTION_CURSES:
-        line = curwnd.getstr() + "\n"
+        linein = curwnd.getstr() + "\n"
         curwnd.refresh()
     else:
         if replayfp and not replayfp.closed:
             while True:
-                line = replayfp.readline()
-                proutn(line)
-                if line == '':
+                linein = replayfp.readline()
+                proutn(linein)
+                if linein == '':
                     prout("*** Replay finished")
                     replayfp.close()
                     break
-                elif line[0] != "#":
+                elif linein[0] != "#":
                     break
         else:
-            line = eval(input()) + "\n"
+            linein = eval(input()) + "\n"
     if logfp:
-        logfp.write(line)
-    return line
+        logfp.write(linein)
+    return linein
 
 def setwnd(wnd):
     "Change windows -- OK for this to be a no-op in tty mode."
@@ -3515,6 +3519,8 @@ def imove(icourse=None, noattack=False):
         # check for edge of galaxy
         kinks = 0
         while True:
+
+
             kink = False
             if icourse.final.i < 0:
                 icourse.final.i = -icourse.final.i
@@ -3562,9 +3568,11 @@ def imove(icourse=None, noattack=False):
             if iquad in ('T', 'K', 'C', 'S', 'R', '?'):
                 for enemy in game.enemies:
                     if enemy.location == game.sector:
-                        break
-                collision(rammed=False, enemy=enemy)
-                return True
+                        collision(rammed=False, enemy=enemy)
+                        return True
+                # This should not happen
+                prout(_("Which way did he go?"))
+                return False
             elif iquad == ' ':
                 skip(1)
                 prouts(_("***RED ALERT!  RED ALERT!"))
@@ -3612,7 +3620,7 @@ def imove(icourse=None, noattack=False):
         game.optime = scheduled(FTBEAM) - game.state.date + 1e-5
     # Move out
     game.quad[game.sector.i][game.sector.j] = '.'
-    for m in range(icourse.moves):
+    for _m in range(icourse.moves):
         icourse.nexttok()
         w = icourse.sector()
         if icourse.origin.quadrant() != icourse.location.quadrant():
@@ -3653,7 +3661,7 @@ def dock(verbose):
         prout(crmshp() + _(" not adjacent to base."))
         return
     game.condition = "docked"
-    if "verbose":
+    if verbose:
         prout(_("Docked."))
     game.ididit = True
     if game.energy < game.inenrg:
@@ -3679,7 +3687,7 @@ def cartesian(loc1=None, loc2=None):
 
 def getcourse(isprobe):
     "Get a course and distance from the user."
-    key = 0
+    key = ""
     dquad = copy.copy(game.quadrant)
     navmode = "unspecified"
     itemp = "curt"
@@ -3821,16 +3829,14 @@ class course:
         if self.bearing < 0.0:
             self.bearing += 12.0
         self.angle = ((15.0 - self.bearing) * 0.5235988)
-        if origin is None:
-            self.origin = cartesian(game.quadrant, game.sector)
-        else:
-            self.origin = cartesian(game.quadrant, origin)
         self.increment = Coord(-math.sin(self.angle), math.cos(self.angle))
         bigger = max(abs(self.increment.i), abs(self.increment.j))
         self.increment /= bigger
         self.moves = int(round(10*self.distance*bigger))
         self.reset()
         self.final = (self.location + self.moves*self.increment).roundtogrid()
+        self.location = self.origin
+        self.nextlocation = None
     def reset(self):
         self.location = self.origin
         self.step = 0
@@ -3847,10 +3853,10 @@ class course:
         return self.location.quadrant()
     def sector(self):
         return self.location.sector()
-    def power(self, warp):
-        return self.distance*(warp**3)*(game.shldup+1)
-    def time(self, warp):
-        return 10.0*self.distance/warp**2
+    def power(self, w):
+        return self.distance*(w**3)*(game.shldup+1)
+    def time(self, w):
+        return 10.0*self.distance/w**2
 
 def impulse():
     "Move under impulse power."
@@ -3862,10 +3868,10 @@ def impulse():
         return
     if game.energy > 30.0:
         try:
-            course = getcourse(isprobe=False)
+            icourse = getcourse(isprobe=False)
         except TrekError:
             return
-        power = 20.0 + 100.0*course.distance
+        power = 20.0 + 100.0*icourse.distance
     else:
         power = 30.0
     if power >= game.energy:
@@ -3882,7 +3888,7 @@ def impulse():
         scanner.chew()
         return
     # Make sure enough time is left for the trip
-    game.optime = course.distance/0.095
+    game.optime = icourse.distance/0.095
     if game.optime >= game.state.remtime:
         prout(_("First Officer Spock- \"Captain, our speed under impulse"))
         prout(_("power is only 0.95 sectors per stardate. Are you sure"))
@@ -3890,13 +3896,13 @@ def impulse():
         if not ja():
             return
     # Activate impulse engines and pay the cost
-    imove(course, noattack=False)
+    imove(icourse, noattack=False)
     game.ididit = True
     if game.alldone:
         return
-    power = 20.0 + 100.0*course.distance
+    power = 20.0 + 100.0*icourse.distance
     game.energy -= power
-    game.optime = course.distance/0.095
+    game.optime = icourse.distance/0.095
     if game.energy <= 0:
         finish(FNRG)
     return
@@ -4247,11 +4253,15 @@ def mayday():
         # There's one in this quadrant
         ddist = (game.base - game.sector).distance()
     else:
+        ibq = None     # Force base-quadrant game to persist past loop
         ddist = FOREVER
         for ibq in game.state.baseq:
             xdist = QUADSIZE * (ibq - game.quadrant).distance()
             if xdist < ddist:
                 ddist = xdist
+        if ibq is None:
+            prout(_("No starbases remain. You are alone in a hostile galaxy."))
+            return
         # Since starbase not in quadrant, set up new quadrant
         game.quadrant = ibq
         newqad()
@@ -4363,12 +4373,13 @@ def abandon():
         while True:
             # position next to base by trial and error
             game.quad[game.sector.i][game.sector.j] = '.'
+            l = QUADSIZE
             for l in range(QUADSIZE):
                 game.sector = game.base.scatter()
                 if game.sector.valid_sector() and \
                        game.quad[game.sector.i][game.sector.j] == '.':
                     break
-            if l < QUADSIZE+1:
+            if l < QUADSIZE:
                 break # found a spot
             game.sector.i=QUADSIZE/2
             game.sector.j=QUADSIZE/2
@@ -4930,7 +4941,7 @@ def report():
             proutn(_("An armed deep space probe is in "))
         else:
             proutn(_("A deep space probe is in "))
-        prout("Quadrant %s." % game.probec)
+        prout("Quadrant %s." % game.probe.quadrant())
     if game.icrystl:
         if game.cryprob <= .05:
             prout(_("Dilithium crystals aboard ship... not yet used."))
@@ -5043,13 +5054,20 @@ def chart():
 def sectscan(goodScan, i, j):
     "Light up an individual dot in a sector."
     if goodScan or (abs(i-game.sector.i)<= 1 and abs(j-game.sector.j) <= 1):
-        textcolor({"green":GREEN,
-                   "yellow":YELLOW,
-                   "red":RED,
-                   "docked":CYAN,
-                   "dead":BROWN}[game.condition])
-        if game.quad[i][j] != game.ship:
-            highvideo()
+        if game.quad[i][j] in ('E', 'F'):
+            textcolor({"green":GREEN,
+                       "yellow":YELLOW,
+                       "red":RED,
+                       "docked":CYAN,
+                       "dead":BROWN}[game.condition])
+        else:
+            textcolor({'?':LIGHTMAGENTA,
+                       'K':LIGHTRED,
+                       'S':LIGHTRED,
+                       'C':LIGHTRED,
+                       'R':LIGHTRED,
+                       'T':LIGHTRED,
+                       }.get(game.quad[i][j], DEFAULT))
         proutn("%c " % game.quad[i][j])
         textcolor(DEFAULT)
     else:
@@ -5680,17 +5698,16 @@ 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)
+        game.options &=~ (OPTION_THOLIAN | OPTION_PLANETS | OPTION_THINGY | OPTION_PROBE | OPTION_RAMMING | OPTION_MVBADDY | OPTION_BLKHOLE | OPTION_BASE | OPTION_WORLDS | OPTION_COLOR)
         game.options |= OPTION_PLAIN
     elif scanner.sees("almy"):
         # Approximates Tom Almy's version.
-        game.options &=~ (OPTION_THINGY | OPTION_BLKHOLE | OPTION_BASE | OPTION_WORLDS)
+        game.options &=~ (OPTION_THINGY | OPTION_BLKHOLE | OPTION_BASE | OPTION_WORLDS | OPTION_COLOR)
         game.options |= OPTION_ALMY
     elif scanner.sees("fancy") or scanner.sees("\n"):
         pass
     elif len(scanner.token):
         proutn(_("What is \"%s\"?") % scanner.token)
-    game.options &=~ OPTION_COLOR
     setpassword()
     if game.passwd == "debug":
         game.idebug = True
@@ -5766,7 +5783,7 @@ def newqad():
     game.enemies = []
     if q.klingons:
         # Position ordinary Klingons
-        for i in range(game.klhere):
+        for _i in range(game.klhere):
             newkling()
         # If we need a commander, promote a Klingon
         for cmdr in game.state.kcmdr:
@@ -5782,7 +5799,7 @@ def newqad():
             e.power = randreal(1175.0,  1575.0) + 125.0*game.skill
             game.iscate = (game.state.remkl > 1)
     # Put in Romulans if needed
-    for i in range(q.romulans):
+    for _i in range(q.romulans):
         Enemy('R', loc=dropin(), power=randreal(400.0,850.0)+50.0*game.skill)
     # If quadrant needs a starbase, put it in
     if q.starbase:
@@ -5838,10 +5855,10 @@ def newqad():
                 game.quad[QUADSIZE-1][QUADSIZE-1] = 'X'
     sortenemies()
     # And finally the stars
-    for i in range(q.stars):
+    for _i in range(q.stars):
         dropin('*')
     # Put in a few black holes
-    for i in range(1, 3+1):
+    for _i in range(1, 3+1):
         if withprob(0.5):
             dropin(' ')
     # Take out X's in corners if Tholian present
@@ -5889,7 +5906,6 @@ commands = [
     ("IMPULSE",          0),
     ("REST",             0),
     ("WARP",             0),
-    ("SCORE",            0),
     ("SENSORS",          OPTION_PLANETS),
     ("ORBIT",            OPTION_PLANETS),
     ("TRANSPORT",        OPTION_PLANETS),
@@ -5913,6 +5929,7 @@ commands = [
     ("CALL",             0),        # Synonym for MAYDAY
     ("QUIT",             0),
     ("HELP",             0),
+    ("SCORE",            OPTION_ALMY),
     ("",                 0),
 ]
 
@@ -6004,6 +6021,8 @@ def makemoves():
             setwnd(message_window)
             clrscr()
             abandon_passed = False
+            cmd = ""   # Force cmd to persist after loop
+            opt = 0    # Force opt to persist after loop
             for (cmd, opt) in commands:
                 # commands after ABANDON cannot be abbreviated
                 if cmd == "ABANDON":
@@ -6057,8 +6076,6 @@ def makemoves():
                 hitme = True
         elif cmd == "WARP":                # warp
             setwarp()
-        elif cmd == "SCORE":                # score
-            score()
         elif cmd == "SENSORS":                # sensors
             sensor()
         elif cmd == "ORBIT":                # orbit
@@ -6118,6 +6135,8 @@ def makemoves():
             game.alldone = True                # quit the game
         elif cmd == "HELP":
             helpme()                        # get help
+        elif cmd == "SCORE":
+            score()                         # see current score
         while True:
             if game.alldone:
                 break                # Game has ended
@@ -6142,27 +6161,27 @@ def makemoves():
     if game.idebug:
         prout("=== Ending")
 
-def cramen(type):
+def cramen(ch):
     "Emit the name of an enemy or feature."
-    if   type == 'R': s = _("Romulan")
-    elif type == 'K': s = _("Klingon")
-    elif type == 'C': s = _("Commander")
-    elif type == 'S': s = _("Super-commander")
-    elif type == '*': s = _("Star")
-    elif type == 'P': s = _("Planet")
-    elif type == 'B': s = _("Starbase")
-    elif type == ' ': s = _("Black hole")
-    elif type == 'T': s = _("Tholian")
-    elif type == '#': s = _("Tholian web")
-    elif type == '?': s = _("Stranger")
-    elif type == '@': s = _("Inhabited World")
+    if   ch == 'R': s = _("Romulan")
+    elif ch == 'K': s = _("Klingon")
+    elif ch == 'C': s = _("Commander")
+    elif ch == 'S': s = _("Super-commander")
+    elif ch == '*': s = _("Star")
+    elif ch == 'P': s = _("Planet")
+    elif ch == 'B': s = _("Starbase")
+    elif ch == ' ': s = _("Black hole")
+    elif ch == 'T': s = _("Tholian")
+    elif ch == '#': s = _("Tholian web")
+    elif ch == '?': s = _("Stranger")
+    elif ch == '@': s = _("Inhabited World")
     else: s = "Unknown??"
     return s
 
-def crmena(stars, enemy, loctype, w):
+def crmena(loud, enemy, loctype, w):
     "Emit the name of an enemy and his location."
     buf = ""
-    if stars:
+    if loud:
         buf += "***"
     buf += cramen(enemy) + _(" at ")
     if loctype == "quadrant":
@@ -6202,17 +6221,17 @@ class sstscanner:
         self.token = ''
         # Fill the token quue if nothing here
         while not self.inqueue:
-            line = cgetline()
+            sline = cgetline()
             if curwnd==prompt_window:
                 clrscr()
                 setwnd(message_window)
                 clrscr()
-            if line == '':
+            if sline == '':
                 return None
-            if not line:
+            if not sline:
                 continue
             else:
-                self.inqueue = line.lstrip().split() + ["\n"]
+                self.inqueue = sline.lstrip().split() + ["\n"]
         # From here on in it's all looking at the queue
         self.token = self.inqueue.pop(0)
         if self.token == "\n":
@@ -6244,22 +6263,22 @@ class sstscanner:
         return s.startswith(self.token)
     def int(self):
         # Round token value to nearest integer
-        return int(round(scanner.real))
+        return int(round(self.real))
     def getcoord(self):
         s = Coord()
-        scanner.nexttok()
-        if scanner.type != "IHREAL":
+        self.nexttok()
+        if self.type != "IHREAL":
             huh()
             return None
-        s.i = scanner.int()-1
-        scanner.nexttok()
-        if scanner.type != "IHREAL":
+        s.i = self.int()-1
+        self.nexttok()
+        if self.type != "IHREAL":
             huh()
             return None
-        s.j = scanner.int()-1
+        s.j = self.int()-1
         return s
     def __repr__(self):
-        return "<sstcanner: token=%s, type=%s, queue=%s>" % (scanner.token, scanner.type, scanner.inqueue)
+        return "<sstcanner: token=%s, type=%s, queue=%s>" % (self.token, self.type, self.inqueue)
 
 def ja():
     "Yes-or-no confirmation."
@@ -6367,9 +6386,8 @@ def debugme():
         atover(True)
 
 if __name__ == '__main__':
-    import getopt, socket
     try:
-        global line, thing, game
+        #global line, thing, game
         game = None
         thing = Thingy()
         game = Gamestate()