awlite

POSIX AWK port of Text Elite game
git clone git://git.luxferre.top/awlite.git
Log | Files | Refs

commit e78a75ac842127a5e2cd51c95b7c7fb567b35edd
Author: Luxferre <lux@ferre>
Date:   Sun, 21 Jan 2024 19:35:11 +0200

Initial upload

Diffstat:
Aawlite.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!" +}