nimmGame
Deutsch   English   

NIM GAME

 

 

GAME DESCRIPTION

 

The Nim game is one of the most popular games in game theory because the winning strategy is relatively easy to figure out. In our example, the user plays against the computer, which follows the winning strategy.

At the beginning of the game, there are 15 matches. The user removes 1, 2, or 3 matches with a mouse click, then it is the computer's turn. The player who removes the last match loses.

Program:

# NimGame.py

from gamegrid import *
import random
            
class Match(Actor):
    def __init__(self):
         Actor.__init__(self, True, "sprites/match.gif")
         
def pressCallback(e):
    global nbMatches
    global nbTakenMatches
    loc = toLocationInGrid(e.getX(), e.getY()) 
    if loc.x > 46 and loc.x < 50 and loc.y > 2 and loc.y < 6:
        if nbTakenMatches == 0:
            setTitle("You have to remove at least 1 match!")
        else:
            nbTakenMatches = 0
            if nbMatches > 0: 
                setTitle("Computer play")
                computerMove()
    else: 
        actor = None
        for y in range(2, 8): 
            actor = getOneActorAt(Location(loc.x, y))
            if actor != None:
                break
        if actor != None:
            if nbTakenMatches == 3:
                setTitle("Take a maximum of 3. Click 'OK' to continue!")
            else:     
                actor.removeSelf()
                nbMatches -= 1
                nbTakenMatches += 1
                setTitle(str(nbMatches) + 
                   " matches remaining. Click 'OK' to continue.")
                if nbMatches == 0:
                    setTitle("You lost!")
                    addActor(Actor("sprites/gameover.gif"),Location(15,4))
        refresh()
    return True  

def nbWin(n):
    f = ((n - 1) // 4) * 4 + 1
    return f
     
def computerMove():
    global nbMatches
    nbRemovedMatches = nbMatches - nbWin(nbMatches)
    if nbRemovedMatches == 0:
      nbRemovedMatches = 1 # optimal strategy impossible
    nbMatches = nbMatches - nbRemovedMatches
    for x in range(nbRemovedMatches):
        matches = getActors(Match)
        if len(matches) > 0:
            k = int(random.random() * len(matches))
            removeActor(matches[k])   
            setTitle(str(nbMatches)+" matches remaining. Your move now.")
    if nbMatches == 0:
        setTitle("You win.")
        addActor(Actor("sprites/gameover.gif"), Location(15, 4))
    refresh()

makeGameGrid(52, 9, 12, False, mousePressed = pressCallback)
nbMatches = 15
nbTakenMatches = 0 
for i in range(15):
    match = Match()
    addActor(match, Location(2 + 3 * i , 4))
addActor(Actor("sprites/btn_ok_0.gif"), Location(48 , 4)) 
setTitle(str(nbMatches) + 
    " matches. Click on 1, 2 or 3 matches to remove, then click 'OK'.")  
show()
doRun()
► Copy to clipboard

 

 

Explanations of the programme code

 
1. if loc.x > 46 and loc.x < 50 and loc.y > 2 and loc.y < 6) :  If the OK button is pressed.

2. for y in range(2, 8):
     actor = getOneActorAt(Location(loc.x, y))
:
so that the matches can be clicked on along their entire length (not just in the middle).

3.
actor.removeSelf(): a match is removed
4. f = ((n - 1) // 4) * 4 + 1 : winning strategy. The computer tries to reach this number of matches.

5. matches = getActors(Match): list of remaining matches.
6. k = int(random.random() * len(matches)): the computer randomly selects one of the remaining matches.