Beginnen wir mit der Erkundung unseres Vertrags für das TicTacToe-Spiel:
Python
# TicTacToe – Beispiel nur zur Veranschaulichung.
import smartpy as sp
@sp.module
def main():
class TicTacToe(sp.Contract):
def __init__(self):
self.data.nbMoves = 0
self.data.winner = 0
self.data.draw = False
self.data.deck = {
0: {0: 0, 1: 0, 2: 0},
1: {0: 0, 1: 0, 2: 0},
2: {0: 0, 1: 0, 2: 0},
}
self.data.nextPlayer = 1
@ sp.entrypoint
def play(self, params):
Assert self.data.winner == 0 und nicht self.data.draw
Assert params.i >= 0 und params.i < 3
behaupten params.j >= 0 und params.j < 3
Assert params.move == self.data.nextPlayer
Assert self.data.deck[params.i][params.j] == 0
self.data.deck[params.i][params.j] = params.move
self.data.nbMoves += 1
self.data.nextPlayer = 3 - self.data.nextPlayer
self.data.winner = self.checkLine(
sp.record(winner=self.data.winner, line=self.data.deck[params.i])
)
self.data.winner = self.checkLine(
sp.record(
Gewinner=self.data.winner,
line={
0: self.data.deck[0][params.j],
1: self.data.deck[1][params.j],
2: self.data.deck[2][params.j],
},
)
)
self.data.winner = self.checkLine(
sp.record(
Gewinner=self.data.winner,
line={
0: self.data.deck[0][0],
1: self.data.deck[1][1],
2: self.data.deck[2][2],
},
)
)
self.data.winner = self.checkLine(
sp.record(
Gewinner=self.data.winner,
line={
0: self.data.deck[0][2],
1: self.data.deck[1][1],
2: self.data.deck[2][0],
},
)
)
if self.data.nbMoves == 9 and self.data.winner == 0:
self.data.draw = True
@sp.private()
def checkLine(self , Gewinner, Zeile):
Gewinner_ = Gewinner
wenn Zeile[0] != 0 und Zeile[0] == Zeile[1] und Zeile[0] == Zeile[2]:
Gewinner_ = Zeile[0]
return won_
# Eine Spiel-Reset-Funktion hinzufügen
@sp.entrypoint
def bestätigen_and_reset(self):
Assert self.data.winner != 0 or self.data.draw
self.__init__()
# Testet
, wenn „Vorlagen“ nicht in __name__ enthalten sind:
@sp.add_test(name="TicTacToe")
def test():
Szenario = sp.test_scenario(main)
Szenario.h1("Tic-Tac-Toe")
# einen Vertrag definieren
c1 = main.TicTacToe()
# seine Darstellung anzeigen
scene.h2("A Abfolge von Interaktionen mit einem Gewinner")
Szenario += c1
Szenario.h2("Nachricht Ausführung")
Szenario.h3("A erster Zug in der Mitte")
c1.play(i=1, j=1, move=1)
scene.h3("A verbotener Zug")
c1.play(i=1, j=1, move=2).run(valid=False)
Szenario.h3("A zweiter Zug")
c1.play(i=1, j=2, move=2)
scene.h3("Other bewegt")
c1.play(i=2, j=1, move=1)
c1.play(i=2, j=2, move=2)
scene.verify(c1.data.winner == 0 )
c1.play(i=0, j=1, move=1)
Scenario.verify(c1.data.winner == 1)
Scenario.p("Player1 hat gewonnen")
c1.play(i=0, j=0, move=2).run(valid=False)
c2 = main.TicTacToe()
Szenario.h2("A Abfolge von Interaktionen mit einem Unentschieden")
Szenario += c2
Szenario.h2("Nachricht Ausführung")
Szenario.h3("A erster Zug in der Mitte")
c2.play(i=1, j=1, move=1)
scene.h3("A verbotener Zug")
c2.play(i=1, j=1, move=2).run(valid=False)
Szenario.h3("A zweiter Zug")
c2.play(i=1, j=2, move=2)
scene.h3("Other bewegt")
c2.play(i=2, j=1, move=1)
c2.play(i=2, j=2, move=2)
c2.play(i=0, j=0, move=1)
c2.play(i=0, j=1, move=2)
c2.play(i=0, j=2, move=1)
c2.play(i=2, j=0 , move=2)
c2.play(i=1, j=0, move=1)
# Tests für Spiel-Reset hinzufügen
scene.h2("Testing Spiel zurückgesetzt")
Szenario.p("Gewinner oder Unentschieden bestätigt, das Spiel wird jetzt zurückgesetzt")
c1.confirm_and_reset()
Szenario.verify(c1.data.nbMoves == 0)
Szenario.verify(c1.data.winner == 0)
Szenario.verify(not c1.data.draw)
c2.confirm_and_reset()
Scenario.verify(c2.data.nbMoves == 0)
Scenario.verify(c2.data.winner == 0)
Scenario.verify(not c2.data.draw)
Der Vertrag für unser TicTacToe-Spiel auf Tezos ist in der Sprache SmartPy verfasst. Es besteht aus zwei Hauptteilen: dem Vertragszustand und der Logik des Spiels.
Der Status des Vertrags wird in der Funktion **init initialisiert.
Es enthält:
nbMoves
: Dies ist ein Zähler für die Anzahl der im Spiel ausgeführten Züge. Es beginnt bei Null.winner
: Hiermit wird der Gewinner des Spiels verfolgt. Anfangs ist es Null, was darauf hinweist, dass es keinen Gewinner gibt.draw
: Dies ist eine Flagge, die anzeigt, ob das Spiel unentschieden endete. Zunächst ist es falsch.deck
: Dies ist ein 3x3-Raster, das das TicTacToe-Brett darstellt. Alle Felder auf der Tafel sind zunächst leer, dargestellt durch Nullen.nextPlayer
: Hier wird angezeigt, wer an der Reihe ist. Das Spiel beginnt mit Spieler 1, daher ist es zunächst auf 1 eingestellt.Die Spiellogik ist in der play
gekapselt. Es führt mehrere Prüfungen durch, um einen gültigen Umzug sicherzustellen:
nextPlayer
übereinstimmt.nbMoves
, wechselt den nextPlayer
und prüft, ob der Zug zu einem Sieg oder einem Unentschieden geführt hat.Die Gewinnbedingung wird in der Zeile und Spalte des letzten Zuges sowie in den beiden Diagonalen überprüft.
Wenn alle Plätze auf dem Spielbrett besetzt sind und kein Spieler gewonnen hat (dh nbMoves
beträgt 9 und winner
ist immer noch 0), wird das Spiel als unentschieden erklärt.
Mit der checkLine
Funktion wird überprüft, ob ein Spieler gewonnen hat. Es prüft, ob alle Felder in einer Reihe (die eine Reihe, eine Spalte oder eine Diagonale sein kann) vom selben Spieler besetzt sind. Wenn ja, wird dieser Spieler zum Gewinner erklärt.
Interaktionen mit dem Vertrag werden als Transaktionen dargestellt. Wenn ein Spieler durch Aufrufen der play
einen Zug ausführt, wird eine Transaktion generiert. Diese Transaktion wird protokolliert und ist im rechten Bereich der SmartPy-IDE zu sehen:
Ein fehlgeschlagener oder ungültiger Umzug würde ebenfalls eine Transaktion generieren, allerdings mit einer Fehlermeldung:
Der erste Zug in unserem TicTacToe-Spiel ist relativ einfach, da das Spielbrett leer ist. Interessanter wird es jedoch mit dem zweiten Zug und den folgenden Zügen. Diese Züge fügen nicht nur Spielsteine zum Spielbrett hinzu, sondern rufen auch die Logik des Spiels hervor, um nach potenziellen Gewinnern zu suchen.
Nach dem ersten Zug wechselt der nextPlayer
Wert zu Spieler 2. Jetzt validiert die play
Funktion den Zug von Spieler 2. Ähnliche Prüfungen werden durchgeführt, um sicherzustellen, dass die Verschiebung gültig ist, dh, dass der ausgewählte Rasterpunkt innerhalb der Grenzen liegt und leer ist.
Wenn jeder Spieler einen Zug macht, entwickelt sich der Spielzustand. Die nbMoves
erhöhen sich, der nextPlayer
schaltet um und das deck
wird aktualisiert. Außerdem prüft der Vertrag nach jedem Zug, ob es einen Gewinner oder ein Unentschieden gibt.
Nachdem beispielsweise der erste Spieler einen Zug in der Mitte des Spielfelds bei i=1, j=1
ausgeführt hat, kann der zweite Spieler an einer anderen Stelle spielen, beispielsweise bei i=1, j=2
. Beide Schritte würden validiert und erfolgreich ausgeführt, wobei die entsprechenden Transaktionen generiert würden.
Nachfolgende Bewegungen werden auf ähnliche Weise fortgesetzt. Jeder Spieler spielt abwechselnd und wählt einen freien Platz auf dem Spielbrett. Nach jedem Zug prüft der Vertrag, ob eine Gewinnbedingung vorliegt. Wenn ein Spieler eine ganze Reihe, Spalte oder Diagonale mit seinem Symbol füllt, endet das Spiel und dieser Spieler wird zum Gewinner erklärt. Die winner
im Vertragsstatus würde entsprechend aktualisiert.
Es ist wichtig zu beachten, dass, sobald ein Spieler gewonnen hat, keine weiteren Züge gültig sind. Jeder Versuch, nach Spielende einen Zug auszuführen, würde als ungültig gewertet und die entsprechende Transaktion würde fehlschlagen.
Bei manchen Spielen kann es vorkommen, dass kein Spieler die Gewinnbedingung erreicht, selbst wenn das gesamte Spielbrett gefüllt ist. Dies führt zu einem Unentschieden. Der Vertrag ist so konzipiert, dass er auch dieser Situation gerecht wird.
Wenn alle Plätze auf dem Spielbrett besetzt sind (nbMoves
gleich 9) und kein Spieler gewonnen hat (winner
bleibt 0), gilt das Spiel als unentschieden. Das draw
Flag im Vertragsstatus ist auf „True“ gesetzt, was bedeutet, dass das Spiel unentschieden endete. Auch hier sind nach diesem Zeitpunkt keine weiteren Züge mehr gültig. Auch alle Zugversuche nach einem Unentschieden würden scheitern.
Der zweite Teil des Testszenarios des TicTacToe-Vertrags demonstriert dieses Zeichnungsszenario. Es simuliert eine Reihe von Zügen, die zu einem Unentschieden führen, und überprüft, ob der Vertrag damit richtig umgeht.
Beginnen wir mit der Erkundung unseres Vertrags für das TicTacToe-Spiel:
Python
# TicTacToe – Beispiel nur zur Veranschaulichung.
import smartpy as sp
@sp.module
def main():
class TicTacToe(sp.Contract):
def __init__(self):
self.data.nbMoves = 0
self.data.winner = 0
self.data.draw = False
self.data.deck = {
0: {0: 0, 1: 0, 2: 0},
1: {0: 0, 1: 0, 2: 0},
2: {0: 0, 1: 0, 2: 0},
}
self.data.nextPlayer = 1
@ sp.entrypoint
def play(self, params):
Assert self.data.winner == 0 und nicht self.data.draw
Assert params.i >= 0 und params.i < 3
behaupten params.j >= 0 und params.j < 3
Assert params.move == self.data.nextPlayer
Assert self.data.deck[params.i][params.j] == 0
self.data.deck[params.i][params.j] = params.move
self.data.nbMoves += 1
self.data.nextPlayer = 3 - self.data.nextPlayer
self.data.winner = self.checkLine(
sp.record(winner=self.data.winner, line=self.data.deck[params.i])
)
self.data.winner = self.checkLine(
sp.record(
Gewinner=self.data.winner,
line={
0: self.data.deck[0][params.j],
1: self.data.deck[1][params.j],
2: self.data.deck[2][params.j],
},
)
)
self.data.winner = self.checkLine(
sp.record(
Gewinner=self.data.winner,
line={
0: self.data.deck[0][0],
1: self.data.deck[1][1],
2: self.data.deck[2][2],
},
)
)
self.data.winner = self.checkLine(
sp.record(
Gewinner=self.data.winner,
line={
0: self.data.deck[0][2],
1: self.data.deck[1][1],
2: self.data.deck[2][0],
},
)
)
if self.data.nbMoves == 9 and self.data.winner == 0:
self.data.draw = True
@sp.private()
def checkLine(self , Gewinner, Zeile):
Gewinner_ = Gewinner
wenn Zeile[0] != 0 und Zeile[0] == Zeile[1] und Zeile[0] == Zeile[2]:
Gewinner_ = Zeile[0]
return won_
# Eine Spiel-Reset-Funktion hinzufügen
@sp.entrypoint
def bestätigen_and_reset(self):
Assert self.data.winner != 0 or self.data.draw
self.__init__()
# Testet
, wenn „Vorlagen“ nicht in __name__ enthalten sind:
@sp.add_test(name="TicTacToe")
def test():
Szenario = sp.test_scenario(main)
Szenario.h1("Tic-Tac-Toe")
# einen Vertrag definieren
c1 = main.TicTacToe()
# seine Darstellung anzeigen
scene.h2("A Abfolge von Interaktionen mit einem Gewinner")
Szenario += c1
Szenario.h2("Nachricht Ausführung")
Szenario.h3("A erster Zug in der Mitte")
c1.play(i=1, j=1, move=1)
scene.h3("A verbotener Zug")
c1.play(i=1, j=1, move=2).run(valid=False)
Szenario.h3("A zweiter Zug")
c1.play(i=1, j=2, move=2)
scene.h3("Other bewegt")
c1.play(i=2, j=1, move=1)
c1.play(i=2, j=2, move=2)
scene.verify(c1.data.winner == 0 )
c1.play(i=0, j=1, move=1)
Scenario.verify(c1.data.winner == 1)
Scenario.p("Player1 hat gewonnen")
c1.play(i=0, j=0, move=2).run(valid=False)
c2 = main.TicTacToe()
Szenario.h2("A Abfolge von Interaktionen mit einem Unentschieden")
Szenario += c2
Szenario.h2("Nachricht Ausführung")
Szenario.h3("A erster Zug in der Mitte")
c2.play(i=1, j=1, move=1)
scene.h3("A verbotener Zug")
c2.play(i=1, j=1, move=2).run(valid=False)
Szenario.h3("A zweiter Zug")
c2.play(i=1, j=2, move=2)
scene.h3("Other bewegt")
c2.play(i=2, j=1, move=1)
c2.play(i=2, j=2, move=2)
c2.play(i=0, j=0, move=1)
c2.play(i=0, j=1, move=2)
c2.play(i=0, j=2, move=1)
c2.play(i=2, j=0 , move=2)
c2.play(i=1, j=0, move=1)
# Tests für Spiel-Reset hinzufügen
scene.h2("Testing Spiel zurückgesetzt")
Szenario.p("Gewinner oder Unentschieden bestätigt, das Spiel wird jetzt zurückgesetzt")
c1.confirm_and_reset()
Szenario.verify(c1.data.nbMoves == 0)
Szenario.verify(c1.data.winner == 0)
Szenario.verify(not c1.data.draw)
c2.confirm_and_reset()
Scenario.verify(c2.data.nbMoves == 0)
Scenario.verify(c2.data.winner == 0)
Scenario.verify(not c2.data.draw)
Der Vertrag für unser TicTacToe-Spiel auf Tezos ist in der Sprache SmartPy verfasst. Es besteht aus zwei Hauptteilen: dem Vertragszustand und der Logik des Spiels.
Der Status des Vertrags wird in der Funktion **init initialisiert.
Es enthält:
nbMoves
: Dies ist ein Zähler für die Anzahl der im Spiel ausgeführten Züge. Es beginnt bei Null.winner
: Hiermit wird der Gewinner des Spiels verfolgt. Anfangs ist es Null, was darauf hinweist, dass es keinen Gewinner gibt.draw
: Dies ist eine Flagge, die anzeigt, ob das Spiel unentschieden endete. Zunächst ist es falsch.deck
: Dies ist ein 3x3-Raster, das das TicTacToe-Brett darstellt. Alle Felder auf der Tafel sind zunächst leer, dargestellt durch Nullen.nextPlayer
: Hier wird angezeigt, wer an der Reihe ist. Das Spiel beginnt mit Spieler 1, daher ist es zunächst auf 1 eingestellt.Die Spiellogik ist in der play
gekapselt. Es führt mehrere Prüfungen durch, um einen gültigen Umzug sicherzustellen:
nextPlayer
übereinstimmt.nbMoves
, wechselt den nextPlayer
und prüft, ob der Zug zu einem Sieg oder einem Unentschieden geführt hat.Die Gewinnbedingung wird in der Zeile und Spalte des letzten Zuges sowie in den beiden Diagonalen überprüft.
Wenn alle Plätze auf dem Spielbrett besetzt sind und kein Spieler gewonnen hat (dh nbMoves
beträgt 9 und winner
ist immer noch 0), wird das Spiel als unentschieden erklärt.
Mit der checkLine
Funktion wird überprüft, ob ein Spieler gewonnen hat. Es prüft, ob alle Felder in einer Reihe (die eine Reihe, eine Spalte oder eine Diagonale sein kann) vom selben Spieler besetzt sind. Wenn ja, wird dieser Spieler zum Gewinner erklärt.
Interaktionen mit dem Vertrag werden als Transaktionen dargestellt. Wenn ein Spieler durch Aufrufen der play
einen Zug ausführt, wird eine Transaktion generiert. Diese Transaktion wird protokolliert und ist im rechten Bereich der SmartPy-IDE zu sehen:
Ein fehlgeschlagener oder ungültiger Umzug würde ebenfalls eine Transaktion generieren, allerdings mit einer Fehlermeldung:
Der erste Zug in unserem TicTacToe-Spiel ist relativ einfach, da das Spielbrett leer ist. Interessanter wird es jedoch mit dem zweiten Zug und den folgenden Zügen. Diese Züge fügen nicht nur Spielsteine zum Spielbrett hinzu, sondern rufen auch die Logik des Spiels hervor, um nach potenziellen Gewinnern zu suchen.
Nach dem ersten Zug wechselt der nextPlayer
Wert zu Spieler 2. Jetzt validiert die play
Funktion den Zug von Spieler 2. Ähnliche Prüfungen werden durchgeführt, um sicherzustellen, dass die Verschiebung gültig ist, dh, dass der ausgewählte Rasterpunkt innerhalb der Grenzen liegt und leer ist.
Wenn jeder Spieler einen Zug macht, entwickelt sich der Spielzustand. Die nbMoves
erhöhen sich, der nextPlayer
schaltet um und das deck
wird aktualisiert. Außerdem prüft der Vertrag nach jedem Zug, ob es einen Gewinner oder ein Unentschieden gibt.
Nachdem beispielsweise der erste Spieler einen Zug in der Mitte des Spielfelds bei i=1, j=1
ausgeführt hat, kann der zweite Spieler an einer anderen Stelle spielen, beispielsweise bei i=1, j=2
. Beide Schritte würden validiert und erfolgreich ausgeführt, wobei die entsprechenden Transaktionen generiert würden.
Nachfolgende Bewegungen werden auf ähnliche Weise fortgesetzt. Jeder Spieler spielt abwechselnd und wählt einen freien Platz auf dem Spielbrett. Nach jedem Zug prüft der Vertrag, ob eine Gewinnbedingung vorliegt. Wenn ein Spieler eine ganze Reihe, Spalte oder Diagonale mit seinem Symbol füllt, endet das Spiel und dieser Spieler wird zum Gewinner erklärt. Die winner
im Vertragsstatus würde entsprechend aktualisiert.
Es ist wichtig zu beachten, dass, sobald ein Spieler gewonnen hat, keine weiteren Züge gültig sind. Jeder Versuch, nach Spielende einen Zug auszuführen, würde als ungültig gewertet und die entsprechende Transaktion würde fehlschlagen.
Bei manchen Spielen kann es vorkommen, dass kein Spieler die Gewinnbedingung erreicht, selbst wenn das gesamte Spielbrett gefüllt ist. Dies führt zu einem Unentschieden. Der Vertrag ist so konzipiert, dass er auch dieser Situation gerecht wird.
Wenn alle Plätze auf dem Spielbrett besetzt sind (nbMoves
gleich 9) und kein Spieler gewonnen hat (winner
bleibt 0), gilt das Spiel als unentschieden. Das draw
Flag im Vertragsstatus ist auf „True“ gesetzt, was bedeutet, dass das Spiel unentschieden endete. Auch hier sind nach diesem Zeitpunkt keine weiteren Züge mehr gültig. Auch alle Zugversuche nach einem Unentschieden würden scheitern.
Der zweite Teil des Testszenarios des TicTacToe-Vertrags demonstriert dieses Zeichnungsszenario. Es simuliert eine Reihe von Zügen, die zu einem Unentschieden führen, und überprüft, ob der Vertrag damit richtig umgeht.