Script Library: 1213 scripts
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 
View scriptLicenseDownload documentation as: HTML or editable
Download scriptHistoryOther scripts by: sunanda

Documentation for: nim-engine.r


    Sunanda
    July 2005
 

1. NIM Engine

This script does two things:

  • Plays a game of NIM under any version of REBOL Core. Pretty basic, as it uses the command line for input and output;
  • Provides a complete API for any more graphic game you might want to write that uses NIM as part of its strategy.

2. NIM

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.

  • Two people play
  • Start with several piles of counters
  • Each player takes it in turn to take as many counters as they like from any one pile
  • The player who takes the last counter wins
  • or, as a variant, the player who takes the last counter wins. NIM-engine will play both versions.

A classic starting position is :

Pile 1 Pile 2 Pile 3
3 4 5

The only winning move (whichever variant you are playing) is to take 2 counters from Pile 1, leaving:

Pile 1 Pile 2 Pile 3
1 4 5

2.1. Variants and terminology

  • common game -- you lose if you take the last counter
  • straight game -- you win if you take the last counter

3. Playing the built-in game

   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.

3.1. Game variants

To play the straight game (win if you take the last counter):

   nim-engine/play-game/type "straight"
 

3.2. Play from a given position:

If you want to specify a starting position:

   nim-engine/play-game/position [5 5 1 3]
 

3.3. Make nim-engine play first:

If you want nim-engine to play first from a random starting position

   nim-engine/play-game/opponent-starts
 

If you want nim-engine to move first from a specified starting position:

   nim-engine/play-game/opponent-starts/position [5 5 1 3]
 

4. Using the API

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]
 

You supply:

  • the game type as a string
  • the current game position

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

4.1. Player names

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"
 ]
 

5. Test driver

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