Also, the nav subsystem (enabling automatic course
setting) can be damaged separately from the main computer (which
handles weapons targeting, ETA calculation, and self-destruct).
+
+After these features were added, I translated this into Python and added
+more:
+
+9. A long-range scan is done silently whenever you call CHART; thus
+the LRSCAN command is no longer needed. (Controlled by OPTION_AUTOSCAN
+and turned off if game type is "plain" or "almy".)
"""
import os,sys,math,curses,time,atexit,readline,cPickle,random,getopt,copy
def __hash__(self):
return hash((x, y))
def __str__(self):
+ if self.x == None or self.y == None:
+ return "Nowhere"
return "%s - %s" % (self.x+1, self.y+1)
__repr__ = __str__
OPTION_CURSES = 0x00000002 # new interface
OPTION_IOMODES = 0x00000003 # cover both interfaces
OPTION_PLANETS = 0x00000004 # planets and mining
-OPTION_THOLIAN = 0x00000008 # Tholians and their webs
-OPTION_THINGY = 0x00000010 # Space Thingy can shoot back
-OPTION_PROBE = 0x00000020 # deep-space probes
+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
-OPTION_MVBADDY = 0x00000100 # more enemies can move
-OPTION_BLKHOLE = 0x00000200 # black hole may timewarp you
-OPTION_BASE = 0x00000400 # bases have good shields
-OPTION_WORLDS = 0x00000800 # logic for inhabited worlds
+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
#
def findevent(evtype): return game.future[evtype]
+class enemy:
+ def __init__(self, loc=None, power=None):
+ if loc:
+ self.kloc = loc
+ else:
+ self.kloc = coord() # enemy sector location
+ self.kpower = power # enemy energy levels
+ self.kdist = self.kavgd = distance(game.sector, e.kloc)
+ def __repr__(self):
+ return "<%s=%f>" % (self.kloc, self.kpower) # For debugging
+
class gamestate:
def __init__(self):
self.options = None # Game options
self.state = snapshot() # A snapshot structure
self.snapsht = snapshot() # Last snapshot taken for time-travel purposes
self.quad = fill2d(QUADSIZE, lambda i, j: IHDOT) # contents of our quadrant
- self.kpower = fill2d(QUADSIZE, lambda i, j: 0.0) # enemy energy levels
- self.kdist = fill2d(QUADSIZE, lambda i, j: 0.0) # enemy distances
- self.kavgd = fill2d(QUADSIZE, lambda i, j: 0.0) # average distances
self.damage = [0.0] * NDEVICES # damage encountered
self.future = [] # future events
for i in range(NEVENTS):
self.future.append(event())
self.passwd = None; # Self Destruct password
- self.ks = fill2d(QUADSIZE, lambda i, j: coord()) # enemy sector locations
+ self.enemies = []
self.quadrant = None # where we are in the large
self.sector = None # where we are in the small
self.tholian = None # coordinates of Tholian
self.nenhere = 0 # number of enemies in quadrant
self.irhere = 0 # Romulans in quadrant
self.isatb = 0 # =1 if super commander is attacking base
- self.tourn = 0 # tournament number
+ self.tourn = None # tournament number
self.proben = 0 # number of moves for probe
self.nprobes = 0 # number of probes available
self.inresor = 0.0 # initial resources
if game.battle == game.quadrant:
return False
# don't leave if over 1000 units of energy
- if game.kpower[loccom] > 1000.0:
+ if game.enemies[loccom].kpower > 1000.0:
return False
# print 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:
- crmena(True, ienm, "sector", game.ks[loccom])
+ crmena(True, ienm, "sector", game.enemies[loccom].kloc)
prout(_(" escapes to Quadrant %s (and regains strength).") % q)
# handle local matters related to escape
- game.quad[game.ks[loccom].x][game.ks[loccom].y] = IHDOT
- game.ks[loccom] = game.ks[game.nenhere]
- game.kavgd[loccom] = game.kavgd[game.nenhere]
- game.kpower[loccom] = game.kpower[game.nenhere]
- game.kdist[loccom] = game.kdist[game.nenhere]
+ game.quad[game.enemies[loccom].kloc.x][game.enemies[loccom].kloc.y] = IHDOT
+ game.enemies[loccom].kloc = game.enemies[game.nenhere].kloc
+ game.enemies[loccom].kavgd = game.enemies[game.nenhere].kavgd
+ game.enemies[loccom].kpower = game.enemies[game.nenhere].kpower
+ game.enemies[loccom].kdist = game.enemies[game.nenhere].kdist
game.klhere -= 1
game.nenhere -= 1
if game.condition != docked:
else:
nbaddys = game.comhere + game.ishere
- dist1 = game.kdist[loccom]
+ dist1 = game.enemies[loccom].kdist
mdist = int(dist1 + 0.5); # Nearest integer distance
# If SC, check with spy to see if should hi-tail it
if ienm==IHS and \
- (game.kpower[loccom] <= 500.0 or (game.condition=="docked" and not damaged(DPHOTON))):
+ (game.enemies[loccom].kpower <= 500.0 or (game.condition=="docked" and not damaged(DPHOTON))):
irun = True
motion = -QUADSIZE
else:
# decide whether to advance, retreat, or hold position
- forces = game.kpower[loccom]+100.0*game.nenhere+400*(nbaddys-1)
+ forces = game.enemies[loccom].kpower+100.0*game.nenhere+400*(nbaddys-1)
if not game.shldup:
forces += 1000; # Good for enemy if shield is down!
if not damaged(DPHASER) or not damaged(DPHOTON):
motion = game.skill
# calculate preferred number of steps
if motion < 0:
- msteps = -motion
+ nsteps = -motion
else:
- msteps = motion
+ nsteps = motion
if motion > 0 and nsteps > mdist:
nsteps = mdist; # don't overshoot
if nsteps > QUADSIZE:
game.quad[next.x][next.y] = ienm
if next != com:
# it moved
- game.ks[loccom] = next
- game.kdist[loccom] = game.kavgd[loccom] = distance(game.sector, next)
+ game.enemies[loccom].kloc = next
+ game.enemies[loccom].kdist = game.enemies[loccom].kavgd = distance(game.sector, next)
if not damaged(DSRSENS) or game.condition == docked:
proutn("***")
cramen(ienm)
proutn(_(" from Sector %s") % com)
- if game.kdist[loccom] < dist1:
+ if game.enemies[loccom].kdist < dist1:
proutn(_(" advances to "))
else:
proutn(_(" retreats to "))
# and do move
if game.comhere:
for i in range(game.nenhere):
- w = game.ks[i]
+ w = game.enemies[i].kloc
if game.quad[w.x][w.y] == IHC:
movebaddy(w, i, IHC)
break
if game.ishere:
for i in range(game.nenhere):
- w = game.ks[i]
+ w = game.enemies[i].kloc
if game.quad[w.x][w.y] == IHS:
movebaddy(w, i, IHS)
break
# commander(s) do.
if game.skill >= SKILL_EXPERT and (game.options & OPTION_MVBADDY):
for i in range(game.nenhere):
- w = game.ks[i]
+ w = game.enemies[i].kloc
if game.quad[w.x][w.y] == IHK or game.quad[w.x][w.y] == IHR:
movebaddy(w, i, game.quad[w.x][w.y])
sortklings();
game.ientesc = False
unschedule(FSCDBAS)
for i in range(game.nenhere):
- if game.quad[game.ks[i].x][game.ks[i].y] == IHS:
+ if game.quad[game.enemies[i].kloc.x][game.enemies[i].kloc.y] == IHS:
break
- game.quad[game.ks[i].x][game.ks[i].y] = IHDOT
- game.ks[i] = game.ks[game.nenhere]
- game.kdist[i] = game.kdist[game.nenhere]
- game.kavgd[i] = game.kavgd[game.nenhere]
- game.kpower[i] = game.kpower[game.nenhere]
+ game.quad[game.enemies[i].kloc.x][game.enemies[i].kloc.y] = IHDOT
+ game.enemies[i].kloc = game.enemies[game.nenhere].kloc
+ game.enemies[i].kdist = game.enemies[game.nenhere].kdist
+ game.enemies[i].kavgd = game.enemies[game.nenhere].kavgd
+ game.enemies[i].kpower = game.enemies[game.nenhere].kpower
game.klhere -= 1
game.nenhere -= 1
if game.condition!=docked:
if game.quad[game.tholian.x][game.tholian.y]==IHDOT:
game.quad[game.tholian.x][game.tholian.y] = IHWEB
game.quad[game.tholian.x][game.tholian.y] = IHT
- game.ks[game.nenhere] = game.tholian
+ game.enemies[game.nenhere].kloc = game.tholian
# check to see if all holes plugged
for i in range(QUADSIZE):
proutn(_(" rammed by "))
else:
proutn(_(" rams "))
- crmena(False, ienm, sector, w)
+ crmena(False, ienm, "sector", w)
if ibumpd:
proutn(_(" (original position)"))
skip(1)
shoved = True
elif iquad in (IHC, IHS): # Hit a commander
if withprob(0.05):
- crmena(True, iquad, sector, w)
+ crmena(True, iquad, "sector", w)
prout(_(" uses anti-photon device;"))
prout(_(" torpedo neutralized."))
return None
elif iquad in (IHR, IHK): # Hit a regular enemy
# find the enemy
for ll in range(game.nenhere):
- if w == game.ks[ll]:
+ if w == game.enemies[ll].kloc:
break
- kp = math.fabs(game.kpower[ll])
+ kp = math.fabs(game.enemies[ll].kpower)
h1 = 700.0 + randrange(100) - \
1000.0 * distance(w, incoming) * math.fabs(math.sin(bullseye-angle))
h1 = math.fabs(h1)
if kp < h1:
h1 = kp
- if game.kpower[ll] < 0:
- game.kpower[ll] -= -h1
+ if game.enemies[ll].kpower < 0:
+ game.enemies[ll].kpower -= -h1
else:
- game.kpower[ll] -= h1
- if game.kpower[ll] == 0:
+ game.enemies[ll].kpower -= h1
+ if game.enemies[ll].kpower == 0:
deadkl(w, iquad, w)
return None
crmena(True, iquad, "sector", w)
prout(_(" damaged but not destroyed."))
return None
proutn(_(" damaged--"))
- game.ks[ll] = jw
+ game.enemies[ll].kloc = jw
shoved = True
break
elif iquad == IHB: # Hit a base
newcnd()
return None
elif iquad == IHP: # Hit a planet
- crmena(True, iquad, sector, w)
+ crmena(True, iquad, "sector", w)
prout(_(" destroyed."))
game.state.nplankl += 1
game.state.galaxy[game.quadrant.x][game.quadrant.y].planet = None
finish(FDPLANET)
return None
elif iquad == IHW: # Hit an inhabited world -- very bad!
- crmena(True, iquad, sector, w)
+ crmena(True, iquad, "sector", w)
prout(_(" destroyed."))
game.state.nworldkl += 1
game.state.galaxy[game.quadrant.x][game.quadrant.y].planet = None
if withprob(0.9):
nova(w)
else:
- crmena(True, IHSTAR, sector, w)
+ crmena(True, IHSTAR, "sector", w)
prout(_(" unaffected by photon blast."))
return None
elif iquad == IHQUEST: # Hit a thingy
return None
elif iquad == IHBLANK: # Black hole
skip(1)
- crmena(True, IHBLANK, sector, w)
+ crmena(True, IHBLANK, "sector", w)
prout(_(" swallows torpedo."))
return None
elif iquad == IHWEB: # hit the web
deadkl(w, iquad, w)
return None
skip(1)
- crmena(True, IHT, sector, w)
+ crmena(True, IHT, "sector", w)
if withprob(0.05):
prout(_(" survives photon blast."))
return None
else: # Problem!
skip(1)
proutn("Don't know how to handle torpedo collision with ")
- crmena(True, iquad, sector, w)
+ crmena(True, iquad, "sector", w)
skip(1)
return None
break
game.quad[jw.x][jw.y]=iquad
prout(_(" displaced by blast to Sector %s ") % jw)
for ll in range(game.nenhere):
- game.kdist[ll] = game.kavgd[ll] = distance(game.sector,game.ks[ll])
+ game.enemies[ll].kdist = game.enemies[ll].kavgd = distance(game.sector,game.enemies[ll].kloc)
sortklings()
return None
skip(1)
def fry(hit):
# critical-hit resolution
- ktr=1
- # a critical hit occured
if hit < (275.0-25.0*game.skill)*randreal(1.0, 1.5):
return
ncrit = int(1.0 + hit/(500.0+randreal(100)))
cdam.append(j)
extradm = (hit*game.damfac)/(ncrit*randreal(75, 100))
game.damage[j] += extradm
- if loop1 > 0:
- for loop2 in range(loop1):
- if j == cdam[loop2]:
- break
- if loop2 < loop1:
- continue
- ktr += 1
- if ktr==3:
- skip(1)
- proutn(_(" and "))
+ skipcount = 0
+ for (i, j) in enumerate(cdam):
proutn(device[j])
+ if skipcount % 3 == 2 and i < len(cdam)-1:
+ skip()
+ skipcount += 1
+ if i < len(cdam)-1:
+ proutn(_(" and "))
prout(_(" damaged."))
if damaged(DSHIELD) and game.shldup:
prout(_("***Shields knocked down."))
if game.skill <= SKILL_FAIR:
where = "sector"
for loop in range(game.nenhere):
- if game.kpower[loop] < 0:
+ if game.enemies[loop].kpower < 0:
continue; # too weak to attack
# compute hit strength and diminish shield power
r = randreal()
# Increase chance of photon torpedos if docked or enemy energy low
if game.condition == "docked":
r *= 0.25
- if game.kpower[loop] < 500:
+ if game.enemies[loop].kpower < 500:
r *= 0.25;
- jay = game.ks[loop]
+ jay = game.enemies[loop].kloc
iquad = game.quad[jay.x][jay.y]
if iquad==IHT or (iquad==IHQUEST and not iqengry):
continue
continue; # Don't waste the effort!
attempt = True; # Attempt to attack
dustfac = 0.8 + randreal(0.5)
- hit = game.kpower[loop]*math.pow(dustfac,game.kavgd[loop])
- game.kpower[loop] *= 0.75
+ hit = game.enemies[loop].kpower*math.pow(dustfac,game.enemies[loop].kavgd)
+ game.enemies[loop].kpower *= 0.75
else: # Enemy uses photon torpedo
course = 1.90985*math.atan2(game.sector.y-jay.y, jay.x-game.sector.x)
hit = 0
attempt = True
prout(" ")
r = (randreal()+randreal())*0.5 - 0.5
- r += 0.002*game.kpower[loop]*r
+ r += 0.002*game.enemies[loop].kpower*r
hit = torpedo(course, r, jay, 1, 1)
if (game.state.remkl + game.state.remcom + game.state.nscrem)==0:
finish(FWON); # Klingons did themselves in!
game.state.crew -= icas
# After attack, reset average distance to enemies
for loop in range(game.nenhere):
- game.kavgd[loop] = game.kdist[loop]
+ game.enemies[loop].kavgd = game.enemies[loop].kdist
sortklings()
return;
def deadkl(w, type, mv):
# kill a Klingon, Tholian, Romulan, or Thingy
# Added mv to allow enemy to "move" before dying
- crmena(True, type, sector, mv)
+ crmena(True, type, "sector", mv)
# Decide what kind of enemy it is and update appropriately
if type == IHR:
# chalk up a Romulan
if is_scheduled(FCDBAS) and game.battle == game.quadrant and type==IHC:
unschedule(FCDBAS)
for i in range(game.nenhere):
- if game.ks[i] == w:
+ if game.enemies[i].kloc == w:
for j in range(i, game.nenhere):
- game.ks[j] = game.ks[j+1]
- game.kpower[j] = game.kpower[j+1]
- game.kavgd[j] = game.kdist[j] = game.kdist[j+1]
- game.ks[game.nenhere].x = 0
- game.ks[game.nenhere].y = 0
- game.kdist[game.nenhere] = 0
- game.kavgd[game.nenhere] = 0
- game.kpower[game.nenhere] = 0
+ game.enemies[j].kloc = game.enemies[j+1].kloc
+ game.enemies[j].kpower = game.enemies[j+1].kpower
+ game.enemies[j].kavgd = game.enemies[j].kdist = game.enemies[j+1].kdist
+ game.enemies[game.nenhere].kloc.x = 0
+ game.enemies[game.nenhere].kloc.y = 0
+ game.enemies[game.nenhere].kdist = 0
+ game.enemies[game.nenhere].kavgd = 0
+ game.enemies[game.nenhere].kpower = 0
game.nenhere -= 1
break
break
return True;
def hittem(hits):
- # register a phaser hit on Klingons and Romulans
- nenhr2 = game.nenhere; kk=1
+ # register a phaser hit on Klingons and Romulans
+ nenhr2 = game.nenhere; kk=0
w = coord()
skip(1)
- for k in range(nenhr2):
- wham = hits[k]
+ for (k, wham) in enumerate(hits):
if wham==0:
continue
dustfac = randreal(0.9, 1.0)
- hit = wham*math.pow(dustfac,game.kdist[kk])
- kpini = game.kpower[kk]
+ hit = wham*math.pow(dustfac,game.enemies[kk].kdist)
+ kpini = game.enemies[kk].kpower
kp = math.fabs(kpini)
if PHASEFAC*hit < kp:
kp = PHASEFAC*hit
- if game.kpower[kk] < 0:
- game.kpower[kk] -= -kp
+ if game.enemies[kk].kpower < 0:
+ game.enemies[kk].kpower -= -kp
else:
- game.kpower[kk] -= kp
- kpow = game.kpower[kk]
- w = game.ks[kk]
+ game.enemies[kk].kpower -= kp
+ kpow = game.enemies[kk].kpower
+ w = game.enemies[kk].kloc
if hit > 0.005:
if not damaged(DSRSENS):
boom(w)
finish(FWON);
if game.alldone:
return
- kk -= 1; # don't do the increment
+ 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:
prout(_("***Mr. Spock- \"Captain, the vessel at Sector %s")%w)
prout(_(" has just lost its firepower.\""))
- game.kpower[kk] = -kpow
+ game.enemies[kk].kpower = -kpow
kk += 1
- return;
+ return
def phasers():
# fire phasers
chew()
if not kz:
for i in range(game.nenhere):
- irec += math.fabs(game.kpower[i])/(PHASEFAC*math.pow(0.90,game.kdist[i]))*randreal(1.01, 1.06) + 1.0
+ irec += math.fabs(game.enemies[i].kpower)/(PHASEFAC*math.pow(0.90,game.enemies[i].kdist))*randreal(1.01, 1.06) + 1.0
kz=1
proutn(_("%d units required. ") % irec)
chew()
hits.append(0.0)
if powrem <= 0:
continue
- hits[i] = math.fabs(game.kpower[i])/(PHASEFAC*math.pow(0.90,game.kdist[i]))
+ hits[i] = math.fabs(game.enemies[i].kpower)/(PHASEFAC*math.pow(0.90,game.enemies[i].kdist))
over = randreal(1.01, 1.06) * hits[i]
temp = powrem
powrem -= hits[i] + over
elif automode == "MANUAL":
rpow = 0.0
for k in range(game.nenhere):
- aim = game.ks[k]
+ aim = game.enemies[k].kloc
ienm = game.quad[aim.x][aim.y]
if msgflag:
proutn(_("Energy available= %.2f") % (avail-0.006))
if key == IHEOL:
chew()
if itarg and k > kz:
- irec=(abs(game.kpower[k])/(PHASEFAC*math.pow(0.9,game.kdist[k]))) * randreal(1.01, 1.06) + 1.0
+ irec=(abs(game.enemies[k].kpower)/(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 "))
- crmena(False, ienm, sector, aim)
+ crmena(False, ienm, "sector", aim)
proutn("- ")
key = scan()
if key == IHALPHA and isit("no"):
game.iseenit = True
announce()
skip(1)
- proutn(_("Lt. Uhura- \"Captain, the starbase in Quadrant %s") % game.battle)
+ prout(_("Lt. Uhura- \"Captain, the starbase in Quadrant %s") % game.battle)
prout(_(" reports that it is under attack and that it can"))
- proutn(_(" hold out only until stardate %d") % (int(scheduled(FCDBAS))))
- prout(".\"")
+ prout(_(" hold out only until stardate %d.\"") % (int(scheduled(FCDBAS))))
if cancelrest():
return
elif evcode == FSCDBAS: # Supercommander destroys base
q.klingons += 1
if game.quadrant == w:
game.klhere += 1
- newkling(game.klhere)
+ game.enemies.append(newkling())
# recompute time left
game.recompute()
# report the disaster if we can
return
# handle initial nova
game.quad[nov.x][nov.y] = IHDOT
- crmena(False, IHSTAR, sector, nov)
+ crmena(False, IHSTAR, "sector", nov)
prout(_(" novas."))
game.state.galaxy[game.quadrant.x][game.quadrant.y].stars -= 1
game.state.starkl += 1
hits[top2][2]=scratch.y
game.state.galaxy[game.quadrant.x][game.quadrant.y].stars -= 1
game.state.starkl += 1
- crmena(True, IHSTAR, sector, scratch)
+ crmena(True, IHSTAR, "sector", scratch)
prout(_(" novas."))
game.quad[scratch.x][scratch.y] = IHDOT
elif iquad == IHP: # Destroy planet
game.state.galaxy[game.quadrant.x][game.quadrant.y].planet = None
game.state.nplankl += 1
- crmena(True, IHP, sector, scratch)
+ crmena(True, IHP, "sector", scratch)
prout(_(" destroyed."))
game.iplnet.pclass = "destroyed"
game.iplnet = None
invalidate(game.base)
game.state.basekl += 1
newcnd()
- crmena(True, IHB, sector, scratch)
+ crmena(True, IHB, "sector", scratch)
prout(_(" destroyed."))
game.quad[scratch.x][scratch.y] = IHDOT
elif iquad in (IHE, IHF): # Buffet ship
deadkl(scratch,iquad, scratch)
elif iquad in (IHC,IHS,IHR): # Damage/destroy big enemies
for ll in range(game.nenhere):
- if game.ks[ll] == scratch:
+ if game.enemies[ll].kloc == scratch:
break
- game.kpower[ll] -= 800.0 # If firepower is lost, die
- if game.kpower[ll] <= 0.0:
+ game.enemies[ll].kpower -= 800.0 # If firepower is lost, die
+ if game.enemies[ll].kpower <= 0.0:
deadkl(scratch, iquad, scratch)
break
newc.x = scratch.x + scratch.x - hits[mm][1]
newc.y = scratch.y + scratch.y - hits[mm][2]
- crmena(True, iquad, sector, scratch)
+ crmena(True, iquad, "sector", scratch)
proutn(_(" damaged"))
if not VALID_SECTOR(newc.x, newc.y):
# can't leave quadrant
iquad1 = game.quad[newc.x][newc.y]
if iquad1 == IHBLANK:
proutn(_(", blasted into "))
- crmena(False, IHBLANK, sector, newc)
+ crmena(False, IHBLANK, "sector", newc)
skip(1)
deadkl(scratch, iquad, newc)
break
proutn(_(", buffeted to Sector %s") % newc)
game.quad[scratch.x][scratch.y] = IHDOT
game.quad[newc.x][newc.y] = iquad
- game.ks[ll] = newc
- game.kdist[ll] = game.kavgd[ll] = distance(game.sector, newc)
+ game.enemies[ll].kloc = newc
+ game.enemies[ll].kdist = game.enemies[ll].kavgd = distance(game.sector, newc)
skip(1)
if top == top2:
break
whammo = 25.0 * game.energy
l=1
while l <= game.nenhere:
- if game.kpower[l]*game.kdist[l] <= whammo:
- deadkl(game.ks[l], game.quad[game.ks[l].x][game.ks[l].y], game.ks[l])
+ if game.enemies[l].kpower*game.enemies[l].kdist <= whammo:
+ deadkl(game.enemies[l].kloc, game.quad[game.enemies[l].kloc.x][game.enemies[l].kloc.y], game.enemies[l].kloc)
l += 1
finish(FDILITHIUM)
def prouts(line):
"print slowly!"
for c in line:
- time.sleep(0.03)
+ if not replayfp or replayfp.closed: # Don't slow down replays
+ time.sleep(0.03)
proutn(c)
if game.options & OPTION_CURSES:
wrefresh(curwnd)
else:
sys.stdout.flush()
- time.sleep(0.03)
+ if not replayfp or replayfp.closed:
+ time.sleep(0.03)
def cgetline():
"Get a line of input."
if replayfp and not replayfp.closed:
while True:
line = replayfp.readline()
+ proutn(line)
if line == '':
prout("*** Replay finished")
replayfp.close()
elif line[0] != "#":
break
else:
- line = raw_input("COMMAND> ")
+ line = raw_input()
if logfp:
logfp.write(line + "\n")
return line
setwnd(lrscan_window)
lrscan_window.clear()
lrscan_window.move(0, 0)
- lrscan()
+ lrscan(silent=False)
def put_srscan_sym(w, sym):
"Emit symbol for short-range scan."
game.quad[game.sector.x][game.sector.y] = game.ship
if game.nenhere:
for m in range(game.nenhere):
- finald = distance(w, game.ks[m])
- game.kavgd[m] = 0.5 * (finald+game.kdist[m])
- game.kdist[m] = finald
+ finald = distance(w, game.enemies[m].kloc)
+ game.enemies[m].kavgd = 0.5 * (finald+game.enemies[m].kdist)
+ game.enemies[m].kdist = finald
sortklings()
if not game.state.galaxy[game.quadrant.x][game.quadrant.y].supernova:
attack(False)
for m in range(game.nenhere):
- game.kavgd[m] = game.kdist[m]
+ game.enemies[m].kavgd = game.enemies[m].kdist
newcnd()
drawmaps(0)
setwnd(message_window)
if game.nenhere != 0 and not novapush:
newcnd()
for m in range(game.nenhere):
- finald = distance(w, game.ks[m])
- game.kavgd[m] = 0.5 * (finald + game.kdist[m])
+ finald = distance(w, game.enemies[m].kloc)
+ game.enemies[m].kavgd = 0.5 * (finald + game.enemies[m].kdist)
#
# Stas Sergeev added the condition
# that attacks only happen if Klingons
prouts(_("Sulu- \"Captain! It's working!\""))
skip(2)
while game.nenhere > 0:
- deadkl(game.ks[1], game.quad[game.ks[1].x][game.ks[1].y],game.ks[1])
+ deadkl(game.enemies[1].kloc, game.quad[game.enemies[1].kloc.x][game.enemies[1].kloc.y],game.enemies[1].kloc)
prout(_("Ensign Chekov- \"Congratulations, Captain!\""))
if (game.state.remkl + game.state.remcom + game.state.nscrem) == 0:
finish(FWON)
(i, (_("s"), "")[i==1]))
skip(1)
-def lrscan():
+def lrscan(silent):
# long-range sensor scan
if damaged(DLRSENS):
# Now allow base's sensors if docked
if game.condition != "docked":
- prout(_("LONG-RANGE SENSORS DAMAGED."))
+ if not silent:
+ prout(_("LONG-RANGE SENSORS DAMAGED."))
return
- prout(_("Starbase's long-range scan"))
- else:
+ if not silent:
+ prout(_("Starbase's long-range scan"))
+ elif not silent:
prout(_("Long-range scan"))
for x in range(game.quadrant.x-1, game.quadrant.x+2):
- proutn(" ")
+ if not silent:
+ proutn(" ")
for y in range(game.quadrant.y-1, game.quadrant.y+2):
if not VALID_QUADRANT(x, y):
- proutn(" -1")
+ if not silent:
+ proutn(" -1")
else:
if not damaged(DRADIO):
game.state.galaxy[x][y].charted = True
game.state.chart[x][y].klingons = game.state.galaxy[x][y].klingons
game.state.chart[x][y].starbase = game.state.galaxy[x][y].starbase
game.state.chart[x][y].stars = game.state.galaxy[x][y].stars
- if game.state.galaxy[x][y].supernova:
+ if not silent and game.state.galaxy[x][y].supernova:
proutn(" ***")
- else:
+ elif not silent:
proutn(" %3d" % (game.state.chart[x][y].klingons*100 + game.state.chart[x][y].starbase * 10 + game.state.chart[x][y].stars))
prout(" ")
def chart():
# display the star chart
chew()
+ if (game.options & OPTION_AUTOSCAN):
+ lrscan(silent=True)
if not damaged(DRADIO):
rechart()
if game.lastchart < game.state.date and game.condition == "docked":
break
game.state.kscmdr = w
game.state.galaxy[w.x][w.y].klingons += 1
- # Place thing (in tournament game, thingx == -1, don't want one!)
+ # Place thing (in tournament game, we don't want one!)
global thing
- if thing == None:
- thing = randplace(GALSIZE)
+ if game.tourn is None:
+ thing = randplace(GALSIZE)
skip(2)
game.state.snap = False
if game.skill == SKILL_NOVICE:
if not game.alive:
game.condition="dead"
-def newkling(i):
- # drop new Klingon into current quadrant
- pi = dropin(IHK)
- game.ks[i] = pi
- game.kdist[i] = game.kavgd[i] = distance(game.sector, pi)
- game.kpower[i] = randreal(300, 450) + 25.0*game.skill
- return pi
+def newkling():
+ # drop new Klingon into current quadrant
+ return enemy(loc=dropin(IHK), power=randreal(300, 450) + 25.0*game.skill)
def newqad(shutup):
# set up a new state of quadrant, for when we enter or re-enter it
game.nenhere = game.klhere + game.irhere
# Position Starship
game.quad[game.sector.x][game.sector.y] = game.ship
+ game.enemies = []
if q.klingons:
- w.x = w.y = 0 # quiet a gcc warning
# Position ordinary Klingons
for i in range(game.klhere):
- w = newkling(i)
+ game.enemies.append(newkling())
# If we need a commander, promote a Klingon
for i in range(game.state.remcom):
if game.state.kcmdr[i] == game.quadrant:
- break
-
- if i <= game.state.remcom:
- game.quad[w.x][w.y] = IHC
- game.kpower[game.klhere] = randreal(950, 1350) + 50.0*game.skill
- game.comhere = True
+ e = game.enemies[game.klhere-1]
+ game.quad[e.kloc.x][e.kloc.y] = IHC
+ e.kpower = randreal(950,1350) + 50.0*game.skill
+ game.comhere = True
+ break
# If we need a super-commander, promote a Klingon
if game.quadrant == game.state.kscmdr:
- game.quad[game.ks[0].x][game.ks[0].y] = IHS
- game.kpower[0] = randreal(1175.0, 1575.0) + 125.0*game.skill
+ e = game.enemies[0]
+ game.quad[e.kloc.x][e.kloc.y] = IHS
+ e.kpower = randreal(1175.0, 1575.0) + 125.0*game.skill
game.iscate = (game.state.remkl > 1)
game.ishere = True
# Put in Romulans if needed
for i in range(game.klhere, game.nenhere):
- w = dropin(IHR)
- game.ks[i] = w
- game.kdist[i] = game.kavgd[i] = distance(game.sector, w)
- game.kpower[i] = randreal(400.0, 850.0) + 50.0*game.skill
+ game.enemies.append(enemy(loc=dropin(IHR),
+ power=randreal(400.0,850.0)+50.0*game.skill))
# If quadrant needs a starbase, put it in
if q.starbase:
game.base = dropin(IHB)
# Check for condition
newcnd()
# And finally the stars
- for i in range(q.stars):
+ for i in range(q.stars):
dropin(IHSTAR)
-
# Check for RNZ
if game.irhere > 0 and game.klhere == 0:
game.neutz = True
prout(_("LEAVE AT ONCE, OR YOU WILL BE DESTROYED!"))
if shutup==0:
# Put in THING if needed
- global thing
if thing == game.quadrant:
- w = dropin(IHQUEST)
- thing = randplace(GALSIZE)
+ e = enemy(dropin(IHQUEST))
+ e.kdist = e.kavgd = distance(game.sector, e.kloc)
+ e.kpower = randreal(6000,6500.0)+250.0*game.skill
+ games.enemies.append(e)
game.nenhere += 1
- game.ks[game.nenhere] = w
- game.kdist[game.nenhere] = game.kavgd[game.nenhere] = \
- distance(game.sector, w)
- game.kpower[game.nenhere] = randreal(6000,6500.0)+250.0*game.skill
if not damaged(DSRSENS):
skip(1)
prout(_("Mr. Spock- \"Captain, this is most unusual."))
if game.quad[game.tholian.x][game.tholian.y] == IHDOT:
break
game.quad[game.tholian.x][game.tholian.y] = IHT
+ game.enemies.append(loc=game.tholian,
+ power=randrange(100, 500) + 25.0*game.skill)
game.nenhere += 1
- game.ks[game.nenhere] = game.tholian
- game.kdist[game.nenhere] = game.kavgd[game.nenhere] = \
- distance(game.sector, game.tholian)
- game.kpower[game.nenhere] = randrange(100, 500) + 25.0*game.skill
# Reserve unoccupied corners
if game.quad[0][0]==IHDOT:
game.quad[0][0] = 'X'
return
while True:
sw = False
- for j in range(game.nenhere):
- if game.kdist[j] > game.kdist[j+1]:
+ for j in range(game.nenhere-1):
+ if game.enemies[j].kdist > game.enemies[j+1].kdist:
sw = True
- t = game.kdist[j]
- game.kdist[j] = game.kdist[j+1]
- game.kdist[j+1] = t
- t = game.kavgd[j]
- game.kavgd[j] = game.kavgd[j+1]
- game.kavgd[j+1] = t
- k = game.ks[j].x
- game.ks[j].x = game.ks[j+1].x
- game.ks[j+1].x = k
- k = game.ks[j].y
- game.ks[j].y = game.ks[j+1].y
- game.ks[j+1].y = k
- t = game.kpower[j]
- game.kpower[j] = game.kpower[j+1]
- game.kpower[j+1] = t
+ t = game.enemies[j].kdist
+ game.enemies[j].kdist = game.enemies[j+1].kdist
+ game.enemies[j+1].kdist = t
+ t = game.enemies[j].kavgd
+ game.enemies[j].kavgd = game.enemies[j+1].kavgd
+ game.enemies[j+1].kavgd = t
+ k = game.enemies[j].kloc.x
+ game.enemies[j].kloc.x = game.enemies[j+1].kloc.x
+ game.enemies[j+1].kloc.x = k
+ k = game.enemies[j].kloc.y
+ game.enemies[j].kloc.y = game.enemies[j+1].kloc.y
+ game.enemies[j+1].kloc.y = k
+ t = game.enemies[j].kpower
+ game.enemies[j].kpower = game.enemies[j+1].kpower
+ game.enemies[j+1].kpower = t
if not sw:
break
chew()
setwnd(prompt_window)
clrscr()
+ proutn("COMMAND> ")
if scan() == IHEOL:
if game.options & OPTION_CURSES:
makechart()
elif cmd == "REQUEST": # status request
request()
elif cmd == "LRSCAN": # long range scan
- lrscan()
+ lrscan(silent=False)
elif cmd == "PHASERS": # phasers
phasers()
if game.ididit:
atover(True)
if __name__ == '__main__':
- global line, thing, game, idebug, iqengry
- game = citem = aaitem = inqueue = None
- line = ''
- thing = coord()
- iqengry = False
- game = gamestate()
- idebug = 0
- game.options = OPTION_ALL &~ (OPTION_IOMODES | OPTION_SHOWME | OPTION_PLAIN | OPTION_ALMY)
- # Disable curses mode until the game logic is working.
- # if os.getenv("TERM"):
- # game.options |= OPTION_CURSES | OPTION_SHOWME
- # else:
- game.options |= OPTION_TTY
- seed = int(time.time())
- (options, arguments) = getopt.getopt(sys.argv[1:], "r:tx")
- 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
- line = replayfp.readline().strip()
- try:
- (leader, key, seed) = line.split()
- seed = eval(seed)
- sys.stderr.write("sst2k: seed set to %s\n" % seed)
- except ValueError:
- sys.stderr.write("sst: replay file %s is ill-formed\n"% val)
- os.exit(1)
- game.options |= OPTION_TTY
- game.options &=~ OPTION_CURSES
- elif switch == '-t':
- game.options |= OPTION_TTY
- game.options &=~ OPTION_CURSES
- elif switch == '-x':
- idebug = True
- else:
- sys.stderr.write("usage: sst [-t] [-x] [startcommand...].\n")
- os.exit(0)
- # where to save the input in case of bugs
try:
- logfp = open("/usr/tmp/sst-input.log", "w")
- except IOError:
- sys.stderr.write("sst: warning, can't open logfile\n")
- if logfp:
- logfp.write("# seed %s\n" % seed)
- random.seed(seed)
- iostart()
- if arguments:
- inqueue = arguments
- else:
- inqueue = None
- while True: # Play a game
- setwnd(fullscreen_window)
- clrscr()
- prelim()
- setup(needprompt=not inqueue)
- if game.alldone:
- score()
- game.alldone = False
- else:
- makemoves()
- skip(1)
- stars()
- skip(1)
- if game.tourn and game.alldone:
- proutn(_("Do you want your score recorded?"))
- if ja() == True:
- chew2()
- freeze(False)
- chew()
- proutn(_("Do you want to play again? "))
- if not ja():
- break
- skip(1)
- prout(_("May the Great Bird of the Galaxy roost upon your home planet."))
- raise SystemExit, 0
+ global line, thing, game, idebug, iqengry
+ game = citem = aaitem = inqueue = None
+ line = ''
+ thing = coord()
+ iqengry = False
+ game = gamestate()
+ idebug = 0
+ game.options = OPTION_ALL &~ (OPTION_IOMODES | OPTION_PLAIN | OPTION_ALMY)
+ # Disable curses mode until the game logic is working.
+ # if os.getenv("TERM"):
+ # game.options |= OPTION_CURSES | OPTION_SHOWME
+ # else:
+ game.options |= OPTION_TTY
+ seed = int(time.time())
+ (options, arguments) = getopt.getopt(sys.argv[1:], "r:tx")
+ 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
+ try:
+ line = replayfp.readline().strip()
+ (leader, key, seed) = line.split()
+ seed = eval(seed)
+ sys.stderr.write("sst2k: seed set to %s\n" % seed)
+ line = replayfp.readline().strip()
+ arguments += line.split()[2:]
+ except ValueError:
+ 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 == '-t':
+ game.options |= OPTION_TTY
+ game.options &=~ OPTION_CURSES
+ elif switch == '-x':
+ idebug = True
+ else:
+ sys.stderr.write("usage: sst [-t] [-x] [startcommand...].\n")
+ raise SystemExit, 1
+ # where to save the input in case of bugs
+ try:
+ logfp = open("/usr/tmp/sst-input.log", "w")
+ except IOError:
+ sys.stderr.write("sst: warning, can't open logfile\n")
+ if logfp:
+ logfp.write("# seed %s\n" % seed)
+ logfp.write("# options %s\n" % " ".join(arguments))
+ random.seed(seed)
+ iostart()
+ if arguments:
+ inqueue = arguments
+ else:
+ inqueue = None
+ while True: # Play a game
+ setwnd(fullscreen_window)
+ clrscr()
+ prelim()
+ setup(needprompt=not inqueue)
+ if game.alldone:
+ score()
+ game.alldone = False
+ else:
+ makemoves()
+ skip(1)
+ stars()
+ skip(1)
+ if game.tourn and game.alldone:
+ proutn(_("Do you want your score recorded?"))
+ if ja() == True:
+ chew2()
+ freeze(False)
+ chew()
+ proutn(_("Do you want to play again? "))
+ if not ja():
+ break
+ skip(1)
+ prout(_("May the Great Bird of the Galaxy roost upon your home planet."))
+ raise SystemExit, 0
+ except KeyboardInterrupt:
+ print""
+ pass
+