fourInARow

FOUR IN A AROW

 

 

SPIELBESCHREIBUNG

 

Four In A Row ist ein Zweipersonen-Strategiespiel. Das Spielbrett besteht aus sieben Spalten (senkrecht) und sechs Reihen (waagrecht). Die Spieler positionieren abwechselnd ihre Spielsteine, indem sie den Spielstein im oberen Kanal durch Bewegung mit der Maus über die gewählte Spalte setzen und per Mausklick herunterlassen. Wenn die Spalte nicht bereits voll ist, besetzt der Spielstein den untersten freien Platz der Spalte. Gewinner ist der Spieler, der es als Erster schafft, vier seiner Spielsteine waagerecht, senkrecht oder diagonal in eine Linie zu bringen. Das Spiel endet unentschieden, wenn das Spielbrett komplett gefüllt ist, ohne dass ein Spieler eine Viererlinie gebildet hat.

 

 

Programm:

# FourInARow.py

from gamegrid import *

#------------- class Token -------------------
class Token(Actor):
    def __init__(self, player):
        Actor.__init__(self, "sprites/token.png", 2)
        self.player = player
        self.show(player)
        self.nb = 0
        self.setActEnabled(False) # do not start act() yet
 
    def act(self):
        global activeToken, isFalling, isFinished
        nextLoc = Location(self.getX(), self.getY() + 1)
        if (getOneActorAt(nextLoc) == None and self.isMoveValid()):
            if self.nb == 6:
                self.nb = 0
                self.setLocationOffset(Point(0, 0))
                self.move()
            else:
                self.setLocationOffset(Point(0, 10 * self.nb))
            self.nb = self.nb + 1         
        else:  # arrived
            self.setActEnabled(False)  # old token will stay where it is
            if check4Win(self.getLocation()):
                if self.player == 0:
                    won = "Yellow"
                else:
                    won = "Red"    
                setTitle("Game Over, player " + won + " won!")                 
                isFinished = True
            else:
                self.player = (self.player + 1) % 2 
                activeToken = Token(self.player)
                addActor(activeToken, Location(6, 0), Location.SOUTH)
                activeToken.setActEnabled(False)
            isFalling = False          

def onMousePressed(e):
    global isFalling
    isFalling = True
    activeToken.setActEnabled(True) # start act()
    
def onMouseMoved(e):
    if isFalling:
        return
    loc = toLocationInGrid(e.getX(), e.getY())
    if not isFinished: 
        activeToken.setX(loc.x)
    refresh() 
    
def getPlayerOfTokenAt(x, y):
    loc = Location(x, y)
    if getOneActorAt(loc) == None:
        return -1
    else:
        return getOneActorAt(loc).getIdVisible()

#for checking nrOfTokens (win situation: nrOfTokens = 4)
def checkDiagonally1(col, row, nrOfTokens):
    for j in range(nrOfTokens):
        adjacentSameTokens = 0
        for i in range(nrOfTokens):
            if (col+i-j) >= 0 and (col+i-j) < 7 and (row+i-j) >= 1 \
               and (row + i - j) < 7 \
               and getPlayerOfTokenAt(col + i - j, row + i - j) == \
                getPlayerOfTokenAt(col, row):
                adjacentSameTokens = adjacentSameTokens + 1
        if adjacentSameTokens >= nrOfTokens:
            return True
    return False

def checkDiagonally2(col, row, nrOfTokens):
    for j in range(nrOfTokens):
        adjacentSameTokens = 0
        for i in range(nrOfTokens):
            if (col - i + j) >= 0 and (col - i + j) < 7 \
               and (row + i - j) >= 1 and (row + i - j) < 7 \
               and getPlayerOfTokenAt(col - i + j, row + i - j) == \
                 getPlayerOfTokenAt(col, row):
                 adjacentSameTokens = adjacentSameTokens + 1
        if adjacentSameTokens >= nrOfTokens:
            return True
    return False

def checkHorizontally(col, row, nrOfTokens):
    adjacentSameTokens = 1
    i = 1
    while col - i >= 0 and getPlayerOfTokenAt(col - i, row) ==\ 
        getPlayerOfTokenAt(col, row):
        adjacentSameTokens = adjacentSameTokens + 1
        i = i + 1
    i = 1
    while col + i < 7 and getPlayerOfTokenAt(col + i, row) ==\ 
        getPlayerOfTokenAt(col, row):
        adjacentSameTokens = adjacentSameTokens + 1
        i = i + 1
    return adjacentSameTokens >= nrOfTokens

def checkVertically(col, row, nrOfTokens):
    adjacentSameTokens = 1
    i = 1
    while row + i < 7 and getPlayerOfTokenAt(col, row + i) ==\ 
       getPlayerOfTokenAt(col, row):
       adjacentSameTokens = adjacentSameTokens + 1
       i = i + 1
    return adjacentSameTokens >= nrOfTokens

#return true, if four are connected through that token
def check4Win(loc):
    col = loc.x
    row = loc.y
    return (checkVertically(col, row, 4) 
      or checkHorizontally(col, row, 4)
      or checkDiagonally1(col, row, 4)
      or checkDiagonally2(col, row, 4))

# ---------------- main ----------------------           
makeGameGrid(7, 7, 70, None, "sprites/connectbg.png", False,
     mousePressed = onMousePressed,
     mouseMoved = onMouseMoved)
setBgColor(makeColor("white"))
isFalling = False
activeToken =  Token(0)
isFinished = False
addActor(activeToken, Location(0, 0), Location.SOUTH)
setSimulationPeriod(30)
addStatusBar(30)
setTitle("Move mouse to a column and click to set the token.")
show()
doRun()
► In Zwischenablage kopieren

 

 

Erklärungen zum Programmcode

 
1. class Token(): ein Spielstein wird durch die Klasse Token() modelliert. Die Spritebilder token_0.png und token_1.png stellen die gelben und roten Steine dar

2.
check4Win(loc): gibt True zurück, falls einer der Checks (horizontal, vertikal und beide Diagonalen) positiv ausfällt

3. onMouseMoved(): der aktive Spielstein wird an die Position des Mauszeigers versetzt

4. onMousePressed(): die Methode act() der Klasse Token wird enabled. Der Spielstein bewegt sich auf den untersten freien Platz in der Spalte

5. \: Lange Zeilen können auf der nächsten Zeile fortgesetzt werden