Files
awk-gold-collection/engines/tch.awk
T
2024-01-23 10:29:28 +02:00

58 lines
2.3 KiB
Awk

#!/sbin/env awk -f
# TCh: the simplest TinyChoice game engine port to POSIX AWK
# Usage: awk -f tch.awk your-story.txt
# Controls: respond with a number to go to a particular choice, q to quit
# Created by Luxferre in 2023, released into public domain
BEGIN {
curscreen = "" # store the current screen key
firstscreen = ""
split("", screens) # init the screens map
if(ARGC < 2) {print "No input story file!"; exit(1)}
while((getline < ARGV[1]) > 0) {
if($0 ~ /^=.*=$/) { # header line processing
if(curscreen) { # finalize the previous entry
gsub(/^\n+/, "", screens[curscreen])
gsub(/\n+$/, "", screens[curscreen])
} else firstscreen = -999
curscreen = tolower(substr($0, 2, length($0)-2))
if(firstscreen == -999) firstscreen = curscreen # save the key value
} else if(curscreen) screens[curscreen] = screens[curscreen] $0 "\n"
}
close(ARGV[1])
delete ARGV[1]
# actual runtime logic
curscreen = ("start" in screens) ? "start" : firstscreen
while(length(curscreen) > 0) { # get the lines of the current screen
l = split(screens[curscreen], lines, "\n")
split("", choices) # init the choices array
ch = 1 # init the choice number
for(i=1;i<=l;i++) { # we must iterate in order
line = lines[i]
if(index(line, "->") > 0) { # we have a choice spec
split(line, rch, /[ \t]*\->[ \t]*/)
tlabel = rch[1] # label is before ->
tscreen = rch[2] # target screen is after ->
gsub(/^[ \t]+/, "", tlabel) # trim leading spaces in the label
gsub(/[ \t]+$/, "", tlabel) # trim trailing spaces in the label
gsub(/^[ \t]+/, "", tscreen) # trim leading spaces in the ref
gsub(/[ \t]+$/, "", tscreen) # trim trailing spaces in the ref
if(!(tscreen in screens)) {
printf("Invalid reference %s!\n", tscreen)
exit(1)
}
choices[ch] = tscreen
printf("%u) %s\n", ch++, tlabel)
} else print line # just print the line "as is"
}
do {
printf "\n> "; if((getline) <= 0) break # prompt for the user choice
if($1 == "q" || $1 == "Q" || $1 == "quit" || $1 == "QUIT") {
print "Bye!"; exit(0)
}
ch = int($1)
} while(!(ch && (ch in choices) && (choices[ch] in screens)))
curscreen = choices[ch] # jump to the selected screen
}
}