commit e78a75ac842127a5e2cd51c95b7c7fb567b35edd
Author: Luxferre <lux@ferre>
Date: Sun, 21 Jan 2024 19:35:11 +0200
Initial upload
Diffstat:
A | awlite.awk | | | 632 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
1 file changed, 632 insertions(+), 0 deletions(-)
diff --git a/awlite.awk b/awlite.awk
@@ -0,0 +1,632 @@
+# awlite: POSIX AWK port of Text Elite 1.5
+# Version 1.5.1-alpha
+# Original C version by Ian Bell, 1999, 2015
+# Porting, corrections and optimizations by Luxferre, 2024
+#
+# Tested on: nawk/one-true-awk, busybox awk, gawk --posix, mawk -W posix
+# Should run on any current POSIX-compliant AWK implementation but
+# must be run with LC_ALL=C environment variable to work correctly!
+#
+# Gameplay differences from the original C version of TE 1.5:
+# - multiple typos corrected in text strings
+# - the "cash" and "sneak" commands are only available to the REPL if running with -v CHEAT=1
+# - alien items are available by default, can be overridden with -v NO_ALIEN_ITEMS=1
+# - economy names are no longer shortened
+# - the "politically correct" goods names are turned on with -v CENSORED=1
+# - the following goods have been renamed: "Robot Slaves" to "Robots", "Liquor/Wines" to "Liquors", "Gem-Strones" to "Gem-stones"
+# - market and local info tables are better aligned
+# ... to be continued ...
+
+# utility functions
+
+# determine (ordered) array length
+function alen(a, i, k) {
+ k = 0
+ for(i in a) k++
+ return k
+}
+
+# split a string with separator into an array but with 0-based indexes
+function asplit(s, a, sep, len, i) {
+ split(s, a, sep) # get 1-based-index array in a
+ len = alen(a)
+ for(i=0;i<len;i++) a[i] = a[i+1] # move everything to the left
+ delete a[len] # delete the last element after moving
+}
+
+# serialize any associative array into a string
+# sep must be a single char not occurring in any key or value
+function assocser(aa, sep, outs, k) {
+ outs = "" # initialize an ordered array string
+ for(k in aa) # iterate over keys
+ outs = outs sep k sep aa[k]
+ return substr(outs, 2) # delete the first sep
+}
+
+# deserialize any associative array from a string
+# sep must be a single char used when calling assocser() function
+function assocdes(s, aa, sep, oa, i, len) {
+ split("", aa) # erase aa array
+ split(s, oa, sep) # get 1-based ordered array in oa
+ len = alen(oa) # ordered array length
+ for(i=1;i<=len;i+=2) # populate aa
+ aa[oa[i]] = oa[i+1]
+}
+
+# get the ASCII code of a character
+# usage: ord(c) => integer
+function ord(c, b) {
+ # init char-to-ASCII mapping if it's not there yet
+ if(!TGL_ORD["#"]) for(b=0;b<256;b++) TGL_ORD[sprintf("%c", b)] = b
+ return int(TGL_ORD[c])
+}
+
+# Required bitwise operations (as POSIX AWK doesn't support them)
+
+function bw_and(a, b, v, r) {
+ v = 1; r = 0
+ while(a > 0 || b > 0) {
+ if((a%2) == 1 && (b%2) == 1) r += v
+ a = int(a/2)
+ b = int(b/2)
+ v *= 2
+ }
+ return int(r)
+}
+function bw_or(a, b, v, r) {
+ v = 1; r = 0
+ while(a > 0 || b > 0) {
+ if((a%2) == 1 || (b%2) == 1) r += v
+ a = int(a/2)
+ b = int(b/2)
+ v *= 2
+ }
+ return int(r)
+}
+function bw_xor(a, b, v, r) {
+ v = 1; r = 0
+ while(a > 0 || b > 0) {
+ if((a%2) != (b%2)) r += v
+ a = int(a/2)
+ b = int(b/2)
+ v *= 2
+ }
+ return int(r)
+}
+
+# ============================ #
+# Game code itself starts here #
+# ============================ #
+
+# PRNG part
+
+function mysrand(seed) {
+ srand(seed)
+ rng_lastrand = seed - 1
+}
+
+function myrand(r) {
+ if(game["use_native_rand"] > 0) return int(rand() * 65536)
+ else { # attempt to optimize McDonnell's generator
+ r = (rng_lastrand * 3677 + 3680) % 2147483647
+ rng_lastrand = r -1
+ return r
+ }
+}
+
+function randbyte() {return myrand()%256}
+
+# other functions
+
+function mymin(a,b) {return (a < b) ? a : b}
+
+# distance between 2 planets
+function distance(p1x, p1y, p2x, p2y, dx, dy) {
+ dx = p1x - p2x
+ dy = p1y - p2y
+ return int(0.5 + 4*sqrt(dx*dx + dy*dy/4))
+}
+
+function rotl(x) { # rotate left 1 bit mod 256
+ x = x % 256 # truncate to a byte first
+ return (x * 2 + ((x > 127) ? 1 : 0)) % 256
+}
+
+function twist(x) { # twister function
+ return (256 * rotl(int(x/256)) + rotl(x%256)) % 65536
+}
+
+function galswitch(seeds) { # galaxy switcher (accepts an array)
+ seeds[0] = twist(seeds[0])
+ seeds[1] = twist(seeds[1])
+ seeds[2] = twist(seeds[2])
+}
+
+function tweakseed(seeds, t) { # another seed tweaker
+ t = (seeds[0] + seeds[1] + seeds[2]) % 65536
+ seeds[0] = seeds[1]
+ seeds[1] = seeds[2]
+ seeds[2] = t
+}
+
+# Generate system info from seed
+# populates the sinfo map
+function makesystem(seeds, sinfo, p1, p2, p3, p4, lnf, ecof, sname) {
+ lnf = bw_and(seeds[0], 64)
+ sinfo["x"] = int(seeds[1] / 256)
+ sinfo["y"] = int(seeds[0] / 256)
+ sinfo["govtype"] = int(seeds[1] / 8) % 8
+ sinfo["economy"] = int(seeds[0] / 256) % 8
+ if(sinfo["govtype"] <= 1) sinfo["economy"] = bw_or(sinfo["economy"], 2)
+ ecof = bw_xor(sinfo["economy"], 7)
+ sinfo["techlev"] = (sinfo["x"] % 4) + ecof + int(sinfo["govtype"] / 2)
+ if((sinfo["govtype"] % 2) == 1) sinfo["techlev"]++
+ sinfo["population"] = 4 * (sinfo["techlev"]) + sinfo["economy"] + sinfo["govtype"] + 1
+ sinfo["productivity"] = ((ecof + 3) * (sinfo["govtype"] + 4)) * sinfo["population"] * 8
+ sinfo["radius"] = 256 * ((int(seeds[2] / 256) % 16) + 11) + sinfo["x"]
+ # goat soup seed parts
+ sinfo["gsseed_a"] = seeds[1] % 256
+ sinfo["gsseed_b"] = int(seeds[1] / 256) % 256
+ sinfo["gsseed_c"] = seeds[2] % 256
+ sinfo["gsseed_d"] = int(seeds[2] / 256) % 256
+ # name pair indexes
+ p1 = 2 * (int(seeds[2] / 256) % 32); tweakseed(seeds)
+ p2 = 2 * (int(seeds[2] / 256) % 32); tweakseed(seeds)
+ p3 = 2 * (int(seeds[2] / 256) % 32); tweakseed(seeds)
+ p4 = 2 * (int(seeds[2] / 256) % 32); tweakseed(seeds)
+ sname = pairs[p1] pairs[p1+1] pairs[p2] pairs[p2+1] pairs[p3] pairs[p3+1]
+ if(lnf) sname = sname pairs[p4] pairs[p4+1]
+ gsub(/\./, "", sname) # remove all dots from sname
+ sinfo["name"] = sname # write the final name variant
+ # return sinfo
+}
+
+# "Goat Soup" planetary description string code
+
+function gs_rnd(sinfo, a, x) { # accepts system info to modify gsseed
+ x = (sinfo["gsseed_a"] * 2) % 256
+ a = x + sinfo["gsseed_c"]
+ if(sinfo["gsseed_a"] > 127) a++
+ sinfo["gsseed_a"] = a % 256
+ sinfo["gsseed_c"] = x
+ x = sinfo["gsseed_b"]
+ a = (int(a / 256) + x + sinfo["gsseed_d"]) % 256
+ sinfo["gsseed_b"] = a
+ sinfo["gsseed_d"] = x
+ return a
+}
+
+# main desc generator, recursive, modifies sinfo as well
+function goat_soup(source, sinfo, l, c, i, j, k, v, rnd, dsel) {
+ l = length(source)
+ for(i=0;i<l;i++) {
+ c = ord(substr(source, i+1, 1))
+ if(c < 128) printf("%c", c)
+ else {
+ if(c <= 164) {
+ rnd = gs_rnd(sinfo)
+ asplit(desc_list[c - 129], dsel, ",") # select the string from list
+ j = ((rnd >= 51) ? 1 : 0) + ((rnd >= 102) ? 1 : 0)
+ j += ((rnd >= 153) ? 1 : 0) + ((rnd >= 204) ? 1 : 0)
+ goat_soup(dsel[j], sinfo)
+ } else {
+ if(c == 176) { # planet name
+ v = sinfo["name"]
+ v = substr(v, 1, 1) tolower(substr(v, 2))
+ printf("%s", v)
+ } else if(c == 177) { # planet name + ian
+ v = sinfo["name"]
+ v = substr(v, 1, 1) tolower(substr(v, 2))
+ # find last "e" or "i" occurrence in v
+ j = match(v, /[eia]+$/)
+ if(j == 0) j = length(v) + 1
+ printf("%sian", substr(v, 1, j - 1))
+ } else if(c == 178) { # random name
+ v = gs_rnd(sinfo) % 4
+ for(j = 0; j <= v; j++) {
+ k = bw_and(62, gs_rnd(sinfo))
+ printf("%c", (j > 0) ? tolower(pairs0[k]) : pairs0[k])
+ printf("%c", tolower(pairs0[k+1]))
+ }
+ } else { printf("<bad char in data [%X]>",c); return }
+ }
+ }
+ }
+}
+
+# Galaxy builder (populates seeds array and global galaxy arrays)
+function buildgalaxy(gnum, seeds, si, i) {
+ asplit("23114 584 46931", seeds, " ")
+ for(i=1;i<gnum;i++) galswitch(seeds)
+ split("", galaxy) # global galaxy array
+ split("", galnames) # global galaxy names array
+ split("", economies) # economy mapping
+ for(i=0;i<galsize;i++) {
+ split("", si) # init a new system info array
+ makesystem(seeds, si) # populate it
+ galaxy[i] = assocser(si, "|") # serialize into the field
+ galnames[i] = si["name"] # populate the name
+ galcoords_x[i] = si["x"] # populate x coordinate
+ galcoords_y[i] = si["y"] # populate y coordinate
+ economies[i] = si["economy"] # populate economy type
+ }
+}
+
+
+# Market functions
+
+# buy amount a of product i, return amount bought
+function gamebuy(i, a, t) {
+ if(player["cash"] < 0) t = 0
+ else {
+ t = mymin(localmarket_quantity[i], a)
+ if(goods_units[i] == 0) t = mymin(player["holdspace"], t)
+ t = mymin(t, int(player["cash"] / localmarket_price[i]))
+ }
+ shipshold[i] = int(shipshold[i]) + t
+ localmarket_quantity[i] -= t
+ player["cash"] -= t * localmarket_price[i]
+ if(goods_units[i] == 0) player["holdspace"] -= t
+ return t
+}
+
+# sell amount a of product i, return amount sold
+function gamesell(i, a, t) {
+ t = mymin(shipshold[i], a)
+ shipshold[i] -= t
+ localmarket_quantity[i] += t
+ if(goods_units[i] == 0) player["holdspace"] += t
+ player["cash"] += t * localmarket_price[i]
+ return t
+}
+
+# generate market for a particular planetary system
+# accepts fluctuation byte and economy type number
+# recreates localmarket_quantity and localmarket_price arrays
+function genmarket(fluct, econtype, i, q, product, changing) {
+ for(i=0;i<=IDX_ALIEN_ITEMS;i++) {
+ product = econtype * goods_grads[i]
+ changing = bw_and(fluct, goods_masks[i])
+ q = (goods_bquants[i] + changing - product + 256) % 256
+ if(q > 127) q = 0
+ localmarket_quantity[i] = q % 64
+ q = (goods_bprices[i] + changing + product) % 256
+ localmarket_price[i] = q * 4
+ }
+ if(NO_ALIEN_ITEMS) localmarket_quantity[IDX_ALIEN_ITEMS] = 0
+}
+
+# display local market from localmarket_quantity and localmarket_price
+function displaymarket(i) {
+ for(i=0;i<=IDX_ALIEN_ITEMS;i++) {
+ printf("\n%-16s", goods_names[i])
+ printf("%-5s", sprintf("%.1f", localmarket_price[i]/10))
+ printf("\t%u%s", localmarket_quantity[i], unitnames[goods_units[i]])
+ printf("\t\t%u", shipshold[i])
+ }
+}
+
+# move to system i
+function gamejump(i, si) {
+ player["currentplanet"] = i
+ assocdes(galaxy[i], si, "|")
+ genmarket(randbyte(), int(si["economy"]))
+}
+
+# print data for given system
+function prisys(sinfo, compressed) {
+ if(compressed) {
+ printf("%10s TL: %2i ", sinfo["name"], sinfo["techlev"] + 1)
+ printf("%-20s %-15s", econnames[sinfo["economy"]], govnames[sinfo["govtype"]])
+ } else {
+ printf("\nSystem: %s", sinfo["name"])
+ printf("\nPosition (%i, %i)", sinfo["x"], sinfo["y"])
+ printf("\nEconomy: (%i) %s", sinfo["economy"], econnames[sinfo["economy"]])
+ printf("\nGovernment: (%i) %s", sinfo["govtype"], govnames[sinfo["govtype"]])
+ printf("\nTech level: %2i", sinfo["techlev"] + 1)
+ printf("\nTurnover: %u", sinfo["productivity"])
+ printf("\nRadius: %u", sinfo["radius"])
+ printf("\nPopulation: %u billion\n", int(sinfo["population"]/8))
+ goat_soup("\217 is \227.", sinfo) # generate and print the description
+ }
+}
+
+# return id of the planet whose name matches passed string
+# closest to current planet - if none, return current planet
+function matchsys(s, d, i, p, cd) {
+ p = player["currentplanet"]
+ d = 9999
+ s = toupper(s) # system names are stored in uppercase
+ for(i=0;i<galsize;i++) {
+ if(index(s, galnames[i]) == 1) { # found i-th system
+ cd = distance(galcoords_x[i], galcoords_y[i], galcoords_x[p], galcoords_y[p])
+ if(cd < d) {d = cd; p = i}
+ }
+ }
+ return p
+}
+
+# direct command implementations (may be further merged into the REPL directly)
+
+# rand command implementation
+function dotweakrand() {game["use_native_rand"] = 1 - game["use_native_rand"] }
+
+# local command implementation
+function dolocal(d, i, p, si) {
+ printf("Galaxy number %i", player["galaxynum"])
+ p = int(player["currentplanet"])
+ for(i=0;i<galsize;i++) {
+ d = distance(galcoords_x[i], galcoords_y[i], galcoords_x[p], galcoords_y[p])
+ if(d <= game["maxfuel"]) {
+ printf("\n %s ", (d <= player["fuel"]) ? "*" : "-")
+ assocdes(galaxy[i], si, "|") # deserialize current system
+ prisys(si, 1)
+ printf(" (%.1f LY)", d/10)
+ }
+ }
+}
+
+# jump to planet name s
+function dojump(s, dest, d, p, si) {
+ dest = matchsys(s) # find the destination
+ p = int(player["currentplanet"])
+ if(dest == p) { printf("\nBad jump"); return 0}
+ d = distance(galcoords_x[dest], galcoords_y[dest], galcoords_x[p], galcoords_y[p])
+ if(d > player["fuel"]) {printf("\nJump too far"); return 0}
+ player["fuel"] -= d
+ gamejump(dest, si)
+ prisys(si, 0)
+ return 1
+}
+
+# dojump without fuel expense
+function dosneak(s, kp, r) {
+ kp = player["fuel"]
+ player["fuel"] = 666
+ r = dojump(s)
+ player["fuel"] = kp
+ return r
+}
+
+# jump to next galaxy (planet number is preserved)
+function dogalhyp() {
+ player["galaxynum"]++
+ if(player["galaxynum"] == 9) player["galaxynum"] = 1
+ buildgalaxy(player["galaxynum"], globalseeds) # build a new galaxy
+}
+
+# print planet info
+function doinfo(s, dest, si) {
+ dest = matchsys(s) # find the system
+ assocdes(galaxy[dest], si, "|") # deserialize found system
+ prisys(si, 0) # print its info
+}
+
+# hold command implementation
+function dohold(a, t, i) {
+ t = 0
+ a = int(a)
+ for(i=0;i<=IDX_ALIEN_ITEMS;i++)
+ if(goods_units[i] == 0) t += shipshold[i]
+ if(t > a) {printf("\nHold too full"); return 0}
+ player["holdspace"] = a - t
+ return 1
+}
+
+# check string s against n options in array a
+# if matches ith element return i+1 else return 0
+function stringmatch(s, a, n, i) {
+ s = tolower(s)
+ for(i=0;i<n;i++)
+ if(index(tolower(a[i]), s) == 1) return i+1
+ return 0
+}
+
+# sell command implementation (accepts space-separated name and amount)
+function dosell(s, sp, pname, pquant, i, t) {
+ split(s, sp, " ")
+ pname = sp[1]
+ pquant = int(sp[2])
+ if(pquant < 1) pquant = 1
+ i = stringmatch(pname, goods_names, IDX_ALIEN_ITEMS + 1)
+ if(i == 0) {printf("\nUnknown product"); return 0}
+ i -= 1 # switch to the real product index
+ t = gamesell(i, pquant)
+ pname = goods_names[i] # update real product name
+ if(t > 0) {
+ printf("\nSelling %i%s of %s", t, goods_units[i], pname)
+ } else printf("\nCannot sell any %s", pname)
+ return 1
+}
+
+# buy command implementation (accepts space-separated name and amount)
+function dobuy(s, sp, pname, pquant, i, t) {
+ split(s, sp, " ")
+ pname = sp[1]
+ pquant = int(sp[2])
+ if(pquant < 1) pquant = 1
+ i = stringmatch(pname, goods_names, IDX_ALIEN_ITEMS + 1)
+ if(i == 0) {printf("\nUnknown product"); return 0}
+ i -= 1 # switch to the real product index
+ t = gamebuy(i, pquant)
+ pname = goods_names[i] # update real product name
+ if(t > 0) {
+ printf("\nBuying %i%s of %s", t, goods_units[i], pname)
+ } else printf("\nCannot buy any %s", pname)
+ return 1
+}
+
+# attempt to buy f tonnes of fuel
+function gamefuel(f) {
+ if((f + player["fuel"]) > game["maxfuel"])
+ f = game["maxfuel"] - player["fuel"]
+ if(game["fuelcost"] > 0 && (f * game["fuelcost"] > player["cash"]))
+ f = int(player["cash"] / game["fuelcost"])
+ player["fuel"] += f
+ player["cash"] -= f * game["fuelcost"]
+ return f
+}
+
+# fuel command implementation
+function dofuel(f) {
+ f = gamefuel(int(10 * f))
+ if(f == 0) printf("\nCan't buy any fuel")
+ else printf("\nBuying %.1fLY fuel", f/10)
+ return 1
+}
+
+# (cheat) alter cash command implementation
+function docash(s) {
+ player["cash"] += int(10 * s)
+ if(player["cash"] < 0) player["cash"] = 0
+}
+
+# show stock market
+function domkt() {
+ displaymarket()
+ printf("\n\nFuel: %.1f\nHoldspace: %it", player["fuel"]/10, player["holdspace"])
+}
+
+# display help
+function dohelp() {
+ printf("\nCommands are:");
+ printf("\nBuy tradegood amount");
+ printf("\nSell tradegood amount");
+ printf("\nFuel amount (buy amount LY of fuel)");
+ printf("\nJump planetname (limited by fuel)");
+ if(CHEAT)
+ printf("\nSneak planetname (any distance - no fuel cost)");
+ printf("\nGalhyp (jumps to next galaxy)");
+ printf("\nInfo planetname (prints info on system)");
+ printf("\nMkt (shows market prices)");
+ printf("\nLocal (lists systems within 7 light years)");
+ if(CHEAT)
+ printf("\nCash number (alters cash - cheating!)");
+ printf("\nHold number (change cargo bay)");
+ printf("\nQuit or ^C (exit)");
+ printf("\nHelp (display this text)");
+ printf("\nRand (toggle RNG)");
+ printf("\n\nAbbreviations allowed eg. b fo 5 = Buy Food 5, m= Mkt");
+}
+
+# Game init procedure: first thing to call in the BEGIN block
+function gameinit() {
+ rng_lastrand = 0 # state for custom PRNG
+ mysrand(12345); # ensure repeatability
+ numForLave = 7 # Lave is the 7th planet in galaxy 1
+
+ split("",game) # overall game state is stored here
+ game["use_native_rand"] = 1
+ game["fuelcost"] = 2 # 0.2 CR/lightyear
+ game["maxfuel"] = 70 # 7.0 LY tank
+
+ split("",player) # current (saveable) player state is stored here
+ player["currentplanet"] = numForLave # current planet (1 to 256)
+ player["galaxynum"] = 1 # current galaxy (1 to 8)
+ player["cash"] = 1000 # current cash
+ player["fuel"] = game["maxfuel"] # current fuel amount
+ player["holdspace"] = 20 # max cargo hold space
+ split("",shipshold) # (saveable) contents of cargo bay, up to 16 items
+
+ # constants and tables
+
+ # unit names
+ asplit("t kg g", unitnames, " ")
+
+ # government names
+ asplit("Anarchy,Feudal,Multi-gov,Dictatorship,Communist,Confederacy,Democracy,Corporate State", govnames, ",")
+
+ # economy names
+ asplit("Rich Industrial,Average Industrial,Poor Industrial,Mainly Industrial,Mainly Agricultural,Rich Agricultural,Average Agricultural,Poor Agricultural", econnames, ",")
+
+ # Goods
+
+ # Data for DB's price/availability generation system:
+ # Base price, Gradient, Base quantity, Mask, Unit, Name
+ split("", commodities) # will split on demand
+ commodities[0] = "19,-2,6,1,0,Food"
+ commodities[1] = "20,-1,10,3,0,Textiles"
+ commodities[2] = "65,-3,2,7,0,Radioactives"
+ commodities[3] = "40,-5,226,31,0," (CENSORED ? "Robots" : "Slaves")
+ commodities[4] = "83,-5,251,15,0," (CENSORED ? "Beverages" : "Liquors")
+ commodities[5] = "196,8,54,3,0,Luxuries"
+ commodities[6] = "235,29,8,120,0," (CENSORED ? "Rare Species" : "Narcotics")
+ commodities[7] = "154,14,56,3,0,Computers"
+ commodities[8] = "117,6,40,7,0,Machinery"
+ commodities[9] = "78,1,17,31,0,Alloys"
+ commodities[10] = "124,13,29,7,0,Firearms"
+ commodities[11] = "176,-9,220,63,0,Furs"
+ commodities[12] = "32,-1,53,3,0,Minerals"
+ commodities[13] = "97,-1,66,7,1,Gold"
+ commodities[14] = "171,-2,55,31,1,Platinum"
+ commodities[15] = "45,-1,250,15,2,Gem-stones"
+ commodities[16] = "53,15,192,7,0,Alien Items"
+
+ IDX_ALIEN_ITEMS=16
+
+ split("", goods_bprices) # holds base prices
+ split("", goods_grads) # holds gradients
+ split("", goods_bquants) # holds base quantities
+ split("", goods_masks) # holds masks
+ split("", goods_units) # holds measurement units
+ split("", goods_names) # holds goods names
+ for(i in commodities) { # it's pre-ordered anyway
+ split(commodities[i], parts, ",") # we can use 1-based here
+ goods_bprices[i] = int(parts[1])
+ goods_grads[i] = int(parts[2])
+ goods_bquants[i] = int(parts[3])
+ goods_masks[i] = int(parts[4])
+ goods_units[i] = int(parts[5])
+ goods_names[i] = parts[6]
+ }
+
+ # localmarket assoc arrays
+ split("", localmarket_quantity)
+ split("", localmarket_price)
+
+ # digrams for planet names
+ asplit("ABOUSEITILETSTONLONUTHNOALLEXEGEZACEBISOUSESARMAINDIREA.ERATENBERALAVETIEDORQUANTEISRION", pairs0, "")
+ asplit("..LEXEGEZACEBISOUSESARMAINDIREA.ERATENBERALAVETIEDORQUANTEISRION", pairs, "")
+
+ # planet description string parts
+ desc_list_str = "fabled,notable,well known,famous,noted|very,mildly,most,reasonably,|ancient,\225,great,vast,pink|\236 \235 plantations,mountains,\234,\224 forests,oceans|shyness,silliness,mating traditions,loathing of \206,love for \206|food blenders,tourists,poetry,discos,\216|talking tree,crab,bat,lobst,\262|beset,plagued,ravaged,cursed,scourged|\226 civil war,\233 \230 \231s,a \233 disease,\226 earthquakes,\226 solar activity|its \203 \204,the \261 \230 \231,its inhabitants' \232 \205,\241,its \215 \216|juice,brandy,water,brew,gargle blasters|\262,\261 \231,\261 \262,\261 \233,\233 \262|fabulous,exotic,hoopy,unusual,exciting|cuisine,night life,casinos,sit coms, \241 |\260,The planet \260,The world \260,This planet,This world|n unremarkable, boring, dull, tedious, revolting|planet,world,place,little planet,dump|wasp,moth,grub,ant,\262|poet,arts graduate,yak,snail,slug|tropical,dense,rain,impenetrable,exuberant|funny,weird,unusual,strange,peculiar|frequent,occasional,unpredictable,dreadful,deadly|\202 \201 for \212,\202 \201 for \212 and \212,\210 by \211,\202 \201 for \212 but \210 by \211,a\220 \221|\233,mountain,edible,tree,spotted|\237,\240,\207oid,\223,\222|ancient,exceptional,eccentric,ingrained,\225|killer,deadly,evil,lethal,vicious|parking meters,dust clouds,ice bergs,rock formations,volcanoes|plant,tulip,banana,corn,\262weed|\262,\261 \262,\261 \233,inhabitant,\261 \262|shrew,beast,bison,snake,wolf|leopard,cat,monkey,goat,fish|\214 \213,\261 \237 \242,its \215 \240 \242,\243 \244,\214 \213|meat,cutlet,steak,burgers,soup|ice,mud,Zero-G,vacuum,\261 ultra|hockey,cricket,karate,polo,tennis"
+ asplit(desc_list_str, desc_list, "|")
+
+ galsize = 256 # number of systems in one galaxy
+
+}
+
+# main code block
+BEGIN {
+ gameinit() # init everything
+ split("", globalseeds) # init galaxy seeds
+ buildgalaxy(player["galaxynum"], globalseeds) # build the current galaxy
+ genmarket(0, economies[player["currentplanet"]]) # build local market
+ printf("\nWelcome to awlite 1.5.1 (based on Text Elite 1.5)\n")
+ dohelp()
+ # start the REPL
+ printf("\n\nCash: %.1f> ", player["cash"]/10)
+ while((getline cmd) > 0) {
+ cmd = tolower(cmd) # accept both uppercase and lowercase
+ spi = index(cmd, " ") # first whitespace in cmd
+ action = (spi == 0) ? cmd : substr(cmd, 1, spi - 1)
+ paramstr = (spi == 0) ? "" : substr(cmd, spi+1)
+ if(cmd == "q" || cmd == "quit") break
+ else if(cmd == "h" || cmd == "help") dohelp()
+ else if(cmd == "r" || cmd == "rand") dotweakrand()
+ else if(cmd == "m" || cmd == "mkt") domkt()
+ else if(cmd == "l" || cmd == "local") dolocal()
+ else if(cmd == "g" || cmd == "galhyp") dogalhyp()
+ else if(action == "i" || action == "info") doinfo(paramstr)
+ else if(action == "b" || action == "buy") dobuy(paramstr)
+ else if(action == "s" || action == "sell") dosell(paramstr)
+ else if(action == "j" || action == "jump") dojump(paramstr)
+ else if(action == "f" || action == "fuel") dofuel(paramstr)
+ else if(action == "ho" || action == "hold") dofuel(paramstr)
+ else if(CHEAT && action == "cash") docash(paramstr)
+ else if(CHEAT && action == "sneak") dosneak(paramstr)
+ else printf("Unknown command")
+ printf("\n\nCash: %.1f> ", player["cash"]/10)
+ }
+ print "\nBye!"
+}