Nim game: Difference between revisions

10,980 bytes added ,  2 months ago
Added various BASIC dialects (Chipmunk Basic, Minimal BASIC, MSX Basic and Quite BASIC)
(Dialects of BASIC moved to the BASIC section.)
(Added various BASIC dialects (Chipmunk Basic, Minimal BASIC, MSX Basic and Quite BASIC))
(7 intermediate revisions by 6 users not shown)
Line 722:
<syntaxhighlight lang="applesoftbasic">0ST$(0)="YOU MUST TAKE 1, 2, OR 3 TOKENS.":FORHEAP=12TO1STEP-4:PRINT"THERE ARE "HEAP" TOKENS REMAINING.":FORI=0TO1:INPUT"HOW MANY WOULD YOU LIKE TO TAKE?";T%:I=T%>0ANDT%<4:PRINTST$(I):NEXTI:PRINT"ON MY TURN I WILL TAKE "4-T%" TOKENS.":NEXTHEAP</syntaxhighlight>
 
==={{header|Craft BasicBASIC256}}===
{{works with|BASIC256|1.99.99.14+}}
<syntaxhighlight lang="basic">title "NIM"
<syntaxhighlight lang="basic">monton = 12
llevar = 0
 
while monton > 0
bgcolor 0,180,0
print "There are "; monton; " tokens remaining. How many would you like to take? ";
cls
input integer llevar
wait
while llevar = 0 or llevar > 3
print "You must take 1, 2, or 3 tokens. How many would you like to take ";
input integer llevar
end while
 
print "On my turn I will take "; 4 - llevar; " token(s)."
let h = 12
monton = monton - 4
end while
 
print
print "I got the last token. I win! Better luck next time."
end</syntaxhighlight>
 
==={{header|Chipmunk Basic}}===
{{trans|FreeBASIC}}
{{works with|Chipmunk Basic|3.6.4}}
<syntaxhighlight lang="vbnet">100 cls
110 monton = 12
120 llevar = 0
130 do while monton > 0
140 print using "There are ## tokens remaining. How many would you like to take";monton;
150 input llevar
160 do while llevar = 0 or llevar > 3
170 input "You must take 1, 2, or 3 tokens. How many would you like to take";llevar
180 loop
190 print "On my turn I will take";4-llevar;" token(s)."
200 monton = monton-4
210 loop
220 print
230 print "I got the last token. I win! Better luck next time."
240 end</syntaxhighlight>
 
==={{header|Craft Basic}}===
<syntaxhighlight lang="basic">let h = 12
 
label loop
 
printalert "There are ", h ," tokens remaining."
input "How many would you like to take? ", t
 
if t > 3 or t < 1 then
 
printalert "You must take between 1 to 3 tokens."
 
endif
Line 744 ⟶ 778:
if h - t < 0 then
 
printalert "You cannot take that many. There's only ", h ," left."
 
endif
Line 773 ⟶ 807:
endif
 
printalert "I will take ", t ," tokens."
let h = h - t
 
Line 928 ⟶ 962:
320 PRINT "You win!"
330 END IF</syntaxhighlight>
 
==={{header|Minimal BASIC}}===
{{trans|Tiny BASIC}}
{{works with|BASICA}}
{{works with|Chipmunk Basic}}
{{works with|GW-BASIC}}
{{works with|MSX BASIC}}
{{works with|PC-BASIC|any}}
{{works with|QBasic}}
<syntaxhighlight lang="qbasic">10 LET H = 12
20 PRINT "There are"
30 PRINT H
40 PRINT "tokens remaining. How many would you like to take?"
50 INPUT T
60 IF T > 3 THEN 170
70 IF T < 1 THEN 170
80 LET H = H - T
90 IF H = 0 THEN 190
100 LET T = 4 - T
110 PRINT "I will take"
120 PRINT T
130 PRINT "tokens."
140 LET H = H - T
150 IF H = 0 THEN 210
160 GOTO 20
170 PRINT "You must take 1, 2, or 3 tokens."
180 GOTO 50
190 PRINT "Congratulations. You got the last token."
200 GOTO 220
210 PRINT "I got the last token. I win. Better luck next time."
220 END</syntaxhighlight>
 
