21 game

You are encouraged to solve this task according to the task description, using any language you may know.
21 is a two player game, the game is played by choosing
a number (1, 2, or 3) to be added to the running total.

The game is won by the player whose chosen number causes the running total
to reach exactly 21.

The running total starts at zero.
One player will be the computer.

Players alternate supplying a number to be added to the running total.



Task

Write a computer program that will:

 do the prompting (or provide a button menu), 
 check for errors and display appropriate error messages, 
 do the additions (add a chosen number to the running total), 
 display the running total, 
 provide a mechanism for the player to quit/exit/halt/stop/close the program,
 issue a notification when there is a winner, and
 determine who goes first (maybe a random or user choice, or can be specified when the game begins). 


1 rem 21 game
2 rem for rosetta code
 
3 rem initialization
4 l$=chr$(157):rem left cursor
5 dim p$(2),hc(2),ca(4):hc(1)=0:hc(2)=0:rem players
6 ca(0)=1:ca(1)=1:ca(2)=3:ca(3)=2:rem computer answers
7 dim cn$(6):for i=1 to 6:read cn$(i):next:rem computer names
8 def fn m(x)=(x-(int(x/4))*4):rem modulo function
 
10 rem optionally set screen colors here
20 print chr$(147);chr$(14):print spc(16);"21 GAME"
25 print:print " The goal of this game is to take turns"
26 print " adding the value of either 1, 2, or 3"
27 print " to a running total. The first player"
28 print " to bring the total to 21..."
29 print:print spc(10);"... WINS THE GAME!"
30 print:gosub 1000
35 print chr$(147):for p=1 to 2
 
40 rem game setup and get players
42 for p=1 to 2
44 print:print "Player";p;l$;", [H]uman or [C]omputer? ";
45 get k$:if k$<>"c" and k$<>"h" then 45
46 print k$:hc(p)=(k$="c")
50 print:print"Player";p;l$",":print"Enter your name";:if hc(p)then goto54
52 input p$(p):next p:goto 60
54 gosub 1500:print "? ";p$(p):next p
60 print:for p=1 to 2:print p;l$;". ";p$(p):next
65 print:print "Is this correct (y/n)? ";
70 get k$:if k$<>"y" and k$<>"n" then 70
75 print k$:if k$="n" then goto 35
80 print:print "Who will play first (1 or 2)? ";
85 get k$:if k$<"1" or k$>"2" then 85
90 fp=asc(k$)-48:print k$:print
95 print "Okay, ";p$(fp);" will play first.":print:gosub 1000
 
100 rem start main game loop
105 pi=fp:rt=0
110 print chr$(147);"Total so far:";rt
115 print:print p$(pi);"'s turn."
120 if hc(pi) then gosub 1200
125 if not hc(pi) then gosub 1100
130 rt=rt+ad
135 if rt=21 then goto 200
140 if rt>21 then print:print p$(pi);" loses by going over 21!!":goto 210
145 pi=pi+1:if pi>2 then pi=1
150 goto 110
 
200 rem winner winner chicken dinner
205 print:print "21! ";p$(pi);" wins the game!!!"
210 print:print "Would you like to play again? ";
215 get k$:if k$<>"n" and k$<>"y" then 215
220 print k$
225 if k$="n" then print:print "Okay, maybe another time. Bye!":end
230 goto 10
 
1000 rem pause for keypress
1010 z$=" Press a key to continue. "
1015 print spc(20-int(len(z$)/2));
1016 print chr$(18);z$;chr$(146)
1020 get k$:if k$="" then 1020
1025 return
 
1100 rem human player move
1105 print:print "How much to add,"
1110 print "1, 2, or 3 (0 to quit)";:input ad
1115 if ad<0 or ad>3 then print:print"Illegal amount. Try again.":goto1105
1120 if ad=0 then print:print "Game was ended by ";p$(pi);".":end
1125 return
 
1200 rem computer player move
1205 print:print "Thinking...";
1210 tt=int(rnd(1)*10)
1215 for t=1 to tt:print ".";:for i=1 to 250:next i,t:print
1220 rm=fn m(rt)
1225 ad=ca(rm)
1230 print:print p$(pi);" adds";ca(rm);l$;"."
1235 for t=1 to 1000:next t
1240 return
 
1500 rem pick a computer name
1505 pn=int(rnd(1)*6)+1:t$=cn$(pn)
1510 if t$=p$(p-1) then goto 1505
1515 p$(p)=t$
1520 return
 
2000 rem some computer names to pick from
2010 data "Commodore 64","VIC-20","Commodore 128","PET"
2020 data "Plus/4","Commodore 16"