Sunanda July 2005
This script does two things:
NIM is one of those simple games that, if you know the simple rule of success, makes you almost unbeatable. If you don't, it is highly frustrating.
The rules are simple.
A classic starting position is :
|Pile 1||Pile 2||Pile 3|
The only winning move (whichever variant you are playing) is to take 2 counters from Pile 1, leaving:
|Pile 1||Pile 2||Pile 3|
do %nim-engine.r nim-engine/play-game
nim-engine will generate a random starting position, and ask you to move.
By default, this is the common game: you lose if you take the last counter.
To play the straight game (win if you take the last counter):
If you want to specify a starting position:
nim-engine/play-game/position [5 5 1 3]
If you want nim-engine to play first from a random starting position
If you want nim-engine to move first from a specified starting position:
nim-engine/play-game/opponent-starts/position [5 5 1 3]
You can use nim-engine.r as a hidden asset in nim-like games you write.
To do that, there is simply one call you need to use:
nim-engine/move "common" [3 4 5]
nim-engine returns an object containing the move to make and some status information:
probe nim-engine/move "common" [3 4 5] make object! [ game-type: "common" game-over?: false winner?: none move: 1x2 piles: [1 4 5] winning?: "nim-engine" ]
|game-type||reflects back the input field|
|game-over?||true/false depending on whether more moves are possible|
|winner?||who won ("human" or "nim-engine") if the game is over -- see below for more details|
|move||(assuming the game wasn't over when you made the call) the move nim-engine is making. A pair: 1x2 means taking 2 from pile 1|
|piles||the updated position block|
|winning?||which player is winning|
nim-engine/move assumes each time you call it you are asking it to make a move.
Which is fine if you are mediating a game between the computer and a human. But may be confusing if you are handling two humans calling each other, or tow computers.
If so, it may help to supply the player names:
>> probe nim-engine/move/names "straight" [0 0 8] ["Cindy" "Carl"] make object! [ game-type: "straight" game-over?: true winner?: "Cindy" move: 3x8 piles: [0 0 0] winning?: "Cindy" ]
If you make changes to this code -- or just want some confidence that it is right, use the build-in test driver:
do %nim-engine.r nim-engine/test-driver
nim-engine will start playing a series of random games with itself, reporting every 100 on the console.
After each move, it analyses the move made and the resultant piles to see if they make sense. If they don't, it reports the anomaly. Any anomaly means that something has gone wrong -- nim-engine has made an invalid move, or corrupted the piles block.
To change the default number of piles and their maximum sizes in the games the test driver runs, find and edit this line:
loop 5 + random/secure 5 [append piles random/secure 20]
(that default lines means each random game starts with 5 to 10 piles each with up to 20 counters)
Last updated: 19-Jul-2005 Nim-engine.r Documentation