==={{header|MSX Basic}}===
{{works with|MSX BASIC|any}}
{{works with|Applesoft BASIC}}
{{works with|BASICA}}
{{works with|Chipmunk Basic}}
{{works with|GW-BASIC}}
{{works with|PC-BASIC|any}}
{{works with|QBasic}}
<syntaxhighlight lang="qbasic">100 CLS : rem 100 HOME for Applesoft BASIC
110 LET M = 12
120 LET L = 0
130 IF M <= 0 THEN GOTO 220
140 PRINT "There are "; M; " tokens remaining. How many would you like to take";
150 INPUT L
160 IF L <> 0 AND L <= 3 THEN GOTO 190
170 PRINT "You must take 1, 2, or 3 tokens. How many would you like to take";
180 GOTO 150
190 PRINT "On my turn I will take "; 4 - L; " token(s)."
200 LET M = M - 4
210 GOTO 130
220 PRINT
230 PRINT "I got the last token. I win! Better luck next time."
240 END</syntaxhighlight>
 
==={{header|PureBasic}}===
<syntaxhighlight lang="PureBasic">OpenConsole()
Define monton.i = 12, llevar.i
 
While monton > 0
Print("There are " + Str(monton) + " tokens remaining. How many would you like to take? ")
llevar = Val(Input())
While llevar = 0 Or llevar > 3
Print("You must take 1, 2, or 3 tokens. How many would you like to take ")
llevar = Val(Input())
Wend
PrintN("On my turn I will take " + Str(4 - llevar) + " token(s).")
monton = monton - 4
Wend
 
PrintN("I got the last token. I win! Better luck next time.")
 
