v1.7: stats command, basic ranking

This commit is contained in:
Luxferre
2024-01-26 15:43:14 +02:00
parent 1ab9911538
commit 2d57dc3c47
2 changed files with 71 additions and 12 deletions
+29 -6
View File
@@ -42,6 +42,7 @@ From now on, the following commands are available (case-insensitive):
* mkt: show local planetary system market prices * mkt: show local planetary system market prices
* local: list planetary systems within 7 lightyears (your max fuel capacity) * local: list planetary systems within 7 lightyears (your max fuel capacity)
* hold: expand your cargo bay to 35t for 400 credits (one-time upgrade only) * hold: expand your cargo bay to 35t for 400 credits (one-time upgrade only)
* stat: show player statistics and overall rank
* save (name): save the gamestate in the current working directory * save (name): save the gamestate in the current working directory
* load (name): load the gamestate from the current working directory * load (name): load the gamestate from the current working directory
* help: display an in-game command help screen * help: display an in-game command help screen
@@ -56,7 +57,7 @@ Fuel price is fixed at 0.2 CR/LY, you can hold 7LY of fuel at most.
== Gameplay differences from the original TE 1.5 C version == == Gameplay differences from the original TE 1.5 C version ==
As of the current version, 1.6.3: As of the current version, 1.7:
* multiple typos corrected in text strings * multiple typos corrected in text strings
* the "cash" and "sneak" commands were removed since v1.6 * the "cash" and "sneak" commands were removed since v1.6
@@ -75,6 +76,7 @@ As of the current version, 1.6.3:
* since v1.6.1, the game gives you a hint if you might have found Raxxla * since v1.6.1, the game gives you a hint if you might have found Raxxla
* since v1.6.3, galaxy names are also displayed with "local" command * since v1.6.3, galaxy names are also displayed with "local" command
(the names were taken from the Archimedes version of Classic Elite) (the names were taken from the Archimedes version of Classic Elite)
* since v1.7, basic ranking and statistics have been introduced
To be continued. This list is expected to grow in the future. To be continued. This list is expected to grow in the future.
@@ -115,19 +117,40 @@ set implementation bumps the version number by 0.1, indicating that it's no
longer fully command-to-command compatible with the previous one. longer fully command-to-command compatible with the previous one.
The first published awlite version was 1.5.8, meaning 8 minor improvements. The first published awlite version was 1.5.8, meaning 8 minor improvements.
- If there are no combat missions or ranks, what are the goals in awlite? - If there are no combat missions, what are the goals in awlite?
Like the original Elite and Text Elite, awlite has no end-game goal. There are, Like the original Elite and Text Elite, awlite has no end-game goal. There are,
however, some milestones you can achieve even now, for instance: however, some milestones you can achieve even now, for instance:
* reaching the Elite trade rank (in v1.7+ - see below);
* reaching a certain amount of credits; * reaching a certain amount of credits;
* collecting certain amounts of rare valuable items; * collecting certain amounts of rare valuable items;
* visiting all planets in all galaxies (2048 total); * visiting all planets in all galaxies (2048 total);
* finding Raxxla (v1.6.1+ will give you a hint when you might have done so). * finding Raxxla (v1.6.1+ will give you a hint when you might have done so).
As of now, player ranking system and statistics are in the works and planned As of now, player ranking system and statistics are in the works. The basic
to be introduced in version 1.7 or 1.8. They will be loosely based upon Trade system of stats and ranks was introduced in v1.7. It is loosely based upon the
and Explorer ranking of Elite Dangerous but are going to be unique to awlite. Trade ranks of Elite Dangerous but the formula is fully unique to awlite.
- How are ranks calculated in awlite v1.7 and above?
To keep things simple, the formula currently only considers the current cash
balance and overall expenses to calculate the profit margin, then taking log2
of it. As of now, the following profit margin to rank mapping is in effect:
* Under 100%: Penniless
* 100% to 200%: Mostly Penniless
* 200% to 400%: Peddler
* 400% to 800%: Dealer
* 800% to 1600%: Merchant
* 1600% to 3200%: Broker
* 3200% to 6400%: Entrepreneur
* 6400% to 12800%: Tycoon
* 12800% and above: Elite
So, to reach Elite trade rank, you need to make 128 times more money than you
spend. This system might change in future versions, as it's not clear whether
or not this is possible at all.
- I found an awesome trade route in awlite. Can I use it in other Elite games? - I found an awesome trade route in awlite. Can I use it in other Elite games?
@@ -149,7 +172,7 @@ being designed.
- How large is awlite? - How large is awlite?
As of now, the entire game is contained in a single file with a little under As of now, the entire game is contained in a single file with a little under
500 SLOC of POSIX AWK code. Future functionality might increase the codebase 550 SLOC of POSIX AWK code. Future functionality might increase the codebase
size, but one of the goals is to keep it under 1000 SLOC no matter what. size, but one of the goals is to keep it under 1000 SLOC no matter what.
- Why AWK? - Why AWK?
+42 -6
View File
@@ -1,5 +1,5 @@
# awlite: POSIX AWK port of Text Elite # awlite: POSIX AWK port of Text Elite
# Version 1.6.3 # Version 1.7
# Original high-level algorithms from Text Elite 1.5 by Ian Bell, 1999, 2015 # Original high-level algorithms from Text Elite 1.5 by Ian Bell, 1999, 2015
# Porting, corrections, improvements and optimizations by Luxferre, 2024 # Porting, corrections, improvements and optimizations by Luxferre, 2024
# #
@@ -20,6 +20,7 @@
# - state saving functionality since v1.6 with "save" and "load" commands # - state saving functionality since v1.6 with "save" and "load" commands
# - since v1.6.1, the game gives you a hint if you might have found Raxxla # - since v1.6.1, the game gives you a hint if you might have found Raxxla
# - since v1.6.3, galaxy names are actually displayed (taken from ArcElite) # - since v1.6.3, galaxy names are actually displayed (taken from ArcElite)
# - since v1.7, "stat" command and basic ranking was introduced
# ... to be continued ... # ... to be continued ...
# utility functions # utility functions
@@ -249,6 +250,7 @@ function gamebuy(i, a, t) {
shipshold[i] = int(shipshold[i]) + t shipshold[i] = int(shipshold[i]) + t
localmarket_quantity[i] -= t localmarket_quantity[i] -= t
player["cash"] -= t * localmarket_price[i] player["cash"] -= t * localmarket_price[i]
player["expense"] += t * localmarket_price[i]
if(goods_units[i] == 0) player["holdspace"] -= t if(goods_units[i] == 0) player["holdspace"] -= t
return t return t
} }
@@ -292,6 +294,7 @@ function displaymarket(i) {
# move to system i # move to system i
function gamejump(i, si) { function gamejump(i, si) {
player["currentplanet"] = i player["currentplanet"] = i
player["jumps"]++
assocdes(galaxy[i], si, "|") assocdes(galaxy[i], si, "|")
genmarket(randbyte(), int(si["economy"])) genmarket(randbyte(), int(si["economy"]))
} }
@@ -368,7 +371,9 @@ function dojump(s, dest, d, p, si) {
function dogalhyp() { function dogalhyp() {
if(player["cash"] > game["galhypcost"]) { if(player["cash"] > game["galhypcost"]) {
player["cash"] -= game["galhypcost"] player["cash"] -= game["galhypcost"]
player["expense"] += game["galhypcost"]
player["galaxynum"]++ player["galaxynum"]++
player["jumps"]++
if(player["galaxynum"] == 9) player["galaxynum"] = 1 if(player["galaxynum"] == 9) player["galaxynum"] = 1
buildgalaxy(player["galaxynum"], globalseeds) # build a new galaxy buildgalaxy(player["galaxynum"], globalseeds) # build a new galaxy
} }
@@ -399,6 +404,7 @@ function dohold(a, t, i) {
if(t > a) {printf("\nHold too full"); return 0} if(t > a) {printf("\nHold too full"); return 0}
player["holdspace"] = a - t player["holdspace"] = a - t
player["cash"] -= game["cargoexpcost"] player["cash"] -= game["cargoexpcost"]
player["expense"] += game["cargoexpcost"]
printf("\nCargo bay expanded to %dt", game["cargoexpsize"]) printf("\nCargo bay expanded to %dt", game["cargoexpsize"])
return 1 return 1
} }
@@ -454,6 +460,7 @@ function gamefuel(f) {
f = int(player["cash"] / game["fuelcost"]) f = int(player["cash"] / game["fuelcost"])
player["fuel"] += f player["fuel"] += f
player["cash"] -= f * game["fuelcost"] player["cash"] -= f * game["fuelcost"]
player["expense"] += f * game["fuelcost"]
return f return f
} }
@@ -478,11 +485,12 @@ function dohelp() {
printf("\nSell product amount") printf("\nSell product amount")
printf("\nFuel amount (buy amount LY of fuel)") printf("\nFuel amount (buy amount LY of fuel)")
printf("\nJump planetname (limited by fuel)") printf("\nJump planetname (limited by fuel)")
printf("\nGalhyp (jumps to next galaxy)") printf("\nGalhyp (jump to next galaxy)")
printf("\nInfo planetname (prints info on system)") printf("\nInfo planetname (print info on system)")
printf("\nMkt (shows market prices)") printf("\nMkt (show market prices)")
printf("\nLocal (lists systems within 7 lightyears)") printf("\nLocal (list systems within 7 lightyears)")
printf("\nHold (expand cargo bay to %dt)", game["cargoexpsize"]) printf("\nHold (expand cargo bay to %dt)", game["cargoexpsize"])
printf("\nStat (show player statistics)")
printf("\nSave playername (save game into current working directory)") printf("\nSave playername (save game into current working directory)")
printf("\nLoad playername (load game from current working directory)") printf("\nLoad playername (load game from current working directory)")
printf("\nQuit or ^D (exit)") printf("\nQuit or ^D (exit)")
@@ -521,6 +529,28 @@ function doload(savename, fn, fs) {
close(fn) close(fn)
} }
# player statistics and ranking display
# ranking formula might be subject to change in future versions
function dostat(profind, rank) {
profind = 0 # profit margin index
rank = 0
if(player["expense"] > 0) {
profind = (player["cash"]-1000) / player["expense"]
rank = int(log(1 + profind) / log(2)) # log base 2
if(rank < 0) rank = 0
if(rank > 8) rank = 8
}
printf("\nRank: %s", ranknames[rank])
printf("\n\n========= Money =========")
printf("\nBalance %17s", sprintf("%.1f CR",player["cash"]/10))
printf("\nExpenses %16s", sprintf("%.1f CR", player["expense"]/10))
printf("\nProfit margin %11s", sprintf("%.2f%%", profind*100))
printf("\n\n======= Ship info =======")
printf("\nFuel %20s", sprintf("%.1f LY", player["fuel"]/10))
printf("\nCargo space %13s", sprintf("%ut", player["holdspace"]))
printf("\nJumps %19s", sprintf("%u", player["jumps"]))
}
# Game init procedure: first thing to call in the BEGIN block # Game init procedure: first thing to call in the BEGIN block
function gameinit() { function gameinit() {
rng_lastrand = 0 # state for custom PRNG rng_lastrand = 0 # state for custom PRNG
@@ -539,6 +569,8 @@ function gameinit() {
player["currentplanet"] = numForLave # current planet (1 to 256) player["currentplanet"] = numForLave # current planet (1 to 256)
player["galaxynum"] = 1 # current galaxy (1 to 8) player["galaxynum"] = 1 # current galaxy (1 to 8)
player["cash"] = 1000 # current cash (100 CR) player["cash"] = 1000 # current cash (100 CR)
player["expense"] = 0 # for tracking overall expenses
player["jumps"] = 0 # for counting interplanetary jumps
player["fuel"] = game["maxfuel"] # current fuel amount player["fuel"] = game["maxfuel"] # current fuel amount
player["holdspace"] = 20 # max cargo hold space player["holdspace"] = 20 # max cargo hold space
split("",shipshold) # (saveable) contents of cargo bay, up to 16 items split("",shipshold) # (saveable) contents of cargo bay, up to 16 items
@@ -557,6 +589,9 @@ function gameinit() {
# economy names # economy names
asplit("Rich Industrial,Average Industrial,Poor Industrial,Mainly Industrial,Mainly Agricultural,Rich Agricultural,Average Agricultural,Poor Agricultural", econnames, ",") asplit("Rich Industrial,Average Industrial,Poor Industrial,Mainly Industrial,Mainly Agricultural,Rich Agricultural,Average Agricultural,Poor Agricultural", econnames, ",")
# rank names
asplit("Penniless,Mostly Penniless,Peddler,Dealer,Merchant,Broker,Entrepreneur,Tycoon,Elite", ranknames, ",")
# Goods # Goods
# Data for DB's price/availability generation system: # Data for DB's price/availability generation system:
@@ -620,7 +655,7 @@ BEGIN {
split("", globalseeds) # init galaxy seeds split("", globalseeds) # init galaxy seeds
buildgalaxy(player["galaxynum"], globalseeds) # build the current galaxy buildgalaxy(player["galaxynum"], globalseeds) # build the current galaxy
genmarket(0, economies[player["currentplanet"]]) # build local market genmarket(0, economies[player["currentplanet"]]) # build local market
printf("\nWelcome to awlite 1.6.3\n") printf("\nWelcome to awlite 1.7\n")
dohelp() dohelp()
# start the REPL # start the REPL
printf("\n\nCash: %.1f> ", player["cash"]/10) printf("\n\nCash: %.1f> ", player["cash"]/10)
@@ -635,6 +670,7 @@ BEGIN {
else if(cmd == "m" || cmd == "mkt") domkt() else if(cmd == "m" || cmd == "mkt") domkt()
else if(cmd == "l" || cmd == "local") dolocal() else if(cmd == "l" || cmd == "local") dolocal()
else if(cmd == "g" || cmd == "galhyp") dogalhyp() else if(cmd == "g" || cmd == "galhyp") dogalhyp()
else if(cmd == "st" || cmd == "stat") dostat()
else if(action == "i" || action == "info") doinfo(paramstr) else if(action == "i" || action == "info") doinfo(paramstr)
else if(action == "b" || action == "buy") dobuy(paramstr) else if(action == "b" || action == "buy") dobuy(paramstr)
else if(action == "s" || action == "sell") dosell(paramstr) else if(action == "s" || action == "sell") dosell(paramstr)