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, cPickle, random, copy, gettext, getpass
+import os, sys, math, curses, time, readline, pickle, random, copy, gettext, getpass
-version="2.1"
+version = "2.1"
docpath = (".", "../doc", "/usr/share/doc/sst")
-def _(str): return gettext.gettext(str)
+def _(st):
+ return gettext.gettext(st)
GALSIZE = 8 # Galaxy size in quadrants
NINHAB = (GALSIZE * GALSIZE / 2) # Number of inhabited worlds
self.i = x
self.j = y
def valid_quadrant(self):
- return self.i>=0 and self.i<GALSIZE and self.j>=0 and self.j<GALSIZE
+ return self.i >= 0 and self.i < GALSIZE and self.j >= 0 and self.j < GALSIZE
def valid_sector(self):
- return self.i>=0 and self.i<QUADSIZE and self.j>=0 and self.j<QUADSIZE
+ return self.i >= 0 and self.i < QUADSIZE and self.j >= 0 and self.j < QUADSIZE
def invalidate(self):
self.i = self.j = None
def is_valid(self):
def roundtogrid(self):
return Coord(int(round(self.i)), int(round(self.j)))
def distance(self, other=None):
- if not other: other = Coord(0, 0)
+ if not other:
+ other = Coord(0, 0)
return math.sqrt((self.i - other.i)**2 + (self.j - other.j)**2)
def bearing(self):
return 1.90985*math.atan2(self.j, self.i)
return "%s - %s" % (self.i+1, self.j+1)
__repr__ = __str__
+class Thingy(Coord):
+ "Do not anger the Space Thingy!"
+ def __init__(self):
+ Coord.__init__(self)
+ self.angered = False
+ def angry(self):
+ self.angered = True
+ def at(self, q):
+ return (q.i, q.j) == (self.i, self.j)
+
class Planet:
def __init__(self):
self.name = None # string-valued if inhabited
self.pclass = None # could be ""M", "N", "O", or "destroyed"
self.crystals = "absent"# could be "mined", "present", "absent"
self.known = "unknown" # could be "unknown", "known", "shuttle_down"
- self.inhabited = False # is it inhabites?
+ self.inhabited = False # is it inhabited?
def __str__(self):
return self.name
class Page:
def __init__(self):
self.stars = None
- self.starbase = None
+ self.starbase = False
self.klingons = None
+ def __repr__(self):
+ return "<%s,%s,%s>" % (self.klingons, self.starbase, self.stars)
def fill2d(size, fillfun):
"Fill an empty list in 2D."
OPTION_COLOR = 0x04000000 # enable color display (experimental, ESR, 2010)
# Define devices
-DSRSENS = 0
-DLRSENS = 1
-DPHASER = 2
-DPHOTON = 3
-DLIFSUP = 4
-DWARPEN = 5
-DIMPULS = 6
-DSHIELD = 7
-DRADIO = 0
-DSHUTTL = 9
-DCOMPTR = 10
-DNAVSYS = 11
-DTRANSP = 12
-DSHCTRL = 13
-DDRAY = 14
-DDSP = 15
-NDEVICES= 16 # Number of devices
+DSRSENS = 0
+DLRSENS = 1
+DPHASER = 2
+DPHOTON = 3
+DLIFSUP = 4
+DWARPEN = 5
+DIMPULS = 6
+DSHIELD = 7
+DRADIO = 0
+DSHUTTL = 9
+DCOMPTR = 10
+DNAVSYS = 11
+DTRANSP = 12
+DSHCTRL = 13
+DDRAY = 14
+DDSP = 15
+NDEVICES = 16 # Number of devices
SKILL_NONE = 0
SKILL_NOVICE = 1
SKILL_EXPERT = 4
SKILL_EMERITUS = 5
-def damaged(dev): return (game.damage[dev] != 0.0)
-def communicating(): return not damaged(DRADIO) or game.condition=="docked"
+def damaged(dev):
+ return (game.damage[dev] != 0.0)
+def communicating():
+ return not damaged(DRADIO) or game.condition=="docked"
# Define future events
FSPY = 0 # Spy event happens always (no future[] entry)
# Abstract out the event handling -- underlying data structures will change
# when we implement stateful events
-def findevent(evtype): return game.future[evtype]
+def findevent(evtype):
+ return game.future[evtype]
class Enemy:
- def __init__(self, type=None, loc=None, power=None):
- self.type = type
+ def __init__(self, etype=None, loc=None, power=None):
+ self.type = etype
self.location = Coord()
+ self.kdist = None
+ self.kavgd = None
if loc:
self.move(loc)
self.power = power # enemy energy level
while i > 0:
i -= 1
self.future.append(Event())
- self.passwd = None; # Self Destruct password
+ self.passwd = None # Self Destruct password
self.enemies = []
self.quadrant = None # where we are in the large
self.sector = None # where we are in the small
self.score = 0.0 # overall score
self.perdate = 0.0 # rate of kills
self.idebug = False # Debugging instrumentation enabled?
+ self.statekscmdr = None # No SuperCommander coordinates yet.
def recompute(self):
# Stas thinks this should be (C expression):
# game.state.remkl + len(game.state.kcmdr) > 0 ?
# He says the existing expression is prone to divide-by-zero errors
# 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))
+ self.state.remtime = self.state.remres/(self.state.remkl + 4*len(self.state.kcmdr))
FWON = 0
FDEPLETE = 1
iq.i = game.quadrant.i+(look.i+(QUADSIZE-1))/QUADSIZE - 1
iq.j = game.quadrant.j+(look.j+(QUADSIZE-1))/QUADSIZE - 1
if not welcoming(iq):
- return False;
+ return False
if enemy.type == 'R':
- return False; # Romulans cannot escape!
+ return False # Romulans cannot escape!
if not irun:
# avoid intruding on another commander's territory
if enemy.type == 'C':
if iq in game.state.kcmdr:
- return False
+ return []
# refuse to leave if currently attacking starbase
if game.battle == game.quadrant:
- return False
+ return []
# don't leave if over 1000 units of energy
if enemy.power > 1000.0:
- return False
- # emit escape message and move out of quadrant.
- # we know this if either short or long range sensors are working
- if not damaged(DSRSENS) or not damaged(DLRSENS) or \
- game.condition == "docked":
- prout(crmena(True, enemy.type, "sector", enemy.location) + \
- (_(" escapes to Quadrant %s (and regains strength).") % iq))
+ return []
+ oldloc = copy.copy(enemy.location)
# handle local matters related to escape
enemy.move(None)
game.klhere -= 1
# Handle global matters related to escape
game.state.galaxy[game.quadrant.i][game.quadrant.j].klingons -= 1
game.state.galaxy[iq.i][iq.j].klingons += 1
- if enemy.type=='S':
+ if enemy.type == 'S':
game.iscate = False
game.ientesc = False
game.isatb = 0
schedule(FSCMOVE, 0.2777)
unschedule(FSCDBAS)
- game.state.kscmdr=iq
+ game.state.kscmdr = iq
else:
for cmdr in game.state.kcmdr:
if cmdr == game.quadrant:
game.state.kcmdr.append(iq)
break
- return True; # success
+ # report move out of quadrant.
+ return [(True, enemy, oldloc, ibq)]
# The bad-guy movement algorithm:
#
def movebaddy(enemy):
"Tactical movement for the bad guys."
- goto = Coord(); look = Coord()
+ goto = Coord()
+ look = Coord()
irun = False
# This should probably be just (game.quadrant in game.state.kcmdr) + (game.state.kscmdr==game.quadrant)
if game.skill >= SKILL_EXPERT:
nbaddys = (((game.quadrant in game.state.kcmdr)*2 + (game.state.kscmdr==game.quadrant)*2+game.klhere*1.23+game.irhere*1.5)/2.0)
else:
nbaddys = (game.quadrant in game.state.kcmdr) + (game.state.kscmdr==game.quadrant)
- dist1 = enemy.kdist
- mdist = int(dist1 + 0.5); # Nearest integer distance
+ old_dist = enemy.kdist
+ mdist = int(old_dist + 0.5) # Nearest integer distance
# If SC, check with spy to see if should hi-tail it
- if enemy.type=='S' and \
+ if enemy.type == 'S' and \
(enemy.power <= 500.0 or (game.condition=="docked" and not damaged(DPHOTON))):
irun = True
motion = -QUADSIZE
# decide whether to advance, retreat, or hold position
forces = enemy.power+100.0*len(game.enemies)+400*(nbaddys-1)
if not game.shldup:
- forces += 1000; # Good for enemy if shield is down!
+ forces += 1000 # Good for enemy if shield is down!
if not damaged(DPHASER) or not damaged(DPHOTON):
if damaged(DPHASER): # phasers damaged
forces += 300.0
motion = ((forces + randreal(200))/150.0) - 5.0
else:
if forces > 1000.0: # Very strong -- move in for kill
- motion = (1.0 - randreal())**2 * dist1 + 1.0
- if game.condition=="docked" and (game.options & OPTION_BASE): # protected by base -- back off !
+ motion = (1.0 - randreal())**2 * old_dist + 1.0
+ if game.condition == "docked" and (game.options & OPTION_BASE): # protected by base -- back off !
motion -= game.skill*(2.0-randreal()**2)
if game.idebug:
proutn("=== MOTION = %d, FORCES = %1.2f, " % (motion, forces))
# don't move if no motion
- if motion==0:
- return
+ if motion == 0:
+ return []
# Limit motion according to skill
if abs(motion) > game.skill:
if motion < 0:
# calculate preferred number of steps
nsteps = abs(int(motion))
if motion > 0 and nsteps > mdist:
- nsteps = mdist; # don't overshoot
+ nsteps = mdist # don't overshoot
if nsteps > QUADSIZE:
- nsteps = QUADSIZE; # This shouldn't be necessary
+ nsteps = QUADSIZE # This shouldn't be necessary
if nsteps < 1:
- nsteps = 1; # This shouldn't be necessary
+ nsteps = 1 # This shouldn't be necessary
if game.idebug:
proutn("NSTEPS = %d:" % nsteps)
# Compute preferred values of delta X and Y
else:
krawlj = -1
success = False
- attempts = 0; # Settle mysterious hang problem
+ attempts = 0 # Settle mysterious hang problem
while attempts < 20 and not success:
attempts += 1
if look.i < 0 or look.i >= QUADSIZE:
- if motion < 0 and tryexit(enemy, look, irun):
- return
+ if motion < 0:
+ return tryexit(enemy, look, irun)
if krawli == m.i or m.j == 0:
break
look.i = goto.i + krawli
krawli = -krawli
elif look.j < 0 or look.j >= QUADSIZE:
- if motion < 0 and tryexit(enemy, look, irun):
- return
+ if motion < 0:
+ return tryexit(enemy, look, irun)
if krawlj == m.j or m.i == 0:
break
look.j = goto.j + krawlj
if game.quad[look.i][look.j] == game.ship and \
(enemy.type == 'C' or enemy.type == 'S'):
collision(rammed=True, enemy=enemy)
- return
+ return []
if krawli != m.i and m.j != 0:
look.i = goto.i + krawli
krawli = -krawli
look.j = goto.j + krawlj
krawlj = -krawlj
else:
- break; # we have failed
+ break # we have failed
else:
success = True
if success:
goto = look
if game.idebug:
- proutn(`goto`)
+ proutn(repr(goto))
else:
- break; # done early
+ break # done early
if game.idebug:
skip(1)
- if enemy.move(goto):
- if not damaged(DSRSENS) or game.condition == "docked":
- proutn(_("*** %s from Sector %s") % (cramen(enemy.type), enemy.location))
- if enemy.kdist < dist1:
- proutn(_(" advances to "))
- else:
- proutn(_(" retreats to "))
- prout("Sector %s." % goto)
+ # Enemy moved, but is still in sector
+ return [(False, enemy, old_dist, goto)]
def moveklings():
"Sequence Klingon tactical movement."
prout("== MOVCOM")
# Figure out which Klingon is the commander (or Supercommander)
# and do move
+ tacmoves = []
if game.quadrant in game.state.kcmdr:
for enemy in game.enemies:
if enemy.type == 'C':
- movebaddy(enemy)
- if game.state.kscmdr==game.quadrant:
+ tacmoves += movebaddy(enemy)
+ if game.state.kscmdr == game.quadrant:
for enemy in game.enemies:
if enemy.type == 'S':
- movebaddy(enemy)
+ tacmoves += movebaddy(enemy)
break
# If skill level is high, move other Klingons and Romulans too!
# Move these last so they can base their actions on what the
if game.skill >= SKILL_EXPERT and (game.options & OPTION_MVBADDY):
for enemy in game.enemies:
if enemy.type in ('K', 'R'):
- movebaddy(enemy)
- sortenemies()
+ tacmoves += movebaddy(enemy)
+ return tacmoves
def movescom(iq, avoid):
"Commander movement helper."
game.state.galaxy[game.state.kscmdr.i][game.state.kscmdr.j].klingons -= 1
game.state.kscmdr = iq
game.state.galaxy[game.state.kscmdr.i][game.state.kscmdr.j].klingons += 1
- if game.state.kscmdr==game.quadrant:
+ if game.state.kscmdr == game.quadrant:
# SC has scooted, remove him from current quadrant
- game.iscate=False
- game.isatb=0
+ game.iscate = False
+ game.isatb = 0
game.ientesc = False
unschedule(FSCDBAS)
for enemy in game.enemies:
if enemy.type == 'S':
- break
- enemy.move(None)
+ enemy.move(None)
game.klhere -= 1
if game.condition != "docked":
newcnd()
proutn(_(" a planet in Quadrant %s has been destroyed") % game.state.kscmdr)
prout(_(" by the Super-commander.\""))
break
- return True; # looks good!
+ return True # looks good!
def supercommander():
"Move the Super Commander."
- iq = Coord(); sc = Coord(); ibq = Coord(); idelta = Coord()
+ iq = Coord()
+ sc = Coord()
+ ibq = Coord()
+ idelta = Coord()
basetbl = []
if game.idebug:
prout("== SUPERCOMMANDER")
# without too many Klingons, and not already under attack.
ifindit = iwhichb = 0
for (i2, base) in enumerate(game.state.baseq):
- i = basetbl[i2][0]; # bug in original had it not finding nearest
- if base==game.quadrant or base==game.battle or not welcoming(base):
+ i = basetbl[i2][0] # bug in original had it not finding nearest
+ if base == game.quadrant or base == game.battle or not welcoming(base):
continue
# if there is a commander, and no other base is appropriate,
# we will take the one with the commander
ifindit = 1
iwhichb = i
break
- if ifindit==0:
+ if ifindit == 0:
return # Nothing suitable -- wait until next time
ibq = game.state.baseq[iwhichb]
# decide how to move toward base
iq = game.state.kscmdr + idelta
if not movescom(iq, avoid):
# failed -- try some other maneuvers
- if idelta.i==0 or idelta.j==0:
+ if idelta.i == 0 or idelta.j == 0:
# attempt angle move
if idelta.i != 0:
iq.j = game.state.kscmdr.j + 1
if not ja():
return
game.resting = False
- game.optime = 0.0; # actually finished
+ game.optime = 0.0 # actually finished
return
# Check for intelligence report
if not game.idebug and \
return
tid = Coord()
if game.tholian.location.i == 0 and game.tholian.location.j == 0:
- tid.i = 0; tid.j = QUADSIZE-1
+ tid.i = 0
+ tid.j = QUADSIZE-1
elif game.tholian.location.i == 0 and game.tholian.location.j == QUADSIZE-1:
- tid.i = QUADSIZE-1; tid.j = QUADSIZE-1
+ tid.i = QUADSIZE-1
+ tid.j = QUADSIZE-1
elif game.tholian.location.i == QUADSIZE-1 and game.tholian.location.j == QUADSIZE-1:
- tid.i = QUADSIZE-1; tid.j = 0
+ tid.i = QUADSIZE-1
+ tid.j = 0
elif game.tholian.location.i == QUADSIZE-1 and game.tholian.location.j == 0:
- tid.i = 0; tid.j = 0
+ tid.i = 0
+ tid.j = 0
else:
# something is wrong!
game.tholian.move(None)
# move in x axis
while here.i != tid.i:
here.i += delta.i
- if game.quad[here.i][here.j]=='.':
+ if game.quad[here.i][here.j] == '.':
game.tholian.move(here)
# move in y axis
while here.j != tid.j:
here.j += delta.j
- if game.quad[here.i][here.j]=='.':
+ if game.quad[here.i][here.j] == '.':
game.tholian.move(here)
# check to see if all holes plugged
for i in range(QUADSIZE):
- if game.quad[0][i]!='#' and game.quad[0][i]!='T':
+ if game.quad[0][i] != '#' and game.quad[0][i] != 'T':
return
- if game.quad[QUADSIZE-1][i]!='#' and game.quad[QUADSIZE-1][i]!='T':
+ if game.quad[QUADSIZE-1][i] != '#' and game.quad[QUADSIZE-1][i] != 'T':
return
- if game.quad[i][0]!='#' and game.quad[i][0]!='T':
+ if game.quad[i][0] != '#' and game.quad[i][0] != 'T':
return
- if game.quad[i][QUADSIZE-1]!='#' and game.quad[i][QUADSIZE-1]!='T':
+ if game.quad[i][QUADSIZE-1] != '#' and game.quad[i][QUADSIZE-1] != 'T':
return
# All plugged up -- Tholian splits
- game.quad[game.tholian.location.i][game.tholian.location.j]='#'
+ game.quad[game.tholian.location.i][game.tholian.location.j] = '#'
dropin(' ')
prout(crmena(True, 'T', "sector", game.tholian) + _(" completes web."))
game.tholian.move(None)
if shraise:
action = "SHUP"
else:
- key = scanner.next()
+ key = scanner.nexttok()
if key == "IHALPHA":
if scanner.sees("transfer"):
action = "NRG"
action = "SHUP"
elif scanner.sees("down"):
action = "SHDN"
- if action=="NONE":
+ if action == "NONE":
proutn(_("Do you wish to change shield energy? "))
if ja():
action = "NRG"
prout(_("Shields raising uses up last of energy."))
finish(FNRG)
return
- game.ididit=True
+ game.ididit = True
return
elif action == "SHDN":
if not game.shldup:
prout(_("Shields already down."))
return
- game.shldup=False
- game.shldchg=True
+ game.shldup = False
+ game.shldchg = True
prout(_("Shields lowered."))
game.ididit = True
return
elif action == "NRG":
- while scanner.next() != "IHREAL":
+ while scanner.nexttok() != "IHREAL":
scanner.chew()
proutn(_("Energy to transfer to shields- "))
nrg = scanner.real
wsum += w
if idx < wsum:
return i
- return None; # we should never get here
+ return None # we should never get here
def collision(rammed, enemy):
- "Collision handling fot rammong events."
+ "Collision handling for rammong events."
prouts(_("***RED ALERT! RED ALERT!"))
skip(1)
prout(_("***COLLISION IMMINENT."))
def torpedo(origin, bearing, dispersion, number, nburst):
"Let a photon torpedo fly"
- if not damaged(DSRSENS) or game.condition=="docked":
+ if not damaged(DSRSENS) or game.condition == "docked":
setwnd(srscan_window)
else:
setwnd(message_window)
# Loop to move a single torpedo
setwnd(message_window)
for step in range(1, QUADSIZE*2):
- if not track.next(): break
+ if not track.nexttok():
+ break
w = track.sector()
if not w.valid_sector():
break
- iquad=game.quad[w.i][w.j]
+ iquad = game.quad[w.i][w.j]
tracktorpedo(w, step, number, nburst, iquad)
- if iquad=='.':
+ if iquad == '.':
continue
# hit something
- if not damaged(DSRSENS) or game.condition == "docked":
- skip(1); # start new line after text track
+ setwnd(message_window)
+ if not damaged(DSRSENS) or game.condition == "docked":
+ skip(1) # start new line after text track
if iquad in ('E', 'F'): # Hit our ship
skip(1)
prout(_("Torpedo hits %s.") % crmshp())
hit = 700.0 + randreal(100) - \
1000.0 * (w-origin).distance() * math.fabs(math.sin(bullseye-track.angle))
- newcnd(); # we're blown out of dock
- if game.landed or game.condition=="docked":
+ newcnd() # we're blown out of dock
+ if game.landed or game.condition == "docked":
return hit # Cheat if on a planet
# 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+randreal(-2.4,2.4), distance=2**0.5)
- displacement.next()
+ displacement = course(track.bearing+randreal(-2.4, 2.4), distance=2**0.5)
+ displacement.nexttok()
bumpto = displacement.sector()
if not bumpto.valid_sector():
return hit
- if game.quad[bumpto.i][bumpto.j]==' ':
+ if game.quad[bumpto.i][bumpto.j] == ' ':
finish(FHOLE)
return hit
- if game.quad[bumpto.i][bumpto.j]!='.':
+ if game.quad[bumpto.i][bumpto.j] != '.':
# can't move into object
return hit
game.sector = bumpto
proutn(crmshp())
- game.quad[w.i][w.j]='.'
- game.quad[bumpto.i][bumpto.j]=iquad
+ game.quad[w.i][w.j] = '.'
+ game.quad[bumpto.i][bumpto.j] = iquad
prout(_(" displaced by blast to Sector %s ") % bumpto)
for enemy in game.enemies:
enemy.kdist = enemy.kavgd = (game.sector-enemy.location).distance()
return None
for enemy in game.enemies:
if w == enemy.location:
- break
- kp = math.fabs(enemy.power)
- h1 = 700.0 + randrange(100) - \
- 1000.0 * (w-origin).distance() * math.fabs(math.sin(bullseye-track.angle))
- h1 = math.fabs(h1)
- if kp < h1:
- h1 = kp
- if enemy.power < 0:
- enemy.power -= -h1
- else:
- enemy.power -= h1
- if enemy.power == 0:
- deadkl(w, iquad, w)
- return None
- proutn(crmena(True, iquad, "sector", w))
- displacement = course(track.bearing+randreal(-2.4,2.4), distance=2**0.5)
- displacement.next()
- bumpto = displacement.sector()
- if not bumpto.valid_sector():
- prout(_(" damaged but not destroyed."))
- return
- if game.quad[bumpto.i][bumpto.j] == ' ':
- prout(_(" buffeted into black hole."))
- deadkl(w, iquad, bumpto)
- if game.quad[bumpto.i][bumpto.j] != '.':
- prout(_(" damaged but not destroyed."))
+ kp = math.fabs(enemy.power)
+ h1 = 700.0 + randrange(100) - \
+ 1000.0 * (w-origin).distance() * math.fabs(math.sin(bullseye-track.angle))
+ h1 = math.fabs(h1)
+ if kp < h1:
+ h1 = kp
+ if enemy.power < 0:
+ enemy.power -= -h1
+ else:
+ enemy.power -= h1
+ if enemy.power == 0:
+ deadkl(w, iquad, w)
+ return None
+ proutn(crmena(True, iquad, "sector", w))
+ displacement = course(track.bearing+randreal(-2.4, 2.4), distance=2**0.5)
+ displacement.nexttok()
+ bumpto = displacement.sector()
+ if not bumpto.valid_sector():
+ prout(_(" damaged but not destroyed."))
+ return
+ if game.quad[bumpto.i][bumpto.j] == ' ':
+ prout(_(" buffeted into black hole."))
+ deadkl(w, iquad, bumpto)
+ if game.quad[bumpto.i][bumpto.j] != '.':
+ prout(_(" damaged but not destroyed."))
+ else:
+ prout(_(" damaged-- displaced by blast to Sector %s ")%bumpto)
+ enemy.location = bumpto
+ game.quad[w.i][w.j] = '.'
+ game.quad[bumpto.i][bumpto.j] = iquad
+ for enemy in game.enemies:
+ enemy.kdist = enemy.kavgd = (game.sector-enemy.location).distance()
+ sortenemies()
+ break
else:
- prout(_(" damaged-- displaced by blast to Sector %s ")%bumpto)
- enemy.location = bumpto
- game.quad[w.i][w.j]='.'
- game.quad[bumpto.i][bumpto.j]=iquad
- for enemy in game.enemies:
- enemy.kdist = enemy.kavgd = (game.sector-enemy.location).distance()
- sortenemies()
+ prout("Internal error, no enemy where expected!")
+ raise SystemExit(1)
return None
elif iquad == 'B': # Hit a base
skip(1)
prout(_("***STARBASE DESTROYED.."))
- game.state.baseq = filter(lambda x: x != game.quadrant, game.state.baseq)
- game.quad[w.i][w.j]='.'
+ game.state.baseq = [x for x in game.state.baseq if x != game.quadrant]
+ game.quad[w.i][w.j] = '.'
game.base.invalidate()
- game.state.galaxy[game.quadrant.i][game.quadrant.j].starbase -= 1
- game.state.chart[game.quadrant.i][game.quadrant.j].starbase -= 1
+ game.state.galaxy[game.quadrant.i][game.quadrant.j].starbase = False
+ game.state.chart[game.quadrant.i][game.quadrant.j].starbase = False
game.state.basekl += 1
newcnd()
return None
# 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 = True
+ thing.angry()
return None
elif iquad == ' ': # Black hole
skip(1)
return None
break
skip(1)
+ setwnd(message_window)
prout(_("Torpedo missed."))
- return None;
+ return None
def fry(hit):
"Critical-hit resolution."
# Select devices and cause damage
cdam = []
while ncrit > 0:
- ncrit -= 1
while True:
j = randdevice()
# Cheat to prevent shuttle damage unless on ship
- if not (game.damage[j]<0.0 or (j==DSHUTTL and game.iscraft != "onship")):
+ if not (game.damage[j]<0.0 or (j == DSHUTTL and game.iscraft != "onship")):
break
cdam.append(j)
extradm = (hit*game.damfac)/(ncrit*randreal(75, 100))
game.damage[j] += extradm
+ ncrit -= 1
skipcount = 0
for (i, j) in enumerate(cdam):
proutn(device[j])
prout(_(" damaged."))
if damaged(DSHIELD) and game.shldup:
prout(_("***Shields knocked down."))
- game.shldup=False
+ game.shldup = False
def attack(torps_ok):
# bad guy attacks us
# game could be over at this point, check
if game.alldone:
return
- attempt = False; ihurt = False;
- hitmax=0.0; hittot=0.0; chgfac=1.0
+ attempt = False
+ ihurt = False
+ hitmax = 0.0
+ hittot = 0.0
+ chgfac = 1.0
where = "neither"
if game.idebug:
prout("=== ATTACK!")
game.neutz = False
return
# commanders get a chance to tac-move towards you
- if (((game.quadrant in game.state.kcmdr or game.state.kscmdr==game.quadrant) and not game.justin) or game.skill == SKILL_EMERITUS) and torps_ok:
- moveklings()
+ if (((game.quadrant in game.state.kcmdr or game.state.kscmdr == game.quadrant) and not game.justin) or game.skill == SKILL_EMERITUS) and torps_ok:
+ for (bugout, enemy, old, goto) in moveklings():
+ if bugout:
+ # we know about this if either short or long range
+ # sensors are working
+ if damaged(DSRSENS) and damaged(DLRSENS) \
+ and game.condition != "docked":
+ prout(crmena(True, enemy.type, "sector", old) + \
+ (_(" escapes to Quadrant %s (and regains strength).") % goto))
+ else: # Enemy still in-sector
+ if enemy.move(goto):
+ if not damaged(DSRSENS) or game.condition == "docked":
+ proutn(_("*** %s from Sector %s") % (cramen(enemy.type), enemy.location))
+ if enemy.kdist < old:
+ proutn(_(" advances to "))
+ else:
+ proutn(_(" retreats to "))
+ 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 == game.quadrant and not thing.angry):
+ if len(game.enemies) == 0 or (len(game.enemies) == 1 and thing.at(game.quadrant) and not thing.angered):
return
# set up partial hits if attack happens during shield status change
pfac = 1.0/game.inshld
where = "sector"
for enemy in game.enemies:
if enemy.power < 0:
- continue; # too weak to attack
+ continue # too weak to attack
# compute hit strength and diminish shield power
r = randreal()
# Increase chance of photon torpedos if docked or enemy energy is low
if game.condition == "docked":
r *= 0.25
if enemy.power < 500:
- r *= 0.25;
- if enemy.type=='T' or (enemy.type=='?' and not thing.angry):
+ r *= 0.25
+ if enemy.type == 'T' or (enemy.type == '?' and not thing.angered):
continue
# different enemies have different probabilities of throwing a torp
usephasers = not torps_ok or \
(enemy.type == 'K' and r > 0.0005) or \
- (enemy.type=='C' and r > 0.015) or \
- (enemy.type=='R' and r > 0.3) or \
- (enemy.type=='S' and r > 0.07) or \
- (enemy.type=='?' and r > 0.05)
+ (enemy.type == 'C' and r > 0.015) or \
+ (enemy.type == 'R' and r > 0.3) or \
+ (enemy.type == 'S' and r > 0.07) or \
+ (enemy.type == '?' and r > 0.05)
if usephasers: # Enemy uses phasers
if game.condition == "docked":
- continue; # Don't waste the effort!
- attempt = True; # Attempt to attack
+ continue # Don't waste the effort!
+ attempt = True # Attempt to attack
dustfac = randreal(0.8, 0.85)
- hit = enemy.power*math.pow(dustfac,enemy.kavgd)
+ hit = enemy.power*math.pow(dustfac, enemy.kavgd)
enemy.power *= 0.75
else: # Enemy uses photon torpedo
# We should be able to make the bearing() method work here
dispersion = (randreal()+randreal())*0.5 - 0.5
dispersion += 0.002*enemy.power*dispersion
hit = torpedo(enemy.location, pcourse, dispersion, number=1, nburst=1)
- if (game.state.remkl + len(game.state.kcmdr) + game.state.nscrem)==0:
- finish(FWON); # Klingons did themselves in!
+ if (game.state.remkl + len(game.state.kcmdr) + game.state.nscrem) == 0:
+ finish(FWON) # Klingons did themselves in!
if game.state.galaxy[game.quadrant.i][game.quadrant.j].supernova or game.alldone:
return # Supernova or finished
if hit == None:
continue
# incoming phaser or torpedo, shields may dissipate it
- if game.shldup or game.shldchg or game.condition=="docked":
+ if game.shldup or game.shldchg or game.condition == "docked":
# shields will take hits
propor = pfac * game.shield
- if game.condition =="docked":
+ if game.condition == "docked":
propor *= 2.1
if propor < 0.1:
propor = 0.1
sortenemies()
return
-def deadkl(w, type, mv):
+def deadkl(w, etype, mv):
"Kill a Klingon, Tholian, Romulan, or Thingy."
# Added mv to allow enemy to "move" before dying
- proutn(crmena(True, type, "sector", mv))
+ proutn(crmena(True, etype, "sector", mv))
# Decide what kind of enemy it is and update appropriately
- if type == 'R':
+ if etype == 'R':
# Chalk up a Romulan
game.state.galaxy[game.quadrant.i][game.quadrant.j].romulans -= 1
game.irhere -= 1
game.state.nromrem -= 1
- elif type == 'T':
+ elif etype == 'T':
# Killed a Tholian
game.tholian = None
- elif type == '?':
+ elif etype == '?':
# Killed a Thingy
global thing
thing = None
unschedule(FSCDBAS)
# For each kind of enemy, finish message to player
prout(_(" destroyed."))
- if (game.state.remkl + len(game.state.kcmdr) + game.state.nscrem)==0:
+ if (game.state.remkl + len(game.state.kcmdr) + game.state.nscrem) == 0:
return
game.recompute()
# Remove enemy ship from arrays describing local conditions
huh()
return None
delta = Coord()
- # FIXME: C code this was translated from is wacky -- why the sign reversal?
- delta.j = (w.j - game.sector.j);
- delta.i = (game.sector.i - w.i);
+ # C code this was translated from is wacky -- why the sign reversal?
+ delta.j = (w.j - game.sector.j)
+ delta.i = (game.sector.i - w.i)
if delta == Coord(0, 0):
skip(1)
prout(_("Spock- \"Bridge to sickbay. Dr. McCoy,"))
return
# First, get torpedo count
while True:
- scanner.next()
+ scanner.nexttok()
if scanner.token == "IHALPHA":
huh()
return
# Next, get targets
target = []
for i in range(n):
- key = scanner.next()
- if i==0 and key == "IHEOL":
- break; # no coordinate waiting, we will try prompting
- if i==1 and key == "IHEOL":
+ key = scanner.nexttok()
+ if i == 0 and key == "IHEOL":
+ break # no coordinate waiting, we will try prompting
+ if i == 1 and key == "IHEOL":
# direct all torpedoes at one target
while i < n:
target.append(target[0])
if game.alldone or game.state.galaxy[game.quadrant.i][game.quadrant.j].supernova:
return
if (game.state.remkl + len(game.state.kcmdr) + game.state.nscrem)<=0:
- finish(FWON);
+ finish(FWON)
def overheat(rpow):
"Check for phasers overheating."
prout(_("Phaser energy dispersed by shields."))
prout(_("Enemy unaffected."))
overheat(rpow)
- return True;
+ return True
def hittem(hits):
"Register a phaser hit on Klingons and Romulans."
- kk = 0
w = Coord()
skip(1)
- for (k, wham) in enumerate(hits):
- if wham==0:
+ kk = 0
+ for wham in hits:
+ if wham == 0:
continue
dustfac = randreal(0.9, 1.0)
- hit = wham*math.pow(dustfac,game.enemies[kk].kdist)
+ hit = wham*math.pow(dustfac, game.enemies[kk].kdist)
kpini = game.enemies[kk].power
kp = math.fabs(kpini)
if PHASEFAC*hit < kp:
else:
proutn(_("Very small hit on "))
ienm = game.quad[w.i][w.j]
- if ienm=='?':
- thing.angry = True
+ if ienm == '?':
+ thing.angry()
proutn(crmena(False, ienm, "sector", w))
skip(1)
if kpow == 0:
deadkl(w, ienm, w)
if (game.state.remkl + len(game.state.kcmdr) + game.state.nscrem)==0:
- finish(FWON);
+ finish(FWON)
if game.alldone:
return
kk -= 1 # don't do the increment
continue
else: # decide whether or not to emasculate klingon
- if kpow>0 and withprob(0.9) and kpow <= randreal(0.4, 0.8)*kpini:
+ if kpow > 0 and withprob(0.9) and kpow <= randreal(0.4, 0.8)*kpini:
prout(_("***Mr. Spock- \"Captain, the vessel at Sector %s")%w)
prout(_(" has just lost its firepower.\""))
game.enemies[kk].power = -kpow
def phasers():
"Fire phasers at bad guys."
hits = []
- kz = 0; k = 1; irec=0 # Cheating inhibitor
- ifast = False; no = False; itarg = True; msgflag = True; rpow=0
+ kz = 0
+ k = 1
+ irec = 0 # Cheating inhibitor
+ ifast = False
+ no = False
+ itarg = True
+ msgflag = True
+ rpow = 0
automode = "NOTSET"
- key=0
+ key = 0
skip(1)
# SR sensors and Computer are needed for automode
if damaged(DSRSENS) or damaged(DCOMPTR):
ifast = True
# Original code so convoluted, I re-did it all
# (That was Tom Almy talking about the C code, I think -- ESR)
- while automode=="NOTSET":
- key=scanner.next()
+ while automode == "NOTSET":
+ key = scanner.nexttok()
if key == "IHALPHA":
if scanner.sees("manual"):
if len(game.enemies)==0:
prout(_("There is no enemy present to select."))
scanner.chew()
key = "IHEOL"
- automode="AUTOMATIC"
+ automode = "AUTOMATIC"
else:
automode = "MANUAL"
- key = scanner.next()
+ key = scanner.nexttok()
elif scanner.sees("automatic"):
if (not itarg) and len(game.enemies) != 0:
automode = "FORCEMAN"
if len(game.enemies)==0:
prout(_("Energy will be expended into space."))
automode = "AUTOMATIC"
- key = scanner.next()
+ key = scanner.nexttok()
elif scanner.sees("no"):
no = True
else:
if automode == "AUTOMATIC":
if key == "IHALPHA" and scanner.sees("no"):
no = True
- key = scanner.next()
+ key = scanner.nexttok()
if key != "IHREAL" and len(game.enemies) != 0:
prout(_("Phasers locked on target. Energy available: %.2f")%avail)
- irec=0
+ irec = 0
while True:
scanner.chew()
if not kz:
for i in range(len(game.enemies)):
- irec += math.fabs(game.enemies[i].power)/(PHASEFAC*math.pow(0.90,game.enemies[i].kdist))*randreal(1.01, 1.06) + 1.0
- kz=1
+ irec += math.fabs(game.enemies[i].power)/(PHASEFAC*math.pow(0.90, game.enemies[i].kdist))*randreal(1.01, 1.06) + 1.0
+ kz = 1
proutn(_("%d units required. ") % irec)
scanner.chew()
proutn(_("Units to fire= "))
- key = scanner.next()
- if key!="IHREAL":
+ key = scanner.nexttok()
+ if key != "IHREAL":
return
rpow = scanner.real
if rpow > avail:
key = "IHEOL"
if not rpow > avail:
break
- if rpow<=0:
+ if rpow <= 0:
# chicken out
scanner.chew()
return
- key=scanner.next()
+ key = scanner.nexttok()
if key == "IHALPHA" and scanner.sees("no"):
no = True
if ifast:
- game.energy -= 200; # Go and do it!
+ game.energy -= 200 # Go and do it!
if checkshctrl(rpow):
return
scanner.chew()
hits.append(0.0)
if powrem <= 0:
continue
- hits[i] = math.fabs(game.enemies[i].power)/(PHASEFAC*math.pow(0.90,game.enemies[i].kdist))
+ hits[i] = math.fabs(game.enemies[i].power)/(PHASEFAC*math.pow(0.90, game.enemies[i].kdist))
over = randreal(1.01, 1.06) * hits[i]
temp = powrem
powrem -= hits[i] + over
prout(cramen(ienm) + _(" can't be located without short range scan."))
scanner.chew()
key = "IHEOL"
- hits[k] = 0; # prevent overflow -- thanks to Alexei Voitenko
+ hits[k] = 0 # prevent overflow -- thanks to Alexei Voitenko
k += 1
continue
if key == "IHEOL":
scanner.chew()
if itarg and k > kz:
- irec=(abs(game.enemies[k].power)/(PHASEFAC*math.pow(0.9,game.enemies[k].kdist))) * randreal(1.01, 1.06) + 1.0
+ irec = (abs(game.enemies[k].power)/(PHASEFAC*math.pow(0.9, game.enemies[k].kdist))) * randreal(1.01, 1.06) + 1.0
kz = k
proutn("(")
if not damaged(DCOMPTR):
proutn("??")
proutn(") ")
proutn(_("units to fire at %s- ") % crmena(False, ienm, "sector", aim))
- key = scanner.next()
+ key = scanner.nexttok()
if key == "IHALPHA" and scanner.sees("no"):
no = True
- key = scanner.next()
+ key = scanner.nexttok()
continue
if key == "IHALPHA":
huh()
return
if key == "IHEOL":
- if k==1: # Let me say I'm baffled by this
+ if k == 1: # Let me say I'm baffled by this
msgflag = True
continue
if scanner.real < 0:
prout(_("Available energy exceeded -- try again."))
scanner.chew()
return
- key = scanner.next(); # scan for next value
+ key = scanner.nexttok() # scan for next value
k += 1
if rpow == 0.0:
# zero energy -- abort
prout(_("Shields raised."))
else:
game.shldup = False
- overheat(rpow);
+ overheat(rpow)
# Code from events,c begins here.
def events():
"Run through the event queue looking for things to do."
- i=0
- fintim = game.state.date + game.optime; yank=0
- ictbeam = False; istract = False
- w = Coord(); hold = Coord()
- ev = Event(); ev2 = Event()
+ i = 0
+ fintim = game.state.date + game.optime
+ yank = 0
+ ictbeam = False
+ istract = False
+ w = Coord()
+ hold = Coord()
+ ev = Event()
+ ev2 = Event()
def tractorbeam(yank):
"Tractor-beaming cases merge here."
else:
prout(_("(Shields not currently useable.)"))
newqad()
- # Adjust finish time to time of tractor beaming
- fintim = game.state.date+game.optime
+ # Adjust finish time to time of tractor beaming?
+ # fintim = game.state.date+game.optime
attack(torps_ok=False)
if not game.state.kcmdr:
unschedule(FTBEAM)
game.state.chart[game.battle.i][game.battle.j].starbase = False
# Remove Starbase from galaxy
game.state.galaxy[game.battle.i][game.battle.j].starbase = False
- game.state.baseq = filter(lambda x: x != game.battle, game.state.baseq)
+ game.state.baseq = [x for x in game.state.baseq if x != game.battle]
if game.isatb == 2:
# reinstate a commander's base attack
game.battle = hold
# Decrement Federation resources and recompute remaining time
game.state.remres -= (game.state.remkl+4*len(game.state.kcmdr))*xtime
game.recompute()
- if game.state.remtime <=0:
+ if game.state.remtime <= 0:
finish(FDEPLETE)
return
# Any crew left alive?
- if game.state.crew <=0:
+ if game.state.crew <= 0:
finish(FCREW)
return
# Is life support adequate?
elif evcode == FSPY: # Check with spy to see if SC should tractor beam
if game.state.nscrem == 0 or \
ictbeam or istract or \
- game.condition=="docked" or game.isatb==1 or game.iscate:
+ game.condition == "docked" or game.isatb == 1 or game.iscate:
return
if game.ientesc or \
(game.energy<2000 and game.torps<4 and game.shield < 1250) or \
continue
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
+ 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))
game.battle = game.state.kscmdr
destroybase()
elif evcode == FCDBAS: # Commander succeeds in destroying base
- if evcode==FCDBAS:
+ if evcode == FCDBAS:
unschedule(FCDBAS)
if not game.state.baseq() \
or not game.state.galaxy[game.battle.i][game.battle.j].starbase:
supercommander()
elif evcode == FDSPROB: # Move deep space probe
schedule(FDSPROB, 0.01)
- if not game.probe.next():
+ if not game.probe.nexttok():
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
#announce()
skip(1)
prout(_("Lt. Uhura- \"The deep space probe is now in Quadrant %s.\"") % game.probe.quadrant())
- pdest = game.state.galaxy[game.probe.quadrant().i][game.probe.quadrant().j]
+ pquad = game.probe.quadrant()
+ pdest = game.state.galaxy[pquad.i][pquad.j]
if communicating():
- chp = game.state.chart[game.probe.quadrant().i][game.probe.quadrant().j]
- chp.klingons = pdest.klingons
- chp.starbase = pdest.starbase
- chp.stars = pdest.stars
+ game.state.chart[pquad.i][pquad.j].klingons = pdest.klingons
+ game.state.chart[pquad.i][pquad.j].starbase = pdest.starbase
+ game.state.chart[pquad.i][pquad.j].stars = pdest.stars
pdest.charted = True
game.probe.moves -= 1 # One less to travel
if game.probe.arrived() and game.isarmed and pdest.stars:
supernova(game.probe) # fire in the hole!
unschedule(FDSPROB)
- if game.state.galaxy[game.quadrant().i][game.quadrant().j].supernova:
+ if game.state.galaxy[pquad.i][pquad.j].supernova:
return
elif evcode == FDISTR: # inhabited system issues distress call
unschedule(FDISTR)
# tell the captain about it if we can
if communicating():
prout(_("Uhura- Captain, %s in Quadrant %s reports it is under attack") \
- % (q.planet, `w`))
+ % (q.planet, repr(w)))
prout(_("by a Klingon invasion fleet."))
if cancelrest():
return
if q.klingons <= 0:
q.status = "secure"
continue
- if game.state.remkl >=MAXKLGAME:
+ if game.state.remkl >= MAXKLGAME:
continue # full right now
# reproduce one Klingon
w = ev.quadrant
"Wait on events."
game.ididit = False
while True:
- key = scanner.next()
+ key = scanner.nexttok()
if key != "IHEOL":
break
proutn(_("How long? "))
start = hits.pop()
for offset.i in range(-1, 1+1):
for offset.j in range(-1, 1+1):
- if offset.j==0 and offset.i==0:
+ if offset.j == 0 and offset.i == 0:
continue
neighbor = start + offset
if not neighbor.valid_sector():
if iquad == 'P':
game.state.nplankl += 1
else:
- game.state.worldkl += 1
+ game.state.nworldkl += 1
prout(crmena(True, 'B', "sector", neighbor) + _(" destroyed."))
game.iplnet.pclass = "destroyed"
game.iplnet = None
game.quad[neighbor.i][neighbor.j] = '.'
elif iquad == 'B': # Destroy base
game.state.galaxy[game.quadrant.i][game.quadrant.j].starbase = False
- game.state.baseq = filter(lambda x: x!= game.quadrant, game.state.baseq)
+ game.state.baseq = [x for x in game.state.baseq if x!= game.quadrant]
game.base.invalidate()
game.state.basekl += 1
newcnd()
game.state.planets[loop].pclass = "destroyed"
npdead += 1
# Destroy any base in supernovaed quadrant
- game.state.baseq = filter(lambda x: x != nq, game.state.baseq)
+ game.state.baseq = [x for x in game.state.baseq if x != nq]
# If starship caused supernova, tally up destruction
if w != None:
game.state.starkl += game.state.galaxy[nq.i][nq.j].stars
skip(1)
prout(_("SELF-DESTRUCT-SEQUENCE-WILL-BE-ABORTED"))
skip(1)
- scanner.next()
+ scanner.nexttok()
if game.passwd != scanner.token:
prouts(_("PASSWORD-REJECTED;"))
skip(1)
curses.nonl()
curses.cbreak()
if game.options & OPTION_COLOR:
- curses.start_color();
+ curses.start_color()
curses.use_default_colors()
- curses.init_pair(curses.COLOR_BLACK, curses.COLOR_BLACK, -1);
- curses.init_pair(curses.COLOR_GREEN, curses.COLOR_GREEN, -1);
- curses.init_pair(curses.COLOR_RED, curses.COLOR_RED, -1);
- curses.init_pair(curses.COLOR_CYAN, curses.COLOR_CYAN, -1);
- curses.init_pair(curses.COLOR_WHITE, curses.COLOR_WHITE, -1);
- curses.init_pair(curses.COLOR_MAGENTA, curses.COLOR_MAGENTA, -1);
- curses.init_pair(curses.COLOR_BLUE, curses.COLOR_BLUE, -1);
- curses.init_pair(curses.COLOR_YELLOW, curses.COLOR_YELLOW, -1);
+ curses.init_pair(curses.COLOR_BLACK, curses.COLOR_BLACK, -1)
+ curses.init_pair(curses.COLOR_GREEN, curses.COLOR_GREEN, -1)
+ curses.init_pair(curses.COLOR_RED, curses.COLOR_RED, -1)
+ curses.init_pair(curses.COLOR_CYAN, curses.COLOR_CYAN, -1)
+ curses.init_pair(curses.COLOR_WHITE, curses.COLOR_WHITE, -1)
+ curses.init_pair(curses.COLOR_MAGENTA, curses.COLOR_MAGENTA, -1)
+ curses.init_pair(curses.COLOR_BLUE, curses.COLOR_BLUE, -1)
+ 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()
global linecount
sys.stdout.write('\n')
proutn(prompt)
- raw_input()
+ if not replayfp:
+ input()
sys.stdout.write('\n' * rows)
linecount = 0
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)
curwnd.refresh()
else:
elif line[0] != "#":
break
else:
- line = raw_input() + "\n"
+ line = eval(input()) + "\n"
if logfp:
logfp.write(line)
return line
"Change windows -- OK for this to be a no-op in tty mode."
global curwnd
if game.options & OPTION_CURSES:
+ # Uncomment this to debug curses problems
+ if logfp:
+ if wnd == fullscreen_window:
+ legend = "fullscreen"
+ elif wnd == srscan_window:
+ legend = "srscan"
+ elif wnd == report_window:
+ legend = "report"
+ elif wnd == status_window:
+ legend = "status"
+ elif wnd == lrscan_window:
+ legend = "lrscan"
+ elif wnd == message_window:
+ legend = "message"
+ elif wnd == prompt_window:
+ legend = "prompt"
+ else:
+ legend = "unknown"
+ logfp.write("#curses: setwnd(%s)\n" % legend)
curwnd = wnd
- curses.curs_set(wnd == fullscreen_window or wnd == message_window or wnd == prompt_window)
+ # Some curses implementations get confused when you try this.
+ try:
+ curses.curs_set(wnd in (fullscreen_window, message_window, prompt_window))
+ except curses.error:
+ pass
def clreol():
"Clear to end of line -- can be a no-op in tty mode"
"Clear screen -- can be a no-op in tty mode."
global linecount
if game.options & OPTION_CURSES:
- curwnd.clear()
- curwnd.move(0, 0)
- curwnd.refresh()
+ curwnd.clear()
+ curwnd.move(0, 0)
+ curwnd.refresh()
linecount = 0
def textcolor(color=DEFAULT):
if game.options & OPTION_COLOR:
if color == DEFAULT:
- curwnd.attrset(0);
+ curwnd.attrset(0)
elif color == BLACK:
- curwnd.attron(curses.color_pair(curses.COLOR_BLACK));
+ curwnd.attron(curses.color_pair(curses.COLOR_BLACK))
elif color == BLUE:
- curwnd.attron(curses.color_pair(curses.COLOR_BLUE));
+ curwnd.attron(curses.color_pair(curses.COLOR_BLUE))
elif color == GREEN:
- curwnd.attron(curses.color_pair(curses.COLOR_GREEN));
+ curwnd.attron(curses.color_pair(curses.COLOR_GREEN))
elif color == CYAN:
- curwnd.attron(curses.color_pair(curses.COLOR_CYAN));
+ curwnd.attron(curses.color_pair(curses.COLOR_CYAN))
elif color == RED:
- curwnd.attron(curses.color_pair(curses.COLOR_RED));
+ curwnd.attron(curses.color_pair(curses.COLOR_RED))
elif color == MAGENTA:
- curwnd.attron(curses.color_pair(curses.COLOR_MAGENTA));
+ curwnd.attron(curses.color_pair(curses.COLOR_MAGENTA))
elif color == BROWN:
- curwnd.attron(curses.color_pair(curses.COLOR_YELLOW));
+ curwnd.attron(curses.color_pair(curses.COLOR_YELLOW))
elif color == LIGHTGRAY:
- curwnd.attron(curses.color_pair(curses.COLOR_WHITE));
+ curwnd.attron(curses.color_pair(curses.COLOR_WHITE))
elif color == DARKGRAY:
- curwnd.attron(curses.color_pair(curses.COLOR_BLACK) | curses.A_BOLD);
+ curwnd.attron(curses.color_pair(curses.COLOR_BLACK) | curses.A_BOLD)
elif color == LIGHTBLUE:
- curwnd.attron(curses.color_pair(curses.COLOR_BLUE) | curses.A_BOLD);
+ curwnd.attron(curses.color_pair(curses.COLOR_BLUE) | curses.A_BOLD)
elif color == LIGHTGREEN:
- curwnd.attron(curses.color_pair(curses.COLOR_GREEN) | curses.A_BOLD);
+ curwnd.attron(curses.color_pair(curses.COLOR_GREEN) | curses.A_BOLD)
elif color == LIGHTCYAN:
- curwnd.attron(curses.color_pair(curses.COLOR_CYAN) | curses.A_BOLD);
+ curwnd.attron(curses.color_pair(curses.COLOR_CYAN) | curses.A_BOLD)
elif color == LIGHTRED:
- curwnd.attron(curses.color_pair(curses.COLOR_RED) | curses.A_BOLD);
+ curwnd.attron(curses.color_pair(curses.COLOR_RED) | curses.A_BOLD)
elif color == LIGHTMAGENTA:
- curwnd.attron(curses.color_pair(curses.COLOR_MAGENTA) | curses.A_BOLD);
+ curwnd.attron(curses.color_pair(curses.COLOR_MAGENTA) | curses.A_BOLD)
elif color == YELLOW:
- curwnd.attron(curses.color_pair(curses.COLOR_YELLOW) | curses.A_BOLD);
+ curwnd.attron(curses.color_pair(curses.COLOR_YELLOW) | curses.A_BOLD)
elif color == WHITE:
- curwnd.attron(curses.color_pair(curses.COLOR_WHITE) | curses.A_BOLD);
+ curwnd.attron(curses.color_pair(curses.COLOR_WHITE) | curses.A_BOLD)
def highvideo():
if game.options & OPTION_COLOR:
# Move out
game.quad[game.sector.i][game.sector.j] = '.'
for m in range(icourse.moves):
- icourse.next()
+ icourse.nexttok()
w = icourse.sector()
if icourse.origin.quadrant() != icourse.location.quadrant():
newquadrant(noattack)
break
elif check_collision(w):
- print "Collision detected"
+ print("Collision detected")
break
else:
game.sector = w
navmode = "manual"
key = "IHEOL"
break
- key = scanner.next()
+ key = scanner.nexttok()
if key == "IHEOL":
proutn(_("Manual or automatic- "))
iprompt = True
elif key == "IHALPHA":
if scanner.sees("manual"):
navmode = "manual"
- key = scanner.next()
+ key = scanner.nexttok()
break
elif scanner.sees("automatic"):
navmode = "automatic"
- key = scanner.next()
+ key = scanner.nexttok()
break
else:
huh()
proutn(_("Destination sector or quadrant§or- "))
scanner.chew()
iprompt = True
- key = scanner.next()
+ key = scanner.nexttok()
if key != "IHREAL":
huh()
raise TrekError
xi = int(round(scanner.real))-1
- key = scanner.next()
+ key = scanner.nexttok()
if key != "IHREAL":
huh()
raise TrekError
xj = int(round(scanner.real))-1
- key = scanner.next()
+ key = scanner.nexttok()
if key == "IHREAL":
# both quadrant and sector specified
xk = int(round(scanner.real))-1
- key = scanner.next()
+ key = scanner.nexttok()
if key != "IHREAL":
huh()
raise TrekError
proutn(_("X and Y displacements- "))
scanner.chew()
iprompt = True
- key = scanner.next()
+ key = scanner.nexttok()
itemp = "verbose"
if key != "IHREAL":
huh()
raise TrekError
delta.j = scanner.real
- key = scanner.next()
+ key = scanner.nexttok()
if key != "IHREAL":
huh()
raise TrekError
self.step = 0
def arrived(self):
return self.location.roundtogrid() == self.final
- def next(self):
+ def nexttok(self):
"Next step on course."
self.step += 1
self.nextlocation = self.location + self.increment
scanner.chew()
return
# Make sure enough time is left for the trip
- game.optime = course.dist/0.095
+ game.optime = course.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"))
game.ididit = True
if game.alldone:
return
- power = 20.0 + 100.0*course.dist
+ power = 20.0 + 100.0*course.distance
game.energy -= power
- game.optime = course.dist/0.095
+ game.optime = course.distance/0.095
if game.energy <= 0:
finish(FNRG)
return
skip(1)
prout(_("Engineering to bridge--"))
if not game.shldup or 0.5*wcourse.power(game.warpfac) > game.energy:
- iwarp = (game.energy/(wcourse.dist+0.05)) ** 0.333333333
+ iwarp = (game.energy/(wcourse.distance+0.05)) ** 0.333333333
if iwarp <= 0:
prout(_("We can't do it, Captain. We don't have enough energy."))
else:
look = wcourse.moves
while look > 0:
look -= 1
- wcourse.next()
+ wcourse.nexttok()
w = wcourse.sector()
if not w.valid_sector():
break
def setwarp():
"Change the warp factor."
while True:
- key=scanner.next()
+ key=scanner.nexttok()
if key != "IHEOL":
break
scanner.chew()
else:
prout(_("Uhura- \"The previous probe is still reporting data, Sir.\""))
return
- key = scanner.next()
+ key = scanner.nexttok()
if key == "IHEOL":
if game.nprobes == 1:
prout(_("1 probe left."))
game.isarmed = False
if key == "IHALPHA" and scanner.token == "armed":
game.isarmed = True
- key = scanner.next()
+ key = scanner.nexttok()
elif key == "IHEOL":
proutn(_("Arm NOVAMAX warhead? "))
game.isarmed = ja()
finish(FMATERIALIZE)
return
game.quad[game.sector.i][game.sector.j]=game.ship
- textcolor(GREEN);
+ textcolor(GREEN)
prout(_("succeeds."))
- textcolor(DEFAULT);
+ textcolor(DEFAULT)
dock(False)
skip(1)
prout(_("Lt. Uhura- \"Captain, we made it!\""))
skip(1)
prouts("WWHOOOIIIIIRRRRREEEE.E.E. . . . . . .")
skip(2)
- if withprob(0.98):
+ if not withprob(0.98):
prouts("BOOOIIIOOOIIOOOOIIIOIING . . .")
skip(2)
prout(_("Scotty- \"Oh my God! I've lost them.\""))
"docked":CYAN,
"dead":BROWN}[game.condition])
if game.quad[i][j] != game.ship:
- highvideo();
+ highvideo()
proutn("%c " % game.quad[i][j])
textcolor(DEFAULT)
else:
if game.condition != "docked":
newcnd()
prstat(_("Condition"), _("%s, %i DAMAGES") % \
- (game.condition.upper(), sum(map(lambda x: x > 0, game.damage))))
+ (game.condition.upper(), sum([x > 0 for x in game.damage])))
if not req or req == 3:
prstat(_("Position"), "%s , %s" % (game.quadrant, game.sector))
if not req or req == 4:
def request():
"Request specified status data, a historical relic from slow TTYs."
requests = ("da","co","po","ls","wa","en","to","sh","kl","sy", "ti")
- while scanner.next() == "IHEOL":
+ while scanner.nexttok() == "IHEOL":
proutn(_("Information desired? "))
scanner.chew()
if scanner.token in requests:
prout(_("COMPUTER DAMAGED, USE A POCKET CALCULATOR."))
skip(1)
return
- if scanner.next() != "IHREAL":
+ if scanner.nexttok() != "IHREAL":
prompt = True
scanner.chew()
proutn(_("Destination quadrant and/or sector? "))
- if scanner.next()!="IHREAL":
+ if scanner.nexttok()!="IHREAL":
huh()
return
w1.j = int(scanner.real-0.5)
- if scanner.next() != "IHREAL":
+ if scanner.nexttok() != "IHREAL":
huh()
return
w1.i = int(scanner.real-0.5)
- if scanner.next() == "IHREAL":
+ if scanner.nexttok() == "IHREAL":
w2.j = int(scanner.real-0.5)
- if scanner.next() != "IHREAL":
+ if scanner.nexttok() != "IHREAL":
huh()
return
w2.i = int(scanner.real-0.5)
while True:
scanner.chew()
proutn(_("Time or arrival date? "))
- if scanner.next()=="IHREAL":
+ if scanner.nexttok()=="IHREAL":
ttime = scanner.real
if ttime > game.state.date:
ttime -= game.state.date # Actually a star date
break
scanner.chew()
proutn(_("Warp factor? "))
- if scanner.next()== "IHREAL":
+ if scanner.nexttok()== "IHREAL":
wfl = True
twarp = scanner.real
if twarp<1.0 or twarp > 10.0:
if not wfl:
return
proutn(_("New warp factor to try? "))
- if scanner.next() == "IHREAL":
+ if scanner.nexttok() == "IHREAL":
wfl = True
twarp = scanner.real
if twarp<1.0 or twarp > 10.0:
(scheduled(FCDBAS)<ttime+game.state.date and game.battle == w1):
prout(_("The starbase there will be destroyed by then."))
proutn(_("New warp factor to try? "))
- if scanner.next() == "IHREAL":
+ if scanner.nexttok() == "IHREAL":
wfl = True
twarp = scanner.real
if twarp<1.0 or twarp > 10.0:
"Save game."
if boss:
scanner.push("emsave.trk")
- key = scanner.next()
+ key = scanner.nexttok()
if key == "IHEOL":
proutn(_("File name: "))
- key = scanner.next()
+ key = scanner.nexttok()
if key != "IHALPHA":
huh()
return
except IOError:
prout(_("Can't freeze game as file %s") % scanner.token)
return
- cPickle.dump(game, fp)
+ pickle.dump(game, fp)
fp.close()
scanner.chew()
"Retrieve saved game."
global game
game.passwd = None
- key = scanner.next()
+ key = scanner.nexttok()
if key == "IHEOL":
proutn(_("File name: "))
- key = scanner.next()
+ key = scanner.nexttok()
if key != "IHALPHA":
huh()
return True
except IOError:
prout(_("Can't thaw game in %s") % scanner.token)
return
- game = cPickle.load(fp)
+ game = pickle.load(fp)
fp.close()
scanner.chew()
return False
game.instar = 0
for i in range(GALSIZE):
for j in range(GALSIZE):
- k = randrange(1, QUADSIZE**2/10+1)
+ # Can't have more stars per quadrant than fit in one decimal digit,
+ # if we do the chart representation will break.
+ k = randrange(1, min(10, QUADSIZE**2/10))
game.instar += k
game.state.galaxy[i][j].stars = k
# Locate star bases in galaxy
+ if game.idebug:
+ prout("=== Allocating %d bases" % game.inbase)
for i in range(game.inbase):
while True:
while True:
prout("=== Saving base #%d, close to #%d" % (i, j))
if not contflag:
break
+ if game.idebug:
+ prout("=== Placing base #%d in quadrant %s" % (i, w))
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
prout(_("%d stardates.") % int(game.intime))
proutn(_("%d starbases in ") % game.inbase)
for i in range(game.inbase):
- proutn(`game.state.baseq[i]`)
+ proutn(repr(game.state.baseq[i]))
proutn(" ")
skip(2)
proutn(_("The Enterprise is currently in Quadrant %s") % game.quadrant)
scanner.chew()
# if not scanner.inqueue: # Can start with command line options
proutn(_("Would you like a regular, tournament, or saved game? "))
- scanner.next()
+ scanner.nexttok()
if scanner.sees("tournament"):
- while scanner.next() == "IHEOL":
+ while scanner.nexttok() == "IHEOL":
proutn(_("Type in tournament number-"))
if scanner.real == 0:
scanner.chew()
proutn(_("What is \"%s\"? ") % scanner.token)
scanner.chew()
while game.length==0 or game.skill==SKILL_NONE:
- if scanner.next() == "IHALPHA":
+ if scanner.nexttok() == "IHALPHA":
if scanner.sees("short"):
game.length = 1
elif scanner.sees("medium"):
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.next() != "IHALPHA":
+ if scanner.nexttok() != "IHALPHA":
scanner.chew()
proutn(_("Choose your game style (plain, almy, fancy or just press enter): "))
- scanner.next()
+ 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)
prout(_("LEAVE AT ONCE, OR YOU WILL BE DESTROYED!"))
# Put in THING if needed
if thing == game.quadrant:
- Enemy(type='?', loc=dropin(),
+ Enemy(etype='?', loc=dropin(),
power=randreal(6000,6500.0)+250.0*game.skill)
if not damaged(DSRSENS):
skip(1)
w.j = withprob(0.5) * (QUADSIZE-1)
if game.quad[w.i][w.j] == '.':
break
- game.tholian = Enemy(type='T', loc=w,
+ game.tholian = Enemy(etype='T', loc=w,
power=randrange(100, 500) + 25.0*game.skill)
# Reserve unoccupied corners
if game.quad[0][0]=='.':
while True:
scanner.chew()
proutn(_("Please type in a secret password- "))
- scanner.next()
+ scanner.nexttok()
game.passwd = scanner.token
if game.passwd != None:
break
def helpme():
"Browse on-line help."
- key = scanner.next()
+ key = scanner.nexttok()
while True:
if key == "IHEOL":
setwnd(prompt_window)
proutn(_("Help on what command? "))
- key = scanner.next()
+ key = scanner.nexttok()
setwnd(message_window)
if key == "IHEOL":
return
- cmds = map(lambda x: x[0], commands)
+ cmds = [x[0] for x in commands]
if scanner.token.upper() in cmds or scanner.token.upper() == "ABBREV":
break
skip(1)
setwnd(prompt_window)
clrscr()
proutn("COMMAND> ")
- if scanner.next() == "IHEOL":
+ if scanner.nexttok() == "IHEOL":
if game.options & OPTION_CURSES:
makechart()
continue
abandon_passed = True
if cmd == scanner.token.upper() or (not abandon_passed \
and cmd.startswith(scanner.token.upper())):
- break;
+ break
if cmd == "":
listCommands()
continue
else:
- break;
+ break
if cmd == "SRSCAN": # srscan
srscan()
elif cmd == "STATUS": # status
elif cmd == "EMEXIT": # Emergency exit
clrscr() # Hide screen
freeze(True) # forced save
- raise SystemExit,1 # And quick exit
+ raise SystemExit(1) # And quick exit
elif cmd == "PROBE":
probe() # Launch probe
if game.ididit:
buf += _("Quadrant ")
elif loctype == "sector":
buf += _("Sector ")
- return buf + `w`
+ return buf + repr(w)
def crmshp():
"Emit our ship name."
self.token = None
self.real = 0.0
self.inqueue = []
- def next(self):
+ def nexttok(self):
# Get a token from the user
self.real = 0.0
self.token = ''
return int(round(scanner.real))
def getcoord(self):
s = Coord()
- scanner.next()
+ scanner.nexttok()
if scanner.type != "IHREAL":
huh()
return None
s.i = scanner.int()-1
- scanner.next()
+ scanner.nexttok()
if scanner.type != "IHREAL":
huh()
return None
"Yes-or-no confirmation."
scanner.chew()
while True:
- scanner.next()
+ scanner.nexttok()
if scanner.token == 'y':
return True
if scanner.token == 'n':
for i in range(NDEVICES):
proutn("Kill %s?" % device[i])
scanner.chew()
- key = scanner.next()
+ key = scanner.nexttok()
if key == "IHALPHA" and scanner.sees("y"):
game.damage[i] = 10.0
proutn("Examine/change events? ")
proutn("never")
proutn("? ")
scanner.chew()
- key = scanner.next()
+ key = scanner.nexttok()
if key == 'n':
unschedule(i)
scanner.chew()
if i == FENSLV or i == FREPRO:
scanner.chew()
proutn("In quadrant- ")
- key = scanner.next()
+ key = scanner.nexttok()
# "IHEOL" says to leave coordinates as they are
if key != "IHEOL":
if key != "IHREAL":
unschedule(i)
continue
w.i = int(round(scanner.real))
- key = scanner.next()
+ key = scanner.nexttok()
if key != "IHREAL":
prout("Event %d canceled, no y coordinate." % (i))
unschedule(i)
try:
global line, thing, game
game = None
- thing = Coord()
- thing.angry = False
+ thing = Thingy()
game = Gamestate()
game.options = OPTION_ALL &~ (OPTION_IOMODES | OPTION_PLAIN | OPTION_ALMY)
if os.getenv("TERM"):
game.options |= OPTION_TTY
seed = int(time.time())
(options, arguments) = getopt.getopt(sys.argv[1:], "r:s:txV")
+ replay = False
for (switch, val) in options:
if switch == '-r':
try:
replayfp = open(val, "r")
except IOError:
sys.stderr.write("sst: can't open replay file %s\n" % val)
- raise SystemExit, 1
+ raise SystemExit(1)
try:
line = replayfp.readline().strip()
- (leader, key, seed) = line.split()
+ (leader, __, seed) = line.split()
seed = eval(seed)
sys.stderr.write("sst2k: seed set to %s\n" % seed)
line = replayfp.readline().strip()
arguments += line.split()[2:]
+ replay = True
except ValueError:
sys.stderr.write("sst: replay file %s is ill-formed\n"% val)
raise SystemExit(1)
elif switch == '-x':
game.idebug = True
elif switch == '-V':
- print "SST2K", version
- raise SystemExit, 0
+ print("SST2K", version)
+ raise SystemExit(0)
else:
sys.stderr.write("usage: sst [-t] [-x] [startcommand...].\n")
- raise SystemExit, 1
+ raise SystemExit(1)
# where to save the input in case of bugs
if "TMPDIR" in os.environ:
tmpdir = os.environ['TMPDIR']
if logfp:
logfp.write("# seed %s\n" % seed)
logfp.write("# options %s\n" % " ".join(arguments))
+ logfp.write("# SST2K version %s\n" % version)
logfp.write("# recorded by %s@%s on %s\n" % \
(getpass.getuser(),socket.gethostname(),time.ctime()))
random.seed(seed)
scanner = sstscanner()
- map(scanner.append, arguments)
+ for arg in arguments:
+ scanner.append(arg)
try:
iostart()
while True: # Play a game
game.alldone = False
else:
makemoves()
+ if replay:
+ break
skip(1)
stars()
skip(1)
prout(_("May the Great Bird of the Galaxy roost upon your home planet."))
finally:
ioend()
- raise SystemExit, 0
+ raise SystemExit(0)
except KeyboardInterrupt:
if logfp:
logfp.close()
- print ""
+ print("")
# End.