PrintN(#CRLF$ + "--- terminado, pulsa RETURN---"): Input()
CloseConsole()</syntaxhighlight>
 
==={{header|QBasic}}===
{{works with|QBasic|1.1}}
{{works with|QuickBasic|4.5}}
<syntaxhighlight lang="qbasic">monton = 12
llevar = 0
 
DO WHILE monton > 0
PRINT USING "There are ## tokens remaining. How many would you like to take"; monton;
INPUT llevar
DO WHILE llevar = 0 OR llevar > 3
INPUT "You must take 1, 2, or 3 tokens. How many would you like to take"; llevar
LOOP
PRINT "On my turn I will take"; 4 - llevar; " token(s)."
monton = monton - 4
LOOP
 
PRINT
PRINT "I got the last token. I win! Better luck next time."
END</syntaxhighlight>
 
==={{header|Quite BASIC}}===
{{trans|Minimal BASIC}}
{{works with|BASICA}}
{{works with|Chipmunk Basic}}
{{works with|GW-BASIC}}
{{works with|MSX BASIC}}
{{works with|PC-BASIC|any}}
{{works with|QBasic}}
<syntaxhighlight lang="qbasic">10 LET H = 12
20 PRINT "There are"
30 PRINT H
40 PRINT "tokens remaining. How many would you like to take?"
50 INPUT ""; T
60 IF T > 3 THEN 170
70 IF T < 1 THEN 170
80 LET H = H - T
90 IF H = 0 THEN 190
100 LET T = 4 - T
110 PRINT "I will take"
120 PRINT T
130 PRINT "tokens."
140 LET H = H - T
150 IF H = 0 THEN 210
160 GOTO 20
170 PRINT "You must take 1, 2, or 3 tokens."
180 GOTO 50
190 PRINT "Congratulations. You got the last token."
200 GOTO 220
210 PRINT "I got the last token. I win. Better luck next time."
220 END</syntaxhighlight>
 
==={{header|Run BASIC}}===
{{works with|Just BASIC}}
{{works with|Liberty BASIC}}
<syntaxhighlight lang="vb">monton = 12
llevar = 0
 
while monton > 0
input "There are "; monton; " tokens remaining. How many would you like to take? "; llevar
while llevar = 0 or llevar > 3
input "You must take 1, 2, or 3 tokens. How many would you like to take "; llevar
wend
 
print "On my turn I will take "; 4 - llevar; " token(s)."
monton = monton - 4
wend
 
print
print "I got the last token. I win! Better luck next time."
end</syntaxhighlight>
 
==={{header|S-Basic}}===
Line 1,062 ⟶ 1,244:
210 PRINT "I got the last token. I win. Better luck next time."
220 END</syntaxhighlight>
 
==={{header|Tiny Craft Basic}}===
<syntaxhighlight lang="basic">5 cls
10 print "NIM"
20 let h = 12
30 print "There are ", h ," tokens remaining."
40 input "How many would you like to take? ", t
50 if t > 3 then 140
60 if t < 1 then 140
70 let h = h - t
80 if h = 0 then 160
90 let t = 4 - t
100 print "I will take ", t ," tokens."
110 let h = h - t
120 if h = 0 then 180
130 goto 30
140 print "You must take between 1 to 3 tokens."
150 goto 40
160 print "Congratulations. You got the last token."
170 goto 190
180 print "I got the last token. I win. Better luck next time."
190 shell "pause"</syntaxhighlight>
 
==={{header|True BASIC}}===
Line 1,107 ⟶ 1,267:
PRINT "Obtuve la última ficha. ¡Gané! Mejor suerte la próxima vez."
END</syntaxhighlight>
 
==={{header|Yabasic}}===
<syntaxhighlight lang="basic">monton = 12
llevar = 0
 
while monton > 0
print "There are ", monton, " tokens remaining. How many would you like to take? ";
input "" llevar
while llevar = 0 or llevar > 3
input "You must take 1, 2, or 3 tokens. How many would you like to take? " llevar
wend
print "On my turn I will take ", 4 - llevar, " token(s)."
monton = monton - 4
wend
 
print "\nI got the last token. I win! Better luck next time."
end</syntaxhighlight>
 
=={{header|BlooP}}==
Line 1,586 ⟶ 1,764:
 
print("I win again.")</syntaxhighlight>
 
=={{header|EasyLang}}==
[Run it]
{{Trans|BASIC256}}
<syntaxhighlight lang="easylang">
token = 12
while token > 0
repeat
print "There are " & token & " tokens remaining."
write "How many would you like to take? (1,2 or 3) "
h = number input
print h
until h >= 1 and h <= 3
.
sleep 1
print "On my turn I will take " & 4 - h & " token(s)."
print ""
token -= 4
.
print "I got the last token. I win! Better luck next time."
</syntaxhighlight>
 
=={{header|Factor}}==
Line 4,186 ⟶ 4,385:
=={{header|Wren}}==
{{trans|Go}}
<syntaxhighlight lang="ecmascriptwren">import "io" for Stdin, Stdout
 
var showTokens = Fn.new { |tokens| System.print("Tokens remaining %(tokens)\n") }
Line 4,238 ⟶ 4,437:
 
Computer wins!
</pre>
 
=={{header|XPL0}}==
{{trans|Go}}
<syntaxhighlight lang "XPL0">func ShowTokens(Tokens);
int Tokens;
[Text(0, "Tokens remaining: ");
IntOut(0, Tokens);
CrLf(0); CrLf(0);
];
 
int Tokens, T, CT;
[Tokens:= 12;
loop [ShowTokens(Tokens);
Text(0, " How many Tokens (1, 2 or 3)? ");
T:= IntIn(0);
if T < 1 or T > 3 then
Text(0, "^m^jMust be a number between 1 and 3. Try again.^m^j^m^j")
else [CT:= 4 - T;
Text(0, " Computer takes ");
IntOut(0, CT);
Text(0, " token");
if CT # 1 then ChOut(0, ^s);
Text(0, ".^m^j^m^j");
Tokens:= Tokens - 4;
];
if Tokens = 0 then
[ShowTokens(0);
Text(0, " Computer wins!^m^j");
return;
];
];
]</syntaxhighlight>
{{out}}
<pre>
Tokens remaining: 12
 
How many Tokens (1, 2 or 3)? 2
Computer takes 2 tokens.
 
Tokens remaining: 8
 
How many Tokens (1, 2 or 3)? 4
 
Must be a number between 1 and 3. Try again.
 
Tokens remaining: 8
 
How many Tokens (1, 2 or 3)? 1
Computer takes 3 tokens.
 
Tokens remaining: 4
 
How many Tokens (1, 2 or 3)? 3
Computer takes 1 token.
 
Tokens remaining: 0
 
Computer wins!
</pre>
 
=={{header|Z80 Assembly}}==
{{works with|CP/M 3.1|YAZE-AG-2.51.2 Z80 emulator}}
{{works with|ZSM4 macro assembler|YAZE-AG-2.51.2 Z80 emulator}}
Use the /S8 switch on the ZSM4 assembler for 8 significant characters for labels and names<br><br>
This assembles to 99 bytes of instructions plus 98 bytes of static data for the texts and buffer, accounting for a total of 197 bytes. Not sure whether the 8080 and 8086 versions counted only instruction size or total program size, but the Z80 provides some powerful looping instructions that help to reduce program size.<br><br>
Please note that I did not bother with conversion from input characters to integers and using comparisons to validate them, nor did I use arithmetic to calculate the computer's move. Instead, I used fixed strings and the cpdr instruction to look up the user's input as well as the computer's response. The CP/M BDOS call ensures that the user can enter a single character only.<br>
<syntaxhighlight lang="z80">
;
; Nim game using Z80 assembly language
;
; Runs under CP/M 3.1 on YAZE-AG-2.51.2 Z80 emulator
; Assembled with zsm4 on same emulator/OS, uses macro capabilities of said assembler
; Created with vim under Windows
;
; 2023-04-28 Xorph
;
 
;
; Useful definitions
;
 
bdos equ 05h ; Call to CP/M BDOS function
readstr equ 0ah ; Read string from console
wrtstr equ 09h ; Write string to console
 
cr equ 0dh ; ASCII control characters
lf equ 0ah
 
buflen equ 01h ; Length of input buffer
maxtok equ 12 ; Starting number of tokens
 
;
; Macro for BDOS calls
;
 
readln macro buf ; Read a line from input
push bc
ld c,readstr
ld de,buf
call bdos
pop bc
endm
 
 
;
; =====================
; Start of main program
; =====================
;
 
cseg
 
ld de,nim ; Print title and initialize
call print
ld c,maxtok ; Register c keeps track of remaining tokens
 
loop:
ld de,tokens ; Print the remaining tokens
call print
ld b,c ; Use b for loop to print remaining tokens
printtk:
ld de,token
call print
djnz printtk
ld de,prompt ; Prompt user for input
call print
readln inputbuf
 
ld a,(bufcont) ; Now check input for validity and compute response
ld hl,validinp+2 ; Start from end of valid string, so bc gets set to numeric equivalent
push bc ; Save token counter, use bc for cpdr
ld bc,3
cpdr ; Use automatic search function
jr nz,printerr ; If input character not found, print error
 
ld hl,mymoves ; Get character for response into a
add hl,bc ; bc contains index into check string as well as response string
pop bc
ld a,(hl)
ld (outbuf),a ; Put it in output buffer
 
ld de,response ; Print the computer's move
call print
 
ld a,c ; Subtract 4 tokens from counter
sub 4
ld c,a
 
jr nz,loop ; If not finished, repeat
ld de,lose ; Otherwise, player lost
call print
 
ret ; Return to CP/M
 
printerr: ; Print error message and try again
pop bc
ld de,wronginp
call print
jp loop
 
print: ; Use subroutine instead of macro for smaller code
push bc
ld c,wrtstr
call bdos
pop bc
ret
 
;
; ===================
; End of main program
; ===================
;
 
;
; ================
; Data definitions
; ================
;
 
dseg
 
inputbuf: ; Input buffer
defb buflen ; Maximum possible length
defb 00h ; Returned length of actual input
bufcont:
defs buflen ; Actual input area
nim:
defb 'Nim$' ; Dialog texts
prompt:
defb cr,lf,'How many will you take (1-3)? $'
response:
defb cr,lf,'I take ' ; No $ here! Saves one print command
outbuf:
defb ' $' ; For printing response
tokens:
defb cr,lf,cr,lf,'Tokens: $'
token:
defb '|$'
lose:
defb cr,lf,'You lose!$'
wronginp:
defb cr,lf,'Wrong input$'
validinp:
defb '123' ; Valid input
mymoves:
defb '321' ; Computer's response
</syntaxhighlight>
 
{{out}}
<pre>
E>nim
Nim
 
Tokens: ||||||||||||
How many will you take (1-3)? 2
I take 2
 
Tokens: ||||||||
How many will you take (1-3)? 4
Wrong input
 
Tokens: ||||||||
How many will you take (1-3)? 3
I take 1
 
Tokens: ||||
How many will you take (1-3)? 1
I take 3
You lose!
E>
</pre>
2,136

edits