Nim game

You are encouraged to solve this task according to the task description, using any language you may know.
Nim is a simple game where the second player ─── if they know the trick ─── will always win.



The game has only 3 rules:

   start with   12   tokens
   each player takes   1,  2,  or  3   tokens in turn
  the player who takes the last token wins.


To win every time,   the second player simply takes 4 minus the number the first player took.   So if the first player takes 1,   the second takes 3 ─── if the first player takes 2,   the second should take 2 ─── and if the first player takes 3,   the second player will take 1.



Task

Design a simple Nim game where the human player goes first, and the computer always wins. The game should enforce the rules.




  &TRIM = 1
  &DUMP = 1
 
  OUTPUT(.prompt, 9, 'T', '-')
 
********************************************************************************
* GETCOUNT() - Get the count of tokens to take.
********************************************************************************
  define('GETCOUNT()I')
  :(GETCOUNT.END)
GETCOUNT         OUTPUT = 'Enter a number between 1 and 3, blank line to exit.'
****************************************
* Data input and integrity check loop.
****************************************
GETCOUNT.LOOP    PROMPT = '> '
                 i = trim(INPUT)
*                Abort on nil entry.
                 eq(size(i), 0)                                                 :S(EXIT)
*                Check range.
                 integer(i)                                                     :F(GETCOUNT.INVALID)
                 lt(i, 4)                                                       :F(GETCOUNT.INVALID)
                 gt(i, 0)                                                       :F(GETCOUNT.INVALID)
*                It all checked out.
                 GETCOUNT = i                                                   :(RETURN)
****************************************
* An invalid entry was caught.
****************************************
GETCOUNT.INVALID OUTPUT = 'Invalid number.'                                     :(GETCOUNT.LOOP)
GETCOUNT.END
 
********************************************************************************
* MAINLINE CODE
********************************************************************************
MAIN      OUTPUT =
          OUTPUT = 'The mysterious game of Nim!'
          OUTPUT = 'Whoever takes the last token of twelve wins.'
          tokens = 12
 
****************************************
* MAIN LOOP
****************************************
MAIN.LOOP OUTPUT =
          OUTPUT = 'There are ' tokens ' tokens remaining.  How many do you want to take?'
 
********************
* Player turn.
********************
MAIN.P    ptake = getcount()
          tokens = tokens - ptake
          OUTPUT = 'You selected ' ptake ' tokens leaving ' tokens '.'
          lt(tokens, 0)                                                :S(ERROR)
          gt(tokens, 12)                                               :S(ERROR)
          eq(tokens, 0)                                                :S(MAIN.PWIN)
 
********************
* Computer turn.
********************
MAIN.C    ctake = 4 - ptake
          tokens = tokens - ctake
          OUTPUT = 'Computer selects ' ctake ' tokens leaving ' tokens '.'
          lt(tokens, 0)                                                    :S(ERROR)
          gt(tokens, 12)                                                   :S(ERROR)
          eq(tokens, 0)                                                    :S(MAIN.CWIN)
 
          :(MAIN.LOOP)
 
****************************************
* Player win is impossible.  Joke code.
****************************************
MAIN.PWIN OUTPUT = 'Player wins.  This is impossible.  You must have cheated.'
          OUTPUT = 'Formatting hard drive...'                                  :(ERROR)
 
****************************************
* Computer win is inevitable.
****************************************
MAIN.CWIN OUTPUT = 'Computer wins.'      :(EXIT)
 
 
********************************************************************************
* On a routine exit we turn off the variable dump.
* If we exit through an error (like branching to a non-existent label 'ERROR')
* then this code doesn't happen and variables get dumped and the line of the
* failed check getting printed.
********************************************************************************
EXIT      OUTPUT = 'Bye!'
          &DUMP = 0
 
END