Auf einem 8×8-Brett legen zwei Spieler abwechslungsweise gelbe und rote Spielsteine. Zu Beginn des Spiels sind bereits je zwei gelbe und rote Steine in der Mitte des Spielbretts gelegt. Die weiteren Spielsteine können per Mausklick in leere Zellen gelegt werden, bei welchen mindestens eine der benachbarten Zellen oben, unten, links oder rechts belegt ist. |
|
Wird ein Stein gelegt, so werden alle gegnerischen Steine, die sich in Reihen oder Diagonalen zwischen dem neuen und bereits gelegten Steinen der eigenen Farbe befinden, durch Steine der eigenen Farbe ersetzt. Das Ziel des Spiels ist es, am Ende möglichst viele eigene Steine auf dem Brett zu haben. Das Spiel ist fertig, wenn alle Zellen belegt sind.
Server |
Client |
Zuerst muss das Serverprogramm gestartet werden. Der Client beginnt das Spiel. Einige Funktionen im Server- und Clientprogramm sind identisch, insbesondere die Übeprüfung der Spielsituation nach jedem Zug. Es ist daher sinnvoll diese Funktionen in einer separaten Datei (reversilib.py) im gleichen Verzeichnis, wie das Server- und Client-Programm, zu speichern und diese zu importieren. Die importierten Funktionen müssen durch Voranstellen von "reversilib." aufgerufen werden.
So wie in den vorhergehenden Beispielen werden jeweils die x- und y-Koordinaten des Mausklicks übermittelt. Die Überprüfung des Spielsituation und das Kehren der Spielsteine erfolgt bei jedem Spieler autonom.
# ReversiServer.py from gamegrid import * from tcpcom import TCPServer import reversilib def onMousePressed(e): global isMyMove, location if not isMyMove or isOver: return location = toLocationInGrid(e.getX(), e.getY()) if getOneActorAt(location) == None and reversilib.hasNeighbours(location): stone = Actor("sprites/token.png", 2) addActor(stone, location) stone.show(1) reversilib.checkStones(1, location) refresh() server.sendMessage(str(location.x) + str(location.y)) # send location isMyMove = False setStatusText("Wait!") if len(getOccupiedLocations()) == 64: reversilib.endOfGame() server.sendMessage("end") def onNotifyExit(): server.terminate() dispose() def onStateChanged(state, msg): global isMyMove,imegeID, 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: if msg == "end": reversilib.endOfGame() else: x = int(msg[0]) y = int(msg[1]) location = Location(x, y) stone = Actor("sprites/token.png", 2) addActor(stone, location) stone.show(0) reversilib.checkStones(0, location) refresh() isMyMove = True setStatusText("Make your move!") isMyMove = False makeGameGrid(8, 8, 60, Color.gray, False, mousePressed = onMousePressed, notifyExit = onNotifyExit) addStatusBar(30) reversilib.initGame() show() port = 5000 server = TCPServer(port, stateChanged = onStateChanged) isOver = False |
# ReversiClient.py from gamegrid import * from tcpcom import TCPClient import reversilib def onMousePressed(e): global isMyMove, location if not isMyMove or isOver: return location = toLocationInGrid(e.getX(), e.getY()) if getOneActorAt(location) == None and reversilib.hasNeighbours(location): stone = Actor("sprites/token.png", 2) addActor(stone, location) stone.show(0) reversilib.checkStones(0, location) refresh() client.sendMessage(str(location.x) + str(location.y)) # send location isMyMove = False setStatusText("Wait!") if len(getOccupiedLocations()) == 64: reversilib.endOfGame() client.sendMessage("end") def onNotifyExit(): client.disconnect() dispose() def onStateChanged(state, msg): global isMyMove, imegeID, 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: if msg == "end": reversilib.endOfGame() else: x = int(msg[0]) y = int(msg[1]) location = Location(x, y) stone = Actor("sprites/token.png", 2) addActor(stone, location) stone.show(1) reversilib.checkStones(1, location) refresh() isMyMove = True setStatusText("Make your move!") isMyMove = False makeGameGrid(8, 8, 60, Color.gray, False, mousePressed = onMousePressed, notifyExit = onNotifyExit) addStatusBar(30) reversilib.initGame() show() host = "localhost" port = 5000 client = TCPClient(host, port, stateChanged = onStateChanged) client.connect() isOver = False |
-----------------------------------------------------------------------------------------------------------------------------------
# reversilib.py from gamegrid import * def initGame(): yellow = Actor("sprites/token.png", 2) yellow2 = Actor("sprites/token.png", 2) red = Actor("sprites/token.png", 2) red2 = Actor("sprites/token.png", 2) addActor(yellow, Location(3, 3)) addActor(yellow2, Location(4, 4)) addActor(red, Location(4, 3)) addActor(red2, Location(3, 4)) yellow.show(0) yellow2.show(0) red.show(1) red2.show(1) #Checks if cell has a neighbour in the north, east, south or west def hasNeighbours(loc): locs = toList(loc.getNeighbourLocations(0.5)) for i in range(4): if getOneActorAt(locs[i]) != None: return True return False # Check for stones in all 8 directions and if they can be turned add list def checkStones(imageID, location): for c in range (0, 360, 45): actors = [] loc = location.getNeighbourLocation(c) a = getOneActorAt(loc) hasSameImageID = False while a != None and not hasSameImageID: if a.getIdVisible() != imageID: actors.append(a) loc = loc.getNeighbourLocation(c) a = getOneActorAt(loc) else: if a.getIdVisible() == imageID: hasSameImageID = True # Turn stones if hasSameImageID: for actor in actors: actor.show(imageID) # endOfGame def endOfGame(): countYellow = 0 countRed = 0 all = getOccupiedLocations() for lc in all: if getOneActorAt(lc).getIdVisible() == 0: countYellow += 1 else: countRed += 1 if len(all) == 64: if countRed > countYellow: setStatusText("Game over. Red wins - " + str(countRed) + ":" + str(countYellow)) elif countRed < countYellow: setStatusText("Game over. Yellow wins - " + str(countYellow) + ":" + str(countRed)) else: setStatusText("The game ended in a tie") |
Erklärungen zum Programmcode:
reversilib.initGame(): Erzeugt das Spielfeld mit 2 roten und gelben Steinen. Diese Funktion ist in reversilib.py definiert | |
locs = toList(loc.getNeighbourLocations(0.5)): Liste der 4 direkt benachbarten Zellen | |
for c in range (0, 360, 45): 8 Richtungen 0, 45, 90, 135,...315 | |
loc = location.getNeighbourLocation(c): Liefert benachbarte Zellen, die in der Richtung c liegen | |
all = getOccupiedLocations(): Liste aller besetzten Zellen |