21 game: Difference between revisions

124,183 bytes added ,  3 months ago
m
 
(86 intermediate revisions by 38 users not shown)
Line 1:
[[Category:Puzzles]]
[[Category:Games]]
<!-- also known as the twenty-one game. !-->
 
{{task}}
 
<!-- also known as the twenty-one game. !-->
<p>
'''21''' is a two player game, the game is played by choosing
a number ('''1''', '''2''', or '''3''') to be added to the ''running&nbsp;total''.
 
The game is won by the player whose chosen number causes the ''running&nbsp;total''
to reach ''exactly''&nbsp;'''21'''.
 
</p>
<p>
The ''running total'' starts at zero.
One player will be the computer.
<br>
Players alternate supplying a number to be added to the ''running&nbsp;total''.
 
</p>
 
<p>
;Task:
Write a computer program that will:
Line 27 ⟶ 25:
::* 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).
</pbr><br>
=={{header|11l}}==
{{trans|Python: Original, with output}}
 
<syntaxhighlight lang="11l">F select_count(game_count)
‘selects a random number if the game_count is less than 18. otherwise chooses the winning number’
Int t
I game_count < 18
t = random:(1..3)
E
t = 21 - game_count
print(‘The computer chooses #.’.format(t))
R t
 
F request_count()
‘request user input between 1,2 and 3. It will continue till either quit(q) or one of those numbers is requested.’
V t = ‘’
L
X.try
t = input(‘Your choice 1 to 3 :’)
I Int(t) C [1, 2, 3]
R Int(t)
E
print(‘Out of range, try again’)
X.catch
I t == ‘q’
R 0
E
print(‘Invalid Entry, try again’)
 
F start()
V game_count = 0
print("Enter q to quit at any time.\nThe computer will choose first.\nRunning total is now #.".format(game_count))
V roundno = 1
L
print("\nROUND #.: \n".format(roundno))
V t = select_count(game_count)
game_count = game_count + t
print("Running total is now #.\n".format(game_count))
I game_count >= 21
print(‘So, commiserations, the computer has won!’)
R 0
t = request_count()
I t == 0
print(‘OK,quitting the game’)
R -1
game_count = game_count + t
print("Running total is now #.\n".format(game_count))
I game_count >= 21
print(‘So, congratulations, you've won!’)
R 1
roundno++
 
V c = 0
V m = 0
L
V o = start()
I o == -1
L.break
E
c += I o == 0 {1} E 0
m += I o == 1 {1} E 0
print(‘Computer wins #. game, human wins #. games’.format(c, m))
V t = input(‘Another game?(press y to continue):’)
I t != ‘y’
L.break</syntaxhighlight>
 
{{out}}
The same as in Python.
 
=={{header|AArch64 Assembly}}==
{{works with|as|Raspberry Pi 3B version Buster 64 bits}}
<syntaxhighlight lang="aarch64 assembly">
/* ARM assembly AARCH64 Raspberry PI 3B */
/* program game21_64.s */
 
/*******************************************/
/* Constantes file */
/*******************************************/
/* for this file see task include a file in language AArch64 assembly*/
.include "../includeConstantesARM64.inc"
 
.equ HITTOTAL, 21
.equ BUFFERSIZE, 10
 
 
/*********************************/
/* Initialized data */
/*********************************/
.data
szMessRules: .ascii "21 Game\n"
.ascii "21 is a two player game, the game is played by choosing a number \n"
.ascii "(1, 2, or 3) to be added to the running total. The game is won by\n"
.ascii "the player whose chosen number causes the running total to reach \n"
.asciz "exactly 21. The running total starts at zero.\n\n\n"
 
szMessHumanChoice: .asciz "Enter your choice (1,2, 3 or type (q)uit to exit): "
szMessErrChoise: .asciz "invalid choice.\n "
szMessHumanBegin: .asciz "The first move is human move.\n"
szMessPiBegin: .asciz "The first move is Raspberry pi. \n"
szMessHumanWon: .asciz "You won. \n"
szMessHumanLost: .asciz "You lost. \n"
szMessTotal: .asciz "The running total is @ \n"
szMessPiChoice: .asciz "Raspberry choice is @ \n"
szMessNewGame: .asciz "New game (y/n) ? \n"
szCarriageReturn: .asciz "\n"
.align 4
qGraine: .quad 123456
/*********************************/
/* UnInitialized data */
/*********************************/
.bss
sZoneConv: .skip 24
sBuffer: .skip BUFFERSIZE
/*********************************/
/* code section */
/*********************************/
.text
.global main
main: // entry of program
ldr x0,qAdrszMessRules
bl affichageMess
1:
mov x10,#0 // total = 0
mov x0,#100
bl genereraleas
cmp x0,#50
blt 2f
ldr x0,qAdrszMessHumanBegin // human begin
bl affichageMess
b 4f
2: // Rasp begin
ldr x0,qAdrszMessPiBegin
bl affichageMess
mov x0,#1
3: // rasp turn
add x10,x10,x0
ldr x1,qAdrsZoneConv
bl conversion10 // call decimal conversion
ldr x0,qAdrszMessPiChoice
ldr x1,qAdrsZoneConv // insert conversion in message
bl strInsertAtCharInc
bl affichageMess
cmp x10,#HITTOTAL
bne 4f
ldr x0,qAdrszMessHumanLost
bl affichageMess
b 12f
4: // display current total
mov x0,x10
ldr x1,qAdrsZoneConv
bl conversion10 // call decimal conversion
ldr x0,qAdrszMessTotal
ldr x1,qAdrsZoneConv // insert conversion in message
bl strInsertAtCharInc
bl affichageMess
 
5: // human turn
ldr x0,qAdrszMessHumanChoice
bl affichageMess
bl saisie
cmp x0,#'q' // quit ?
beq 100f
cmp x0,#'Q'
beq 100f
cmp x0,#'1'
add x9,x10,1
csel x10,x9,x10,eq
beq 6f
cmp x0,#'2'
add x9,x10,2
csel x10,x9,x10,eq
beq 6f
cmp x0,#'3'
add x9,x10,3
csel x10,x9,x10,eq
beq 6f
ldr x0,qAdrszMessErrChoise
bl affichageMess
b 5b
6:
cmp x10,#HITTOTAL // total = maxi ?
beq 11f // yes -> human won
cmp x10,#5 // else compute rasp number
mov x9,5 // compare total and optimun
7:
cmp x10,x9
ble 8f
add x9,x9,4
b 7b
8:
sub x0,x9,x10 // compute number rasp
9: // control number rasp
cmp x0,#0
ble 10f
cmp x0,#3
ble 3b
10: // if not ok, generate random number
mov x0,#2
bl genereraleas
add x0,x0,#1
b 3b // and loop
11: // display human won
ldr x0,qAdrszMessHumanWon
bl affichageMess
12: // display new game ?
ldr x0,qAdrszCarriageReturn
bl affichageMess
ldr x0,qAdrszMessNewGame
bl affichageMess
bl saisie
cmp x0,#'y'
beq 1b
cmp x0,#'Y'
beq 1b
100: // standard end of the program
mov x0, #0 // return code
mov x8, #EXIT // request to exit program
svc #0 // perform the system call
qAdrszCarriageReturn: .quad szCarriageReturn
qAdrszMessRules: .quad szMessRules
qAdrszMessHumanBegin: .quad szMessHumanBegin
qAdrszMessPiBegin: .quad szMessPiBegin
qAdrszMessPiChoice: .quad szMessPiChoice
qAdrszMessTotal: .quad szMessTotal
qAdrszMessHumanChoice: .quad szMessHumanChoice
qAdrszMessHumanLost: .quad szMessHumanLost
qAdrszMessHumanWon: .quad szMessHumanWon
qAdrszMessNewGame: .quad szMessNewGame
qAdrszMessErrChoise: .quad szMessErrChoise
qAdrsZoneConv: .quad sZoneConv
/******************************************************************/
/* string saisie */
/******************************************************************/
/* x0 return the first character of human entry */
saisie:
stp x1,lr,[sp,-16]! // save registers
stp x2,x8,[sp,-16]! // save registers
mov x0,#STDIN // Linux input console
ldr x1,qAdrsBuffer // buffer address
mov x2,#BUFFERSIZE // buffer size
mov x8,#READ // request to read datas
svc 0 // call system
ldr x1,qAdrsBuffer // buffer address
ldrb w0,[x1] // load first character
100:
ldp x2,x8,[sp],16 // restaur 2 registers
ldp x1,lr,[sp],16 // restaur 2 registers
ret // return to address lr x30
qAdrsBuffer: .quad sBuffer
/***************************************************/
/* Generation random number */
/***************************************************/
/* x0 contains limit */
genereraleas:
stp x1,lr,[sp,-16]! // save registers
stp x2,x3,[sp,-16]! // save registers
stp x4,x5,[sp,-16]! // save registers
ldr x4,qAdrqGraine
ldr x2,[x4]
ldr x3,qNbDep1
mul x2,x3,x2
ldr x3,qNbDep2
add x2,x2,x3
str x2,[x4] // maj de la graine pour l appel suivant
cmp x0,#0
beq 100f
udiv x3,x2,x0
msub x0,x3,x0,x2 // résult = remainder
100: // end function
ldp x4,x5,[sp],16 // restaur 2 registers
ldp x2,x3,[sp],16 // restaur 2 registers
ldp x1,lr,[sp],16 // restaur 2 registers
ret // return to address lr x30
/*****************************************************/
qAdrqGraine: .quad qGraine
qNbDep1: .quad 0x0019660d
qNbDep2: .quad 0x3c6ef35f
 
/********************************************************/
/* File Include fonctions */
/********************************************************/
/* for this file see task include a file in language AArch64 assembly */
.include "../includeARM64.inc"
</syntaxhighlight>
 
 
=={{header|Ada}}==
<syntaxhighlight lang="ada">with Ada.Text_IO;
with Ada.Numerics.Discrete_Random;
 
procedure Game_21 is
 
procedure Put (Item : String) is
begin
for Char of Item loop
Ada.Text_IO.Put (Char);
delay 0.010;
end loop;
end Put;
 
procedure New_Line is
begin
Ada.Text_IO.New_Line;
end New_Line;
 
procedure Put_Line (Item : String) is
begin
Put (Item);
New_Line;
end Put_LIne;
 
type Player_Kind is (Human, Computer);
type Score_Type is range 0 .. 21;
subtype Amount_Range is Score_Type range 1 .. 3;
 
package Amount_Generators is
new Ada.Numerics.Discrete_Random (Amount_Range);
 
Gen : Amount_Generators.Generator;
Total : Score_Type := 0;
Choice : Character;
Player : Player_Kind;
Amount : Amount_Range;
begin
Amount_Generators.Reset (Gen);
 
Put_Line ("--- The 21 Game ---"); New_Line;
 
Put ("Who is starting human or computer (h/c) ? ");
Ada.Text_IO.Get_Immediate (Choice);
New_Line;
 
case Choice is
when 'c' | 'C' => Player := Computer;
when 'h' | 'H' => Player := Human;
when others => return;
end case;
 
Play_Loop : loop
New_Line;
Put ("Runing total is "); Put (Total'Image); New_Line;
New_Line;
 
case Player is
 
when Human =>
Put_Line ("It is your turn !");
Input_Loop : loop
Put ("Enter choice 1 .. 3 (0 to end) : ");
Ada.Text_IO.Get_Immediate (Choice);
 
case Choice is
when '1' .. '3' =>
Amount := Amount_Range'Value ("" & Choice);
exit Input_Loop;
 
when '0' =>
exit Play_Loop;
 
when others =>
Put_Line ("Choice must be in 1 .. 3");
end case;
end loop Input_Loop;
New_Line;
 
when Computer =>
delay 1.500;
Amount := Amount_Generators.Random (Gen);
Put ("Computer chooses: "); Put (Amount'Image); New_Line;
delay 0.800;
 
end case;
 
New_Line;
Amount := Score_Type'Min (Amount, Score_Type'Last - Total);
Put (" "); Put (Total'Image); Put (" + "); Put (Amount'Image); Put (" = ");
Total := Total + Amount;
Put (Total'Image);
New_Line;
 
if Total = 21 then
New_Line;
Put ("... and we have a WINNER !!"); New_Line;
delay 0.500;
Put_Line (" ... and the winner is ...");
delay 1.000;
Put_Line (" " & Player'Image);
exit;
end if;
 
Player := (case Player is
when Computer => Human,
when Human => Computer);
end loop Play_Loop;
end Game_21;</syntaxhighlight>
 
=={{header|Applesoft BASIC}}==
{{trans|Commodore BASIC}}
Most comments are removed, see [[#Commodore_BASIC|Commodore BASIC]] for comments. The code is compacted, see the [[#Commodore_BASIC|Commodore BASIC]] listing for a line-by-line listing.
 
All text is upper case as only the the Apple IIe and later models have can display lower case on the text screen. Input is converted to upper case as the earlier models may not be able to enter lower case from the keyboard.
 
Commodore control codes are converted to the equivilent Applesoft BASIC command: ?CHR$(147); is HOME ?CHR$(18); is INVERSE and ?CHR$(146); is NORMAL. The code is adjusted when printing a numeric variables as Applesoft BASIC does not print any spaces. There are a few other changes: VAL function instead of ASC to convert number, FOR instead of GOTO or THEN, and
WAIT instead of GET in a loop.
 
<syntaxhighlight lang="gwbasic"> 5 DIM P$(2),HC(2),CA(4),CN$(6): READ CA(0),CA(1),CA(2),CA(3): FOR I = 1 TO 6: READ CN$(I): NEXT : DEF FN M(X) = (X - ( INT (X / 4)) * 4): DEF FN U(K) = K - (K > 95) * 32:L$ = " ":M$ = CHR$ (13): DATA 1,1,3,2
9 FOR PLAY = 0 TO 1
10 REM SET SCREEN COLORS HERE
11 LET C% = INT ( RND (1) * 16)
12 LET B% = INT ( RND (1) * 15 + C% + 1): IF B% > 15 THEN B% = B% - 16
13 POKE 49186,C% + B% * 16: REM FOREGROUND&BACKGROUND
14 POKE 49204, INT ( RND (1) * 16): REM BORDER
20 HOME : PRINT M$ SPC( 16);"21 GAME"M$M$" THE GOAL OF THIS GAME IS TO TAKE TURNS"M$" ADDING THE VALUE OF EITHER 1, 2, OR 3"M$" TO A RUNNING TOTAL. THE FIRST PLAYER"M$" TO BRING THE TOTAL TO 21..."M$M$ SPC( 10);"... WINS THE GAME!"M$
30 GOSUB 1000
40 FOR SETUP = 0 TO 1: HOME : PRINT
42 FOR P = 1 TO 2
44 PRINT M$"PLAYER";L$;P;", [H]UMAN OR [C]OMPUTER? ";
45 FOR K = 0 TO 1: GET K$:K$ = CHR$ ( FN U( ASC (K$))):K = K$ = "C" OR K$ = "H": NEXT K
46 PRINT K$M$M$"PLAYER";L$;P;",": PRINT "ENTER YOUR NAME";
50 LET HC(P) = (K$ = "C"): IF HC(P) THEN FOR PC = 0 TO 1:PN = INT ( RND (1) * 6) + 1:T$ = CN$(PN):PC = T$ < > P$(P - 1): NEXT PC:P$(P) = T$: PRINT "? ";P$(P)
52 IF NOT HC(P) THEN INPUT P$(P)
54 NEXT P
60 FOR P = 1 TO 2: PRINT M$L$;P;". ";P$(P);: NEXT P: PRINT M$M$"IS THIS CORRECT (Y/N)? ";: FOR K = 0 TO 1: GET K$:K$ = CHR$ ( FN U( ASC (K$))):K = K$ = "Y" OR K$ = "N": NEXT K: PRINT K$:SETUP = K$ < > "N"
70 NEXT SETUP
80 PRINT M$"WHO WILL PLAY FIRST (1 OR 2)? ";: FOR K = 0 TO 1: GET K$:K = K$ = "1" OR K$ = "2": NEXT K
90 FP = VAL (K$): PRINT K$M$M$"OKAY, ";P$(FP);" WILL PLAY FIRST."M$: GOSUB 1000
100 LET RT = 0:PI = FP - 1
110 FOR GAME = 0 TO 1
115 PI = PI * (PI < 2) + 1: HOME : PRINT "TOTAL SO FAR:";L$;RT;M$M$P$(PI);"'S TURN."
120 IF HC(PI) THEN PRINT M$"THINKING...";:TT = INT ( RND (1) * 10): FOR T = 1 TO TT: PRINT ".";: FOR I = 1 TO 250: NEXT I,T:RM = FN M(RT):AD = CA(RM): PRINT M$M$P$(PI);" ADDS";L$;CA(RM);".": FOR T = 1 TO 1000: NEXT T
125 IF NOT HC(PI) THEN FOR AMOUNT = 0 TO 1: PRINT MID$ (M$ + "ILLEGAL AMOUNT. TRY AGAIN." + M$,1,AMOUNT * 255)M$"HOW MUCH TO ADD,": INPUT "1, 2, OR 3 (0 TO QUIT) ?";AD:AMOUNT = AD > = 0 AND AD < = 3: NEXT AMOUNT
128 LET RT = RT + AD:GAME = RT > = 21 OR AD = 0
130 NEXT GAME
140 IF RT > 21 THEN PRINT M$P$(PI);" LOSES BY GOING OVER 21!!"
150 IF RT = 21 THEN PRINT M$"21! ";P$(PI);" WINS THE GAME!!!"
160 IF NOT AD THEN PRINT M$"GAME WAS ENDED BY ";P$(PI);".":PLAY = 1
210 IF AD THEN PRINT : PRINT "WOULD YOU LIKE TO PLAY AGAIN? ";: FOR K = 0 TO 1: GET K$:K$ = CHR$ ( FN U( ASC (K$))):K = K$ = "N" OR K$ = "Y": NEXT K: PRINT K$:PLAY = K$ = "N"
220 NEXT PLAY
230 IF AD THEN PRINT M$"OKAY, MAYBE ANOTHER TIME. BYE!"
240 END
1000 Z$ = " PRESS A KEY TO CONTINUE. ": PRINT SPC( 20 - INT ( LEN (Z$) / 2));: INVERSE : PRINT Z$;: NORMAL : WAIT 49152,128:K = PEEK (49168): RETURN
2010 DATA "APPLE IIE","APPLE II PLUS","APPLE IIC","APPLE II","APPLE IIGS","MACINTOSH LC"</syntaxhighlight>
=={{header|ARM Assembly}}==
{{works with|as|Raspberry Pi}}
<syntaxhighlight lang="arm assembly">
/* ARM assembly Raspberry PI */
/* program game21.s */
 
/* REMARK 1 : this program use routines in a include file
see task Include a file language arm assembly
for the routine affichageMess conversion10
see at end of this program the instruction include */
/* for constantes see task include a file in arm assembly */
/************************************/
/* Constantes */
/************************************/
.include "../constantes.inc"
.equ STDIN, 0 @ Linux input console
.equ READ, 3 @ Linux syscall
.equ HITTOTAL, 21
.equ BUFFERSIZE, 10
 
 
/*********************************/
/* Initialized data */
/*********************************/
.data
szMessRules: .ascii "21 Game\n"
.ascii "21 is a two player game, the game is played by choosing a number \n"
.ascii "(1, 2, or 3) to be added to the running total. The game is won by\n"
.ascii "the player whose chosen number causes the running total to reach \n"
.asciz "exactly 21. The running total starts at zero.\n\n\n"
 
szMessHumanChoice: .asciz "Enter your choice (1,2, 3 or type (q)uit to exit): "
szMessErrChoise: .asciz "invalid choice.\n "
szMessHumanBegin: .asciz "The first move is human move.\n"
szMessPiBegin: .asciz "The first move is Raspberry pi. \n"
szMessHumanWon: .asciz "You won. \n"
szMessHumanLost: .asciz "You lost. \n"
szMessTotal: .asciz "The running total is @ \n"
szMessPiChoice: .asciz "Raspberry choice if @ \n"
szMessNewGame: .asciz "New game (y/n) ? \n"
szCarriageReturn: .asciz "\n"
.align 4
iGraine: .int 123456
/*********************************/
/* UnInitialized data */
/*********************************/
.bss
sZoneConv: .skip 24
sBuffer: .skip BUFFERSIZE
/*********************************/
/* code section */
/*********************************/
.text
.global main
main: @ entry of program
ldr r0,iAdrszMessRules
bl affichageMess
1:
mov r10,#0 @ total = 0
mov r0,#100
bl genereraleas
cmp r0,#50
blt 2f
ldr r0,iAdrszMessHumanBegin @ human begin
bl affichageMess
b 4f
2: @ Rasp begin
ldr r0,iAdrszMessPiBegin
bl affichageMess
mov r0,#1
3: @ rasp turn
add r10,r10,r0
ldr r1,iAdrsZoneConv
bl conversion10 @ call decimal conversion
ldr r0,iAdrszMessPiChoice
ldr r1,iAdrsZoneConv @ insert conversion in message
bl strInsertAtCharInc
bl affichageMess
cmp r10,#HITTOTAL
bne 4f
ldr r0,iAdrszMessHumanLost
bl affichageMess
b 10f
4: @ display current total
mov r0,r10
ldr r1,iAdrsZoneConv
bl conversion10 @ call decimal conversion
ldr r0,iAdrszMessTotal
ldr r1,iAdrsZoneConv @ insert conversion in message
bl strInsertAtCharInc
bl affichageMess
 
5: @ human turn
ldr r0,iAdrszMessHumanChoice
bl affichageMess
bl saisie
cmp r0,#'q' @ quit ?
beq 100f
cmp r0,#'Q'
beq 100f
cmp r0,#'1'
addeq r10,r10,#1
beq 6f
cmp r0,#'2'
addeq r10,r10,#2
beq 6f
cmp r0,#'3'
addeq r10,r10,#3
beq 6f
ldr r0,iAdrszMessErrChoise
bl affichageMess
b 5b
6:
cmp r10,#HITTOTAL @ total = maxi ?
beq 9f @ yes -> human won
cmp r10,#5 @ else compute rasp number
rsble r0,r10,#5
ble 7f
cmp r10,#9
rsble r0,r10,#9
ble 7f
cmp r10,#13
rsble r0,r10,#13
ble 7f
cmp r10,#17
rsble r0,r10,#17
ble 7f
cmp r10,#21
rsble r0,r10,#21
ble 7f
7: @ control number rasp
cmp r0,#0
ble 8f
cmp r0,#3
ble 3b
8: @ if not ok, generate random number
mov r0,#2
bl genereraleas
add r0,r0,#1
b 3b @ and loop
9: @ display human won
ldr r0,iAdrszMessHumanWon
bl affichageMess
10: @ display new game ?
ldr r0,iAdrszCarriageReturn
bl affichageMess
ldr r0,iAdrszMessNewGame
bl affichageMess
bl saisie
cmp r0,#'y'
beq 1b
cmp r0,#'Y'
beq 1b
100: @ standard end of the program
mov r0, #0 @ return code
mov r7, #EXIT @ request to exit program
svc #0 @ perform the system call
iAdrszCarriageReturn: .int szCarriageReturn
iAdrszMessRules: .int szMessRules
iAdrszMessHumanBegin: .int szMessHumanBegin
iAdrszMessPiBegin: .int szMessPiBegin
iAdrszMessPiChoice: .int szMessPiChoice
iAdrszMessTotal: .int szMessTotal
iAdrszMessHumanChoice: .int szMessHumanChoice
iAdrszMessHumanLost: .int szMessHumanLost
iAdrszMessHumanWon: .int szMessHumanWon
iAdrszMessNewGame: .int szMessNewGame
iAdrszMessErrChoise: .int szMessErrChoise
iAdrsZoneConv: .int sZoneConv
/******************************************************************/
/* string saisie */
/******************************************************************/
/* r0 return the first character of human entry */
saisie:
push {r1-r7,lr} @ save registers
mov r0,#STDIN @ Linux input console
ldr r1,iAdrsBuffer @ buffer address
mov r2,#BUFFERSIZE @ buffer size
mov r7,#READ @ request to read datas
svc 0 @ call system
ldr r1,iAdrsBuffer @ buffer address
ldrb r0,[r1] @ load first character
100:
pop {r1-r7,lr}
bx lr @ return
iAdrsBuffer: .int sBuffer
/***************************************************/
/* Generation random number */
/***************************************************/
/* r0 contains limit */
genereraleas:
push {r1-r4,lr} @ save registers
ldr r4,iAdriGraine
ldr r2,[r4]
ldr r3,iNbDep1
mul r2,r3,r2
ldr r3,iNbDep1
add r2,r2,r3
str r2,[r4] @ maj de la graine pour l appel suivant
cmp r0,#0
beq 100f
mov r1,r0 @ divisor
mov r0,r2 @ dividende
bl division
mov r0,r3 @ résult = remainder
100: @ end function
pop {r1-r4,lr} @ restaur registers
bx lr @ return
/*****************************************************/
iAdriGraine: .int iGraine
iNbDep1: .int 0x343FD
iNbDep2: .int 0x269EC3
/***************************************************/
/* ROUTINES INCLUDE */
/***************************************************/
.include "../affichage.inc"
</syntaxhighlight>
<pre>
The first move is human move.
The running total is 0
Enter your choice (1,2, 3 or type (q)uit to exit): 4
invalid choice.
Enter your choice (1,2, 3 or type (q)uit to exit): 1
Raspberry choice if 1
The running total is 2
Enter your choice (1,2, 3 or type (q)uit to exit): 3
Raspberry choice if 2
The running total is 7
Enter your choice (1,2, 3 or type (q)uit to exit): 1
Raspberry choice if 1
The running total is 9
Enter your choice (1,2, 3 or type (q)uit to exit): 2
Raspberry choice if 2
The running total is 13
Enter your choice (1,2, 3 or type (q)uit to exit): 3
Raspberry choice if 1
The running total is 17
Enter your choice (1,2, 3 or type (q)uit to exit): 1
Raspberry choice if 3
You lost.
 
New game (y/n) ?
y
The first move is Raspberry pi.
</pre>
 
=={{header|Arturo}}==
 
<syntaxhighlight lang="rebol">print "-----------------------------"
print " Welcome to 21 Game"
print "-----------------------------"
 
players: ["A" "B"]
currentPlayer: sample players
nextPlayer: first players -- currentPlayer
runningTotal: new 0
num: 0
 
getNum: function [][
result: strip input "Enter a number (1,2,3) / x to exit: "
if result="x" -> exit
return result
]
 
loop.forever @[currentPlayer nextPlayer] 'plays [
print ["Running total:" runningTotal]
print ["Player" plays "turn"]
 
num: getNum
 
while [or? [not? numeric? num][not? contains? 1..3 to :integer num]][
num: getNum
]
 
runningTotal: runningTotal + to :integer num
 
print ""
 
if runningTotal=21 [
print ["Running total is 21. Player" plays "won!"]
exit
]
]
</syntaxhighlight>
 
{{out}}
 
<pre>-----------------------------
Welcome to 21 Game
-----------------------------
Running total: 0
Player B turn
Enter a number (1,2,3) / x to exit: 1
 
Running total: 1
Player A turn
Enter a number (1,2,3) / x to exit: 2
 
Running total: 3
Player B turn
Enter a number (1,2,3) / x to exit: 1
 
Running total: 4
Player A turn
Enter a number (1,2,3) / x to exit: 3
 
Running total: 7
Player B turn
Enter a number (1,2,3) / x to exit: 4
Enter a number (1,2,3) / x to exit: 2
 
Running total: 9
Player A turn
Enter a number (1,2,3) / x to exit: 3
 
Running total: 12
Player B turn
Enter a number (1,2,3) / x to exit: 1
 
Running total: 13
Player A turn
Enter a number (1,2,3) / x to exit: 2
 
Running total: 15
Player B turn
Enter a number (1,2,3) / x to exit: 3
 
Running total: 18
Player A turn
Enter a number (1,2,3) / x to exit: 3
 
Running total is 21. Player A won!</pre>
 
=={{header|AutoHotkey}}==
<syntaxhighlight lang="autohotkey">Gui, font, S16
Gui, add, Radio, vRadioC , Cake
Gui, add, Radio, vRadioE x+0 Checked, Easy
Gui, add, Radio, vRadioH x+0, Hard
Gui, add, text, xs vT, Total : 00
Gui, add, text, xs vComputer, Computer Dealt 00
Gui, add, text, xs Section, Player 1
loop, 3
Gui, add, button, x+5 vPlayer1_%A_Index% gTotal, % A_Index
Gui, add, button, xs vReset gReset, reset
Gui show,, 21 Game
Winners := [1,5,9,13,17,21]
gosub, reset
return
;-----------------------------------
reset:
total := 0
GuiControl,, T, % "Total : " SubStr("00" Total, -1)
GuiControl,, Computer, % "Computer Waiting"
Loop 3
GuiControl, Enable, % "Player1_" A_Index
Random, rnd, 0, 1
if rnd
{
Loop 3
GuiControl, Disable, % "Player1_" A_Index
gosub ComputerTurn
}
return
;-----------------------------------
Total:
Added := SubStr(A_GuiControl, 9,1)
Total += Added
GuiControl,, T, % "Total : " SubStr("00" Total, -1)
if (total >= 21)
{
MsgBox % "Player 1 Wins"
gosub reset
return
}
Loop 3
GuiControl, Disable, % "Player1_" A_Index
gosub, ComputerTurn
return
;-----------------------------------
ComputerTurn:
Gui, Submit, NoHide
Sleep 500
if RadioE
{
if (total < 13)
RadioC := true
else
RadioH := true
}
if RadioC
{
Random, Deal, 1, 3
total += Deal
}
if RadioH
{
for i, v in Winners
if (total >= v)
continue
else
{
Deal := v - total
if Deal > 3
Random, Deal, 1, 3
total += Deal
break
}
}
GuiControl,, T, % "Total : " SubStr("00" Total, -1)
GuiControl,, Computer, % "Computer Dealt " Deal
if (total=21)
{
MsgBox Computer Wins
gosub, reset
}
else
Loop 3
GuiControl, Enable, % "Player1_" A_Index
return</syntaxhighlight>
 
=={{header|AWK}}==
<syntaxhighlight lang="awk"># Game 21 - an example in AWK language for Rosseta Code.
 
BEGIN {
srand();
GOAL = 21;
best[0] = 1; best[1] = 1; best[2] = 3; best[3] = 2;
 
print\
"21 Game \n"\
" \n"\
"21 is a two player game, the game is played by choosing a number \n"\
"(1, 2, or 3) to be added to the running total. The game is won by\n"\
"the player whose chosen number causes the running total to reach \n"\
"exactly 21. The running total starts at zero. \n\n";
 
newgame();
prompt();
 
}
 
/[123]/ {
move = strtonum($0);
if (move + total <= GOAL) {
update("human", strtonum($0));
update("ai", best[total % 4]);
}
else
invalid();
prompt();
}
/[^123]/ {
if ($0 == "quit") {
print "goodbye";
exit;
}
else {
invalid();
prompt();
}
}
 
function prompt(){
print "enter your choice (or type quit to exit): ";
}
 
function invalid(){
print "invalid move";
}
 
function newgame() {
print "\n---- NEW GAME ----\n";
print "\nThe running total is currently zero.\n";
total = 0;
if (rand() < 0.5) {
print "The first move is AI move.\n";
update("ai", best[total % 4]);
}
else
print "The first move is human move.\n";
}
 
function update(player, move) {
printf "%8s: %d = %d + %d\n\n", player, total + move, total, move;
total += move;
if (total == GOAL) {
printf "The winner is %s.\n\n", player;
newgame();
}
}</syntaxhighlight>
{{Output}}
<pre>
gawk -f Game21.awk
21 Game
 
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.
 
 
 
---- NEW GAME ----
 
 
The running total is currently zero.
 
The first move is human move.
 
enter your choice (or type quit to exit):
1
human: 1 = 0 + 1
 
ai: 2 = 1 + 1
 
enter your choice (or type quit to exit):
2
human: 4 = 2 + 2
 
ai: 5 = 4 + 1
 
enter your choice (or type quit to exit):
3
human: 8 = 5 + 3
 
ai: 9 = 8 + 1
 
enter your choice (or type quit to exit):
1
human: 10 = 9 + 1
 
ai: 13 = 10 + 3
 
enter your choice (or type quit to exit):
2
human: 15 = 13 + 2
 
ai: 17 = 15 + 2
 
enter your choice (or type quit to exit):
1
human: 18 = 17 + 1
 
ai: 21 = 18 + 3
 
The winner is ai.
 
 
---- NEW GAME ----
 
 
The running total is currently zero.
 
The first move is human move.
 
enter your choice (or type quit to exit):
wow
invalid move
222
invalid move
enter your choice (or type quit to exit):
1
human: 1 = 0 + 1
 
ai: 2 = 1 + 1
 
enter your choice (or type quit to exit):
quit
goodbye</pre>
 
=={{header|BASIC}}==
==={{header|BASIC256}}===
{{trans|FreeBASIC}}
<syntaxhighlight lang="qbasic">PLAYER = 1
COMP = 0
 
sum = 0
total = 0
turn = int(rand + 0.5)
dim precomp = {1, 1, 3, 2}
 
while sum < 21
turn = 1 - turn
print "The sum is "; sum
if turn = PLAYER then
print "It is your turn."
while total < 1 or total > 3 or total + sum > 21
input "How many would you like to total? ", total
end while
else
print "It is the computer's turn."
total = precomp[sum mod 4]
print "The computer totals ", total, "."
end if
print
sum += total
total = 0
end while
 
if turn = PLAYER then
print "Congratulations. You win."
else
print "Bad luck. The computer wins."
end if</syntaxhighlight>
 
==={{header|Chipmunk Basic}}===
{{trans|Commodore BASIC}}
{{works with|Chipmunk Basic|3.6.4}}
{{works with|MSX BASIC}}
<syntaxhighlight lang="qbasic">100 rem 21 game
110 rem for rosetta code
120 '
130 rem initialization
140 l$ = chr$(157) : rem left cursor
150 dim p$(2),hc(2),ca(4) : hc(1) = 0 : hc(2) = 0 : rem players
160 ca(0) = 1 : ca(1) = 1 : ca(2) = 3 : ca(3) = 2 : rem computer answers
170 dim cn$(6) : for i = 1 to 6 : read cn$(i) : next i : rem computer names
180 def fnm(X)=(X-(INT(X/4))*4):REM modulo function
190 '
200 rem optionally set screen colors here
210 cls
220 print " 21 GAME"
230 print : print " The goal of this game is to take turns"
240 print " adding the value of either 1, 2, or 3"
250 print " to a running total. The first player"
260 print " to bring the total to 21..."
270 print : print " ... WINS THE GAME!"
280 print : gosub 1110
290 for p = 1 to 2
300 '
310 rem game setup and get players
320 for p = 1 to 2
330 print : print "Player ";p;l$;", [H]uman or [C]omputer? ";
340 k$ = inkey$ : if k$ <> "c" and k$ <> "h" then 340
350 print k$ : hc(p) = (k$ = "c")
360 print : print "Player";p;l$ "," : print "Enter your name"; : if hc(p) then goto 400
370 input p$(p)
380 next p
390 goto 420
400 gosub 1340 : print "? ";p$(p)
410 next p
420 print
430 for p = 1 to 2 : print p;l$;". ";p$(p) : next p
440 print : print "Is this correct (y/n)? ";
450 k$ = inkey$ : if k$ <> "y" and k$ <> "n" then 450
460 print k$ : if k$ = "n" then goto 290
470 print : print "Who will play first (1 or 2)? ";
480 k$ = inkey$ : if k$ < "1" or k$ > "2" then 480
490 fp = asc(k$)-48 : print k$ : print
500 print "Okay, ";p$(fp);" will play first." : print : gosub 1110
510 cls
520 '
530 rem start main game loop
540 pi = fp : rt = 0
550 print "Total so far:";rt
560 print : print p$(pi);"'s turn."
570 if hc(pi) then gosub 1240
580 if not hc(pi) then gosub 1170
590 rt = rt+ad
600 if rt = 21 then goto 680
610 if rt > 21 then print : print p$(pi);" loses by going over 21!!" : goto 700
620 pi = pi+1 : if pi > 2 then pi = 1
630 goto 550
640 print : print " ... WINS THE GAME!"
650 print : gosub 1110
660 '
670 for p = 1 to 2
680 rem winner winner chicken dinner
690 print : print "21! ";p$(pi);" wins the game!!!"
700 print : print "Would you like to play again? ";
710 k$ = inkey$ : if k$ <> "n" and k$ <> "y" then 710
720 print k$
730 if k$ = "n" then print : print "Okay, maybe another time. Bye!" : end
740 goto 200
750 print k$ : hc(p) = (k$ = "c")
760 print : print "Player";p;l$ "," : print "Enter your name"; : if hc(p) then goto 800
770 input p$(p)
780 next p
790 goto 820
800 gosub 1340 : print "? ";p$(p)
810 next p
820 print : for p = 1 to 2 : print p;l$;". ";p$(p) : next p
830 print : print "Is this correct (y/n)? ";
840 k$ = inkey$ : if k$ <> "y" and k$ <> "n" then 840
850 print k$ : if k$ = "n" then goto 660
860 print : print "Who will play first (1 or 2)? ";
870 k$ = inkey$ : if k$ < "1" or k$ > "2" then 870
880 fp = asc(k$)-48 : print k$ : print
890 print "Okay, ";p$(fp);" will play first." : print : gosub 1110
900 '
910 rem start main game loop
920 pi = fp : rt = 0
930 print chr$(147);"Total so far: ";rt
940 print : print p$(pi);"'s turn."
950 if hc(pi) then gosub 1240
960 if not hc(pi) then gosub 1170
970 rt = rt+ad
980 if rt = 21 then goto 1030
990 if rt > 21 then print : print p$(pi);" loses by going over 21!!" : goto 1050
1000 pi = pi+1 : if pi > 2 then pi = 1
1010 goto 930
1020 '
1030 rem winner winner chicken dinner
1040 print : print "21! ";p$(pi);" wins the game!!!"
1050 print : print "Would you like to play again? ";
1060 k$ = inkey$ : if k$ <> "n" and k$ <> "y" then 1060
1070 print k$
1080 if k$ = "n" then print : print "Okay, maybe another time. Bye!" : end
1090 goto 490
1100 '
1110 rem pause for keypress
1120 z$ = " Press a key to continue. "
1130 print z$
1140 k$ = inkey$ : if k$ = "" then 1140
1150 return
1160 '
1170 rem human player move
1180 print : print "How much to add,"
1190 print "1, 2, or 3 (0 to quit)"; : input ad
1200 if ad < 0 or ad > 3 then print : print "Illegal amount. Try again." : goto 1180
1210 if ad = 0 then print : print "Game was ended by ";p$(pi);"." : end
1220 return
1230 '
1240 rem computer player move
1250 print : print "Thinking...";
1260 tt = int(rnd(1)*10)
1270 for t = 1 to tt : print "."; : for i = 1 to 250 : next i : next t : print
1280 rm = fn m(rt)
1290 ad = ca(rm)
1300 print : print p$(pi);" adds ";ca(rm);l$;"."
1310 for t = 1 to 1000 : next t
1320 return
1330 '
1340 rem pick a computer name
1350 pn = int(rnd(1)*6)+1 : t$ = cn$(pn)
1360 if t$ = p$(p-1) then goto 1350
1370 p$(p) = t$
1380 return
1390 '
1400 rem some computer names to pick from
1410 data "Commodore 64","VIC-20","Commodore 128"
1420 data "PET","Plus/4","Commodore 16"</syntaxhighlight>
 
==={{header|IS-BASIC}}===
<syntaxhighlight lang="is-basic">100 PROGRAM "21Game.bas"
110 RANDOMIZE
120 LET SUM,ADD=0
130 LET TURN=RND(2)-1
140 CLEAR SCREEN
150 PRINT "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."
160 PRINT "The running total starts at zero. One player will be the computer.":PRINT
170 DO
180 LET TURN=NOT TURN
190 SET #102:INK 3:PRINT "The sum is";SUM:SET #102:INK 1
200 IF TURN THEN
210 PRINT "It is your turn.":PRINT "How many would you like to add? (1-3): ";
220 LET ADD=READKEY
230 IF ADD>21-SUM THEN PRINT "You can only add";21-SUM
240 ELSE
250 LET ADD=4-MOD(SUM-1,4)
260 IF ADD=4 THEN LET ADD=RND(3)+1
270 PRINT "It is the computer's turn.":PRINT "The computer adds";ADD
280 END IF
290 PRINT :LET SUM=SUM+ADD
300 LOOP WHILE SUM<21
310 IF TURN THEN
320 PRINT "Congratulations. You win."
330 ELSE
340 PRINT "Bad luck. The computer wins."
350 END IF
360 END
370 DEF READKEY
380 DO
390 LET T$=INKEY$
400 LOOP WHILE T$>"3" OR T$<"1"
410 PRINT T$:LET READKEY=VAL(T$)
420 END DEF </syntaxhighlight>
 
==={{header|MSX Basic}}===
{{works with|MSX BASIC|any}}
The [[#Chipmunk Basic|Chipmunk Basic]] solution works without any changes.
 
==={{header|PureBasic}}===
{{trans|FreeBASIC}}
<syntaxhighlight lang="purebasic">If OpenConsole()
PLAYER.i = 1
COMP.i = 0
sum.i = 0
total.i = 0
turn.i = Random(1) + 0.5
Dim precomp.i(3)
precomp(0) = 1
precomp(1) = 1
precomp(2) = 3
precomp(3) = 2
While sum < 21
turn = 1 - turn
PrintN("The sum is " + Str(sum))
If turn = PLAYER
PrintN("It is your turn.")
While total < 1 Or total > 3 Or total + sum > 21
Print("How many would you like to total? ")
total = Val(Input())
Wend
Else
PrintN("It is the computer's turn.")
total = precomp(sum % 4)
PrintN("The computer totals " + Str(total) + ".")
EndIf
PrintN("")
sum + total
total = 0
Wend
If turn = PLAYER
PrintN("Congratulations. You win.")
Else
PrintN("Bad luck. The computer wins.")
EndIf
Input()
EndIf</syntaxhighlight>
 
==={{header|QBasic}}===
{{trans|FreeBASIC}}
{{works with|QBasic|1.1}}
{{works with|QuickBasic|4.5}}
<syntaxhighlight lang="qbasic">PLAYER = 1
COMP = 0
RANDOMIZE TIMER
 
sum = 0
total = 0
turn = INT(RND + 0.5)
DIM precomp(0 TO 3)
precomp(0) = 1 : precomp(1) = 1
precomp(2) = 3 : precomp(3) = 2
 
WHILE sum < 21
turn = 1 - turn
PRINT "The sum is "; sum
IF turn = PLAYER THEN
PRINT "It is your turn."
WHILE total < 1 OR total > 3 OR total + sum > 21
INPUT "How many would you like to total? ", total
WEND
ELSE
PRINT "It is the computer's turn."
total = precomp(sum MOD 4)
PRINT "The computer totals"; total; "."
END IF
PRINT
sum = sum + total
total = 0
WEND
 
IF turn = PLAYER THEN
PRINT "Congratulations. You win."
ELSE
PRINT "Bad luck. The computer wins."
END IF</syntaxhighlight>
 
==={{header|True BASIC}}===
{{trans|QBasic}}
<syntaxhighlight lang="qbasic">LET player = 1
LET comp = 0
RANDOMIZE
LET sum = 0
LET total = 0
LET turn = INT(RND+0.5)
DIM precomp(0 TO 3)
LET precomp(0) = 1
LET precomp(1) = 1
LET precomp(2) = 3
LET precomp(3) = 2
DO WHILE sum < 21
LET turn = 1-turn
PRINT "The sum is "; sum
IF turn = player THEN
PRINT "It is your turn."
DO WHILE total < 1 OR total > 3 OR total+sum > 21
INPUT prompt "How many would you like to total? ": total
LOOP
ELSE
PRINT "It is the computer's turn."
LET total = precomp(remainder(round(sum),4))
PRINT USING "The computer totals #.": total
END IF
PRINT
LET sum = sum+total
LET total = 0
LOOP
IF turn = player THEN PRINT "Congratulations. You win." ELSE PRINT "Bad luck. The computer wins."
END</syntaxhighlight>
 
==={{header|PureBasic}}===
{{trans|FreeBASIC}}
<syntaxhighlight lang="vb">If OpenConsole()
PLAYER.i = 1
COMP.i = 0
sum.i = 0
total.i = 0
turn.i = Random(1) + 0.5
Dim precomp.i(3)
precomp(0) = 1
precomp(1) = 1
precomp(2) = 3
precomp(3) = 2
While sum < 21
turn = 1 - turn
PrintN("The sum is " + Str(sum))
If turn = PLAYER
PrintN("It is your turn.")
While total < 1 Or total > 3 Or total + sum > 21
Print("How many would you like to total? ")
total = Val(Input())
Wend
Else
PrintN("It is the computer's turn.")
total = precomp(sum % 4)
PrintN("The computer totals " + Str(total) + ".")
EndIf
PrintN("")
sum + total
total = 0
Wend
If turn = PLAYER
PrintN("Congratulations. You win.")
Else
PrintN("Bad luck. The computer wins.")
EndIf
Input()
EndIf</syntaxhighlight>
 
==={{header|Yabasic}}===
{{trans|FreeBASIC}}
<syntaxhighlight lang="vb">PLAYER = 1
COMP = 0
 
sum = 0
total = 0
turn = int(ran() + 0.5)
dim precomp(3)
precomp(0) = 1 : precomp(1) = 1
precomp(2) = 3 : precomp(3) = 2
 
while sum < 21
turn = 1 - turn
print "The sum is ", sum
if turn = PLAYER then
print "It is your turn."
while total < 1 or total > 3 or total + sum > 21
input "How many would you like to total? " total
wend
else
print "It is the computer's turn."
total = precomp(mod(sum, 4))
print "The computer totals ", total, "."
fi
print
sum = sum + total
total = 0
wend
 
if turn = PLAYER then
print "Congratulations. You win."
else
print "Bad luck. The computer wins."
fi</syntaxhighlight>
 
=={{header|bash}}==
<langsyntaxhighlight lang="bash">shopt -s expand_aliases
alias bind_variables='
{
Line 165 ⟶ 1,591:
fi
21_Game
</syntaxhighlight>
</lang>
 
=={{header|C}}==
<langsyntaxhighlight Clang="c">/**
* Game 21 - an example in C language for Rosseta Code.
*
Line 249 ⟶ 1,675:
static const int precomputed[] = { 1, 1, 3, 2, 1, 1, 3, 2, 1, 1, 3, 2, 1, 1,
3, 2, 1, 1, 3, 2, 1, 1, 3, 2, 1, 1, 3, 2, 1, 1, 3 };
update(_("ai"), precomputed[total]);
#elif MIN_MOVE == 1 && MAX_MOVE == 3
static const int precomputed[] = { 1, 1, 3, 2};
update(_("ai"), precomputed[total % (MAX_MOVE + 1)]);
#else
int i;
Line 262 ⟶ 1,688:
if (total + i == GOAL)
move = i;
update(_("ai"), move);
#endif
}
Line 307 ⟶ 1,733:
}
}
}</langsyntaxhighlight>
{{out}}
<pre>21 Game
Line 403 ⟶ 1,829:
=={{header|C++}}==
===Model View Controller===
<langsyntaxhighlight lang="cpp">/**
* Game 21 - an example in C++ language for Rosseta Code.
*
Line 603 ⟶ 2,029:
}
return EXIT_SUCCESS; // dead code
}</langsyntaxhighlight>
 
===Model View Presenter===
<langsyntaxhighlight lang="cpp">/**
* Game 21 - an example in C++ language for Rosseta Code.
*
Line 845 ⟶ 2,271:
return EXIT_SUCCESS; // dead code
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 920 ⟶ 2,346:
 
=={{header|C sharp|C#}}==
<langsyntaxhighlight lang="csharp">// 21 Game
 
using System;
Line 1,073 ⟶ 2,499:
 
 
</syntaxhighlight>
</lang>
=={{header|Commodore BASIC}}==
 
Written for BASIC v2 on the Commodore 64, this should be mostly compatible with all Commodore machines running any version of BASIC v2 and above. This implementation allows for one or both players to be either human or computer players. Also note that the computer player's "Thinking..." routine is a purely random delay meant to allow any human user time to process the flow of the game.
 
<syntaxhighlight lang="gwbasic">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"</syntaxhighlight>
 
{{output}}
 
<pre> 21 GAME
The goal of this game is to take turns
adding the value of either 1, 2, or 3
to a running total. The first player
to bring the total to 21...
... WINS THE GAME!
Press a key to continue.
 
 
Player 1, [H]uman or [C]omputer? h
Player 1,
Enter your name? Mike
Player 2, [H]uman or [C]omputer? c
Player 2,
Enter your name? Commodore 64
1. Mike
2. Commodore 64
Is this correct (y/n)? y
Who will play first (1 or 2)? 1
Okay, Mike will play first.
Press a key to continue.
 
 
Total so far: 0
 
Mike's turn.
How much to add,
1, 2, or 3 (0 to quit)? 1
 
Total so far: 1
Commodore 64's turn.
Thinking..........
Commodore 64 adds 1.
 
Total so far: 2
 
Mike's turn.
How much to add,
1, 2, or 3 (0 to quit)? 3
 
Total so far: 5
Commodore 64's turn.
Thinking..........
Commodore 64 adds 1.
 
 
 
...[LATER IN THE GAME]...
 
Total so far: 17
Commodore 64's turn.
Thinking.........
Commodore 64 adds 1.
 
Total so far: 18
 
Mike's turn.
How much to add,
1, 2, or 3 (0 to quit)? 3
 
21! Mike wins the game!!!
Would you like to play again? n
Okay, maybe another time. Bye!
ready.
&#9608;
</pre>
 
=={{header|Delphi}}==
See Pascal[https://rosettacode.org/wiki/21_Game#Pascal]
 
=={{header|EasyLang}}==
The computer plays optimally
<syntaxhighlight>
print "Who reaches 21, wins"
print "Do you want to begin (y/n)"
who = 1
if input = "n"
who = 2
.
who$[] = [ "Human" "Computer" ]
repeat
if who = 1
repeat
print ""
print "Choose 1,2 or 3 (q for quit)"
a$ = input
n = number a$
until a$ = "q" or (n >= 1 and n <= 3)
.
else
sleep 1
if sum mod 4 = 1
n = randint 3
else
n = 4 - (sum + 3) mod 4
.
.
sum += n
print who$[who] & ": " & n & " --> " & sum
until sum >= 21 or a$ = "q"
who = who mod 2 + 1
.
if a$ <> "q"
print ""
if who = 0
print "Congratulation, you won"
else
print "Sorry, you lost"
.
.
</syntaxhighlight>
 
=={{header|Factor}}==
A difficulty system has been implemented. The player chooses a difficulty from 1-10. There is a <code>difficulty in 10</code> chance that the computer opponent gets to move first. There is a <code>difficulty in 10</code> chance each turn that the computer opponent will make the optimal move (i.e. setting the total to a number of the form <code>4n+1</code>) as opposed to a random move. At difficulty level 10, it is impossible for the human player to win the game.
{{works with|Factor|0.99 2020-07-03}}
<langsyntaxhighlight lang="factor">USING: accessors combinators.random continuations formatting io
kernel math math.functions math.parser multiline qw random
sequences ;
Line 1,158 ⟶ 2,818:
.welcome nl [ <game> do-turns ] with-return ;
 
MAIN: play-21-game</langsyntaxhighlight>
{{out}}
<pre>
Line 1,197 ⟶ 2,857:
+human+ wins!
</pre>
 
=={{header|F sharp|F#}}==
<syntaxhighlight lang="fsharp">
type Player =
| Computer
| Person
type Play = {runningTotal:int; nextTurn:Player}
type Win =
| ByExact of Player
| ByOtherExceeded of Player
type Status =
| Start
| Playing of Play
| Winner of Win
| Exit
 
let rnd = System.Random ()
let randomFirstPlayer () =
let selection = rnd.Next 2
if selection = 0 then Computer else Person
let computerChose current =
if current > 17 then 21-current // win strategy
else if current > 13 && current < 17 then 17-current // naive thwart opponent strategy
else rnd.Next(1, (min 4 (21-current+1)))
 
let (|Exact|Exceeded|Under|) i = if i = 21 then Exact else if i > 21 then Exceeded else Under
let (|ValidNumber|InvalidInput|Quit|) (s:string) =
let trimmed = s.Trim().ToLower()
if trimmed = "1" || trimmed = "2" || trimmed = "3" then ValidNumber
else if trimmed = "q" then Quit
else InvalidInput
let readable = function | Computer -> "Computer is" | Person -> "You are"
 
let rec looper = function
| Start ->
let firstPlayer = randomFirstPlayer ()
printfn $"{readable firstPlayer} randomly selected to go first."
looper (Playing {runningTotal=0; nextTurn=firstPlayer})
| Playing play ->
match play with
| {runningTotal=Exact; nextTurn=Person} -> looper (Winner (ByExact Computer))
| {runningTotal=Exact; nextTurn=Computer} -> looper (Winner (ByExact Person))
| {runningTotal=Exceeded; nextTurn=player} -> looper (Winner (ByOtherExceeded player))
| {runningTotal=r; nextTurn=player} ->
match player with
| Computer ->
let computerChoice = computerChose r
let total = r+computerChoice
printfn $"Computer entered {computerChoice}. Current total now: {total}."
looper (Playing {runningTotal=total; nextTurn=Person})
| Person ->
let input = printf "Enter number 1, 2, or 3 (or q to exit): "; System.Console.ReadLine ()
match input with
| ValidNumber ->
let playerChoice = System.Int32.Parse input
let total = r+playerChoice
printfn $"Player entered {playerChoice}. Current total now: {total}."
looper (Playing {runningTotal=total; nextTurn=Computer})
| Quit -> looper Exit
| InvalidInput -> printfn "Invalid input. Try again."; looper (Playing play)
| Winner win ->
match win with
| ByExact player -> printfn $"{readable player} the winner by getting to 21."; looper Exit
| ByOtherExceeded player -> printfn $"{readable player} the winner by not exceeding 21."; looper Exit
| Exit -> printfn "Thanks for playing!"
let run () = looper Start
</syntaxhighlight>
{{out}}
<pre>
You are randomly selected to go first.
Enter number 1, 2, or 3 (or q to exit): 5
Invalid input. Try again.
Enter number 1, 2, or 3 (or q to exit): a
Invalid input. Try again.
Enter number 1, 2, or 3 (or q to exit): 3
Player entered 3. Current total now: 3.
Computer entered 3. Current total now: 6.
Enter number 1, 2, or 3 (or q to exit): 3
Player entered 3. Current total now: 9.
Computer entered 1. Current total now: 10.
Enter number 1, 2, or 3 (or q to exit): 2
Player entered 2. Current total now: 12.
Computer entered 2. Current total now: 14.
Enter number 1, 2, or 3 (or q to exit): 1
Player entered 1. Current total now: 15.
Computer entered 2. Current total now: 17.
Enter number 1, 2, or 3 (or q to exit): 2
Player entered 2. Current total now: 19.
Computer entered 2. Current total now: 21.
Computer is the winner by getting to 21.
Thanks for playing!
 
</pre>
 
=={{header|Forth}}==
<syntaxhighlight lang="forth">: READKEY
1+ BEGIN
KEY DUP 27 = ABORT" Bye!"
48 - 2DUP > OVER 0 > AND IF
DUP 48 + EMIT CR SWAP DROP EXIT
THEN DROP
REPEAT
;
: 21GAME CLS
0 2 RND 1-
." 21 is a two player game." CR
." 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."
BEGIN
NOT
CR ." The sum is " OVER . CR
SWAP OVER IF
." How many would you like add?"
." (1-3) " 3 READKEY
ELSE
." It is the computer's turn."
4 OVER 1- 4 MOD -
DUP 4 = IF 3 RND 1+ MIN THEN
DUP CR ." Computer adds " . CR
THEN + SWAP
OVER 21 < NOT UNTIL
CR
IF ." Congratulations. You win."
ELSE ." Bad Luck. Computer wins."
THEN CR DROP
;</syntaxhighlight>
 
=={{header|Fortran}}==
<langsyntaxhighlight Fortranlang="fortran">! game 21 - an example in modern fortran language for rosseta code.
 
subroutine ai
Line 1,256 ⟶ 3,045:
program main
common itotal, igoal
print *,"game 21 - an example in fortran iv language for rosseta code."
print *,""
print *,"21 is a two player game, the game is played by choosing a number"
Line 1,273 ⟶ 3,062:
if (mod(irand(0), 2) .eq. 0) then
print *, "the first move is ai move."
print *, ""
call ai
else
print *, "the first move is human move."
print *, ""
do while(itotal .lt. igoal)
call human
call ai
end do
end if
print *, ""
end do
do while(itotal .lt. igoal)
end program main</lang>
call human
call ai
end do
end do
end program main</syntaxhighlight>
{{out}}
<pre>game 21 - an example in fortran language for rosseta code.
Line 1,344 ⟶ 3,132:
enter 1 or 2 or 3 (or 0 to exit)
0</pre>
 
=={{Header|FreeBASIC}}==
<syntaxhighlight lang="freebasic">#define PLAYER 1
#define COMP 0
randomize timer
 
dim as uinteger sum, add = 0
dim as uinteger turn = int(rnd+0.5)
dim as uinteger precomp(0 to 3) = { 1, 1, 3, 2 }
 
while sum < 21:
turn = 1 - turn
print using "The sum is ##"; sum
if turn = PLAYER then
print "It is your turn."
while add < 1 orelse add > 3 orelse add+sum > 21
input "How many would you like to add? ", add
wend
else
print "It is the computer's turn."
add = precomp(sum mod 4)
print using "The computer adds #."; add
end if
print
sum = sum + add
add = 0
wend
 
if turn = PLAYER then
print "Congratulations. You win."
else
print "Bad luck. The computer wins."
end if</syntaxhighlight>
 
=={{Header|FutureBasic}}==
A fairly simple game, but this FutureBasic code builds a full, stand-alone, interactive app for it in about 100 LOC. It includes three levels of play, selectable via a popup menu:
* Min level has the computer play at random, choosing the optimal play only 1/3 of the time. Good for learning, or for kids.
* Mid level gives the computer its optimal play 2/3 of the time, making for more varied and interesting play.
* Max level always chooses the optimal play, meaning when the computer starts, it can't lose, which seems less fun.
*
<syntaxhighlight lang="futurebasic">
 
begin globals
begin enum 1
_btn1
_btn2
_btn3
_sum
_msg
_popup
_skill
_human = 0
_robot
end enum
str15 cr : cr = chr$(13)
str255 string(1) : short who = _human
byte best(3), sum, num, skill = 1 //Medium skill
poke int @best(0), 33751297 //Initialize computer responses
end globals
 
local fn buildWindow
subclass window 1, @"21 Game in FutureBasic" , ( 0, 0,640,200 )
popupbutton _popup,, 1, @"Minimum;Medium;Maximum" , ( 80, 17,100, 32 )
textlabel _msg , @"Original code: J. Reeve", ( 20,160,600, 32 )
textlabel _skill , @"Skill level:", ( 20, 12, 75, 32 )
textfield _sum ,, @"0",( 530,85,90,60 )
button _btn1 ,, , @"1",( 245,20,50,50 ),,NSBezelStyleRegularSquare
button _btn2 ,, , @"2",( 295,20,50,50 ),,NSBezelStyleRegularSquare
button _btn3 ,, , @"3",( 345,20,50,50 ),,NSBezelStyleRegularSquare
ControlSetAlignment( _msg, NSTextAlignmentCenter )
ControlSetAlignment( _sum, NSTextAlignmentCenter )
TextFieldSetEditable( _sum, no )
ControlSetFontWithName( _msg, @"Menlo", 15.0 )
ControlSetFontWithName( _btn1, @"Menlo", 20.0 )
ControlSetFontWithName( _btn2, @"Menlo", 20.0 )
ControlSetFontWithName( _btn3, @"Menlo", 20.0 )
ControlSetFontWithName( _sum, @"Menlo", 32.0 )
text @"menlo", 15.0
end fn
 
local fn show( add as byte )
CFStringRef msg
if (sum + add) > 21 then beep : exit fn
button 1, who : button 2, who : button 3, who
sum += add : cls
ControlSetIntegerValue( _sum, sum )
string( who ) += "+" + chr$( add or 48 ) + " "
print cr;cr;cr;string( _human );cr;cr;string( _robot )
if sum < 21
if who == _robot then msg = @"Your turn..." else msg = @"My turn..."
else
if who == _robot
msg = @"Too bad. I win. Press any key to play again."
else
msg = @"Congratulations! YOU WIN! Press any key to play again."
end if
end if
if peek( @string( who ) ) > 20 then textlabel _msg, msg
who = who xor _robot
end fn
 
local fn play( add as byte )
if sum + add > 21 then beep : exit fn
fn show( add ) //Show human's play
if sum < 21
if (skill + maybe) > 0 then num = best(sum mod 4) else num = rnd(3)
if sum + num > 21 then num = 21 - sum
timerbegin 1.0, NO //wait a sec before playing
fn show( num ) //Show computer's play
timerend
end if
end fn
 
local fn start
sum = 0 : cls
string( _human ) = " You: " : string( _robot ) = " Computer: "
string( 1-who ) += " "
if who == _robot
if skill == 2 then num = 1 else num = rnd( 3 )
textlabel _msg, fn StringWithFormat( @"I'll start with %i.", num )
fn show( num )
else
ControlSetIntegerValue( _sum, sum )
textlabel _msg, @"You start. Type or click 1, 2, or 3."
end if
end fn
 
local fn DoDialog( evt as long, tag as long)
byte key
select ( evt )
case _windowKeyUp
if sum == 21 then fn start : exit fn
if who == _robot then exit fn
key = intval( fn EventCharacters )
if key > 0 && key < 4 then fn play( key )
case _btnClick
if tag < _popup then beep : fn play( tag ) : exit fn
skill = popupbutton( _popup )
case _windowWillClose : end
end select
end fn
 
fn buildWindow
fn start
on dialog fn doDialog
handleevents
</syntaxhighlight>
{{out}}
[[File:FutureBasic screenshot for 21 Game.png]]
 
=={{header|Gambas}}==
<syntaxhighlight lang="gambas">
' Gambas module file
 
Private gameConunt As Integer = 0
Private numRound As Integer = 1
Private winPlayer As Integer = 0
Private winComputer As Integer = 0
 
 
Public Sub Main()
 
Dim entra As String
 
Print "Enter q to quit at any time\nThe computer will choose first"
 
While gameConunt < 21
Print "ROUND: " & numRound & "\n"
gameConunt += selectCount(gameConunt)
Print Subst("Running total is now &1 \n ", gameConunt)
If gameConunt = 21 Then
Inc winComputer
Print "The computer has won !\n"
endGame()
Endif
gameConunt += humanCount(gameConunt)
Print Subst("Running total is now &1", gameConunt)
If gameConunt = 21 Then
Inc winPlayer
Print "Congratulations! You've won!\n"
endGame()
Endif
Inc numRound
Wend
 
End
 
Private Function selectCount(cou As Integer) As Integer
 
Dim a As Integer
 
Randomize
 
If cou < 18 Then
a = Int(Rnd(1, 4))
Else
a = 21 - cou
Endif
 
Print "The computer choose " & a
 
Return a
 
End
 
Private Function humanCount(cou As Integer) As Integer
 
Dim entra As String
Dim a As Integer
 
While True
Print "Your choice 1 to 3"
Input entra
If entra = "q" Then
Print "Good Bye!"
Quit
Endif
Try a = CInt(entra)
If Error Then
Print "Invalid entry, try again"
Continue
Endif
If a < 1 Or a > 3 Then
Print "Out of range, try again"
Continue
Endif
If a + cou > 21 Then
Print "The sum is greater than 21, try again"
Continue
Endif
Return a
Wend
 
End
 
 
Private Sub endGame()
 
Dim entra As String
 
Print Subst("Computer wins &1 games, human wins &2 games", winComputer, winPlayer)
Print "\nPlay again? (y/n)"
Input entra
If entra = "y" Or entra = "Y" Then
numRound = 1
gameConunt = 0
Print "Enter q to quit at any time\nThe computer will choose first"
Else
Print "Good Bye!"
Quit
Endif
 
End</syntaxhighlight>
 
<pre>
Enter q to quit at any time
The computer will choose first
ROUND: 1
 
The computer choose 2
Running total is now 2
Your choice 1 to 3
4
Out of range, try again
Your choice 1 to 3
0
Out of range, try again
Your choice 1 to 3
g
Invalid entry, try again
Your choice 1 to 3
1
Running total is now 3
ROUND: 2
 
The computer choose 2
Running total is now 5
Your choice 1 to 3
3
Running total is now 8
ROUND: 3
 
The computer choose 2
Running total is now 10
Your choice 1 to 3
3
Running total is now 13
ROUND: 4
 
The computer choose 2
Running total is now 15
Your choice 1 to 3
3
Running total is now 18
ROUND: 5
 
The computer choose 3
Running total is now 21
The computer has won !
 
computer wins 1 games, human wins 0 games
 
Play again? (y/n)
 
Good Bye!
</pre>
 
=={{header|GDScript}}==
{{works with|Godot|4.0}}
 
<syntaxhighlight lang="gdscript">
extends MainLoop
 
 
enum Player {Human, Computer}
 
const target: int = 21
 
 
# -1 is returned to request quit
func get_player_choice(total: int) -> int:
while true:
printraw("Player's choice: ")
var input: String = OS.read_string_from_stdin().strip_edges()
 
if input == "quit":
return -1
 
if not input.is_valid_int():
print("Please input an integer.")
continue
 
var input_int := int(input)
if input_int < 1 or input_int > 3:
print("Please pick a number from 1 to 3")
continue
 
if input_int + total > target:
print("Please do not exceed a total of %d" % target)
continue
 
return input_int
 
# This is required since Godot does not detect the unreachable code path
OS.crash("unreachable")
return 0
 
 
func get_computer_choice(total: int) -> int:
# This can be shortened using max() if you do not have type checking OCD
var remaining: int = target - total
return randi_range(1, 3 if remaining > 3 else remaining)
 
 
func play() -> void:
print("""\
Welcome to the 21 game.
Type quit to exit.""")
var total: int = 0
var player: Player
match randi_range(1, 2):
1:
player = Player.Human
print("You will go first.")
2:
player = Player.Computer
print("The computer will go first.")
 
while true:
print("\nThe total is %d" % total)
 
var choice: int
match player:
Player.Human:
choice = get_player_choice(total)
if choice == -1:
return
Player.Computer:
choice = get_computer_choice(total)
print("The computer plays %d" % choice)
assert(1 <= choice and choice <= 3)
 
total += choice
if total == target:
match player:
Player.Human: print("You win!")
Player.Computer: print("The computer won, you lose.")
return
assert(total < target)
 
match player:
Player.Human: player = Player.Computer
Player.Computer: player = Player.Human
 
 
func _process(_delta: float) -> bool:
randomize()
play()
return true
 
</syntaxhighlight>
 
=={{header|Go}}==
 
To give the human player a reasonable chance whoever goes first, the computer always chooses randomly when the running total is below 18 but otherwise chooses the exact number needed to win the game.
<langsyntaxhighlight lang="go">package main
 
import (
Line 1,447 ⟶ 3,641:
}
}
}</langsyntaxhighlight>
 
{{out}}
Line 1,553 ⟶ 3,747:
=={{header|Haskell}}==
The computer chooses values randomly.
<langsyntaxhighlight lang="haskell">import System.Random
import System.IO
import System.Exit
Line 1,616 ⟶ 3,810:
putStrLn $ (fst names) ++ " has won the game"
when (y == 1) $ do
putStrLn $ (snd names) ++ " has won the game"</langsyntaxhighlight>
 
=={{header|J}}==
The main definition <tt>g21</tt> starts the game. J doesn't support niladic verbs. Although the <tt>y</tt> argument has no effect, it must be given. The empty literal vector <nowiki>''</nowiki> types quickly, hence often used to trigger niladic verbs. g21 does not superfluously penalize final sums exceeding 21.
<syntaxhighlight lang="j">
g21=: summarize@play@setup ::('g21: error termination'"_)
 
NB. non-verb must be defined before use, otherwise are assumed verbs.
Until=: 2 :'u^:(0-:v)^:_'
 
t=: 'score turn choice'
(t)=: i. # ;: t
empty erase't'
 
Fetch=: &{
Alter=: }
 
play=: move Until done
done=: 21 <: score Fetch
move=: [: update you`it@.(turn Fetch)
 
update=: swap@display@add
add=: score Alter~ (score Fetch + choice Fetch)
display=: [ ([: echo 'sum: {}' format~ score Fetch)
swap=: turn Alter~ ([: -. turn Fetch)
 
it=: ([ [: echo 'It chose {}.' format~ choice Fetch)@(choice Alter~ cb)
cb=: (1:`r`3:`2:)@.(4 | score Fetch) NB. computer brain
r=: 3 :'>:?3'
 
you=: qio1@check@acquire@prompt
prompt=: [ ([: echo 'your choice?'"_)
acquire=: choice Alter~ ('123' i. 0 { ' ' ,~ read)
check=: (choice Alter~ (665 - score Fetch))@([ ([: echo 'g21: early termination'"_))^:(3 = choice Fetch)
qio1=: choice Alter~ ([: >: choice Fetch)
 
setup=: ([ [: echo 'On your turn enter 1 2 or 3, other entries exit'"_)@((3 :'?2') turn Alter ])@0 0 0"_ NB. choose first player randomly
summarize=: ' won' ,~ (];._2 'it you ') {~ turn Fetch
 
read=: 1!:1@:1:
write=: 1!:2 4: NB. unused
format=: ''&$: :([: ; (a: , [: ":&.> [) ,. '{}' ([ (E. <@}.;._1 ]) ,) ])
</syntaxhighlight>
<pre>
g21''
On your turn enter 1 2 or 3, other entries exit
It chose 1.
sum: 1
your choice?
q
g21: early termination
sum: 666
you won
 
g21''
On your turn enter 1 2 or 3, other entries exit
your choice?
2
sum: 2
It chose 3.
sum: 5
your choice?
1
sum: 6
It chose 3.
sum: 9
your choice?
2
sum: 11
It chose 2.
sum: 13
your choice?
3
sum: 16
It chose 1.
sum: 17
your choice?
1
sum: 18
It chose 3.
sum: 21
it won
</pre>
 
=={{header|Java}}==
Options for creating a game:
Line 1,634 ⟶ 3,912:
The computer strategy is to see if a valid value will win the game. If so, that value is selected. Otherwise, a random value among the valid values is selected.
 
<langsyntaxhighlight lang="java">
import java.util.Random;
import java.util.Scanner;
Line 1,770 ⟶ 4,048:
 
}
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,915 ⟶ 4,193:
=={{header|Javascript}}==
The solution as a Javascript script inside a page written in HTML5. It should work with all modern browsers.
<langsyntaxhighlight lang="javascript"><!DOCTYPE html><html lang="en">
 
<head>
Line 2,073 ⟶ 4,351:
 
</body>
</html></langsyntaxhighlight>
 
=={{header|Julia}}==
The computer or player can always win if they go first and choose a number that brings the total to one of the following: 1, 5, 9, 13, or 17. To make things vary more, there is a choice of computer play level at the start. The computer will randomly respond with level 1 and choose a random response 1/4 of the time at level 2.
<langsyntaxhighlight lang="julia">
function trytowin(n)
if 21 - n < 4
Line 2,160 ⟶ 4,438:
 
play21game()
</syntaxhighlight>
</lang>
 
=={{header|Koka}}==
<syntaxhighlight lang="koka">
import std/num/random
import std/os/readline
 
effect exit
final ctl exit(): ()
 
type player
Player
Computer
 
fun other(p: player): player
match p
Player -> Computer
Computer -> Player
 
fun show(p: player): string
match p
Player -> "Player"
Computer -> "Computer"
 
fun get-selection(max-int: int)
val i = readline().trim().parse-int()
match i
Just(x) | x >= 1 && x <= max-int -> x
_ ->
println("Please enter a number between 1 and " ++ max-int.show ++ " or press q to quit")
get-selection(max-int)
 
fun play(p: player, total: int)
println("Total: " ++ total.show)
match total
21 ->
// The player who reaches 21 wins the game, which is the player in the last loop
println(p.other.show ++ " wins!")
return ()
_ -> ()
val max = if total + 3 > 21 then 21 - total else 3
match p
Player ->
println("Player's turn")
val selection = get-selection(max)
play(p.other, total + selection)
Computer ->
println("Computer's turn")
val selection = (random-int() % max) + 1
println("Computer chooses " ++ selection.show)
play(p.other, total + selection)
 
fun main()
with final ctl exit() ()
"21 is a two player game. The game is played by choosing a number (1, 2, 3) to".println
"be added to the running total. The game is won by the player whose chosen number".println
"causes the running total to reach exactly 21. The running total starts at zero.".println
"".println
"You can quit the game at any time by typing 'q'.".println
val playerGoesFirst = random-bool()
val p1 = if playerGoesFirst then Player else Computer
play(p1, 0)
</syntaxhighlight>
=={{header|Lua}}==
<langsyntaxhighlight lang="lua">
gamewon = false
running_total = 0
Line 2,213 ⟶ 4,552:
 
end
</syntaxhighlight>
</lang>
 
=={{header|Mathematica}} / {{header|Wolfram Language}}==
<syntaxhighlight lang="mathematica">SeedRandom[1234];
ClearAll[ComputerChoose, HumanChoose]
ComputerChoose[n_] := If[n < 18, RandomChoice[{1, 2, 3}], 21 - n]
HumanChoose[] := ChoiceDialog["How many?", {1 -> 1, 2 -> 2, 3 -> 3, "Quit" -> -1}]
runningtotal = 0;
whofirst = ChoiceDialog["Who goes first?", {"You" -> 1, "Computer" -> 2}];
While[runningtotal < 21,
If[whofirst == 1,
choice = HumanChoose[];
If[choice == -1, Break[]];
Print["You choose = ", choice];
runningtotal += choice;
Print["Running total = ", runningtotal];
If[runningtotal == 21, Print["You won!"]; Break[]];
choice = ComputerChoose[runningtotal];
Print["Computer choose = ", choice];
runningtotal += choice;
Print["Running total = ", runningtotal];
If[runningtotal == 21, Print["Computer won!"]; Break[]];
,
choice = ComputerChoose[runningtotal];
Print["Computer choose = ", choice];
runningtotal += choice;
Print["Running total = ", runningtotal];
If[runningtotal == 21, Print["Computer won!"]; Break[]];
choice = HumanChoose[];
If[choice == -1, Break[]];
Print["You choose = ", choice];
runningtotal += choice;
Print["Running total = ", runningtotal];
If[runningtotal == 21, Print["You won!"]; Break[]];
];
]</syntaxhighlight>
{{out}}
<pre>You choose = 2
Running total = 2
Computer choose = 3
Running total = 5
You choose = 3
Running total = 8
Computer choose = 1
Running total = 9
You choose = 3
Running total = 12
Computer choose = 1
Running total = 13
You choose = 1
Running total = 14
Computer choose = 2
Running total = 16
You choose = 1
Running total = 17
Computer choose = 3
Running total = 20
You choose = 1
Running total = 21
You won!</pre>
 
 
=={{header|Nim}}==
There is a simple strategy which allows the first player to win in any case. It consists to choose a value which gives
a running total equal to 1, 5, 9, 13 or 17. So never let the computer starts as the program uses this strategy.
<syntaxhighlight lang="nim">
# 21 game.
 
import random
import strformat
import strutils
 
const
Target = 21
PossibleChoices: array[18..20, seq[string]] = [@["1", "2", "3"], @["1", "2"], @["1"]]
Targets = [1, 5, 9, 13, 17, 21] # Totals that a player must obtain to win.
 
#---------------------------------------------------------------------------------------------------
 
proc printTotal(total: int) =
## Print the running total.
echo fmt"Running total is now {total}."
 
#---------------------------------------------------------------------------------------------------
 
proc computerPlays(total: var int) =
## Make the computer play.
var choice: int
if total in Targets:
# No winning choice. Choose a random value.
choice = rand(1..3)
else:
# Find the running total to get.
for val in Targets:
if val > total:
choice = val - total
break
inc total, choice
echo fmt"I choose {choice}."
printTotal(total)
 
#---------------------------------------------------------------------------------------------------
 
proc prompt(message: string; answers: openArray[string]): int =
## Prompt a message and get an answer checking its validity against possible answers.
 
while true:
stdout.write(message & ' ')
try:
result = answers.find(stdin.readLine())
if result >= 0:
break
echo fmt"Please answer one of: {answers.join("", "")}."
except EOFError:
echo ""
return # Quit.
 
#---------------------------------------------------------------------------------------------------
 
randomize()
 
echo "21 is a two player game. The game is played by choosing a number (1, 2, 3) to\n" &
"be added to the running total. The game is won by the player whose chosen number\n" &
"causes the running total to reach exactly 21. The running total starts at zero.\n"
echo "You can quit the game at any time by typing 'q'."
 
block mainLoop:
 
while true:
var total = 0
 
# Choose the player who will play first.
var answer = prompt("Who will play first ('you', 'me')?", ["q", "you", "me"])
if answer == 0:
echo "Quitting game."
break
elif answer == 1:
computerPlays(total)
 
# Internal game loop.
while true:
 
# Ask player its choice.
let choices = if total > 18: PossibleChoices[total] else: PossibleChoices[18]
let choice = prompt(fmt"Your choice ({choices.join("", "")})?", "q" & choices)
if choice == 0:
echo "Quitting game."
break mainLoop
 
# Update running total and check if player win.
inc total, choice
printTotal(total)
if total == Target:
echo "Congratulations, you win."
break
 
# Make computer play.
computerPlays(total)
if total == Target:
echo "Sorry, I win."
break
 
# Ask player for another game.
answer = prompt("Do you want to play another game (y, n)", ["q", "y", "n"])
if answer != 1:
echo "Quitting game."
break
</syntaxhighlight>
 
{{out}}
<pre>
21 is a two player game. The game is played by choosing a number (1, 2, 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.
 
You can quit the game at any time by typing 'q'.
Who will play first (you, me)? x
Please, answer one of: q, you, me.
Who will play first ('you', 'me')? you
I choose 1.
Running total is now 1.
Your choice (1, 2, 3)? 4
Please answer one of: q, 1, 2, 3.
Your choice (1, 2, 3)? 3
Running total is now 4.
I choose 1.
Running total is now 5.
Your choice (1, 2, 3)? 3
Running total is now 8.
I choose 1.
Running total is now 9.
Your choice (1, 2, 3)? 3
Running total is now 12.
I choose 1.
Running total is now 13.
Your choice (1, 2, 3)? 3
Running total is now 16.
I choose 1.
Running total is now 17.
Your choice (1, 2, 3)? 3
Running total is now 20.
I choose 1.
Running total is now 21.
Sorry, I win.
Do you want to play another game (y, n) y
Who will play first (you, me)? me
Your choice (1, 2, 3)? 1
Running total is now 1.
I choose 2.
Running total is now 3.
Your choice (1, 2, 3)? 2
Running total is now 5.
I choose 2.
Running total is now 7.
Your choice (1, 2, 3)? 2
Running total is now 9.
I choose 1.
Running total is now 10.
Your choice (1, 2, 3)? 3
Running total is now 13.
I choose 3.
Running total is now 16.
Your choice (1, 2, 3)? 1
Running total is now 17.
I choose 2.
Running total is now 19.
Your choice (1, 2)? 2
Running total is now 21.
Congratulations, you win.
Do you want to play another game (y, n) n
Quitting game.
</pre>
 
=={{header|Objeck}}==
<langsyntaxhighlight lang="objeck">class TwentyOne {
@quit : Bool;
@player_total : Int;
Line 2,310 ⟶ 4,880:
return 0;
}
}</langsyntaxhighlight>
 
=={{header|Pascal|Delphi}}==
<langsyntaxhighlight lang="pascal">
program Game21;
 
Line 2,517 ⟶ 5,087:
end;
end.
</syntaxhighlight>
</lang>
 
=={{header|Perl}}==
{{trans|Raku}}
<langsyntaxhighlight lang="perl">print <<'HERE';
The 21 game. Each player chooses to add 1, 2, or 3 to a running total.
The player whose turn it is when the total reaches 21 wins. Enter q to quit.
Line 2,556 ⟶ 5,126:
my $i = $insults[1+int rand($#insults)];
print "$i, $g is not an integer between 1 and 3...\n"
}</langsyntaxhighlight>
{{out}}
<pre>The 21 game. Each player chooses to add 1, 2, or 3 to a running total.
Line 2,577 ⟶ 5,147:
 
=={{header|Phix}}==
{{libheader|Phix/pGUI}}
If the computer goes first you cannot win.<br>
{{libheader|Phix/online}}
Once the computer stops displaying "no clear strategy" you cannot win.<br>
If the computer goes first you cannot win, it will say "(you've already lost)" as soon as you have.<br>
The computer_first flag only applies to the first game. After winning, losing, or conceding, you go first.
You can run this online [http://phix.x10.mx/p2js/21Game.htm here]. (As noted below, a few improvements are in order.)
<lang Phix>bool computer_first = false
<!--<syntaxhighlight lang="phix">(phixonline)-->
bool show_spoiler = false
<span style="color: #000080;font-style:italic;">--
 
-- demo\rosetta\21_Game.exw
integer total = 0
-- ========================
 
--</span>
procedure computer_play()
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span> <span style="color: #000080;font-style:italic;">-- DEV NORMALIZESIZE, CANFOCUS, "You" not checked, VALUE_HANDLE.
integer move = 0
-- The radio_texts simply don't do anything at all in p2js.</span>
for i=1 to 3 do
<span style="color: #008080;">constant</span> <span style="color: #000000;">title</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"21 Game"</span><span style="color: #0000FF;">,</span>
if mod(total+i,4)=1 then
<span style="color: #000000;">help_text</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"""
move = i
Play by choosing 1, 2, or 3 to add to the running total (initially 0).
exit
end if
The first player to reach 21 wins.
end for
if move=0 then
If the computer goes first you cannot win.
puts(1,"no clear strategy\n")
move = rand(min(3,21-total))
If you leave your opponent on 18, 19, or 20, they will play {3,2,1} and win.
end if
If you leave your opponent on 17, simply match their play {1,2,3} with {3,2,1} and win.
printf(1,"Total is %d. I play %d.\n",{total,move})
If you leave your opponent on 14, 15, or 16, they'll leave you on 17 and win.
total += move
So the aim is 21 (doh), and before that 17, 13, 9, 5, and 1. Anything else loses.
if total=21 then
"""</span><span style="color: #0000FF;">,</span>
puts(1,"21! I win!\n")
<span style="color: #000000;">radio_texts</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"You"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Computer"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Random"</span><span style="color: #0000FF;">},</span>
end if
<span style="color: #000000;">button_text</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"one"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"two"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"three"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"concede"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"new game"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"quit"</span><span style="color: #0000FF;">}</span>
end procedure
<span style="color: #004080;">integer</span> <span style="color: #000000;">total</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
 
puts(1,"\n21 game\n\n")
<span style="color: #008080;">include</span> <span style="color: #000000;">pGUI</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
puts(1,"Press escape or q to quit the game, c to concede and start a new game from 0\n\n")
<span style="color: #004080;">Ihandle</span> <span style="color: #000000;">dlg</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">vbox</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">frame</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">radios</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">playstate</span>
 
<span style="color: #004080;">sequence</span> <span style="color: #000000;">radioset</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">buttons</span>
if computer_first then
printf(1,"Total is %d.\n",{total})
<span style="color: #008080;">function</span> <span style="color: #000000;">show_help</span><span style="color: #0000FF;">()</span>
computer_play()
<span style="color: #7060A8;">IupMessage</span><span style="color: #0000FF;">(</span><span style="color: #000000;">title</span><span style="color: #0000FF;">,</span><span style="color: #000000;">help_text</span><span style="color: #0000FF;">)</span>
elsif show_spoiler then
<span style="color: #008080;">return</span> <span style="color: #004600;">IUP_IGNORE</span> <span style="color: #000080;font-style:italic;">-- (don't open browser help!)</span>
-- The secret to winning!
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
puts(1,sq_sub("Uif!pomz!xbz!up!xjo!jt!qmbz!2!gjstu-!uifo!5.=dpnqvufs!npwf?!fwfsz!ujnf",1)&"\n\n")
end if
<span style="color: #008080;">function</span> <span style="color: #000000;">play</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
 
<span style="color: #008080;">if</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
while 1 do
<span style="color: #008080;">if</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">=</span><span style="color: #000000;">6</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #004600;">IUP_CLOSE</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
printf(1,"Total is %d. enter 1, 2, or 3: ",{total})
<span style="color: #004080;">string</span> <span style="color: #000000;">title</span>
integer ch = wait_key()
<span style="color: #008080;">if</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">></span><span style="color: #000000;">3</span> <span style="color: #008080;">then</span>
puts(1,iff(ch=#1B?"esc":ch)&"\n")
<span style="color: #000080;font-style:italic;">-- concede or new_game</span>
if ch>='1' and ch<='3' then
<span style="color: #000000;">total</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
ch -= '0'
<span style="color: #000000;">title</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">=</span><span style="color: #000000;">4</span><span style="color: #0000FF;">?</span><span style="color: #008000;">"(conceded) "</span><span style="color: #0000FF;">:</span><span style="color: #008000;">""</span><span style="color: #0000FF;">)</span>
if total+ch>21 then
<span style="color: #000000;">title</span> <span style="color: #0000FF;">&=</span> <span style="color: #008000;">"Total is 0"</span>
puts(1,"Too big\n")
<span style="color: #004080;">Ihandle</span> <span style="color: #000000;">r</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupGetAttributePtr</span><span style="color: #0000FF;">(</span><span style="color: #000000;">radios</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"VALUE_HANDLE"</span><span style="color: #0000FF;">)</span>
else
<span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">r</span><span style="color: #0000FF;">,</span><span style="color: #000000;">radioset</span><span style="color: #0000FF;">)</span>
total += ch
<span style="color: #008080;">if</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">=</span><span style="color: #000000;">2</span> <span style="color: #008080;">or</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">=</span><span style="color: #000000;">3</span> <span style="color: #008080;">and</span> <span style="color: #7060A8;">rand</span><span style="color: #0000FF;">(</span><span style="color: #000000;">2</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
if total=21 then
<span style="color: #000000;">title</span> <span style="color: #0000FF;">&=</span> <span style="color: #008000;">","</span> <span style="color: #000080;font-style:italic;">-- trigger a computer move</span>
puts(1,"21! You win!\n")
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
else
<span style="color: #7060A8;">IupSetInt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">buttons</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #000000;">3</span><span style="color: #0000FF;">],</span><span style="color: #008000;">"ACTIVE"</span><span style="color: #0000FF;">,</span><span style="color: #004600;">true</span><span style="color: #0000FF;">)</span>
computer_play()
<span style="color: end if#008080;">else</span>
<span style="color: #000080;font-style:italic;">-- n = 1..3</span>
end if
<span style="color: #000000;">title</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"Total is %d"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">total</span><span style="color: #0000FF;">)</span>
elsif ch=#1B or lower(ch)='q' then
<span style="color: #008080;">if</span> <span style="color: #000000;">total</span><span style="color: #0000FF;">=</span><span style="color: #000000;">21</span> <span style="color: #000080;font-style:italic;">-- (from key_cb)</span>
puts(1,"Quitting\n")
<span style="color: #008080;">or</span> <span style="color: #000000;">total</span><span style="color: #0000FF;">+</span><span style="color: #000000;">n</span><span style="color: #0000FF;">></span><span style="color: #000000;">21</span> <span style="color: #008080;">then</span> <span style="color: #000080;font-style:italic;">-- (invalid)</span>
exit
<span style="color: #008080;">return</span> <span style="color: #004600;">IUP_IGNORE</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
if lower(ch)='c' or total=21 then
<span style="color: #000000;">total</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">n</span>
total = 0
<span style="color: #000000;">title</span> <span style="color: #0000FF;">&=</span> <span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">", you play %d (-&gt; %d),"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">total</span><span style="color: #0000FF;">})</span>
end if
<span style="color: #008080;">if</span> <span style="color: #000000;">total</span><span style="color: #0000FF;">=</span><span style="color: #000000;">21</span> <span style="color: #008080;">then</span> <span style="color: #000000;">title</span> <span style="color: #0000FF;">&=</span> <span style="color: #008000;">" you win"</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end while</lang>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
{{out}}
<span style="color: #008080;">if</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #008000;">','</span><span style="color: #0000FF;">,</span><span style="color: #000000;">title</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">and</span> <span style="color: #000000;">total</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">21</span> <span style="color: #008080;">then</span>
<pre>
<span style="color: #000080;font-style:italic;">-- computer move</span>
21 game
<span style="color: #004080;">sequence</span> <span style="color: #000000;">moves</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">rand</span><span style="color: #0000FF;">(</span><span style="color: #000000;">3</span><span style="color: #0000FF;">),</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">}</span>
 
<span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">moves</span><span style="color: #0000FF;">[</span><span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">total</span><span style="color: #0000FF;">,</span><span style="color: #000000;">4</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
Press escape or q to quit the game, c to concede and start a new game from 0
<span style="color: #000000;">total</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">n</span>
 
<span style="color: #000000;">title</span> <span style="color: #0000FF;">&=</span> <span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">" computer plays %d (-&gt; %d)"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">total</span><span style="color: #0000FF;">})</span>
Total is 0. enter 1, 2, or 3: 1
<span style="color: #008080;">if</span> <span style="color: #000000;">total</span><span style="color: #0000FF;">=</span><span style="color: #000000;">21</span> <span style="color: #008080;">then</span>
no clear strategy
<span style="color: #000000;">title</span> <span style="color: #0000FF;">&=</span> <span style="color: #008000;">", computer wins"</span>
Total is 1. I play 3.
<span style="color: #008080;">elsif</span> <span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">total</span><span style="color: #0000FF;">,</span><span style="color: #000000;">4</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span>
Total is 4. enter 1, 2, or 3: 1
<span style="color: #000000;">title</span> <span style="color: #0000FF;">&=</span> <span style="color: #008000;">", (you've already lost)"</span>
no clear strategy
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
Total is 5. I play 1.
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
Total is 6. enter 1, 2, or 3: 3
<span style="color: #008080;">if</span> <span style="color: #000000;">total</span><span style="color: #0000FF;">=</span><span style="color: #000000;">21</span> <span style="color: #008080;">then</span>
no clear strategy
<span style="color: #000000;">title</span> <span style="color: #0000FF;">&=</span> <span style="color: #008000;">" GAME OVER"</span>
Total is 9. I play 1.
<span style="color: #7060A8;">IupSetInt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">buttons</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #000000;">4</span><span style="color: #0000FF;">],</span><span style="color: #008000;">"ACTIVE"</span><span style="color: #0000FF;">,</span><span style="color: #004600;">false</span><span style="color: #0000FF;">)</span>
Total is 10. enter 1, 2, or 3: 1
<span style="color: #008080;">else</span>
Total is 11. I play 2.
<span style="color: #008080;">if</span> <span style="color: #000000;">total</span><span style="color: #0000FF;">></span><span style="color: #000000;">18</span> <span style="color: #008080;">then</span>
Total is 13. enter 1, 2, or 3: 3
<span style="color: #7060A8;">IupSetInt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">buttons</span><span style="color: #0000FF;">[</span><span style="color: #000000;">22</span><span style="color: #0000FF;">-</span><span style="color: #000000;">total</span><span style="color: #0000FF;">..</span><span style="color: #000000;">3</span><span style="color: #0000FF;">],</span><span style="color: #008000;">"ACTIVE"</span><span style="color: #0000FF;">,</span><span style="color: #004600;">false</span><span style="color: #0000FF;">)</span>
Total is 16. I play 1.
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
Total is 17. enter 1, 2, or 3: 2
<span style="color: #7060A8;">IupSetInt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">buttons</span><span style="color: #0000FF;">[</span><span style="color: #000000;">4</span><span style="color: #0000FF;">],</span><span style="color: #008000;">"ACTIVE"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">total</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">0</span><span style="color: #0000FF;">)</span>
Total is 19. I play 2.
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
21! I win!
<span style="color: #7060A8;">IupSetFocus</span><span style="color: #0000FF;">(</span><span style="color: #000000;">dlg</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- (stops inactive button beeping)</span>
Total is 0. enter 1, 2, or 3: q
<span style="color: #7060A8;">IupSetStrAttribute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">playstate</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"TITLE"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">title</span><span style="color: #0000FF;">)</span>
Quitting
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
</pre>
<span style="color: #008080;">return</span> <span style="color: #004600;">IUP_IGNORE</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">button_cb</span><span style="color: #0000FF;">(</span><span style="color: #004080;">Ihandle</span> <span style="color: #000000;">ih</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">title</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupGetAttribute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ih</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"TITLE"</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">play</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">title</span><span style="color: #0000FF;">,</span><span style="color: #000000;">button_text</span><span style="color: #0000FF;">))</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">cb_button</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">Icallback</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"button_cb"</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">key_cb</span><span style="color: #0000FF;">(</span><span style="color: #004080;">Ihandle</span> <span style="color: #000080;font-style:italic;">/*dlg*/</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">atom</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">=</span><span style="color: #004600;">K_ESC</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #004600;">IUP_CLOSE</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> <span style="color: #000080;font-style:italic;">-- (standard practice for me)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">=</span><span style="color: #004600;">K_F5</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #004600;">IUP_DEFAULT</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> <span style="color: #000080;font-style:italic;">-- (let browser reload work)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">=</span><span style="color: #004600;">K_F1</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #000000;">show_help</span><span style="color: #0000FF;">()</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">play</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">upper</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">),</span><span style="color: #008000;">"123CNQ"</span><span style="color: #0000FF;">))</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #7060A8;">IupOpen</span><span style="color: #0000FF;">()</span>
<span style="color: #000000;">playstate</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupLabel</span><span style="color: #0000FF;">(</span><span style="color: #008000;">""</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"EXPAND=HORIZONTAL, PADDING=10x10"</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">radioset</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">apply</span><span style="color: #0000FF;">(</span><span style="color: #004600;">true</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">IupToggle</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">radio_texts</span><span style="color: #0000FF;">,{</span><span style="color: #008000;">"RIGHTBUTTON=YES, CANFOCUS=NO"</span><span style="color: #0000FF;">}})</span>
<span style="color: #000000;">buttons</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">apply</span><span style="color: #0000FF;">(</span><span style="color: #004600;">true</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">IupButton</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">button_text</span><span style="color: #0000FF;">,</span><span style="color: #000000;">cb_button</span><span style="color: #0000FF;">,{</span><span style="color: #008000;">"PADDING=5x5"</span><span style="color: #0000FF;">}})</span>
<span style="color: #000000;">radios</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupRadio</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">IupHbox</span><span style="color: #0000FF;">(</span><span style="color: #000000;">radioset</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"GAP=45"</span><span style="color: #0000FF;">))</span>
<span style="color: #000000;">frame</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupHbox</span><span style="color: #0000FF;">({</span><span style="color: #7060A8;">IupLabel</span><span style="color: #0000FF;">(</span><span style="color: #008000;">`First Player:`</span><span style="color: #0000FF;">),</span><span style="color: #000000;">radios</span><span style="color: #0000FF;">},</span><span style="color: #008000;">"NORMALIZESIZE=VERTICAL"</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">vbox</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupVbox</span><span style="color: #0000FF;">({</span><span style="color: #000000;">frame</span><span style="color: #0000FF;">,</span><span style="color: #000000;">playstate</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">IupHbox</span><span style="color: #0000FF;">(</span><span style="color: #000000;">buttons</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"GAP=10"</span><span style="color: #0000FF;">)},</span><span style="color: #008000;">"MARGIN=20x10"</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">dlg</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupDialog</span><span style="color: #0000FF;">(</span><span style="color: #000000;">vbox</span><span style="color: #0000FF;">,</span><span style="color: #008000;">`TITLE="%s", MINSIZE=540x200`</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">title</span><span style="color: #0000FF;">})</span>
<span style="color: #7060A8;">IupShow</span><span style="color: #0000FF;">(</span><span style="color: #000000;">dlg</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">IupSetCallback</span><span style="color: #0000FF;">({</span><span style="color: #000000;">dlg</span><span style="color: #0000FF;">,</span><span style="color: #000000;">buttons</span><span style="color: #0000FF;">},</span><span style="color: #008000;">"KEY_CB"</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">Icallback</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"key_cb"</span><span style="color: #0000FF;">))</span>
<span style="color: #7060A8;">IupSetAttributeHandle</span><span style="color: #0000FF;">(</span><span style="color: #004600;">NULL</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"PARENTDIALOG"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">dlg</span><span style="color: #0000FF;">)</span>
<span style="color: #0000FF;">{}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">play</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"new game"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">button_text</span><span style="color: #0000FF;">))</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">platform</span><span style="color: #0000FF;">()!=</span><span style="color: #004600;">JS</span> <span style="color: #008080;">then</span>
<span style="color: #7060A8;">IupMainLoop</span><span style="color: #0000FF;">()</span>
<span style="color: #7060A8;">IupClose</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<!--</syntaxhighlight>-->
 
=={{header|PHP}}==
The solution as a server-side PHP7 script and HTML5.
<langsyntaxhighlight PHPlang="php"><!DOCTYPE html>
<html lang="en">
 
Line 2,807 ⟶ 5,410:
?>
 
</body></langsyntaxhighlight>
 
=={{header|Picat}}==
{{trans|Julia}}
<syntaxhighlight lang="picat">import util.
 
main =>
N = 0,
Level = prompt("Level of play (1=dumb, 3=smart)"),
Algo = choosewisely,
if Level == "1" then
Algo := choosefoolishly
elseif Level == "2" then
Algo := choosesemiwisely
elseif Level != "3" then
println("Bad choice syntax--default to smart choice")
end,
Whofirst = prompt("Does computer go first? (y or n)"),
if Whofirst[1] == 'y' || Whofirst[1] == 'Y' then
N := apply(Algo, N)
end,
while (N < 21)
N := playermove(N),
if N == 21 then
println("Player wins! Game over, gg!"),
halt
end,
N := apply(Algo,N)
end.
trytowin(N) =>
if 21 - N < 4 then
printf("Computer chooses %w and wins. GG!\n", 21 - N),
halt
end.
 
choosewisely(N) = NextN =>
trytowin(N),
Targets = [1, 5, 9, 13, 17, 21],
once ((member(Target, Targets), Target > N)),
Bestmove = Target - N,
if Bestmove > 3 then
printf("Looks like I could lose. Choosing a 1, total now %w.\n", N + 1),
NextN = N+1
else
printf("On a roll, choosing a %w, total now %w.\n", Bestmove, N + Bestmove),
NextN = N + Bestmove
end.
choosefoolishly(N) = NextN =>
trytowin(N),
Move = random() mod 3 + 1,
printf("Here goes, choosing %w, total now %w.", Move, N+Move),
NextN = N+Move.
choosesemiwisely(N) = NextN =>
trytowin(N),
if frand() > 0.75 then
NextN = choosefoolishly(N)
else
NextN = choosewisely(N)
end.
prompt(S) = Input =>
printf(S ++ ": => "),
Input = strip(read_line()).
playermove(N) = NextN =>
Rang = cond(N > 19, "1 is all", cond(N > 18, "1 or 2", "1, 2 or 3")),
Prompt = to_fstring("Your choice (%s), 0 to exit", Rang),
Nstr = prompt(Prompt),
if Nstr == "0" then
halt
elseif Nstr == "1" then
NextN = N+1
elseif Nstr == "2" && N < 20 then
NextN = N + 2
elseif Nstr == "3" && N < 19 then
NextN = N + 3
else
NextN = playermove(N)
end.
</syntaxhighlight>
 
=={{header|Python}}==
===Python: Original, with output===
 
{{works with|Python 2.X and 3.X}}
<langsyntaxhighlight lang="python">
from random import randint
def start():
Line 2,874 ⟶ 5,560:
print("Computer wins {0} game, human wins {1} games".format(c,m))
t = raw_input("Another game?(press y to continue):")
r = (t=="y")</langsyntaxhighlight>
 
{{out}}
Line 3,004 ⟶ 5,690:
Your choice 1 to 3 :q
OK,quitting the game
</pre>
 
===Python: using tkinter===
<syntaxhighlight lang="python">
''' Python 3.6.5 code using Tkinter graphical user interface.
Starting player chosen randomly. '''
from tkinter import *
from tkinter import messagebox
import random
 
# ************************************************
 
class Game:
def __init__(self, gw):
self.window = gw
self.won = 0
self.lost = 0
self.score = 0
self.puter_turn = None
self.var123 = IntVar()
self.varsub = IntVar()
 
# top frame:
self.top_fr = Frame(gw,
width=600,
height=100,
bg='dodger blue')
self.top_fr.pack(fill=X)
 
self.hdg = Label(self.top_fr,
text=' 21 Game ',
font='arial 22 bold',
fg='navy',
bg='lemon chiffon')
self.hdg.place(relx=0.5, rely=0.5,
anchor=CENTER)
 
self.play_btn = Button(self.top_fr,
text='Play\nGame',
bd=5,
bg='navy',
fg='lemon chiffon',
font='arial 12 bold',
command=self.play_game)
self.play_btn.place(relx=0.92, rely=0.5,
anchor=E)
 
self.quit_btn = Button(self.top_fr,
text='Quit\nGame',
bd=5,
bg='navy',
fg='lemon chiffon',
font='arial 12 bold',
command=self.quit_game)
self.quit_btn.place(relx=0.07, rely=0.5,
anchor=W)
 
# bottom frame:
self.btm_fr = Frame(gw,
width=600,
height=500,
bg='lemon chiffon')
self.btm_fr.pack(fill=X)
 
self.msg = Label(self.btm_fr,
text="(Click 'Play' or 'Quit')",
font='arial 16 bold',
fg='navy',
bg='lemon chiffon')
self.msg.place(relx=0.5, rely=0.1,
anchor=CENTER)
 
self.hdg = Label(self.btm_fr,
text="Scoreboard",
font='arial 16 bold',
fg='navy',
bg='lemon chiffon')
self.hdg.place(relx=0.5, rely=0.2,
anchor=CENTER)
 
self.score_msg = Label(self.btm_fr,
text="0",
font='arial 16 bold',
fg='navy',
bg='dodger blue',
width=8)
self.score_msg.place(relx=0.5, rely=0.27,
anchor=CENTER)
 
self.ch_fr = LabelFrame(self.btm_fr,
text='Choose a number',
bg='dodger blue',
fg='navy',
bd=8,
relief=RIDGE,
font='arial 16 bold')
self.ch_fr.place(relx=0.5, rely=0.5,
anchor=CENTER)
 
self.radio1 = Radiobutton(self.ch_fr,
text='1',
state='disabled',
font='arial 16 bold',
fg='navy',
bg='dodger blue',
variable=self.var123,
value=1)
self.radio1.pack()
 
self.radio2 = Radiobutton(self.ch_fr,
text='2',
state='disabled',
font='arial 16 bold',
fg='navy',
bg='dodger blue',
variable=self.var123,
value=2)
self.radio2.pack()
 
self.radio3 = Radiobutton(self.ch_fr,
text='3',
state='disabled',
font='arial 16 bold ',
fg='navy',
bg='dodger blue',
variable=self.var123,
value=3)
self.radio3.pack()
 
self.submit_btn = Button(self.btm_fr,
text='SUBMIT',
state='disabled',
bd=5,
bg='navy',
fg='lemon chiffon',
font='arial 12 bold',
command=self.submit)
self.submit_btn.place(relx=0.5, rely=0.75,
anchor=CENTER)
 
self.won_lbl = Label(self.btm_fr,
text="Won: 0",
font='arial 16 bold',
fg='navy',
bg='lemon chiffon')
self.won_lbl.place(relx=0.85, rely=0.88,
anchor=W)
 
self.lost_lbl = Label(self.btm_fr,
text="Lost: 0",
font='arial 16 bold',
fg='navy',
bg='lemon chiffon')
self.lost_lbl.place(relx=0.85, rely=0.93,
anchor=W)
 
# play one game:
def play_game(self):
self.play_btn.config(state='disabled')
# pick who goes first randomly:
self.puter_turn = random.choice([True, False])
self.score = 0
self.score_msg.config(text=self.score)
if not self.puter_turn:
m = 'your turn'
self.msg.config(text=m)
# alternate turns until 21 is reached:
while self.score != 21:
if self.puter_turn:
self.puter_plays()
else:
self.user_plays()
self.puter_turn = not self.puter_turn
self.play_btn.config(state='normal')
return
 
# computer picks a number:
def puter_plays(self):
if self.score == 20:
x = 1
elif self.score == 19:
x = random.choice([1, 2])
else:
x = random.choice([1, 2, 3])
self.score += x
self.score_msg.config(text=self.score)
if self.score == 21:
m = 'Computer won!'
self.lost += 1
self.lost_lbl.config(text='Lost: ' + str(self.lost))
else:
m = 'Computer chose ' + str(x) + ', your turn'
self.msg.config(text=m)
return
 
# user picks a number:
def user_plays(self):
self.set_user_state('normal')
while True:
# wait for submit button to be pressed:
self.submit_btn.wait_variable(self.varsub)
x = self.var123.get()
if x + self.score > 21:
m = 'Score cannot exceed 21, try again'
messagebox.showerror('Error', m)
elif x not in (1,2,3):
m = 'No selection made'
messagebox.showerror('Error', m)
else:
break
self.score += x
if self.score == 21:
m = 'You won!'
self.msg.config(text=m)
self.score_msg.config(text=self.score)
self.won += 1
self.won_lbl.config(text='Won: ' + str(self.won))
# reset and disable radio buttons:
self.var123.set(0)
self.set_user_state('disabled')
return
 
# set radio buttons to 'disabled' or 'normal':
def set_user_state(self, state):
self.radio1.config(state=state)
self.radio2.config(state=state)
self.radio3.config(state=state)
self.submit_btn.config(state=state)
return
def quit_game(self):
self.window.destroy()
 
# indicate that submit button was pressed:
def submit(self):
self.varsub.set(0)
 
# ************************************************
 
root = Tk()
root.title('21 Game')
root.geometry('600x600+100+50')
root.resizable(False, False)
g = Game(root)
root.mainloop()
</syntaxhighlight>
 
=={{header|Quackery}}==
 
<syntaxhighlight lang="quackery"> [ say
"Who goes first: Computer, Player"
say " or Random?" cr
[ $ "Enter C, P or R: " input
dup size 1 != iff drop again
0 peek
dup char C = iff [ drop 0 ] done
dup char P = iff [ drop 1 ] done
char R = iff [ 2 random ] done
again ]
cr
dup iff [ say "You go first." ]
else [ say "I will go first." ]
cr ] is chooseplayer ( --> n )
 
forward is player ( n --> n x )
 
[ [ dup 17 > iff 1 done
4 over 4 mod
dup 0 = if [ drop 3 ]
- ]
dup say "Computer chooses " echo
say "." cr
+ ' player ] is computer ( n --> n x )
 
[ say "Choose 1 2 or 3 (running "
$ "total must not exceed 21, Q to quit): " input
dup $ "Q" = iff [ drop 21 999 ] done
trim reverse trim reverse
$->n not iff drop again
dup 1 4 within not iff drop again
2dup + 21 > iff drop again
+ ' computer ] resolves player ( n --> n x )
 
[ say "The player who makes 21 loses." cr
0 chooseplayer
iff [ ' player ] else [ ' computer ]
[ say "Running total is "
over echo say "." cr cr
do
over 21 = until ]
cr
dup 999 = iff
[ drop 2drop say "Quitter!" ] done
' computer = iff
[ say "The computer won!" ]
else [ say "You won! Well done!" ]
drop ] is play ( --> )</syntaxhighlight>
 
{{out}}
 
As a dialogue in the Quackery shell.
 
<pre>/O> play
...
The player who makes 21 loses.
Who goes first: Computer, Player or Random?
Enter C, P or R: C
 
I will go first.
Running total is 0.
 
Computer chooses 1.
Running total is 1.
 
Choose 1 2 or 3 (running total must not exceed 21, Q to quit): Q
 
Quitter!
Stack empty.
 
/O> play
...
The player who makes 21 loses.
Who goes first: Computer, Player or Random?
Enter C, P or R: R
 
You go first.
Running total is 0.
 
Choose 1 2 or 3 (running total must not exceed 21, Q to quit): 2
Running total is 2.
 
Computer chooses 2.
Running total is 4.
 
Choose 1 2 or 3 (running total must not exceed 21, Q to quit): 3
Running total is 7.
 
Computer chooses 1.
Running total is 8.
 
Choose 1 2 or 3 (running total must not exceed 21, Q to quit): 1
Running total is 9.
 
Computer chooses 3.
Running total is 12.
 
Choose 1 2 or 3 (running total must not exceed 21, Q to quit): 4
Choose 1 2 or 3 (running total must not exceed 21, Q to quit): 1
Running total is 13.
 
Computer chooses 3.
Running total is 16.
 
Choose 1 2 or 3 (running total must not exceed 21, Q to quit): 3
Running total is 19.
 
Computer chooses 1.
Running total is 20.
 
Choose 1 2 or 3 (running total must not exceed 21, Q to quit): 2
Choose 1 2 or 3 (running total must not exceed 21, Q to quit): 1
 
The computer won!
Stack empty.
 
/O> </pre>
 
=={{header|R}}==
<syntaxhighlight lang="r">game21<-function(first = c("player","ai","random"),sleep=.5){
state = 0
finished = F
turn = 1
if(length(first)==1 && startsWith(tolower(first),"r")){
first = rbinom(1,1,.5)
}else{
first = (length(first)>1 || startsWith(tolower(first),"p"))
}
while(!finished){
if(turn>1 || first){
cat("The total is now",state,"\n");Sys.sleep(sleep)
while(T){
player.move = readline(prompt = "Enter move: ")
if((player.move=="1"||player.move=="2"||player.move=="3") && state+as.numeric(player.move)<=21){
player.move = as.numeric(player.move)
state = state + player.move
break
}else if(tolower(player.move)=="exit"|tolower(player.move)=="quit"|tolower(player.move)=="end"){
cat("Goodbye.\n")
finished = T
break
}else{
cat("Error: invaid entry.\n")
}
}
}
if(state == 21){
cat("You win!\n")
finished = T
}
if(!finished){
cat("The total is now",state,"\n");Sys.sleep(sleep)
while(T){
ai.move = sample(1:3,1)
if(state+ai.move<=21){
break
}
}
state = state + ai.move
cat("The AI chooses",ai.move,"\n");Sys.sleep(sleep)
if(state == 21){
cat("The AI wins!\n")
finished = T
}
}
turn = turn + 1
}
}</syntaxhighlight>
 
<syntaxhighlight lang="text">game21()</syntaxhighlight>
{{out}}
<pre>The total is now 0
Enter move: 3
The total is now 3
The AI chooses 2
The total is now 5
Enter move: 3
The total is now 8
The AI chooses 3
The total is now 11
Enter move: 3
The total is now 14
The AI chooses 2
The total is now 16
Enter move: 1
The total is now 17
The AI chooses 3
The total is now 20
Enter move: 1
The total is now 21
You win!</pre>
 
<syntaxhighlight lang="r">game21(first = "ai")</syntaxhighlight>
{{out}}
<pre>The total is now 0
The AI chooses 2
The total is now 2
Enter move: quit
Goodbye.
</pre>
 
=={{header|Racket}}==
 
<langsyntaxhighlight lang="racket">#lang racket
 
(define limit 21)
Line 3,043 ⟶ 6,179:
[(= new-total limit) (win human-turn?)]
[(> new-total limit) (win (not human-turn?))]
[else (loop new-total (not human-turn?))]))</langsyntaxhighlight>
 
{{out}}
Line 3,092 ⟶ 6,228:
{{works with|Rakudo|2018.09}}
Since there is no requirement that the computer play sensibly, it always plays a random guess so the player has some chance to win.
<syntaxhighlight lang="raku" perl6line>say qq :to 'HERE';
The 21 game. Each player chooses to add 1, 2, or 3 to a running total.
The player whose turn it is when the total reaches 21 wins. Enter q to quit.
Line 3,122 ⟶ 6,258:
print ('Yo mama,', 'Jeez,', 'Ummmm,', 'Grow up,', 'Did you even READ the instructions?').roll;
say " $g is not an integer between 1 & 3..."
}</langsyntaxhighlight>
{{out|Sample game}}
<pre>The 21 game. Each player chooses to add 1, 2, or 3 to a running total.
Line 3,157 ⟶ 6,293:
 
This REXX version allows the user to choose if the computer should go first.
<langsyntaxhighlight lang="rexx">/*REXX program plays the 21 game with a human, each player chooses 1, 2, or 3 which */
/*──────────── is added to the current sum, the first player to reach 21 exactly wins.*/
sep= copies('─', 8); sep2= " "copies('═', 8)" " /*construct an eye─catching msg fences.*/
Line 3,166 ⟶ 6,302:
if $==goal then leave /*the user won the game with the last #*/
call ?; if y==. then y= random(1, 3) /*get computer's choice or a random #*/
say sep 'The computer chooses ' y " as it'sits choice." /*inform player.*/
call tot y, 0 /*call subroutine to show the total. */
end /*j*/
Line 3,193 ⟶ 6,329:
if bad then iterate /*Had an error? Then get another number*/
x= x/1; if $+x>goal then call ser "Number will cause the sum to exceed " goal': ' x
end /*until*/; return</langsyntaxhighlight>
{{out|output|text=''':'''}}
<pre>
Line 3,202 ⟶ 6,338:
3 ◄■■■■■■■■■■ user input
──────── The game total is now ════════ 3 ════════
──────── The computer chooses 2 as it'sits choice.
──────── The game total is now ════════ 5 ════════
 
Line 3,208 ⟶ 6,344:
3 ◄■■■■■■■■■■ user input
──────── The game total is now ════════ 8 ════════
──────── The computer chooses 1 as it'sits choice.
──────── The game total is now ════════ 9 ════════
 
Line 3,214 ⟶ 6,350:
3 ◄■■■■■■■■■■ user input
──────── The game total is now ════════ 12 ════════
──────── The computer chooses 1 as it'sits choice.
──────── The game total is now ════════ 13 ════════
 
Line 3,220 ⟶ 6,356:
3 ◄■■■■■■■■■■ user input
──────── The game total is now ════════ 16 ════════
──────── The computer chooses 1 as it'sits choice.
──────── The game total is now ════════ 17 ════════
 
Line 3,226 ⟶ 6,362:
1 ◄■■■■■■■■■■ user input
──────── The game total is now ════════ 18 ════════
──────── The computer chooses 3 as it'sits choice.
──────── The game total is now ════════ 21 ════════
 
Line 3,233 ⟶ 6,369:
 
=={{header|Ring}}==
<langsyntaxhighlight lang="ring">
# Project : 21 Game
 
Line 3,342 ⟶ 6,478:
}
}
</syntaxhighlight>
</lang>
Output:<br>
[http://kepkezelo.com/images/1hyutakip6vo1t1rpypy.jpg 21 Game]
 
=={{header|Ruby}}==
<syntaxhighlight lang="ruby">
<lang Ruby>
# 21 Game - an example in Ruby for Rosetta Code.
 
Line 3,454 ⟶ 6,590:
end
puts 'Good bye!'
</syntaxhighlight>
</lang>
 
=={{header|rustRust}}==
<langsyntaxhighlight lang="rust">use rand::Rng;
use std::io;
 
Line 3,682 ⟶ 6,818:
println!("player: {} win: {}", players[1].get_name(), players[1].wins);
}
</syntaxhighlight>
</lang>
 
=={{header|Scala}}==
<syntaxhighlight lang="scala">
object Game21 {
 
import scala.collection.mutable.ListBuffer
import scala.util.Random
 
val N = 21 // the same game would also work for N other than 21...
 
val RND = new Random() // singular random number generator; add a seed number, if you want reproducibility
 
/** tuple: name and a play function: (rest: remaining number, last: value of opponent's last move) => new move
*/
type Player = (String, (Int,Int) => Int)
 
// indeed, the following could also be written using a class and instances, I've choosen a
// more functional and math way (using tuples)...
val playerRandom:Player = ("RandomRobot", { (rest, last) =>
if (rest <= 3) rest
else 1 + RND.nextInt(3)
})
val playerBest:Player = ("BestRobot", { (rest, last) =>
val i = rest % 4
if (i > 0) i else 1 + RND.nextInt(3)
})
val playerHuman:Player = ("YOU", { (rest, last) =>
println("Rest: "+rest)
println("Last: "+last)
var in = ""
while (in!="1" && in!="2" && in!="3") {
in = scala.io.StdIn.readLine("Your move (1,2,3,q)> ").trim
if ("q" == in)
throw new Exception("q => quit")
}
in.toInt
})
 
/** Execute a whole game. NOTE that we're counting DOWN from N to 0!
* @param players
* @return list of all moves
*/
def play(players:Seq[Player]):Seq[Int] = {
require(players.size == 2)
var last = -1
var rest = N
var p = 0 // player 0 always starts
val l = ListBuffer[Int]() // list of all moves
while (rest > 0) {
last = players(p)._2(rest,last)
require(1<=last && last<=3,"Player must always play 1,2,3: "+last)
l += last
rest -= last
p = 1 - p // other player's turn
}
l.toSeq
}
 
/** Evaluate a whole game.
* @param game list of moves of one game
* @param rest mainly for recursion
* @return evaluation, for each move a tuple: (rest, what was played, whether this player won in the end)
*/
def evaluate(game:Seq[Int],rest:Int=N):Seq[(Int,Int,Boolean)] = {
if (game.size == 0) Seq()
else Seq((rest,game.head,game.size%2 == 1)) ++ evaluate(game.tail,rest - game.head)
}
 
def main(args: Array[String]): Unit = {
// here you can put whatever player combination you like
val players = Seq(playerRandom,playerRandom) // random robot vs random robot
//val players = Seq(playerRandom,playerBest) // random robot vs best robot
//val players = Seq(playerHuman,playerBest) // You vs best robot
var p0won = 0
val n = 1000 // number of games to play
var m = 0 // games actually played (a human player might quit before n)
try {
(1 to n).foreach { i =>
val g = play(players)
require(g.sum == N) // some validity checks
val e = evaluate(g)
require(e.size == g.size && e.last._3 && e(0)._3 != e(1)._3) // some validity checks
if (e(0)._3) p0won += 1
m += 1
println(i + ": " + players(0)._1 + " " + (if (e(0)._3) "won" else "lost") + " against " + players(1)._1 + ". " + g + " => " + e)
}
} catch {
case t:Throwable => println(t.getMessage)
}
println("Player0: "+players(0)._1)
println("Player1: "+players(1)._1)
println(f"Player0 won ${p0won} times out of ${m}, or ${p0won * 100.0 / m}%%")
}
}
</syntaxhighlight>
 
=={{header|uBasic/4tH}}==
{{trans|FreeBASIC}}
<syntaxhighlight lang="text">dim @p(4)
 
push 1, 1, 3, 2
for i = 3 to 0 step -1 : @p(i) = pop() : next
a = 0 : t = rnd(2)
do while s < 21
t = 1 - t
print using "The sum is _#"; s
if t = 1 then
print "It is your turn."
do
while (a < 1) + (a > 3) + (a+s > 21)
input "How many would you like to add? ", a
loop
else
print "It is the computer's turn."
a = @p(s % 4)
print using "The computer adds #."; a
endif
 
print
s = s + a
a = 0
loop
if t = 1 then
print "Congratulations. You win."
else
print "Bad luck. The computer wins."
endif</syntaxhighlight>
=={{header|Visual Basic .NET}}==
 
Line 3,694 ⟶ 6,958:
<p>
The file MainWindow.xaml.vb with Visual Basic source code.
</p><langsyntaxhighlight lang="vbnet">' Game 21 in VB.NET - an example for Rosetta Code
 
Class MainWindow
Line 3,757 ⟶ 7,021:
End If
End Sub
End Class</langsyntaxhighlight>
<p>
The file MainWindow.xaml with GUI source code written in XAML.
</p><langsyntaxhighlight lang="xml"><Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Line 3,789 ⟶ 7,053:
</Grid>
</Window>
</syntaxhighlight>
</lang>
 
=={{header|V (Vlang)}}==
{{trans|Go}}
<syntaxhighlight lang="v (vlang)">import os
import rand
import rand.seed
import strconv
 
fn get_choice(mut total &int) bool {
for {
text := os.input("Your choice 1 to 3 : ")
if text == "q" || text == "Q" {
return true
}
input := strconv.atoi(text) or {-1}
if input == -1 {
println("Invalid number, try again")
continue
}
new_total := *total + input
match true {
input < 1 || input > 3 {
println("Out of range, try again")
}
new_total > 21 {
println("Too big, try again")
}
else {
total = new_total
println("Running total is now ${*total}")
return false
}
}
}
return false
}
fn main() {
rand.seed(seed.time_seed_array(2))
mut computer := rand.intn(2) or {0} != 0
println("Enter q to quit at any time\n")
if computer {
println("The computer will choose first")
} else {
println("You will choose first")
}
println("\nRunning total is now 0\n")
mut choice := 0
mut total := 0
for round := 1; ; round++ {
println("ROUND $round:\n")
for i := 0; i < 2; i++ {
if computer {
if total < 18 {
choice = 1 + rand.intn(3) or {1}
} else {
choice = 21 - total
}
total += choice
println("The computer chooses $choice")
println("Running total is now $total")
if total == 21 {
println("\nSo, commiserations, the computer has won!")
return
}
} else {
quit := get_choice(mut total)
if quit {
println("OK, quitting the game")
return
}
if total == 21 {
println("\nSo, congratulations, you've won!")
return
}
}
println('')
computer = !computer
}
}
}</syntaxhighlight>
 
{{out}}
Sample game:
<pre>
Enter 0 to quit at any time
 
You will choose first
 
Running total is now 0
 
ROUND 1:
 
Your choice 1 to 3: 3
Running total is now 3
 
The computer chooses 2
Running total is now 5
 
ROUND 2:
 
Your choice 1 to 3: 3
Running total is now 8
 
The computer chooses 1
Running total is now 9
 
ROUND 3:
 
Your choice 1 to 3: 3
Running total is now 12
 
The computer chooses 3
Running total is now 15
 
ROUND 4:
 
Your choice 1 to 3: 2
Running total is now 17
 
The computer chooses 3
Running total is now 20
 
ROUND 5:
 
Your choice 1 to 3: 1
Running total is now 21
 
So, congratulations, you've won!
</pre>
 
=={{header|Wren}}==
{{trans|Go}}
{{libheader|Wren-fmt}}
{{libheader|Wren-ioutil}}
<syntaxhighlight lang="wren">import "./fmt" for Conv
import "./ioutil" for Input
import "random" for Random
 
var total = 0
var quit = false
 
var getChoice = Fn.new {
while (true) {
var input = Input.integer("Your choice 1 to 3: ", 0, 3)
if (input == 0) {
quit = true
return
}
var newTotal = total + input
if (newTotal > 21) {
System.print("Too big, try again")
} else {
total = newTotal
System.print("Running total is now %(total)")
return
}
}
}
 
var rand = Random.new()
var computer = Conv.itob(rand.int(2))
System.print("Enter 0 to quit at any time\n")
if (computer) {
System.print("The computer will choose first")
} else {
System.print("You will choose first")
}
System.print("\nRunning total is now 0\n")
var round = 1
while (true) {
System.print("ROUND %(round):\n")
for (i in 0..1) {
if (computer) {
var choice = (total < 18) ? 1 + rand.int(3) : 21 - total
total = total + choice
System.print("The computer chooses %(choice)")
System.print("Running total is now %(total)")
if (total == 21) {
System.print("\nSo, commiserations, the computer has won!")
return
}
} else {
getChoice.call()
if (quit) {
System.print("OK, quitting the game")
return
}
if (total == 21) {
System.print("\nSo, congratulations, you've won!")
return
}
}
System.print()
computer = !computer
}
round = round + 1
}</syntaxhighlight>
 
{{out}}
Sample game:
<pre>
Enter 0 to quit at any time
 
You will choose first
 
Running total is now 0
 
ROUND 1:
 
Your choice 1 to 3: 3
Running total is now 3
 
The computer chooses 2
Running total is now 5
 
ROUND 2:
 
Your choice 1 to 3: 3
Running total is now 8
 
The computer chooses 1
Running total is now 9
 
ROUND 3:
 
Your choice 1 to 3: 3
Running total is now 12
 
The computer chooses 3
Running total is now 15
 
ROUND 4:
 
Your choice 1 to 3: 2
Running total is now 17
 
The computer chooses 3
Running total is now 20
 
ROUND 5:
 
Your choice 1 to 3: 1
Running total is now 21
 
So, congratulations, you've won!
</pre>
2,056

edits