"""
sst.py =-- Super Star Trek in Python
+This code is a Python translation of a C translation of a FORTRAN original.
+The FORTRANness still shows in many ways, notably the use of 1-origin index
+an a lot of parallel arrays where a more modern language would use structures
+or objects.
"""
-import os, sys, math, curses
+import os, sys, math, curses, time
SSTDOC = "/usr/share/doc/sst/sst.doc"
DDSP = 15
NDEVICES= 16 # Number of devices
+SKILL_NONE = 0
+SKILL_NOVICE = 1
+SKILL_FAIR = 2
+SKILL_GOOD = 3
+SKILL_EXPERT = 4
+SKILL_EMERITUS = 5
+
def damaged(dev): return (game.damage[dev] != 0.0)
# Define future events
self.probeinx = 0.0 # probe x,y increment
self.probeiny = 0.0 #
self.height = 0.0 # height of orbit around planet
-
+ def recompute(self):
+ # Stas thinks this should be (C expression):
+ # game.state.remkl + game.state.remcom > 0 ?
+ # game.state.remres/(game.state.remkl + 4*game.state.remcom) : 99
+ # 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*game.state.remcom)
# From enumerated type 'feature'
IHR = 'R'
IHK = 'K'
game.quad[w.x][w.y] = IHDOT
if (game.state.remkl + game.state.remcom + game.state.nscrem)==0:
return
-
- game.state.remtime = game.state.remres/(game.state.remkl + 4*game.state.remcom)
-
+ game.recompute()
# Remove enemy ship from arrays describing local conditions
if is_scheduled(FCDBAS) and same(game.battle, game.quadrant) and type==IHC:
unschedule(FCDBAS)
game.shldup = False
overheat(rpow);
+# Code from events,c begins here.
+
+# This isn't a real event queue a la BSD Trek yet -- you can only have one
+# event of each type active at any given time. Mostly these means we can
+# only have one FDISTR/FENSLV/FREPRO sequence going at any given time
+# BSD Trek, from which we swiped the idea, can have up to 5.
+
+import math
+
+def unschedule(evtype):
+ # remove an event from the schedule
+ game.future[evtype].date = FOREVER
+ return game.future[evtype]
+
+def is_scheduled(evtype):
+ # is an event of specified type scheduled
+ return game.future[evtype].date != FOREVER
+
+def scheduled(evtype):
+ # when will this event happen?
+ return game.future[evtype].date
+
+def schedule(evtype, offset):
+ # schedule an event of specified type
+ game.future[evtype].date = game.state.date + offset
+ return game.future[evtype]
+
+def postpone(evtype, offset):
+ # postpone a scheduled event
+ game.future[evtype].date += offset
+
+def cancelrest():
+ # rest period is interrupted by event
+ if game.resting:
+ skip(1)
+ proutn(_("Mr. Spock- \"Captain, shall we cancel the rest period?\""))
+ if ja() == True:
+ game.resting = False
+ game.optime = 0.0
+ return True
+
+ return False
+
+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()
+
+ def tractorbeam():
+ # tractor beaming cases merge here
+ yank = math.sqrt(yank)
+ announce()
+ game.optime = (10.0/(7.5*7.5))*yank # 7.5 is yank rate (warp 7.5)
+ skip(1)
+ proutn("***")
+ crmshp()
+ prout(_(" caught in long range tractor beam--"))
+ # If Kirk & Co. screwing around on planet, handle
+ atover(True) # atover(true) is Grab
+ if game.alldone:
+ return
+ if game.icraft: # Caught in Galileo?
+ finish(FSTRACTOR)
+ return
+ # Check to see if shuttle is aboard
+ if game.iscraft == "offship":
+ skip(1)
+ if Rand() > 0.5:
+ prout(_("Galileo, left on the planet surface, is captured"))
+ prout(_("by aliens and made into a flying McDonald's."))
+ game.damage[DSHUTTL] = -10
+ game.iscraft = "removed"
+ else:
+ prout(_("Galileo, left on the planet surface, is well hidden."))
+ if evcode==0:
+ game.quadrant = game.state.kscmdr
+ else:
+ game.quadrant = game.state.kcmdr[i]
+ game.sector = randplace(QUADSIZE)
+ crmshp()
+ proutn(_(" is pulled to "))
+ proutn(cramlc(quadrant, game.quadrant))
+ proutn(", ")
+ prout(cramlc(sector, game.sector))
+ if game.resting:
+ prout(_("(Remainder of rest/repair period cancelled.)"))
+ game.resting = False
+ if not game.shldup:
+ if not damaged(DSHIELD) and game.shield > 0:
+ doshield(True) # raise shields
+ game.shldchg=False
+ else:
+ prout(_("(Shields not currently useable.)"))
+ newqad(False)
+ # Adjust finish time to time of tractor beaming
+ fintim = game.state.date+game.optime
+ attack(False)
+ if game.state.remcom <= 0:
+ unschedule(FTBEAM)
+ else:
+ schedule(FTBEAM, game.optime+expran(1.5*game.intime/game.state.remcom))
+
+ def destroybase():
+ # Code merges here for any commander destroying base
+ # Not perfect, but will have to do
+ # Handle case where base is in same quadrant as starship
+ if same(game.battle, game.quadrant):
+ game.state.chart[game.battle.x][game.battle.y].starbase = False
+ game.quad[game.base.x][game.base.y] = IHDOT
+ game.base.x=game.base.y=0
+ newcnd()
+ skip(1)
+ prout(_("Spock- \"Captain, I believe the starbase has been destroyed.\""))
+ elif game.state.rembase != 1 and \
+ (not damaged(DRADIO) or game.condition == "docked"):
+ # Get word via subspace radio
+ announce()
+ skip(1)
+ prout(_("Lt. Uhura- \"Captain, Starfleet Command reports that"))
+ proutn(_(" the starbase in "))
+ proutn(cramlc(quadrant, game.battle))
+ prout(_(" has been destroyed by"))
+ if game.isatb == 2:
+ prout(_("the Klingon Super-Commander"))
+ else:
+ prout(_("a Klingon Commander"))
+ game.state.chart[game.battle.x][game.battle.y].starbase = False
+ # Remove Starbase from galaxy
+ game.state.galaxy[game.battle.x][game.battle.y].starbase = False
+ for i in range(1, game.state.rembase+1):
+ if same(game.state.baseq[i], game.battle):
+ game.state.baseq[i] = game.state.baseq[game.state.rembase]
+ game.state.rembase -= 1
+ if game.isatb == 2:
+ # reinstate a commander's base attack
+ game.battle = hold
+ game.isatb = 0
+ else:
+ invalidate(game.battle)
+
+ if idebug:
+ prout("=== EVENTS from %.2f to %.2f:" % (game.state.date, fintim))
+ for i in range(1, NEVENTS):
+ if i == FSNOVA: proutn("=== Supernova ")
+ elif i == FTBEAM: proutn("=== T Beam ")
+ elif i == FSNAP: proutn("=== Snapshot ")
+ elif i == FBATTAK: proutn("=== Base Attack ")
+ elif i == FCDBAS: proutn("=== Base Destroy ")
+ elif i == FSCMOVE: proutn("=== SC Move ")
+ elif i == FSCDBAS: proutn("=== SC Base Destroy ")
+ elif i == FDSPROB: proutn("=== Probe Move ")
+ elif i == FDISTR: proutn("=== Distress Call ")
+ elif i == FENSLV: proutn("=== Enslavement ")
+ elif i == FREPRO: proutn("=== Klingon Build ")
+ if is_scheduled(i):
+ prout("%.2f" % (scheduled(i)))
+ else:
+ prout("never")
+ radio_was_broken = damaged(DRADIO)
+ hold.x = hold.y = 0
+ while True:
+ # Select earliest extraneous event, evcode==0 if no events
+ evcode = FSPY
+ if game.alldone:
+ return
+ datemin = fintim
+ for l in range(1, NEVENTS):
+ if game.future[l].date < datemin:
+ evcode = l
+ if idebug:
+ prout("== Event %d fires" % (evcode))
+ datemin = game.future[l].date
+ xtime = datemin-game.state.date
+ game.state.date = datemin
+ # Decrement Federation resources and recompute remaining time
+ game.state.remres -= (game.state.remkl+4*game.state.remcom)*xtime
+ game.recompute()
+ if game.state.remtime <=0:
+ finish(FDEPLETE)
+ return
+ # Any crew left alive?
+ if game.state.crew <=0:
+ finish(FCREW)
+ return
+ # Is life support adequate?
+ if damaged(DLIFSUP) and game.condition != "docked":
+ if game.lsupres < xtime and game.damage[DLIFSUP] > game.lsupres:
+ finish(FLIFESUP)
+ return
+ game.lsupres -= xtime
+ if game.damage[DLIFSUP] <= xtime:
+ game.lsupres = game.inlsr
+ # Fix devices
+ repair = xtime
+ if game.condition == "docked":
+ repair /= game.docfac
+ # Don't fix Deathray here
+ for l in range(0, NDEVICES):
+ if game.damage[l] > 0.0 and l != DDRAY:
+ if game.damage[l]-repair > 0.0:
+ game.damage[l] -= repair
+ else:
+ game.damage[l] = 0.0
+ # If radio repaired, update star chart and attack reports
+ if radio_was_broken and not damaged(DRADIO):
+ prout(_("Lt. Uhura- \"Captain, the sub-space radio is working and"))
+ prout(_(" surveillance reports are coming in."))
+ skip(1)
+ if not game.iseenit:
+ attackreport(False)
+ game.iseenit = True
+ rechart()
+ prout(_(" The star chart is now up to date.\""))
+ skip(1)
+ # Cause extraneous event EVCODE to occur
+ game.optime -= xtime
+ if evcode == FSNOVA: # Supernova
+ announce()
+ supernova(False)
+ schedule(FSNOVA, expran(0.5*game.intime))
+ if game.state.galaxy[game.quadrant.x][game.quadrant.y].supernova:
+ return
+ 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:
+ return
+ if game.ientesc or \
+ (game.energy<2000 and game.torps<4 and game.shield < 1250) or \
+ (damaged(DPHASER) and (damaged(DPHOTON) or game.torps<4)) or \
+ (damaged(DSHIELD) and \
+ (game.energy < 2500 or damaged(DPHASER)) and \
+ (game.torps < 5 or damaged(DPHOTON))):
+ # Tractor-beam her!
+ istract = True
+ yank = distance(game.state.kscmdr, game.quadrant)
+ ictbeam = True
+ tractorbeam()
+ else:
+ return
+ elif evcode == FTBEAM: # Tractor beam
+ if game.state.remcom == 0:
+ unschedule(FTBEAM)
+ continue
+ i = Rand()*game.state.remcom+1.0
+ yank = square(game.state.kcmdr[i].x-game.quadrant.x) + square(game.state.kcmdr[i].y-game.quadrant.y)
+ if istract or game.condition == "docked" or yank == 0:
+ # Drats! Have to reschedule
+ schedule(FTBEAM,
+ game.optime + expran(1.5*game.intime/game.state.remcom))
+ continue
+ ictbeam = True
+ tractorbeam()
+ elif evcode == FSNAP: # Snapshot of the universe (for time warp)
+ game.snapsht = game.state
+ game.state.snap = True
+ schedule(FSNAP, expran(0.5 * game.intime))
+ elif evcode == FBATTAK: # Commander attacks starbase
+ if game.state.remcom==0 or game.state.rembase==0:
+ # no can do
+ unschedule(FBATTAK)
+ unschedule(FCDBAS)
+ continue
+ i = 0
+ for j in range(1, game.state.rembase+1):
+ for k in range(1, game.state.remcom+1):
+ if same(game.state.baseq[j], game.state.kcmdr[k]) and \
+ not same(game.state.baseq[j], game.quadrant) and \
+ not same(game.state.baseq[j], game.state.kscmdr):
+ i = 1
+ if i == 1:
+ continue
+ if j>game.state.rembase:
+ # no match found -- try later
+ schedule(FBATTAK, expran(0.3*game.intime))
+ unschedule(FCDBAS)
+ continue
+ # commander + starbase combination found -- launch attack
+ game.battle = game.state.baseq[j]
+ schedule(FCDBAS, 1.0+3.0*Rand())
+ if game.isatb: # extra time if SC already attacking
+ postpone(FCDBAS, scheduled(FSCDBAS)-game.state.date)
+ game.future[FBATTAK].date = game.future[FCDBAS].date + expran(0.3*game.intime)
+ game.iseenit = False
+ if damaged(DRADIO) and game.condition != "docked":
+ continue # No warning :-(
+ game.iseenit = True
+ announce()
+ skip(1)
+ proutn(_("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(".\"")
+ if cancelrest():
+ return
+ elif evcode == FSCDBAS: # Supercommander destroys base
+ unschedule(FSCDBAS)
+ game.isatb = 2
+ if not game.state.galaxy[game.state.kscmdr.x][game.state.kscmdr.y].starbase:
+ continue # WAS RETURN!
+ hold = game.battle
+ game.battle = game.state.kscmdr
+ destroybase()
+ elif evcode == FCDBAS: # Commander succeeds in destroying base
+ if evcode==FCDBAS:
+ unschedule(FCDBAS)
+ # find the lucky pair
+ for i in range(1, game.state.remcom+1):
+ if same(game.state.kcmdr[i], game.battle):
+ break
+ if i > game.state.remcom or game.state.rembase == 0 or \
+ not game.state.galaxy[game.battle.x][game.battle.y].starbase:
+ # No action to take after all
+ invalidate(game.battle)
+ continue
+ destroybase()
+ elif evcode == FSCMOVE: # Supercommander moves
+ schedule(FSCMOVE, 0.2777)
+ if not game.ientesc and not istract and game.isatb != 1 and \
+ (not game.iscate or not game.justin):
+ supercommander()
+ elif evcode == FDSPROB: # Move deep space probe
+ schedule(FDSPROB, 0.01)
+ game.probex += game.probeinx
+ game.probey += game.probeiny
+ i = (int)(game.probex/QUADSIZE +0.05)
+ j = (int)(game.probey/QUADSIZE + 0.05)
+ if game.probec.x != i or game.probec.y != j:
+ game.probec.x = i
+ game.probec.y = j
+ if not VALID_QUADRANT(i, j) or \
+ game.state.galaxy[game.probec.x][game.probec.y].supernova:
+ # Left galaxy or ran into supernova
+ if not damaged(DRADIO) or game.condition == "docked":
+ announce()
+ skip(1)
+ proutn(_("Lt. Uhura- \"The deep space probe "))
+ if not VALID_QUADRANT(j, i):
+ proutn(_("has left the galaxy"))
+ else:
+ proutn(_("is no longer transmitting"))
+ prout(".\"")
+ unschedule(FDSPROB)
+ continue
+ if not damaged(DRADIO) or game.condition == "docked":
+ announce()
+ skip(1)
+ proutn(_("Lt. Uhura- \"The deep space probe is now in "))
+ proutn(cramlc(quadrant, game.probec))
+ prout(".\"")
+ pdest = game.state.galaxy[game.probec.x][game.probec.y]
+ # Update star chart if Radio is working or have access to radio
+ if not damaged(DRADIO) or game.condition == "docked":
+ chp = game.state.chart[game.probec.x][game.probec.y]
+ chp.klingons = pdest.klingons
+ chp.starbase = pdest.starbase
+ chp.stars = pdest.stars
+ pdest.charted = True
+ game.proben -= 1 # One less to travel
+ if game.proben == 0 and game.isarmed and pdest.stars:
+ # lets blow the sucker!
+ supernova(True, game.probec)
+ unschedule(FDSPROB)
+ if game.state.galaxy[game.quadrant.x][game.quadrant.y].supernova:
+ return
+ elif evcode == FDISTR: # inhabited system issues distress call
+ unschedule(FDISTR)
+ # try a whole bunch of times to find something suitable
+ for i in range(100):
+ # need a quadrant which is not the current one,
+ # which has some stars which are inhabited and
+ # not already under attack, which is not
+ # supernova'ed, and which has some Klingons in it
+ w = randplace(GALSIZE)
+ q = game.state.galaxy[w.x][w.y]
+ if not (same(game.quadrant, w) or q.planet == NOPLANET or \
+ game.state.planets[q.planet].inhabited == UNINHABITED or \
+ q.supernova or q.status!=secure or q.klingons<=0):
+ break
+ else:
+ # can't seem to find one; ignore this call
+ if idebug:
+ prout("=== Couldn't find location for distress event.")
+ continue
+ # got one!! Schedule its enslavement
+ ev = schedule(FENSLV, expran(game.intime))
+ ev.quadrant = w
+ q.status = distressed
+
+ # tell the captain about it if we can
+ if not damaged(DRADIO) or game.condition == "docked":
+ prout(_("Uhura- Captain, %s in Quadrant %s reports it is under attack" \
+ % (systnames[q.planet], `w`)))
+ prout(_("by a Klingon invasion fleet."))
+ if cancelrest():
+ return
+ elif evcode == FENSLV: # starsystem is enslaved
+ ev = unschedule(FENSLV)
+ # see if current distress call still active
+ q = game.state.galaxy[ev.quadrant.x][ev.quadrant.y]
+ if q.klingons <= 0:
+ q.status = "secure"
+ continue
+ q.status = "enslaved"
+
+ # play stork and schedule the first baby
+ ev2 = schedule(FREPRO, expran(2.0 * game.intime))
+ ev2.quadrant = ev.quadrant
+
+ # report the disaster if we can
+ if not damaged(DRADIO) or game.condition == "docked":
+ prout(_("Uhura- We've lost contact with starsystem %s" % \
+ systnames[q.planet]))
+ prout(_("in Quadrant %s.\n" % ev.quadrant))
+ elif evcode == FREPRO: # Klingon reproduces
+ # If we ever switch to a real event queue, we'll need to
+ # explicitly retrieve and restore the x and y.
+ ev = schedule(FREPRO, expran(1.0 * game.intime))
+ # see if current distress call still active
+ q = game.state.galaxy[ev.quadrant.x][ev.quadrant.y]
+ if q.klingons <= 0:
+ q.status = "secure"
+ continue
+ if game.state.remkl >=MAXKLGAME:
+ continue # full right now
+ # reproduce one Klingon
+ w = ev.quadrant
+ if game.klhere >= MAXKLQUAD:
+ try:
+ # this quadrant not ok, pick an adjacent one
+ for i in range(w.x - 1, w.x + 2):
+ for j in range(w.y - 1, w.y + 2):
+ if not VALID_QUADRANT(i, j):
+ continue
+ q = game.state.galaxy[w.x][w.y]
+ # check for this quad ok (not full & no snova)
+ if q.klingons >= MAXKLQUAD or q.supernova:
+ continue
+ raise "FOUNDIT"
+ else:
+ continue # search for eligible quadrant failed
+ except "FOUNDIT":
+ w.x = i
+ w.y = j
+ # deliver the child
+ game.state.remkl += 1
+ q.klingons += 1
+ if same(game.quadrant, w):
+ newkling(++game.klhere)
+
+ # recompute time left
+ game.recompute()
+ # report the disaster if we can
+ if not damaged(DRADIO) or game.condition == "docked":
+ if same(game.quadrant, w):
+ prout(_("Spock- sensors indicate the Klingons have"))
+ prout(_("launched a warship from %s." \
+ % systnames[q.planet]))
+ else:
+ prout(_("Uhura- Starfleet reports increased Klingon activity"))
+ if q.planet != NOPLANET:
+ proutn(_("near %s" % systnames[q.planet]))
+ prout(_("in %s.\n" % cramlc(quadrant, w)))
+
+def wait():
+ # wait on events
+ game.ididit = False
+ while True:
+ key = scan()
+ if key != IHEOL:
+ break
+ proutn(_("How long? "))
+ chew()
+ if key != IHREAL:
+ huh()
+ return
+ origTime = delay = aaitem
+ if delay <= 0.0:
+ return
+ if delay >= game.state.remtime or game.nenhere != 0:
+ proutn(_("Are you sure? "))
+ if ja() == False:
+ return
+
+ # Alternate resting periods (events) with attacks
+
+ game.resting = True
+ while True:
+ if delay <= 0:
+ game.resting = False
+ if not game.resting:
+ prout(_("%d stardates left." % int(game.state.remtime)))
+ return
+ temp = game.optime = delay
+ if game.nenhere:
+ rtime = 1.0 + Rand()
+ if rtime < temp:
+ temp = rtime
+ game.optime = temp
+ if game.optime < delay:
+ attack(False)
+ if game.alldone:
+ return
+ events()
+ game.ididit = True
+ if game.alldone:
+ return
+ delay -= temp
+ # Repair Deathray if long rest at starbase
+ if origTime-delay >= 9.99 and game.condition == "docked":
+ game.damage[DDRAY] = 0.0
+ # leave if quadrant supernovas
+ if game.state.galaxy[game.quadrant.x][game.quadrant.y].supernova:
+ break
+ game.resting = False
+ game.optime = 0
+
+# A nova occurs. It is the result of having a star hit with a
+# photon torpedo, or possibly of a probe warhead going off.
+# Stars that go nova cause stars which surround them to undergo
+# the same probabilistic process. Klingons next to them are
+# destroyed. And if the starship is next to it, it gets zapped.
+# If the zap is too much, it gets destroyed.
+
+def nova(nov):
+ # star goes nova
+ course = (0.0, 10.5, 12.0, 1.5, 9.0, 0.0, 3.0, 7.5, 6.0, 4.5)
+ newc = coord(); scratch = coord()
+
+ if Rand() < 0.05:
+ # Wow! We've supernova'ed
+ supernova(False, nov)
+ return
+
+ # handle initial nova
+ game.quad[nov.x][nov.y] = IHDOT
+ crmena(False, IHSTAR, sector, nov)
+ prout(_(" novas."))
+ game.state.galaxy[game.quadrant.x][game.quadrant.y].stars -= 1
+ game.state.starkl += 1
+
+ # Set up stack to recursively trigger adjacent stars
+ bot = top = top2 = 1
+ kount = 0
+ icx = icy = 0
+ hits[1][1] = nov.x
+ hits[1][2] = nov.y
+ while True:
+ for mm in range(bot, top+1):
+ for nn in range(1, 3+1): # nn,j represents coordinates around current
+ for j in range(1, 3+1):
+ if j==2 and nn== 2:
+ continue
+ scratch.x = hits[mm][1]+nn-2
+ scratch.y = hits[mm][2]+j-2
+ if not VALID_SECTOR(scratch.y, scratch.x):
+ continue
+ iquad = game.quad[scratch.x][scratch.y]
+ # Empty space ends reaction
+ if iquad in (IHDOT, IHQUEST, IHBLANK, IHT, IHWEB):
+ break
+ elif iquad == IHSTAR: # Affect another star
+ if Rand() < 0.05:
+ # This star supernovas
+ scratch = supernova(False)
+ return
+ top2 += 1
+ hits[top2][1]=scratch.x
+ 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)
+ prout(_(" novas."))
+ game.quad[scratch.x][scratch.y] = IHDOT
+ elif iquad == IHP: # Destroy planet
+ game.state.galaxy[game.quadrant.x][game.quadrant.y].planet = NOPLANET
+ game.state.nplankl += 1
+ crmena(True, IHP, sector, scratch)
+ prout(_(" destroyed."))
+ game.state.planets[game.iplnet].pclass = destroyed
+ game.iplnet = 0
+ invalidate(game.plnet)
+ if game.landed:
+ finish(FPNOVA)
+ return
+ game.quad[scratch.x][scratch.y] = IHDOT
+ elif iquad == IHB: # Destroy base
+ game.state.galaxy[game.quadrant.x][game.quadrant.y].starbase = False
+ for i in range(1, game.state.rembase+1):
+ if same(game.state.baseq[i], game.quadrant):
+ break
+ game.state.baseq[i] = game.state.baseq[game.state.rembase]
+ game.state.rembase -= 1
+ invalidate(game.base)
+ game.state.basekl += 1
+ newcnd()
+ crmena(True, IHB, sector, scratch)
+ prout(_(" destroyed."))
+ game.quad[scratch.x][scratch.y] = IHDOT
+ elif iquad in (IHE, IHF): # Buffet ship
+ prout(_("***Starship buffeted by nova."))
+ if game.shldup:
+ if game.shield >= 2000.0:
+ game.shield -= 2000.0
+ else:
+ diff = 2000.0 - game.shield
+ game.energy -= diff
+ game.shield = 0.0
+ game.shldup = False
+ prout(_("***Shields knocked out."))
+ game.damage[DSHIELD] += 0.005*game.damfac*Rand()*diff
+ else:
+ game.energy -= 2000.0
+ if game.energy <= 0:
+ finish(FNOVA)
+ return
+ # add in course nova contributes to kicking starship
+ icx += game.sector.x-hits[mm][1]
+ icy += game.sector.y-hits[mm][2]
+ kount += 1
+ elif iquad == IHK: # kill klingon
+ deadkl(scratch,iquad, scratch)
+ elif iquad in (IHC,IHS,IHR): # Damage/destroy big enemies
+ for ll in range(1, game.nenhere+1):
+ if same(game.ks[ll], scratch):
+ break
+ game.kpower[ll] -= 800.0 # If firepower is lost, die
+ if game.kpower[ll] <= 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)
+ proutn(_(" damaged"))
+ if not VALID_SECTOR(newc.x, newc.y):
+ # can't leave quadrant
+ skip(1)
+ break
+ iquad1 = game.quad[newc.x][newc.y]
+ if iquad1 == IHBLANK:
+ proutn(_(", blasted into "))
+ crmena(False, IHBLANK, sector, newc)
+ skip(1)
+ deadkl(scratch, iquad, newc)
+ break
+ if iquad1 != IHDOT:
+ # can't move into something else
+ skip(1)
+ break
+ proutn(_(", buffeted to "))
+ proutn(cramlc(sector, 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)
+ skip(1)
+ if top == top2:
+ break
+ bot = top + 1
+ top = top2
+ if kount==0:
+ return
+
+ # Starship affected by nova -- kick it away.
+ game.dist = kount*0.1
+ icx = sgn(icx)
+ icy = sgn(icy)
+ game.direc = course[3*(icx+1)+icy+2]
+ if game.direc == 0.0:
+ game.dist = 0.0
+ if game.dist == 0.0:
+ return
+ game.optime = 10.0*game.dist/16.0
+ skip(1)
+ prout(_("Force of nova displaces starship."))
+ imove(True)
+ game.optime = 10.0*game.dist/16.0
+ return
+
+def supernova(induced, w=None):
+ # star goes supernova
+ num = 0; npdead = 0
+ nq = coord()
+
+ if w != None:
+ nq = w
+ else:
+ stars = 0
+ # Scheduled supernova -- select star
+ # logic changed here so that we won't favor quadrants in top
+ # left of universe
+ for nq.x in range(1, GALSIZE+1):
+ for nq.y in range(1, GALSIZE+1):
+ stars += game.state.galaxy[nq.x][nq.y].stars
+ if stars == 0:
+ return # nothing to supernova exists
+ num = Rand()*stars + 1
+ for nq.x in range(1, GALSIZE+1):
+ for nq.y in range(1, GALSIZE+1):
+ num -= game.state.galaxy[nq.x][nq.y].stars
+ if num <= 0:
+ break
+ if num <=0:
+ break
+ if idebug:
+ proutn("=== Super nova here?")
+ if ja() == True:
+ nq = game.quadrant
+
+ if not same(nq, game.quadrant) or game.justin:
+ # it isn't here, or we just entered (treat as enroute)
+ if not damaged(DRADIO) or game.condition == "docked":
+ skip(1)
+ prout(_("Message from Starfleet Command Stardate %.2f" % game.state.date))
+ prout(_(" Supernova in Quadrant %s; caution advised." % nq))
+ else:
+ ns = coord()
+ # we are in the quadrant!
+ num = Rand()* game.state.galaxy[nq.x][nq.y].stars + 1
+ for ns.x in range(1, QUADSIZE+1):
+ for ns.y in range(1, QUADSIZE+1):
+ if game.quad[ns.x][ns.y]==IHSTAR:
+ num -= 1
+ if num==0:
+ break
+ if num==0:
+ break
+
+ skip(1)
+ prouts(_("***RED ALERT! RED ALERT!"))
+ skip(1)
+ prout(_("***Incipient supernova detected at Sector %s" % ns))
+ if square(ns.x-game.sector.x) + square(ns.y-game.sector.y) <= 2.1:
+ proutn(_("Emergency override attempts t"))
+ prouts("***************")
+ skip(1)
+ stars()
+ game.alldone = True
+
+ # destroy any Klingons in supernovaed quadrant
+ kldead = game.state.galaxy[nq.x][nq.y].klingons
+ game.state.galaxy[nq.x][nq.y].klingons = 0
+ if same(nq, game.state.kscmdr):
+ # did in the Supercommander!
+ game.state.nscrem = game.state.kscmdr.x = game.state.kscmdr.y = game.isatb = 0
+ game.iscate = False
+ unschedule(FSCMOVE)
+ unschedule(FSCDBAS)
+ if game.state.remcom:
+ maxloop = game.state.remcom
+ for l in range(1, maxloop+1):
+ if same(game.state.kcmdr[l], nq):
+ game.state.kcmdr[l] = game.state.kcmdr[game.state.remcom]
+ invalidate(game.state.kcmdr[game.state.remcom])
+ game.state.remcom -= 1
+ kldead -= 1
+ if game.state.remcom==0:
+ unschedule(FTBEAM)
+ break
+ game.state.remkl -= kldead
+ # destroy Romulans and planets in supernovaed quadrant
+ nrmdead = game.state.galaxy[nq.x][nq.y].romulans
+ game.state.galaxy[nq.x][nq.y].romulans = 0
+ game.state.nromrem -= nrmdead
+ # Destroy planets
+ for loop in range(game.inplan):
+ if same(game.state.planets[loop].w, nq):
+ game.state.planets[loop].pclass = destroyed
+ npdead += 1
+ # Destroy any base in supernovaed quadrant
+ if game.state.rembase:
+ maxloop = game.state.rembase
+ for loop in range(1, maxloop+1):
+ if same(game.state.baseq[loop], nq):
+ game.state.baseq[loop] = game.state.baseq[game.state.rembase]
+ invalidate(game.state.baseq[game.state.rembase])
+ game.state.rembase -= 1
+ break
+ # If starship caused supernova, tally up destruction
+ if induced:
+ game.state.starkl += game.state.galaxy[nq.x][nq.y].stars
+ game.state.basekl += game.state.galaxy[nq.x][nq.y].starbase
+ game.state.nplankl += npdead
+ # mark supernova in galaxy and in star chart
+ if same(game.quadrant, nq) or not damaged(DRADIO) or game.condition == "docked":
+ game.state.galaxy[nq.x][nq.y].supernova = True
+ # If supernova destroys last Klingons give special message
+ if (game.state.remkl + game.state.remcom + game.state.nscrem)==0 and not same(nq, game.quadrant):
+ skip(2)
+ if not induced:
+ prout(_("Lucky you!"))
+ proutn(_("A supernova in %s has just destroyed the last Klingons." % nq))
+ finish(FWON)
+ return
+ # if some Klingons remain, continue or die in supernova
+ if game.alldone:
+ finish(FSNOVAED)
+ return
+
+# Code from finish.c ends here.
+
+def selfdestruct():
+ # self-destruct maneuver
+ # Finish with a BANG!
+ chew()
+ if damaged(DCOMPTR):
+ prout(_("Computer damaged; cannot execute destruct sequence."))
+ return
+ prouts(_("---WORKING---")); skip(1)
+ prouts(_("SELF-DESTRUCT-SEQUENCE-ACTIVATED")); skip(1)
+ prouts(" 10"); skip(1)
+ prouts(" 9"); skip(1)
+ prouts(" 8"); skip(1)
+ prouts(" 7"); skip(1)
+ prouts(" 6"); skip(1)
+ skip(1)
+ prout(_("ENTER-CORRECT-PASSWORD-TO-CONTINUE-"))
+ skip(1)
+ prout(_("SELF-DESTRUCT-SEQUENCE-OTHERWISE-"))
+ skip(1)
+ prout(_("SELF-DESTRUCT-SEQUENCE-WILL-BE-ABORTED"))
+ skip(1)
+ scan()
+ chew()
+ if game.passwd != citem:
+ prouts(_("PASSWORD-REJECTED;"))
+ skip(1)
+ prouts(_("CONTINUITY-EFFECTED"))
+ skip(2)
+ return
+ prouts(_("PASSWORD-ACCEPTED")); skip(1)
+ prouts(" 5"); skip(1)
+ prouts(" 4"); skip(1)
+ prouts(" 3"); skip(1)
+ prouts(" 2"); skip(1)
+ prouts(" 1"); skip(1)
+ if Rand() < 0.15:
+ prouts(_("GOODBYE-CRUEL-WORLD"))
+ skip(1)
+ kaboom()
+
+def kaboom():
+ stars()
+ if game.ship==IHE:
+ prouts("***")
+ prouts(_("********* Entropy of "))
+ crmshp()
+ prouts(_(" maximized *********"))
+ skip(1)
+ stars()
+ skip(1)
+ if game.nenhere != 0:
+ 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])
+ l += 1
+ finish(FDILITHIUM)
+
+def killrate():
+ "Compute our rate of kils over time."
+ return ((game.inkling + game.incom + game.inscom) - (game.state.remkl + game.state.remcom + game.state.nscrem))/(game.state.date-game.indate)
+
+def badpoints():
+ "Compute demerits."
+ badpt = 5.0*game.state.starkl + \
+ game.casual + \
+ 10.0*game.state.nplankl + \
+ 300*game.state.nworldkl + \
+ 45.0*game.nhelp +\
+ 100.0*game.state.basekl +\
+ 3.0*game.abandoned
+ if game.ship == IHF:
+ badpt += 100.0
+ elif game.ship == None:
+ badpt += 200.0
+ return badpt
+
+
+def finish(ifin):
+ # end the game, with appropriate notfications
+ igotit = False
+ game.alldone = True
+ skip(3)
+ prout(_("It is stardate %.1f." % (game.state.date)))
+ skip(1)
+ if ifin == FWON: # Game has been won
+ if game.state.nromrem != 0:
+ prout(_("The remaining %d Romulans surrender to Starfleet Command.") %
+ game.state.nromrem)
+
+ prout(_("You have smashed the Klingon invasion fleet and saved"))
+ prout(_("the Federation."))
+ game.gamewon = True
+ if game.alive:
+ badpt = badpoints()
+ if badpt < 100.0:
+ badpt = 0.0 # Close enough!
+ # killsPerDate >= RateMax
+ if game.state.date-game.indate < 5.0 or \
+ killrate() >= 0.1*game.skill*(game.skill+1.0) + 0.1 + 0.008*badpt:
+ skip(1)
+ prout(_("In fact, you have done so well that Starfleet Command"))
+ if game.skill == SKILL_NOVICE:
+ prout(_("promotes you one step in rank from \"Novice\" to \"Fair\"."))
+ elif game.skill == SKILL_FAIR:
+ prout(_("promotes you one step in rank from \"Fair\" to \"Good\"."))
+ elif game.skill == SKILL_GOOD:
+ prout(_("promotes you one step in rank from \"Good\" to \"Expert\"."))
+ elif game.skill == SKILL_EXPERT:
+ prout(_("promotes you to Commodore Emeritus."))
+ skip(1)
+ prout(_("Now that you think you're really good, try playing"))
+ prout(_("the \"Emeritus\" game. It will splatter your ego."))
+ elif game.skill == SKILL_EMERITUS:
+ skip(1)
+ proutn(_("Computer- "))
+ prouts(_("ERROR-ERROR-ERROR-ERROR"))
+ skip(2)
+ prouts(_(" YOUR-SKILL-HAS-EXCEEDED-THE-CAPACITY-OF-THIS-PROGRAM"))
+ skip(1)
+ prouts(_(" THIS-PROGRAM-MUST-SURVIVE"))
+ skip(1)
+ prouts(_(" THIS-PROGRAM-MUST-SURVIVE"))
+ skip(1)
+ prouts(_(" THIS-PROGRAM-MUST-SURVIVE"))
+ skip(1)
+ prouts(_(" THIS-PROGRAM-MUST?- MUST ? - SUR? ? -? VI"))
+ skip(2)
+ prout(_("Now you can retire and write your own Star Trek game!"))
+ skip(1)
+ elif game.skill >= SKILL_EXPERT:
+ if game.thawed and not idebug:
+ prout(_("You cannot get a citation, so..."))
+ else:
+ proutn(_("Do you want your Commodore Emeritus Citation printed? "))
+ chew()
+ if ja() == True:
+ igotit = True
+ # Only grant long life if alive (original didn't!)
+ skip(1)
+ prout(_("LIVE LONG AND PROSPER."))
+ score()
+ if igotit:
+ plaque()
+ return
+ elif ifin == FDEPLETE: # Federation Resources Depleted
+ prout(_("Your time has run out and the Federation has been"))
+ prout(_("conquered. Your starship is now Klingon property,"))
+ prout(_("and you are put on trial as a war criminal. On the"))
+ proutn(_("basis of your record, you are "))
+ if (game.state.remkl + game.state.remcom + game.state.nscrem)*3.0 > (game.inkling + game.incom + game.inscom):
+ prout(_("acquitted."))
+ skip(1)
+ prout(_("LIVE LONG AND PROSPER."))
+ else:
+ prout(_("found guilty and"))
+ prout(_("sentenced to death by slow torture."))
+ game.alive = False
+ score()
+ return
+ elif ifin == FLIFESUP:
+ prout(_("Your life support reserves have run out, and"))
+ prout(_("you die of thirst, starvation, and asphyxiation."))
+ prout(_("Your starship is a derelict in space."))
+ elif ifin == FNRG:
+ prout(_("Your energy supply is exhausted."))
+ skip(1)
+ prout(_("Your starship is a derelict in space."))
+ elif ifin == FBATTLE:
+ proutn(_("The "))
+ crmshp()
+ prout(_("has been destroyed in battle."))
+ skip(1)
+ prout(_("Dulce et decorum est pro patria mori."))
+ elif ifin == FNEG3:
+ prout(_("You have made three attempts to cross the negative energy"))
+ prout(_("barrier which surrounds the galaxy."))
+ skip(1)
+ prout(_("Your navigation is abominable."))
+ score()
+ elif ifin == FNOVA:
+ prout(_("Your starship has been destroyed by a nova."))
+ prout(_("That was a great shot."))
+ skip(1)
+ elif ifin == FSNOVAED:
+ proutn(_("The "))
+ crmshp()
+ prout(_(" has been fried by a supernova."))
+ prout(_("...Not even cinders remain..."))
+ elif ifin == FABANDN:
+ prout(_("You have been captured by the Klingons. If you still"))
+ prout(_("had a starbase to be returned to, you would have been"))
+ prout(_("repatriated and given another chance. Since you have"))
+ prout(_("no starbases, you will be mercilessly tortured to death."))
+ elif ifin == FDILITHIUM:
+ prout(_("Your starship is now an expanding cloud of subatomic particles"))
+ elif ifin == FMATERIALIZE:
+ prout(_("Starbase was unable to re-materialize your starship."))
+ prout(_("Sic transit gloria mundi"))
+ elif ifin == FPHASER:
+ proutn(_("The "))
+ crmshp()
+ prout(_(" has been cremated by its own phasers."))
+ elif ifin == FLOST:
+ prout(_("You and your landing party have been"))
+ prout(_("converted to energy, disipating through space."))
+ elif ifin == FMINING:
+ prout(_("You are left with your landing party on"))
+ prout(_("a wild jungle planet inhabited by primitive cannibals."))
+ skip(1)
+ prout(_("They are very fond of \"Captain Kirk\" soup."))
+ skip(1)
+ proutn(_("Without your leadership, the "))
+ crmshp()
+ prout(_(" is destroyed."))
+ elif ifin == FDPLANET:
+ prout(_("You and your mining party perish."))
+ skip(1)
+ prout(_("That was a great shot."))
+ skip(1)
+ elif ifin == FSSC:
+ prout(_("The Galileo is instantly annihilated by the supernova."))
+ prout(_("You and your mining party are atomized."))
+ skip(1)
+ proutn(_("Mr. Spock takes command of the "))
+ crmshp()
+ prout(_(" and"))
+ prout(_("joins the Romulans, reigning terror on the Federation."))
+ elif ifin == FPNOVA:
+ prout(_("You and your mining party are atomized."))
+ skip(1)
+ proutn(_("Mr. Spock takes command of the "))
+ crmshp()
+ prout(_(" and"))
+ prout(_("joins the Romulans, reigning terror on the Federation."))
+ elif ifin == FSTRACTOR:
+ prout(_("The shuttle craft Galileo is also caught,"))
+ prout(_("and breaks up under the strain."))
+ skip(1)
+ prout(_("Your debris is scattered for millions of miles."))
+ proutn(_("Without your leadership, the "))
+ crmshp()
+ prout(_(" is destroyed."))
+ elif ifin == FDRAY:
+ prout(_("The mutants attack and kill Spock."))
+ prout(_("Your ship is captured by Klingons, and"))
+ prout(_("your crew is put on display in a Klingon zoo."))
+ elif ifin == FTRIBBLE:
+ prout(_("Tribbles consume all remaining water,"))
+ prout(_("food, and oxygen on your ship."))
+ skip(1)
+ prout(_("You die of thirst, starvation, and asphyxiation."))
+ prout(_("Your starship is a derelict in space."))
+ elif ifin == FHOLE:
+ prout(_("Your ship is drawn to the center of the black hole."))
+ prout(_("You are crushed into extremely dense matter."))
+ elif ifin == FCREW:
+ prout(_("Your last crew member has died."))
+ if game.ship == IHF:
+ game.ship = None
+ elif game.ship == IHE:
+ game.ship = IHF
+ game.alive = False
+ if (game.state.remkl + game.state.remcom + game.state.nscrem) != 0:
+ goodies = game.state.remres/game.inresor
+ baddies = (game.state.remkl + 2.0*game.state.remcom)/(game.inkling+2.0*game.incom)
+ if goodies/baddies >= 1.0+0.5*Rand():
+ prout(_("As a result of your actions, a treaty with the Klingon"))
+ prout(_("Empire has been signed. The terms of the treaty are"))
+ if goodies/baddies >= 3.0+Rand():
+ prout(_("favorable to the Federation."))
+ skip(1)
+ prout(_("Congratulations!"))
+ else:
+ prout(_("highly unfavorable to the Federation."))
+ else:
+ prout(_("The Federation will be destroyed."))
+ else:
+ prout(_("Since you took the last Klingon with you, you are a"))
+ prout(_("martyr and a hero. Someday maybe they'll erect a"))
+ prout(_("statue in your memory. Rest in peace, and try not"))
+ prout(_("to think about pigeons."))
+ game.gamewon = True
+ score()
+
+def score():
+ # compute player's score
+ timused = game.state.date - game.indate
+
+ iskill = game.skill
+ if (timused == 0 or (game.state.remkl + game.state.remcom + game.state.nscrem) != 0) and timused < 5.0:
+ timused = 5.0
+ perdate = killrate()
+ ithperd = 500*perdate + 0.5
+ iwon = 0
+ if game.gamewon:
+ iwon = 100*game.skill
+ if game.ship == IHE:
+ klship = 0
+ elif game.ship == IHF:
+ klship = 1
+ else:
+ klship = 2
+ if not game.gamewon:
+ game.state.nromrem = 0 # None captured if no win
+ iscore = 10*(game.inkling - game.state.remkl) \
+ + 50*(game.incom - game.state.remcom) \
+ + ithperd + iwon \
+ + 20*(game.inrom - game.state.nromrem) \
+ + 200*(game.inscom - game.state.nscrem) \
+ - game.state.nromrem \
+ - badpoints()
+ if not game.alive:
+ iscore -= 200
+ skip(2)
+ prout(_("Your score --"))
+ if game.inrom - game.state.nromrem:
+ prout(_("%6d Romulans destroyed %5d" %
+ (game.inrom - game.state.nromrem, 20*(game.inrom - game.state.nromrem))))
+ if game.state.nromrem:
+ prout(_("%6d Romulans captured %5d" %
+ (game.state.nromrem, game.state.nromrem)))
+ if game.inkling - game.state.remkl:
+ prout(_("%6d ordinary Klingons destroyed %5d" %
+ (game.inkling - game.state.remkl, 10*(game.inkling - game.state.remkl))))
+ if game.incom - game.state.remcom:
+ prout(_("%6d Klingon commanders destroyed %5d" %
+ (game.incom - game.state.remcom, 50*(game.incom - game.state.remcom))))
+ if game.inscom - game.state.nscrem:
+ prout(_("%6d Super-Commander destroyed %5d" %
+ (game.inscom - game.state.nscrem, 200*(game.inscom - game.state.nscrem))))
+ if ithperd:
+ prout(_("%6.2f Klingons per stardate %5d" %
+ (perdate, ithperd)))
+ if game.state.starkl:
+ prout(_("%6d stars destroyed by your action %5d" %
+ (game.state.starkl, -5*game.state.starkl)))
+ if game.state.nplankl:
+ prout(_("%6d planets destroyed by your action %5d" %
+ (game.state.nplankl, -10*game.state.nplankl)))
+ if (game.options & OPTION_WORLDS) and game.state.nworldkl:
+ prout(_("%6d inhabited planets destroyed by your action %5d" %
+ (game.state.nplankl, -300*game.state.nworldkl)))
+ if game.state.basekl:
+ prout(_("%6d bases destroyed by your action %5d" %
+ (game.state.basekl, -100*game.state.basekl)))
+ if game.nhelp:
+ prout(_("%6d calls for help from starbase %5d" %
+ (game.nhelp, -45*game.nhelp)))
+ if game.casual:
+ prout(_("%6d casualties incurred %5d" %
+ (game.casual, -game.casual)))
+ if game.abandoned:
+ prout(_("%6d crew abandoned in space %5d" %
+ (game.abandoned, -3*game.abandoned)))
+ if klship:
+ prout(_("%6d ship(s) lost or destroyed %5d" %
+ (klship, -100*klship)))
+ if not game.alive:
+ prout(_("Penalty for getting yourself killed -200"))
+ if game.gamewon:
+ proutn(_("Bonus for winning "))
+ if game.skill == SKILL_NOVICE: proutn(_("Novice game "))
+ elif game.skill == SKILL_FAIR: proutn(_("Fair game "))
+ elif game.skill == SKILL_GOOD: proutn(_("Good game "))
+ elif game.skill == SKILL_EXPERT: proutn(_("Expert game "))
+ elif game.skill == SKILL_EMERITUS: proutn(_("Emeritus game"))
+ prout(" %5d" % (iwon))
+ skip(1)
+ prout(_("TOTAL SCORE %5d" % iscore))
+
+def plaque():
+ # emit winner's commemmorative plaque
+ skip(2)
+ while True:
+ proutn(_("File or device name for your plaque: "))
+ cgetline(winner, sizeof(winner))
+ try:
+ fp = open(winner, "w")
+ break
+ except IOError:
+ prout(_("Invalid name."))
+
+ proutn(_("Enter name to go on plaque (up to 30 characters): "))
+ cgetline(winner, sizeof(winner))
+ # The 38 below must be 64 for 132-column paper
+ nskip = 38 - len(winner)/2
+
+ fp.write("\n\n\n\n")
+ # --------DRAW ENTERPRISE PICTURE.
+ fp.write(" EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n" )
+ fp.write(" EEE E : : : E\n" )
+ fp.write(" EE EEE E : : NCC-1701 : E\n")
+ fp.write("EEEEEEEEEEEEEEEE EEEEEEEEEEEEEEE : : : E\n")
+ fp.write(" E EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n")
+ fp.write(" EEEEEEEEE EEEEEEEEEEEEE E E\n")
+ fp.write(" EEEEEEE EEEEE E E E E\n")
+ fp.write(" EEE E E E E\n")
+ fp.write(" E E E E\n")
+ fp.write(" EEEEEEEEEEEEE E E\n")
+ fp.write(" EEE : EEEEEEE EEEEEEEE\n")
+ fp.write(" :E : EEEE E\n")
+ fp.write(" .-E -:----- E\n")
+ fp.write(" :E : E\n")
+ fp.write(" EE : EEEEEEEE\n")
+ fp.write(" EEEEEEEEEEEEEEEEEEEEEEE\n")
+ fp.write("\n\n\n")
+ fp.write(_(" U. S. S. ENTERPRISE\n"))
+ fp.write("\n\n\n\n")
+ fp.write(_(" For demonstrating outstanding ability as a starship captain\n"))
+ fp.write("\n")
+ fp.write(_(" Starfleet Command bestows to you\n"))
+ fp.write("\n")
+ fp.write("%*s%s\n\n" % (nskip, "", winner))
+ fp.write(_(" the rank of\n\n"))
+ fp.write(_(" \"Commodore Emeritus\"\n\n"))
+ fp.write(" ")
+ if game.skill == SKILL_EXPERT:
+ fp.write(_(" Expert level\n\n"))
+ elif game.skill == SKILL_EMERITUS:
+ fp.write(_("Emeritus level\n\n"))
+ else:
+ fp.write(_(" Cheat level\n\n"))
+ timestring = ctime()
+ fp.write(_(" This day of %.6s %.4s, %.8s\n\n" %
+ (timestring+4, timestring+20, timestring+11)))
+ fp.write(_(" Your score: %d\n\n" % iscore))
+ fp.write(_(" Klingons per stardate: %.2f\n" % perdate))
+ fp.close()