Comencemos explorando nuestro contrato para el juego TicTacToe:
Python
# TicTacToe: ejemplo solo con fines ilustrativos.
importar smartpy como sp
@sp.module
def main():
clase TicTacToe(sp.Contract):
def __init__(self):
self.data.nbMoves = 0
self.data.winner = 0
self.data.draw = Falso
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):
afirmar self.data.winner == 0 y no self.data.draw
afirmar params.i >= 0 y parámetros.i < 3
afirmar params.j >= 0 y parámetros.j < 3
afirmar params.move == self.data.nextPlayer
afirmar 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(ganador=self.data.ganador, línea=self.data.deck[params.i])
)
self.datos.ganador = self.checkLine(
sp.record(
ganador=self.data.ganador,
línea={
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(
ganador=self.data.ganador,
línea={
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(
ganador=self.data.ganador,
línea ={
0: self.data.deck[0][2],
1: self.data.deck[1][1],
2: self.data.deck[2][0],
},
)
)
si self.data.nbMoves == 9 y self.data.winner == 0:
self.data.draw = True
@sp.private()
def checkLine(self , ganador, línea):
ganador_ = ganador
si línea[0] != 0 y línea[0] == línea[1] y línea[0] == línea[2]:
ganador_ = línea[0]
return ganador_
# Agregar una función de reinicio del juego
@sp.entrypoint
def confirm_and_reset(self):
afirmar self.data.winner! = 0 o self.data.draw
self.__init__()
# Pruebas
si las "plantillas" no están en __name__:
@sp.add_test(name="TicTacToe")
def test():
escenario = sp.test_scenario(main)
escenario.h1("Tic-Tac-Toe")
# definir un contrato
c1 = main.TicTacToe()
# mostrar su representación
escenario.h2("A secuencia de interacciones con un ganador")
escenario += c1
escenario.h2("Mensaje ejecución")
escenario.h3("A primer movimiento en el centro")
c1.play(i=1, j=1, movimiento=1)
escenario.h3("A movimiento prohibido")
c1.play(i=1, j=1, move=2).run(valid=False)
escenario.h3("A segundo movimiento")
c1.play(i=1, j=2, movimiento=2)
escenario.h3("Otro movimientos")
c1.play(i=2, j=1, movimiento=1)
c1.play(i=2, j=2, movimiento=2)
escenario.verify(c1.data.winner == 0 )
c1.play(i=0, j=1, mover=1)
escenario.verify(c1.data.winner == 1)
escenario.p("Jugador1 ha ganado")
c1.play(i=0, j=0, move=2).run(valid=False)
c2 = principal.TicTacToe()
escenario.h2("A secuencia de interacciones con un empate")
escenario += c2
escenario.h2("Mensaje ejecución")
escenario.h3("A primer movimiento en el centro")
c2.play(i=1, j=1, movimiento=1)
escenario.h3("A movimiento prohibido")
c2.play(i=1, j=1, move=2).run(valid=False)
escenario.h3("A segundo movimiento")
c2.play(i=1, j=2, movimiento=2)
escenario.h3("Otro mueve")
c2.play(i=2, j=1, movimiento=1)
c2.play(i=2, j=2, movimiento=2)
c2.play(i=0, j=0, mover=1)
c2.play(i=0, j=1, mover=2)
c2.play(i=0, j=2, mover=1)
c2.play(i=2, j=0 , move=2)
c2.play(i=1, j=0, move=1)
# Agregar pruebas para reiniciar el juego
escenario.h2("Pruebas reinicio del juego")
escenario.p("Ganador o sorteo confirmado, ahora reiniciando el juego")
c1.confirm_and_reset()
escenario.verify(c1.data.nbMoves == 0)
escenario.verify(c1.data.winner == 0)
escenario.verify(no c1.datos.draw)
c2.confirm_and_reset()
escenario.verify(c2.data.nbMoves == 0)
escenario.verify(c2.data.winner == 0)
escenario.verify(no c2.datos.draw)
El contrato de nuestro juego TicTacToe en Tezos está escrito en lenguaje SmartPy. Consta de dos partes principales: el estado del contrato y la lógica del juego.
El estado del contrato se inicializa en la función **init .
Incluye:
nbMoves
: Este es un contador del número de movimientos realizados en el juego. Comienza en cero.winner
: Esto realiza un seguimiento del ganador del juego. Inicialmente, es cero, lo que indica que no hay ganador.draw
: Esta es una bandera que indica si el juego ha terminado en empate. Inicialmente, es falso.deck
: Esta es una cuadrícula de 3x3 que representa el tablero TicTacToe. Todos los espacios del tablero están inicialmente vacíos y representados por ceros.nextPlayer
: Esto indica a quién le toca jugar. El juego comienza con el jugador 1, por lo que inicialmente está configurado en 1.La lógica del juego está resumida en la función play
. Realiza varias comprobaciones para garantizar un movimiento válido:
nextPlayer
.nbMoves
, cambia el nextPlayer
y verifica si el movimiento resultó en una victoria o un empate.La condición de ganancia se verifica en la fila y columna del último movimiento, así como en las dos diagonales.
Si todos los espacios en el tablero están ocupados y ningún jugador ha ganado (es decir, nbMoves
equivale a 9 y winner
sigue siendo 0), el juego se declara empatado.
La función checkLine
se utiliza para comprobar si algún jugador ha ganado. Comprueba si todos los espacios de una línea (que puede ser una fila, una columna o una diagonal) están ocupados por el mismo jugador. Si es así, ese jugador es declarado ganador.
Las interacciones con el contrato se representan como transacciones. Cuando un jugador realiza un movimiento llamando a la función play
, genera una transacción. Esta transacción se registra y se puede ver en el panel derecho del IDE de SmartPy:
Un movimiento fallido o no válido también generaría una transacción pero con una indicación de error:
El primer movimiento en nuestro juego TicTacToe es relativamente sencillo ya que el tablero de juego está vacío. Sin embargo, las cosas se ponen más interesantes con el segundo movimiento y los siguientes. Estos movimientos no sólo añaden piezas al tablero de juego, sino que también invocan la lógica del juego para buscar posibles ganadores.
Después del primer movimiento, el valor nextPlayer
cambia al jugador 2. Ahora, la función play
valida el movimiento del jugador 2. Se realizan comprobaciones similares para garantizar que el movimiento sea válido, es decir, que el punto de la cuadrícula seleccionado esté dentro de los límites y esté vacío.
A medida que cada jugador realiza un movimiento, el estado del juego evoluciona. Los nbMoves
aumentan, el nextPlayer
cambia y el deck
se actualiza. Además, después de cada movimiento, el contrato comprueba si hay un ganador o si hay empate.
Por ejemplo, después de que el primer jugador hace un movimiento en el centro del tablero en i=1, j=1
, el segundo jugador puede jugar en un lugar diferente, digamos i=1, j=2
. Ambos movimientos se validarían y ejecutarían con éxito, generándose las transacciones correspondientes.
Los movimientos posteriores continúan de manera similar. Cada jugador se turna para jugar, eligiendo un lugar vacío en el tablero. Después de cada movimiento, el contrato comprueba si hay alguna condición ganadora. Si un jugador llena una fila, columna o diagonal completa con su símbolo, el juego termina y ese jugador es declarado ganador. La variable winner
en el estado del contrato se actualizará en consecuencia.
Es importante tener en cuenta que una vez que un jugador ha ganado, no son válidos más movimientos. Cualquier intento de realizar un movimiento una vez finalizado el juego se considerará inválido y la transacción correspondiente fracasará.
En algunos juegos, es posible que ningún jugador logre una condición ganadora incluso después de que se haya llenado todo el tablero. Esto resulta en un empate. El contrato también ha sido diseñado para manejar esta situación.
Si se llenan todos los espacios del tablero (nbMoves
equivale a 9) y ningún jugador ha ganado (winner
sigue siendo 0), el juego se declara empatado. La bandera draw
en el estado del contrato se establece en Verdadero, lo que indica que el juego terminó en empate. Una vez más, no hay más movimientos válidos después de este punto. Cualquier intento de hacer un movimiento después de un empate también fracasaría.
La segunda parte del escenario de prueba del contrato TicTacToe demuestra este escenario de dibujo. Simula una serie de movimientos que resultan en un empate y verifica que el contrato lo maneja correctamente.
Comencemos explorando nuestro contrato para el juego TicTacToe:
Python
# TicTacToe: ejemplo solo con fines ilustrativos.
importar smartpy como sp
@sp.module
def main():
clase TicTacToe(sp.Contract):
def __init__(self):
self.data.nbMoves = 0
self.data.winner = 0
self.data.draw = Falso
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):
afirmar self.data.winner == 0 y no self.data.draw
afirmar params.i >= 0 y parámetros.i < 3
afirmar params.j >= 0 y parámetros.j < 3
afirmar params.move == self.data.nextPlayer
afirmar 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(ganador=self.data.ganador, línea=self.data.deck[params.i])
)
self.datos.ganador = self.checkLine(
sp.record(
ganador=self.data.ganador,
línea={
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(
ganador=self.data.ganador,
línea={
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(
ganador=self.data.ganador,
línea ={
0: self.data.deck[0][2],
1: self.data.deck[1][1],
2: self.data.deck[2][0],
},
)
)
si self.data.nbMoves == 9 y self.data.winner == 0:
self.data.draw = True
@sp.private()
def checkLine(self , ganador, línea):
ganador_ = ganador
si línea[0] != 0 y línea[0] == línea[1] y línea[0] == línea[2]:
ganador_ = línea[0]
return ganador_
# Agregar una función de reinicio del juego
@sp.entrypoint
def confirm_and_reset(self):
afirmar self.data.winner! = 0 o self.data.draw
self.__init__()
# Pruebas
si las "plantillas" no están en __name__:
@sp.add_test(name="TicTacToe")
def test():
escenario = sp.test_scenario(main)
escenario.h1("Tic-Tac-Toe")
# definir un contrato
c1 = main.TicTacToe()
# mostrar su representación
escenario.h2("A secuencia de interacciones con un ganador")
escenario += c1
escenario.h2("Mensaje ejecución")
escenario.h3("A primer movimiento en el centro")
c1.play(i=1, j=1, movimiento=1)
escenario.h3("A movimiento prohibido")
c1.play(i=1, j=1, move=2).run(valid=False)
escenario.h3("A segundo movimiento")
c1.play(i=1, j=2, movimiento=2)
escenario.h3("Otro movimientos")
c1.play(i=2, j=1, movimiento=1)
c1.play(i=2, j=2, movimiento=2)
escenario.verify(c1.data.winner == 0 )
c1.play(i=0, j=1, mover=1)
escenario.verify(c1.data.winner == 1)
escenario.p("Jugador1 ha ganado")
c1.play(i=0, j=0, move=2).run(valid=False)
c2 = principal.TicTacToe()
escenario.h2("A secuencia de interacciones con un empate")
escenario += c2
escenario.h2("Mensaje ejecución")
escenario.h3("A primer movimiento en el centro")
c2.play(i=1, j=1, movimiento=1)
escenario.h3("A movimiento prohibido")
c2.play(i=1, j=1, move=2).run(valid=False)
escenario.h3("A segundo movimiento")
c2.play(i=1, j=2, movimiento=2)
escenario.h3("Otro mueve")
c2.play(i=2, j=1, movimiento=1)
c2.play(i=2, j=2, movimiento=2)
c2.play(i=0, j=0, mover=1)
c2.play(i=0, j=1, mover=2)
c2.play(i=0, j=2, mover=1)
c2.play(i=2, j=0 , move=2)
c2.play(i=1, j=0, move=1)
# Agregar pruebas para reiniciar el juego
escenario.h2("Pruebas reinicio del juego")
escenario.p("Ganador o sorteo confirmado, ahora reiniciando el juego")
c1.confirm_and_reset()
escenario.verify(c1.data.nbMoves == 0)
escenario.verify(c1.data.winner == 0)
escenario.verify(no c1.datos.draw)
c2.confirm_and_reset()
escenario.verify(c2.data.nbMoves == 0)
escenario.verify(c2.data.winner == 0)
escenario.verify(no c2.datos.draw)
El contrato de nuestro juego TicTacToe en Tezos está escrito en lenguaje SmartPy. Consta de dos partes principales: el estado del contrato y la lógica del juego.
El estado del contrato se inicializa en la función **init .
Incluye:
nbMoves
: Este es un contador del número de movimientos realizados en el juego. Comienza en cero.winner
: Esto realiza un seguimiento del ganador del juego. Inicialmente, es cero, lo que indica que no hay ganador.draw
: Esta es una bandera que indica si el juego ha terminado en empate. Inicialmente, es falso.deck
: Esta es una cuadrícula de 3x3 que representa el tablero TicTacToe. Todos los espacios del tablero están inicialmente vacíos y representados por ceros.nextPlayer
: Esto indica a quién le toca jugar. El juego comienza con el jugador 1, por lo que inicialmente está configurado en 1.La lógica del juego está resumida en la función play
. Realiza varias comprobaciones para garantizar un movimiento válido:
nextPlayer
.nbMoves
, cambia el nextPlayer
y verifica si el movimiento resultó en una victoria o un empate.La condición de ganancia se verifica en la fila y columna del último movimiento, así como en las dos diagonales.
Si todos los espacios en el tablero están ocupados y ningún jugador ha ganado (es decir, nbMoves
equivale a 9 y winner
sigue siendo 0), el juego se declara empatado.
La función checkLine
se utiliza para comprobar si algún jugador ha ganado. Comprueba si todos los espacios de una línea (que puede ser una fila, una columna o una diagonal) están ocupados por el mismo jugador. Si es así, ese jugador es declarado ganador.
Las interacciones con el contrato se representan como transacciones. Cuando un jugador realiza un movimiento llamando a la función play
, genera una transacción. Esta transacción se registra y se puede ver en el panel derecho del IDE de SmartPy:
Un movimiento fallido o no válido también generaría una transacción pero con una indicación de error:
El primer movimiento en nuestro juego TicTacToe es relativamente sencillo ya que el tablero de juego está vacío. Sin embargo, las cosas se ponen más interesantes con el segundo movimiento y los siguientes. Estos movimientos no sólo añaden piezas al tablero de juego, sino que también invocan la lógica del juego para buscar posibles ganadores.
Después del primer movimiento, el valor nextPlayer
cambia al jugador 2. Ahora, la función play
valida el movimiento del jugador 2. Se realizan comprobaciones similares para garantizar que el movimiento sea válido, es decir, que el punto de la cuadrícula seleccionado esté dentro de los límites y esté vacío.
A medida que cada jugador realiza un movimiento, el estado del juego evoluciona. Los nbMoves
aumentan, el nextPlayer
cambia y el deck
se actualiza. Además, después de cada movimiento, el contrato comprueba si hay un ganador o si hay empate.
Por ejemplo, después de que el primer jugador hace un movimiento en el centro del tablero en i=1, j=1
, el segundo jugador puede jugar en un lugar diferente, digamos i=1, j=2
. Ambos movimientos se validarían y ejecutarían con éxito, generándose las transacciones correspondientes.
Los movimientos posteriores continúan de manera similar. Cada jugador se turna para jugar, eligiendo un lugar vacío en el tablero. Después de cada movimiento, el contrato comprueba si hay alguna condición ganadora. Si un jugador llena una fila, columna o diagonal completa con su símbolo, el juego termina y ese jugador es declarado ganador. La variable winner
en el estado del contrato se actualizará en consecuencia.
Es importante tener en cuenta que una vez que un jugador ha ganado, no son válidos más movimientos. Cualquier intento de realizar un movimiento una vez finalizado el juego se considerará inválido y la transacción correspondiente fracasará.
En algunos juegos, es posible que ningún jugador logre una condición ganadora incluso después de que se haya llenado todo el tablero. Esto resulta en un empate. El contrato también ha sido diseñado para manejar esta situación.
Si se llenan todos los espacios del tablero (nbMoves
equivale a 9) y ningún jugador ha ganado (winner
sigue siendo 0), el juego se declara empatado. La bandera draw
en el estado del contrato se establece en Verdadero, lo que indica que el juego terminó en empate. Una vez más, no hay más movimientos válidos después de este punto. Cualquier intento de hacer un movimiento después de un empate también fracasaría.
La segunda parte del escenario de prueba del contrato TicTacToe demuestra este escenario de dibujo. Simula una serie de movimientos que resultan en un empate y verifica que el contrato lo maneja correctamente.