awk-gold-collection

My best software created for POSIX AWK
git clone git://git.luxferre.top/awk-gold-collection.git
Log | Files | Refs | Submodules | README

tch.awk (2356B)


      1 #!/sbin/env awk -f
      2 # TCh: the simplest TinyChoice game engine port to POSIX AWK
      3 # Usage: awk -f tch.awk your-story.txt
      4 # Controls: respond with a number to go to a particular choice, q to quit
      5 # Created by Luxferre in 2023, released into public domain
      6 
      7 BEGIN {
      8   curscreen = "" # store the current screen key
      9   firstscreen = ""
     10   split("", screens) # init the screens map
     11   if(ARGC < 2) {print "No input story file!"; exit(1)}
     12   while((getline < ARGV[1]) > 0) {
     13     if($0 ~ /^=.*=$/) { # header line processing
     14       if(curscreen) { # finalize the previous entry
     15         gsub(/^\n+/, "", screens[curscreen])
     16         gsub(/\n+$/, "", screens[curscreen])
     17       } else firstscreen = -999
     18       curscreen = tolower(substr($0, 2, length($0)-2))
     19       if(firstscreen == -999) firstscreen = curscreen # save the key value
     20     } else if(curscreen) screens[curscreen] = screens[curscreen] $0 "\n"
     21   }
     22   close(ARGV[1])
     23   delete ARGV[1]
     24   # actual runtime logic
     25   curscreen = ("start" in screens) ? "start" : firstscreen 
     26   while(length(curscreen) > 0) { # get the lines of the current screen
     27     l = split(screens[curscreen], lines, "\n")
     28     split("", choices) # init the choices array
     29     ch = 1 # init the choice number
     30     for(i=1;i<=l;i++) { # we must iterate in order
     31       line = lines[i]
     32       if(index(line, "->") > 0) { # we have a choice spec
     33         split(line, rch, /[ \t]*\->[ \t]*/)
     34         tlabel = rch[1] # label is before ->
     35         tscreen = rch[2] # target screen is after ->
     36         gsub(/^[ \t]+/, "", tlabel) # trim leading spaces in the label
     37         gsub(/[ \t]+$/, "", tlabel) # trim trailing spaces in the label
     38         gsub(/^[ \t]+/, "", tscreen) # trim leading spaces in the ref
     39         gsub(/[ \t]+$/, "", tscreen) # trim trailing spaces in the ref
     40         if(!(tscreen in screens)) {
     41           printf("Invalid reference %s!\n", tscreen)
     42           exit(1)
     43         }
     44         choices[ch] = tscreen
     45         printf("%u) %s\n", ch++, tlabel)
     46       } else print line # just print the line "as is"
     47     }
     48     do {
     49       printf "\n> "; if((getline) <= 0) break # prompt for the user choice
     50       if($1 == "q" || $1 == "Q" || $1 == "quit" || $1 == "QUIT") {
     51         print "Bye!"; exit(0)
     52       }
     53       ch = int($1)
     54     } while(!(ch && (ch in choices) && (choices[ch] in screens)))
     55     curscreen = choices[ch] # jump to the selected screen
     56   }
     57 }