Nim game: Difference between revisions
Added various BASIC dialects (Chipmunk Basic, Minimal BASIC, MSX Basic and Quite BASIC)
(+add Pike) |
(Added various BASIC dialects (Chipmunk Basic, Minimal BASIC, MSX Basic and Quite BASIC)) |
||
(37 intermediate revisions by 17 users not shown) | |||
Line 3:
{{task}}
Nim is a simple game where the second
Line 12:
To win every time, the second player simply takes 4 minus the number the first player took. So if the first player takes 1, the second takes 3
;Task:
Design a simple Nim game where the human player goes first, and the computer always wins. The game should enforce the rules.
=={{header|11l}}==
{{trans|Python}}
<
F getTokens(curTokens) -> N
Line 47 ⟶ 45:
compTurn(tokens)
print(‘Computer wins!’)</
{{out}}
Line 79 ⟶ 77:
It may not be a very interesting game, but it assembles to only 222 bytes.
<
puts: equ 9
putch: equ 2
Line 167 ⟶ 165:
lose: db 13,10,'You lose!$'
nl: db 13,10,'$'
wronginp: db 8,7,32,8,'$' ; beep and erase choice</
=={{header|8086 Assembly}}==
Line 187 ⟶ 185:
<
bits 16
cpu 8086
Line 246 ⟶ 244:
tokens: db 13,10,13,10,'Tokens: $'
lose: db 13,10,'You lose!$'
wronginp: db 8,7,32,8,'$' </
=={{header|Action!}}==
<
BYTE t,max
Line 295 ⟶ 293:
player=1-player
OD
RETURN</
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Nim_game.png Screenshot from Atari 8-bit computer]
Line 320 ⟶ 318:
{{works with|Ada|Ada|2012}}
<
procedure Nim is
Line 364 ⟶ 362:
TIO.Put_Line("Computer won!");
end Nim;</
{{out}}
<pre> 12 tokens remain.
Line 387 ⟶ 385:
=={{header|ALGOL 68}}==
<
# gets a single character answer from standin and returns it #
PROC answer = ( STRING prompt )CHAR:
Line 427 ⟶ 425:
DO SKIP OD;
print( ( "I win!", newline ) )
END</
{{out}}
<pre>
Line 444 ⟶ 442:
=={{header|ALGOL-M}}==
<
BEGIN
Line 524 ⟶ 522:
WRITE("THANKS FOR PLAYING!");
END </
{{out}}
<pre>
THE GAME OF NIM
WE
PLAYER MAY TAKE BETWEEN 1 AND 3 TOKENS.
THE PLAYER WHO TAKES THE LAST TOKEN WINS.
Line 557 ⟶ 555:
</pre>
=={{header|
<syntaxhighlight lang="rebol">total: 12
while ø [
tk: 0
print "YOUR turn:"
while [not? contains? 1..3 tk: <= to :integer input "How many tokens will you take? (1-3) "][]
total: total-tk
print [total "tokens remaining\n"]
print ["COMPUTER's turn:"]
print ["taking:" 4-tk]
total: total-(4-tk)
print [total "tokens remaining\n"]
if total=0 [
print "COMPUTER won. :)"
break
]
]</syntaxhighlight>
{{out}}
<pre>YOUR turn:
How many tokens will you take? (1-3) 3
9 tokens remaining
COMPUTER's turn:
taking: 1
8 tokens remaining
YOUR turn:
How many tokens will you take? (1-3) 2
6 tokens remaining
COMPUTER's turn:
taking: 2
4 tokens remaining
YOUR turn:
How many tokens will you take? (1-3) 1
3 tokens remaining
COMPUTER's turn:
taking: 3
0 tokens remaining
COMPUTER won. :)</pre>
=={{header|AsciiDots}}==
<syntaxhighlight lang="asciidots">
%$LMRTX
.-$"Nim Dots"-$""-
Line 584 ⟶ 626:
L-------------*---*>$_#-$" dots remaining."-$""
T
</syntaxhighlight>
{{out}}
Line 615 ⟶ 657:
=={{header|AutoHotkey}}==
<syntaxhighlight lang="autohotkey">Play:
tokens := 12
while tokens {
Line 631 ⟶ 673:
else
ExitApp
return</
=={{header|AWK}}==
<syntaxhighlight lang="awk">
# syntax: GAWK -f NIM_GAME.AWK
BEGIN {
Line 659 ⟶ 701:
printf("%s takes %d token%s; there are %d remaining\n",who,ans,(ans==1)?"":"s",tokens)
}
</syntaxhighlight>
{{out}}
<pre>
Line 674 ⟶ 716:
computer wins
</pre>
=={{header|BASIC}}==
==={{header|Applesoft BASIC}}===
This one-liner demonstrates the 240 character line limit. The program has been crafted to be exactly 244 characters long. The last 4 characters HEAP will be truncated from the last statement in the line. The HEAP variable is optional in the out-most NEXT statement so the program still runs correctly.
<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|BASIC256}}===
{{works with|BASIC256|1.99.99.14+}}
<syntaxhighlight lang="basic">monton = 12
llevar = 0
while monton > 0
print "There are "; monton; " tokens remaining. How many would you like to take? ";
input integer llevar
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)."
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
alert "There are ", h ," tokens remaining."
input "How many would you like to take? ", t
if t > 3 or t < 1 then
alert "You must take between 1 to 3 tokens."
endif
if h - t < 0 then
alert "You cannot take that many. There's only ", h ," left."
endif
if t <= 3 and t >= 1 and h - t >= 0 then
let h = h - t
if h = 0 then
alert "Congratulations. You got the last token."
end
endif
let t = 4 - t
if h >= 15 then
let t = 3
endif
if h <= 3 then
let t = h
endif
alert "I will take ", t ," tokens."
let h = h - t
if h = 0 then
alert "I got the last token. I win. Better luck next time."
end
endif
endif
goto loop</syntaxhighlight>
==={{header|FreeBASIC}}===
<syntaxhighlight lang="freebasic">dim as ubyte heap=12, take
while heap > 0
print using "There are ## tokens remaining. How many would you like to take?"; heap
input take
while take=0 orelse take>3
print "You must take 1, 2, or 3 tokens. How many would you like to take?"
input take
wend
print using "On my turn I will take ## tokens."; 4-take
heap = heap - 4
wend
print "I got the last token. I win! Better luck next time."</syntaxhighlight>
==={{header|FTCBASIC}}===
<syntaxhighlight lang="basic">define tokens = 12, take = 0
gosub intro
do
print "There are " \
print tokens \
print " tokens remaining."
crlf
print "How many would you like to take? " \
input take
if take > 3 or take < 1 then
print "You must take between 1 to 3 tokens."
endif
if tokens - take < 0 then
print "You cannot take that many."
endif
if take <= 3 and take >= 1 and tokens - take >= 0 then
let tokens = tokens - take
if tokens = 0 then
bell
print "Congratulations. You got the last token."
pause
end
endif
let take = 4 - take
if tokens >= 15 then
let take = 3
endif
if tokens <= 3 then
let take = tokens
endif
print "I will take " \
print take \
print " of the tokens."
let tokens = tokens - take
if tokens = 0 then
print "I got the last token. I win. Better luck next time."
pause
end
endif
endif
loop
sub intro
cls
print "NIM game"
crlf
print "Press any key to play..."
cls
return</syntaxhighlight>
==={{header|GW-BASIC}}===
<syntaxhighlight lang="gwbasic">10 HEAP = 12
20 WHILE HEAP>0
30 TAKE = 0
40 PRINT "There are ";HEAP;" tokens left."
50 WHILE TAKE < 1 OR TAKE > 3 OR TAKE > HEAP
60 INPUT "How many would you like to take? ", TAKE
70 IF TAKE = HEAP THEN GOTO 140
80 WEND
90 PRINT "I will take ";4-TAKE;" tokens."
100 HEAP = HEAP - 4
110 WEND
120 PRINT "I got the last token. Better luck next time."
130 END
140 PRINT "You got the last token. Congratulations!"
150 END</syntaxhighlight>
==={{header|IS-BASIC}}===
<syntaxhighlight lang="is-basic">100 PROGRAM "Nim.bas"
110 RANDOMIZE
120 CLEAR SCREEN
130 LET TOKENS=12
140 PRINT "Starting with";TOKENS;"tokens.":PRINT
150 DO
160 PRINT "How many tokens will you take? (1-3) ";
170 DO
180 LET K=VAL(INKEY$)
190 LOOP UNTIL K>0 AND K<4
200 LET TOKENS=MAX(TOKENS-K,0):LET G=0
210 PRINT K:PRINT TAB(19);TOKENS;"remainig.":PRINT
220 IF TOKENS>0 THEN
230 LET L=MOD(TOKENS,4)
240 IF L=0 THEN LET L=MIN(RND(3)+1,TOKENS)
250 LET TOKENS=TOKENS-L:LET G=-1
260 PRINT "Computer takes";L;"tokens.";TOKENS;"remaining.":PRINT
270 END IF
280 LOOP WHILE TOKENS>0
290 IF G THEN
300 PRINT "Computer wins!"
310 ELSE
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}}===
<syntaxhighlight lang="basic">
$constant maxtokens = 12
$constant machine = 0
$constant human = 1
$constant false = 0
$constant true = 0FFFFH
procedure welcome
print "Welcome to the Game of Nim."
print "We begin with";maxtokens;" tokens. On each turn, a player"
print "may take between 1 and 3 tokens. The player who takes the"
print "last token wins."
print
end
procedure show(n = integer)
var i = integer
print "Available tokens:";n;" ";
rem - provide a visual display
for i = 1 to n
print "o ";
next i
print
end
function getnum(lowlim, toplim = integer) = integer
var ok, n = integer
repeat
begin
input "You take:";n
if n < lowlim or n > toplim then
begin
print "Must take between";lowlim;" and";toplim
print "Try again."
ok = false
end
else
ok = true
end
until ok
end = n
function play(player, tokens, taken = integer) = integer
if player = human then
taken = getnum(1,3)
else
begin
if tokens <= 3 then
taken = tokens
else
taken = 4 - taken
end
end = taken
procedure report(player = integer)
if player = human then
print "You took the last one. You win. Congratulations!"
else
print "I took the last one, so I win. Sorry about that."
end
var player, tokens, taken = integer
welcome
tokens = maxtokens
taken = 0
player = human
print "You go first."
repeat
begin
show tokens
taken = play(player, tokens, taken)
if player = machine then print "I took:";taken
tokens = tokens - taken
if tokens > 0 then player = 1 - player
end
until tokens <= 0
report player
print "Thanks for playing!"
end </syntaxhighlight>
{{out}}
<pre>
Welcome to the Game of Nim.
We begin with 12 tokens. On each turn, a
player may take between 1 and 3 tokens. The player
who takes the last token wins.
You go first.
Available tokens: 12 o o o o o o o o o o o o
You take:? 4
Must take between 1 and 3
Try again.
You take:? 3
Available tokens: 9 o o o o o o o o o
I took: 1
Available tokens: 8 o o o o o o o o
You take:? 2
Available tokens: 6 o o o o o o
I took: 2
Available tokens: 4 o o o o
You take:? 1
Available tokens: 3 o o o
I took: 3
I took the last one, so I win. Sorry about that.
Thanks for playing!
</pre>
==={{Header|Tiny BASIC}}===
{{works with|TinyBasic}}
<syntaxhighlight lang="basic">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 GOTO 170
70 IF T < 1 THEN GOTO 170
80 LET H = H - T
90 IF H = 0 THEN GOTO 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 GOTO 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 END
210 PRINT "I got the last token. I win. Better luck next time."
220 END</syntaxhighlight>
==={{header|True BASIC}}===
{{works with|QBasic}}
{{works with|Just BASIC}}
{{works with|Liberty BASIC}}
<syntaxhighlight lang="qbasic">LET monton = 12
LET llevar = 0
DO WHILE monton > 0
PRINT "Quedan"; monton; "fichas. ¿Cuántas te gustaría tomar";
INPUT llevar
DO WHILE llevar = 0 Or llevar > 3
PRINT "Debes tomar 1, 2, o 3 fichas. ¿Cuántas te gustaría tomar";
INPUT llevar
LOOP
PRINT "Es mi turno, tomaré"; 4-llevar; "ficha(s)."
LET monton = monton - 4
LOOP
PRINT
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}}==
Bloop has no input capabilites, so the game is defined as a procedure, called with 3 numbers (since the game will last only 3 rounds anyhow). The procedure can be called with more numbers - extra parameters are ignored in most implementations I have found. Since there is no easy way to get more inputs, any incorrect values are converted to correct ones.
<syntaxhighlight lang="bloop">
DEFINE PROCEDURE ''DIVIDE'' [A,B]:
BLOCK 0: BEGIN
Line 769 ⟶ 1,380:
PLAY_GAME [1,4,3];
</syntaxhighlight>
{{out}}
Line 798 ⟶ 1,409:
=={{header|C}}==
<syntaxhighlight lang="c">
#include <stdio.h>
Line 858 ⟶ 1,469:
return remainingTokens;
}
</syntaxhighlight>
{{Out}}
Line 894 ⟶ 1,505:
=={{header|C++}}==
{{trans|Go}}
<
#include <limits>
Line 928 ⟶ 1,539:
}
}
}</
{{out}}
Line 966 ⟶ 1,577:
=={{header|C#}}==
<
using System;
Line 1,004 ⟶ 1,615:
}
}
</syntaxhighlight>
{{out}}
Sample game:
Line 1,025 ⟶ 1,636:
I take 2.
I win again.
</pre>
=={{header|Clojure}}==
<syntaxhighlight lang="clojure">(loop [n 12]
(print (format "%s remain, take how many?\n> " n)) (flush)
(let [v (try (Long. (clojure.string/trim (read-line)))
(catch Exception _ 0))]
(if (#{1 2 3} v)
(do (println (format "You took %s, leaving %s, computer takes %s..."
v (- n v) (- 4 v)))
(if (= 4 n)
(println "Computer wins. 😐")
(recur (- n 4))))
(do (println "Please enter 1, 2, or 3...")
(recur n)))))
</syntaxhighlight>
{{out}}
Sample game:
<pre>harold@freeside:~/src/clj-nim$ rlwrap clj -M nim.clj
12 remain, take how many?
3
You took 3, leaving 9, computer takes 1...
8 remain, take how many?
2
You took 2, leaving 6, computer takes 2...
4 remain, take how many?
1
You took 1, leaving 3, computer takes 3...
Computer wins. 😐
</pre>
=={{header|Common Lisp}}==
<
(defun pturn (curTokens)
(write-string "How many tokens would you like to take?: ")
Line 1,057 ⟶ 1,699:
(return)))
(write-string "Computer wins!")
</syntaxhighlight>
{{out}}
Line 1,088 ⟶ 1,730:
=={{header|Crystal}}==
<
until tokens <= 0
Line 1,099 ⟶ 1,741:
end
puts "Computer wins."</
=={{header|Dyalect}}==
<
print("You can take 1, 2, or 3 on your turn.")
print("Whoever takes the last token wins.\n")
Line 1,121 ⟶ 1,763:
}
print("I win again.")</
=={{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}}==
<
IN: rosetta-code.nim-game
Line 1,146 ⟶ 1,809:
: nim-game ( -- ) 12 round drop "Computer wins!" print ;
MAIN: nim-game</
{{out}}
<pre>
Line 1,176 ⟶ 1,839:
=={{header|Fermat}}==
<
while heap>0 do
!!('There are ',heap,' tokens left. How many do you want to take?');
Line 1,188 ⟶ 1,851:
od;
!!('I got the last token. Better luck next time!');</
{{out}}<pre>There are 12 tokens left. How many do you want to take?
>take := 4
Line 1,201 ⟶ 1,864:
On my turn I will take 2 tokens.
I got the last token. Better luck next time!</pre>
=={{header|Go}}==
<
import (
Line 1,262 ⟶ 1,908:
}
}
}</
{{out}}
Line 1,292 ⟶ 1,938:
Computer wins!
</pre>
=={{header|Haskell}}==
<
import System.IO
Line 1,345 ⟶ 1,974:
main :: IO ()
main = play 12</
{{out}}
<pre>
Line 1,363 ⟶ 1,992:
Computer Wins!
</pre>
=={{header|J}}==
Line 1,394 ⟶ 1,997:
Implementation:
<
prompt tokens=: 12
}}
Line 1,413 ⟶ 2,016:
echo 'I take ',(":t=. 4-y),' tokens'
prompt tokens=:tokens-t
}}</
Sample session:
<
tokens: 12
take 1, 2 or 3 tokens
Line 1,434 ⟶ 2,037:
I take 2 tokens
tokens: 0
game over</
=={{header|Java}}==
<
import java.util.Scanner;
Line 1,492 ⟶ 2,095:
}
</syntaxhighlight>
{{out}}
Line 1,530 ⟶ 2,133:
=== Browser Version ===
This is the easy but dirty way - with prompt for input, and console.log for output. The Nim class was structured so that input and output could be customized, for example to use HTML DOM elements for in and out, instead of the terminal.
<syntaxhighlight lang="javascript">
class Nim {
constructor(tokens, printFun) {
Line 1,582 ⟶ 2,185:
}
}
</syntaxhighlight>
{{out}}
Line 1,615 ⟶ 2,218:
Computer wins.
</pre>
=={{header|jq}}==
{{works with|jq}}
'''Also works with gojq, the Go implementation of jq.'''
<syntaxhighlight lang=jq>
def play($tokens):
label $out
| "There are \($tokens) tokens. Take at most \([$tokens,3]|min) or enter q to quit.",
( foreach inputs as $in ( {$tokens};
if $in == "q" then break $out
else .in = $in
| if $in | test("^[0-9]+$") then .in |= tonumber else .in = null end
| if .in and .in > 0 and .in < 4
then (4 - .in) as $ct
| (if $ct == 1 then "" else "s" end) as $s
| .emit = " Computer takes \($ct) token\($s);"
| .tokens += -4
else .emit = "Please enter a number from 1 to \([3, .tokens]|min) inclusive."
end
end;
.emit,
if .tokens == 0
then "\nComputer wins!", break $out
elif .tokens < 0 then "\nCongratulations!", break $out
else "\(.tokens) tokens remain. How many tokens will you take?"
end )) ;
play(12)
</syntaxhighlight>
<pre>
$ jq -nRr -f nim-game.jq
There are 12 tokens. Take at most 3 or enter q to quit.
2
Computer takes 2 tokens;
8 tokens remain. How many tokens will you take?
1
Computer takes 3 tokens;
4 tokens remain. How many tokens will you take?
4
Please enter a number from 1 to 3 inclusive.
4 tokens remain. How many tokens will you take?
3
Computer takes 1 token;
Computer wins!
</pre>
=={{header|Julia}}==
{{trans|Raku}}
<
tcount = 12
takenum = 0
Line 1,641 ⟶ 2,291:
nimgame()
</
<pre>
12 tokens remain.
Line 1,660 ⟶ 2,310:
=={{header|Kotlin}}==
{{trans|Go}}
<
fun showTokens(tokens: Int) {
Line 1,686 ⟶ 2,336:
}
}
}</
{{output}}
Line 1,718 ⟶ 2,368:
=={{header|Lua}}==
<syntaxhighlight lang="lua">
tokens = 12
Line 1,758 ⟶ 2,408:
print ("Computer wins.")
</syntaxhighlight>
{{out}}
Line 1,796 ⟶ 2,446:
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<
While[n > 0,
c = ChoiceDialog["Current amount = " <> ToString[n] <> "\nHow many do you want to pick?", {1 -> 1, 2 -> 2, 3 -> 3}];
Line 1,803 ⟶ 2,453:
n -= (4 - c);
]
ChoiceDialog["Current amount = " <> ToString[n] <> "\n You lost!"]</
=={{header|MiniScript}}==
{{trans|Lua}}
<
print "Nim Game"
Line 1,846 ⟶ 2,496:
end while
print "Computer wins."</
{{out}}
<pre>Nim Game
Line 1,878 ⟶ 2,528:
=={{header|Nim}}==
<
import terminal
Line 1,916 ⟶ 2,566:
computer()
styledEcho(styleBright, "Computer wins!")</
{{out}}
Line 1,950 ⟶ 2,600:
=={{header|OCaml}}==
{{trans|Python|with plurals added, loops turned to recursion and string input handled}}
<
print_string "How many tokens would you like to take? ";
let n = read_int_opt () |> Option.value ~default:0 in
Line 1,975 ⟶ 2,625:
if tokens = 0 then print_endline "Computer wins!" else play_game tokens
let () = play_game 12</
{{out}}
<pre>
Line 1,995 ⟶ 2,645:
Computer wins!
</pre>
=={{header|Pascal}}==
{{works with|Free Pascal}}
<syntaxhighlight lang=Pascal>
program Nim;
{$mode objfpc}{$H+}
uses
sysutils;
const
maxtokens = 12;
machine = 0;
human = 1;
var
player, tokens, taken : integer;
procedure Welcome;
begin
writeln('The Game of Nim');
writeln;
writeln('This is one of many variants of the classic game of');
writeln('Nim. We start with',maxtokens,' tokens. On each turn a player');
writeln('takes between 1 and 3 tokens. The player who takes');
writeln('the last token wins.');
writeln;
end;
procedure ShowRemaining(n : integer);
begin
writeln('Available tokens: ', n);
end;
function getnum(lowlim, toplim : integer) : integer ;
var
n : integer;
ok : boolean;
begin
repeat
write('You take: ');
readln(n);
if (n < lowlim) or (n > toplim) then
begin
writeln('Must take between ',lowlim,' and ',toplim);
write('Try again: ');
ok := false;
end
else
ok := true;
until ok;
getnum := n;
end;
function PlayTurn(player, taken, tokens : integer) : integer;
begin
if player = human then
taken := getnum(1,3)
else { machine's move this time }
begin
if tokens <= 3 then
taken := tokens { take all if 3 or less remain }
else
taken := 4 - taken; { othewise, follow winning strategy }
end;
PlayTurn := taken;
end;
procedure Report(winner : integer);
begin
if winner = human then
writeln('You took the last one, so you win. Congratulations!')
else
writeln('I took the last one, so I win. Sorry about that.');
end;
begin
Welcome;
tokens := maxtokens;
taken := 0;
player := human;
writeln('You go first');
repeat
ShowRemaining(tokens);
taken := PlayTurn(player, taken, tokens);
if player = machine then writeln('I took: ',taken);
tokens := tokens - taken;
if tokens > 0 then player := 1 - player;
until tokens <= 0;
report(player);
writeln('Thanks for playing!');
readln;
end.
</syntaxhighlight>
{{out}}
<pre>
The Game of Nim
This is one of many variants of the classic game of
Nim. We start with 12 tokens. On each turn a player
takes between 1 and 3 tokens. The player who takes
the last token wins.
You go first
Available tokens: 12
You take: 4
Must take between 1 and 3
Try again: 3
Available tokens: 9
I took: 1
Available tokens: 8
You take: 2
Available tokens: 6
I took: 2
Available tokens: 4
You take: 1
Available tokens: 3
I took: 3
I took the last one, so I win. Sorry about that.
Thanks for playing!
</pre>
=={{header|Pebble}}==
<syntaxhighlight lang="pebble">
;NIM game example program for x86 DOS
;Compiles with Pebble to com file under 1kb.
program examples\nim
data
int tokens[12]
int take[0]
begin
call intro
label gameloop
echo "There are"
echo [tokens]
echo " tokens remaining."
crlf
echo "How many would you like to take? "
input [take]
if [take] > 3 | [take] < 1 then
echo "You must take between 1 to 3 tokens."
endif
if [take] <= 3 & [take] >= 1 then
[tokens] = [tokens] - [take]
if [tokens] = 0 then
bell
echo "Congratulations. You got the last token."
pause
kill
endif
[take] = 4 - [take]
echo "I will take"
echo [take]
echo " tokens.
[tokens] = [tokens] - [take]
if [tokens] = 0 then
echo "I got the last token. I win. Better luck next time."
pause
kill
endif
endif
goto gameloop
end
sub intro
cls
echo "NIM game"
crlf
ret
</syntaxhighlight>
=={{header|Perl}}==
{{trans|Raku}}
<
use warnings;
use feature 'say';
Line 2,014 ⟶ 2,861:
say "Computer wins." and last
if $tokens <= 0;
}</
{{out}}
<pre>12 tokens remaining.
Line 2,037 ⟶ 2,884:
=={{header|Phix}}==
{{trans|Raku}}
<!--<
<span style="color: #008080;">without</span> <span style="color: #008080;">js</span> <span style="color: #000080;font-style:italic;">-- getc</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">tokens</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">12</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">player</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
Line 2,049 ⟶ 2,896:
<span style="color: #000000;">tokens</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">4</span><span style="color: #0000FF;">;</span> <span style="color: #000000;">player</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<!--</
{{out}}
<pre>
Line 2,061 ⟶ 2,908:
{{trans|Python}}
<
void get_tokens(int cur_tokens) {
Line 2,093 ⟶ 2,940:
write("Computer wins!\n");
return 0;
}</
{{out}}
Line 2,127 ⟶ 2,974:
=={{header|Plain English}}==
<
Start up.
Play the game of Nim.
Line 2,159 ⟶ 3,006:
Format the count and "piece" or "pieces" into a string.
Write "The computer took " then the string then "." on the console.
Put the count into the pieces.</
{{out}}
<pre>
Line 2,180 ⟶ 3,027:
=={{header|Prolog}}==
<
next_turn(N) :-
Line 2,199 ⟶ 3,046:
-> format('Computer wins!')
; next_turn(N2)
).</
{{out}}
<pre>
Line 2,231 ⟶ 3,078:
=={{header|Python}}==
Works on Python 3
<syntaxhighlight lang="python">
print("Py Nim\n")
Line 2,264 ⟶ 3,111:
print("Computer wins!")
</syntaxhighlight>
{{out}}
Line 2,292 ⟶ 3,139:
Computer wins!
</pre>
=={{header|Quackery}}==
<syntaxhighlight lang="Quackery"> [ $ "Take how many tokens? (1-3) "
input
trim reverse
trim reverse
$->n
not iff drop again
dup 1 4 within
not iff drop again ] is getmove ( --> n )
[ 12
[ say "There are "
dup echo
say " tokens." cr cr
getmove tuck -
4 rot - dup
cr say "Computer takes "
echo
say "." cr cr
-
dup 0 = until ]
drop
say "Computer wins." cr ] is play ( --> )</syntaxhighlight>
{{out}}
As a dialogue in the Quackery shell.
<pre>/O> play
...
There are 12 tokens.
Take how many tokens? (1-3) 1
Computer takes 3.
There are 8 tokens.
Take how many tokens? (1-3) 2
Computer takes 2.
There are 4 tokens.
Take how many tokens? (1-3) 3
Computer takes 1.
Computer wins.
Stack empty.
</pre>
=={{header|R}}==
<
##
Line 2,315 ⟶ 3,214:
}
</syntaxhighlight>
{{out}}
Line 2,349 ⟶ 3,248:
=={{header|Racket}}==
<
#lang racket
Line 2,383 ⟶ 3,282:
(pturn 12)
</syntaxhighlight>
=={{header|Raku}}==
Line 2,389 ⟶ 3,288:
{{works with|Rakudo|2019.03}}
<syntaxhighlight lang="raku"
loop {
Line 2,398 ⟶ 3,297:
say "Computer takes {4 - $player}.\n$tokens tokens remaining.\n";
say "Computer wins." and last if $tokens <= 0;
}</
{{out|Sample output}}
<pre>12 tokens remaining.
Line 2,423 ⟶ 3,322:
=={{header|Red}}==
<
date: 2021-10-24
version: 0.6.4
Line 2,453 ⟶ 3,352:
tokens: subtract tokens subtract 4 n
]
print "Computer wins!"</
{{out}}
<pre>
Line 2,477 ⟶ 3,376:
=={{header|REXX}}==
Programming notes: extra error checking was done with specific informative error messages. Also included was a method of quitting the game. The number of (starting) tokens (the ''pot'') can be specified on the command line, the default is '''12'''.
<
parse arg pot _ . 1 __ /*obtain optional argument from the CL.*/
if pot=='' | pot=="," then pot= 12 /*Not specified? Then use the default.*/
Line 2,519 ⟶ 3,418:
show: say; say pad "Tokens remaining: " arg(1)' ' pad; say; return
s: if arg(1)==1 then return arg(3); return word(arg(2) 's',1)
ser: if ok then say pad '***error***' arg(1); ok= 0; return</
{{out|output|text= when using the default input:}}
<pre>
Line 2,550 ⟶ 3,449:
=={{header|Ring}}==
<
# Project : CalmoSoft Nim Game
# Date : 16/04/2020-13:27:07
Line 2,926 ⟶ 3,825:
win.close()
app.Quit()
</syntaxhighlight>
Necessary image files:
[http://www.mediafire.com/file/8z9tus0owwkv92q/Images.zip/file Images file]
Line 2,933 ⟶ 3,832:
<br><br>
[https://youtu.be/b4mP6TrARKI Nim Game - video]
=={{header|RPL}}==
This task is an opportunity to showcase the use of both persistent variables and local variables, the latter vanishing once the program executed.
The computer has been named "HAL" rather than "Player 2" or "Computer" to keep the message length under 16 characters, which is the width of the HP-28 display.
To play, initialize the game by entering the word <code>NUNIM</code>, then input your moves followed by the word <code>PLNIM</code> until you will lose. The case for a human win is nevertheless coded to appear as a a fair game.
{{works with|Halcyon Calc|4.2.7}}
≪ "Tokens = " tokens →STR +
"1..3 PLNIM?"
≫
'DispN' STO
≪ CLEAR 12 'tokens' STO // emptying the stack and creating a persistent variable
DispN
≫
'NUNIM' STO
≪ → move // creating a local variable, with value = content of stack level 1:
≪ IF { 1 2 3 } move POS
THEN
"You take " move →STR +
'tokens' move STO- // substracting the value of a local variable from a persistent variable directly
IF tokens 0 ≤
THEN "You win!"
ELSE
4 move - tokens MIN "HAL takes " OVER →STR + 'tokens' ROT STO-
IF tokens 0 ≤ THEN DROP "HAL wins!" ELSE DispN END
END
ELSE move →STR " is illegal" + DispN
END
≫ ≫
'PLNIM' STO // 67 words, 4% stack
NUNIM
3 PLNIM
4 PLNIM
2 PLNIM
2 PLNIM
{{out}}
<pre>
15: "Tokens = 12"
14: "1..3 PLNIM?"
13: "You take 3"
12: "HAL takes 1"
11: "Tokens = 8"
10: "1..3 PLNIM?"
9: "4 is illegal"
8: "Tokens = 8"
7: "1..3 PLNIM?"
6: "You take 2"
5: "HAL takes 2"
4: "Tokens = 4"
3: "1..3 PLNIM?"
2: "You take 2"
1: "HAL wins!"
</pre>
=={{header|Ruby}}==
<
puts "There are #{remaining} dots.\nHow many dots would you like to take? "
unless (num=gets.to_i).between?(1, 3)
Line 2,945 ⟶ 3,899:
puts "Computer took the last and wins."
</syntaxhighlight>
{{out}}
<pre>There are 12 dots.
Line 2,973 ⟶ 3,927:
=={{header|Rust}}==
<
fn main() {
let mut tokens = 12;
Line 3,032 ⟶ 3,986:
println!("");
}
</syntaxhighlight>
{{out}}
sample game:
Line 3,070 ⟶ 4,024:
Computer wins!
</pre>
=={{header|Scala}}==
<
var tokens = 12
Line 3,209 ⟶ 4,058:
println("Computer wins!")
}
</syntaxhighlight>
=={{header|Smalltalk}}==
{{works with|GNU Smalltalk}}
<
Object subclass: Nim [
| tokens |
Line 3,274 ⟶ 4,123:
g := Nim new.
g mainLoop.
</syntaxhighlight>
{{out}}
sample game:
Line 3,310 ⟶ 4,159:
=={{header|SNOBOL4}}==
{{works with|CSNOBOL4}}
<
&DUMP = 1
Line 3,397 ⟶ 4,246:
&DUMP = 0
END</
<pre>The mysterious game of Nim!
Line 3,430 ⟶ 4,279:
=={{header|Swift}}==
<
while tokens != 0 {
Line 3,456 ⟶ 4,305:
print()
}</
{{out}}
Line 3,473 ⟶ 4,322:
I win!</pre>
=={{
{{trans|Go}}
<
fn show_tokens(tokens int) {
Line 3,550 ⟶ 4,352:
}
}
}</
{{out}}
Line 3,580 ⟶ 4,382:
Computer wins!
</pre>
=={{header|Wren}}==
{{trans|Go}}
<
var showTokens = Fn.new { |tokens| System.print("Tokens remaining %(tokens)\n") }
Line 3,607 ⟶ 4,408:
break
}
}</
{{out}}
Line 3,636 ⟶ 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>
|