TigerJython | xx für Gymnasien |
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. |
Player 0 |
Player 1 |
Die beiden Spieler wählen das gleiche Topic /swissgame/four in a row und müssen vor dem Spielbeginn die Programmzeile player = 0 bzw. player = 1 ergänzen. Der Player 0 beginnt.
# FourInARow.py from gamegrid import * from mqttclient import GameClient import fourlib player = x # set player = 0 or player = 1 myTopic = "/swissgame/four_in_a_row" def onMousePressed(e): global isMyMove, location if not isMyMove or fourlib.isOver: return location = toLocationInGrid(e.getX(), e.getY()) token = fourlib.Token(player) addActor(token, location, Location.SOUTH) client.sendMessage(str(location.x)) # send location isMyMove = False setStatusText("Wait!") def onNotifyExit(): client.disconnect() dispose() def onStateChanged(state): global isMyMove if state == "CONNECTING": setStatusText("Connecting to broker...") elif state == "CONNECTED": setStatusText("Connected. Waiting for partner...") elif state == "READY": if player == 0: setStatusText("Make a move!") isMyMove = True else: setStatusText("Wait for partner's move!") elif state == "DISCONNECTED": setStatusText("Partner disconnected!") isMyMove = False def onMessageReceived(msg): global isMyMove, location x = int(msg[0]) location = Location(x, 0) token = fourlib.Token((player + 1) % 2) 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() setTitle("Player #" + str(player)) host = "m2m.eclipse.org" client = GameClient(onStateChanged, onMessageReceived, myTopic) client.connect(host) |
Die Klasse Token und die Funktionen zur Überprüfung der Spielsituation werden in der Datei fourlib.py gespeichert und im Hauptprogramm mit import fourlib importiert.
# 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 |