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 mit Mausklick im oberen Kanal über die gewählte Spalte setzen. Der Spielstein bewegt nach unten und besetzt 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. |
Server |
Client |
Einige Funktionen und die Klasse Token() werden sowohl im Server- als auch im Clientprogramm benötigt. Diese Programmteile werden in der Datei fourlib.py gespeichert.
Server (wird zuerst gestartet):
# TcpFourServer.py from gamegrid import * from tcpcom import TCPServer import fourlib def onMousePressed(e): global isMyMove, location if not isMyMove or fourlib.isOver: return location = toLocationInGrid(e.getX(), e.getY()) token = fourlib.Token(1) addActor(token, location, Location.SOUTH) server.sendMessage(str(location.x)) # send location isMyMove = False setStatusText("Wait!") def onNotifyExit(): server.terminate() dispose() def onStateChanged(state, msg): global isMyMove, location if state == TCPServer.PORT_IN_USE: setStatusText("TCP port occupied. Restart IDE.") if state == TCPServer.LISTENING: setStatusText("Waiting for a partner to play") if state == TCPServer.CONNECTED: setStatusText("Client connected. Wait for partner's move!") elif state == TCPServer.MESSAGE: x = int(msg[0]) location = Location(x, 0) token = fourlib.Token(0) addActor(token, location, Location.SOUTH) isMyMove = True setStatusText("Make your move!") makeGameGrid(7, 7, 70, None, "sprites/connectbg.png", False, mousePressed = onMousePressed, notifyExit = onNotifyExit) setBgColor(makeColor("white")) addStatusBar(30) isMyMove = False show() setSimulationPeriod(30) doRun() port = 5000 server = TCPServer(port, stateChanged = onStateChanged) |
------------------------------------------------------------------------------------------------------------------------------
Client:
# TcpFourClient.py from gamegrid import * from tcpcom import TCPClient import fourlib def onMousePressed(e): global isMyMove, location if not isMyMove or fourlib.isOver: return location = toLocationInGrid(e.getX(), e.getY()) token = fourlib.Token(0) addActor(token, location, Location.SOUTH) client.sendMessage(str(location.x)) setStatusText("Wait!") def onNotifyExit(): client.disconnect() dispose() def onStateChanged(state, msg): global isMyMove, location if state == TCPClient.CONNECTED: setStatusText("Connection established. You play!") isMyMove = True elif state == TCPClient.CONNECTION_FAILED: setStatusText("Connection failed") elif state == TCPClient.DISCONNECTED: setStatusText("Server died") isMyMove = False elif state == TCPClient.MESSAGE: x = int(msg[0]) location = Location(x, 0) token = fourlib.Token(1) addActor(token, location, Location.SOUTH) isMyMove = True setStatusText("Make your move!") makeGameGrid(7, 7, 70, None, "sprites/connectbg.png", False, mousePressed = onMousePressed, notifyExit = onNotifyExit) setBgColor(makeColor("white")) isMyMove = False addStatusBar(30) show() setSimulationPeriod(30) doRun() host = "localhost" port = 5000 client = TCPClient(host, port, stateChanged = onStateChanged) client.connect() |
------------------------------------------------------------------------------------------------------------------------------------
Import-Datei:
# fourlib.py from gamegrid import * isOver = False #----------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 def act(self): global isOver 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 checkOver(self.getLocation()): if self.player == 0: won = "Yellow" else: won = "Red" setStatusText("Game Over, player " + won + " won!") isOver = True #----------check Game over------------------------------------- def getId(x, y): loc = Location(x, y) if getOneActorAt(loc) == None: return -1 else: return getOneActorAt(loc).getIdVisible() #check for four def checkDiagonal(col, row): for j in range(4): nb = 0 for i in range(4): if (col + i - j) >= 0 and (col + i - j) < 7 and (row + i - j) >= 1 \ and (row + i - j) < 7 \ and getId(col + i - j, row + i - j) == getId(col, row): nb = nb + 1 if nb >= 4: return True return False def checkDiagonal2(col, row): for j in range(4): nb = 0 for i in range(4): if (col - i + j) >= 0 and (col - i + j) < 7 \ and (row + i - j) >= 1 and (row + i - j) < 7 \ and getId(col - i + j, row + i - j) == getId(col, row): nb = nb + 1 if nb >= 4: return True return False def checkHorizontal(col, row): nb = 1 i = 1 while col - i >= 0 and getId(col - i, row) == getId(col, row): nb = nb + 1 i += 1 i = 1 while col + i < 7 and getId(col + i, row) == getId(col, row): nb = nb + 1 i += 1 return nb >= 4 def checkVertical(col, row): nb = 1 i = 1 while row + i < 7 and getId(col, row + i) == getId(col, row): nb = nb + 1 i += 1 return nb >= 4 #return true, if four in a row def checkOver(loc): col = loc.x row = loc.y return (checkVertical(col, row) or checkHorizontal(col, row) or checkDiagonal(col, row) or checkDiagonal2(col, row)) |
Erklärungen zum Programmcode:
class Token(): Die Spielsteine sind Objekte der Klasse Token(). Die Klasse verwendet zwei Spritebilder token_0.png für die gelben und token_1.png für die roten Steine. In der Methode act() wird die Bewegung der Spielsteine festgelegt | |
checkOver(loc) gibt True zurück, falls einer der Checks (horizontal, vertikal und beide Diagonalen) positiv ausfällt |