Solitaire Game


Wie der Name Solitaire sagt, wird dieses Spiel meistens von einer einzigen Person gespielt. Das Spiel wird mit 32 Spielsteinen, die kreuzförmig in 33 Feldern angeordnet sind, gestartet. Das Feld im Zentrum ist leer. Ziel ist es alle Steine bis auf einen zu eliminieren, in dem man sie mit einem Nachbarstein überspringt. Die Spielsteine werden mit der gedrückten Maustaste an die neue Position gezogen, wobei man nur senkrecht oder waagrecht aber nicht diagonal springen darf.

   
erlaubt
 
nicht erlaubt
 

Bei unserer Spielimplementierung werden die Steine bei unerlaubten Zügen an die Ausgangsposition zurückversetzt.

#Solitaire.py

from gamegrid import *

def checkGameOver():
    global isGameOver
    marbles = getActors() 
    if len(marbles) == 1:
        isGameOver = True
        addActor(Actor("sprites/you_win.gif"), Location(3, 3))
    else:
        if not isMovePossible():
           isGameOver = True
           addActor(Actor("sprites/gameover.gif"), Location(3, 3))

def isMovePossible():
   for a in getActors():  # run over all remaining marbles
        for x in range(7): # run over all holes
            for y in range(7):
                loc = Location(x, y)
                if getOneActorAt(loc) == None and \
                  getRemoveMarble(a.getLocation(), Location(x, y)) != None:
                    return True
   return False
    
def getRemoveMarble(start, dest):
    if getOneActorAt(start) == None:
        return None
    if getOneActorAt(dest) != None:
        return None
    if not isMarbleLocation(dest):
        return None
    if dest.x - start.x == 2 and dest.y == start.y:
        return getOneActorAt(Location(start.x + 1, start.y))
    if start.x - dest.x == 2 and dest.y == start.y:
        return getOneActorAt(Location(start.x - 1, start.y))
    if dest.y - start.y == 2 and dest.x == start.x:
        return getOneActorAt(Location(start.x, start.y + 1))
    if start.y - dest.y == 2 and dest.x == start.x:
        return getOneActorAt(Location(start.x, start.y - 1))
    return None

def isMarbleLocation(loc):
    if loc.x < 0 or loc.x > 6 or loc.y < 0 or loc.y > 6:
        return False
    if (loc.x == 0 or loc.x == 1 or loc.x == 5 or loc.x == 6) and \
       (loc.y == 0 or loc.y == 1 or loc.y == 5 or loc.y == 6):
        return False
    return True

def initBoard():
    for x in range(7):
        for y in range(7):
            loc = Location(x, y)
            if isMarbleLocation(loc):
                marble = Actor("sprites/marble.png")
                addActor(marble, loc)
    removeActorsAt(Location(3, 3)) # Remove marble in center

def pressEvent(e):
    global startLoc, movingMarble
    if isGameOver:
        return
    startLoc = toLocationInGrid(e.getX(), e.getY())
    movingMarble = getOneActorAt(startLoc)  

def dragEvent(e):
    if isGameOver:
        return
    if movingMarble == None:
        return
    startPoint = toPoint(startLoc)
    movingMarble.setLocationOffset(e.getX() - startPoint.x, 
                                   e.getY() - startPoint.y) 

def releaseEvent(e):
    if isGameOver:
        return
    if movingMarble == None:
        return
    destLoc = toLocationInGrid(e.getX(), e.getY())
    movingMarble.setLocationOffset(0, 0)
    removeMarble = getRemoveMarble(startLoc, destLoc)
    if removeMarble != None:
        removeActor(removeMarble)
        movingMarble.setLocation(destLoc)    
        checkGameOver()

startLoc = None
movingMarble = None
isGameOver = False

makeGameGrid(7, 7, 70, None, "sprites/solitaire_board.png", False,
   mousePressed = pressEvent, mouseDragged = dragEvent, 
   mouseReleased = releaseEvent)
setBgColor(Color(255, 166, 0))
setSimulationPeriod(20)
initBoard()
show()
doRun()
Programmcode markieren (Ctrl+C kopieren, Ctrl+V einfügen)

 

Erklärungen zum Programmcode:

checkGameOver(): Das Spiel ist fertig, fass nur ein Stein übrig bleibt. In diesem Fall hat der Spieler gewonnen. Es gibt aber auch Spielsituationen, bei welchen noch mehrere Spielsteine auf dem Brett liegen, es ist aber kein Spielzug mehr möglich.
pressEvent(e) : Wählt einen Stein aus
dragEvent(e): Der Stein kann mit gedrückten Maustaste bewegt werden
releaseEvent(e): Der Stei wird an der aktuellen Position abgelegt, dabei muss überprüft werden, ob der Zug korrekt ist
getRemoveMarble(start, dest): Gibt beim legalen Zug den zu entfernenden Stein und beim nichterlaubten Zug None zurück