Task

Given a jumbled list of the numbers   1   to   9   that are definitely   not   in
ascending order.

Show the list,   and then ask the player how many digits from the
left to reverse.

Reverse those digits,   then ask again,   until all the digits end up in ascending order.



The score is the count of the reversals needed to attain the ascending order.



Note: Assume the player's input does not need extra validation.



Related tasks

   Sorting algorithms/Pancake sort
   Pancake sorting.
   Topswops


procedure main(cq)                                             # Number Reversal Game
local x,nums,R,flips
 
$define PROTECT ["WIN","ASK"]
$define MAGIC   ["xyzzy","abracadabra","hocus","pocus","presto","changeo","open","sesame","irs"]
 
put(cq,"game")                                                 # start command queue - use command line
rule := string(&digits--'0')                                   # ruler and move commands
every put(protected := [], map(!PROTECT))                      # protected commands
every put(magic := [], !MAGIC)
 
while x := get(cq) | "MOVE" do {                               # command from queue or ask for move
   case x of {                      
      "help" | "h" | "?" :                                     # --- start of user facing commands ---
         write("Input a position.  The list will be flipped left to right at that point.\n",
	       "You win when the list is sorted.\n",
	       "Commands:\n",
               "   help, h, ? - shows this\n",
               "   new, g     - new game\n",			   
               "   ruler, r   - shows a ruler\n",
               "   show, s    - shows the list\n",
               "   <n>        - flips the list at ruler position n\n",
               "   quit, q    - quit\n",
               "and various magic words.\n"
               ) & put(cq,"rule")
      "game" | "g" | "new"  : {
         put(cq,"help")                                     
         flips := 0
         nums := rule
         until nums ~== rule do 
         every !nums :=: ?nums                                 # shuffle
         }
      "rule" | "ruler" | "r" : 
         put(cq,"show") & every writes(" " || " " | !(if /mirror then rule else reverse(rule)) | "\n") 
      "show" | "s" :
         every writes(" " || "=" | !nums | " =\n") 
      !rule : {                                                #  0 - 9 for flipping
         if /mirror then nums[1+:x] := reverse(nums[1+:x]) 
         else nums[0-:x] := reverse(nums[0-:x]) 		 
         flips +:= 1
         put(cq,if nums == rule then "WIN" else "show")
         }
      "quit" | "q" : 
         break write("Goodbye.") 
      !magic:                                                  # --- start of magic 
         write("That has no power here.  Try again!") 
      "magic" | "mirror" | "m" : {                        
         mirror := if /mirror then 1 else &null 
         write("Wait! What is this? The writing has reversed.")
         }		   
      !protected:                                              # --- Start of internal (upper case) and protected commands
         put(cq,?rule) & write("Tisk, Tisk, don't try and cheat.  Take a random penalty flip!") 		  
      "MOVE" :                                                  
         put(cq,ask("Command? : ") ) 		 
      "WIN" : 
         put(cq,"ASK") & write("Congratulations you won in ",flips," flips!") 
      "ASK" :
         put(cq,case ask("Play another game? : ") of { "y"|"yes" : "game"; "n"|"no" : "quit"; default : "ASK" } ) 
      default:                                                 # --- say what?
         write("Sorry I don't know that command, try help?")
      }
   }
end
 
procedure ask(s)                       #: ask for input with prompt s and return the 1st word in lower case
writes(\s)
map(trim(read())) ? return tab(upto(' ')|0)
end 
 