1# TicTacToe - Example for illustrative purposes only.
2
3import smartpy as sp
4
5
6@sp.module
7def main():
8 class TicTacToe(sp.Contract):
9 def __init__(self):
10 self.data.nbMoves = 0
11 self.data.winner = 0
12 self.data.draw = False
13 self.data.deck = {
14 0: {0: 0, 1: 0, 2: 0},
15 1: {0: 0, 1: 0, 2: 0},
16 2: {0: 0, 1: 0, 2: 0},
17 }
18 self.data.nextPlayer = 1
19
20 @sp.entrypoint
21 def play(self, params):
22 assert self.data.winner == 0 and not self.data.draw
23 assert params.i >= 0 and params.i < 3
24 assert params.j >= 0 and params.j < 3
25 assert params.move == self.data.nextPlayer
26 assert self.data.deck[params.i][params.j] == 0
27 self.data.deck[params.i][params.j] = params.move
28 self.data.nbMoves += 1
29 self.data.nextPlayer = 3 - self.data.nextPlayer
30 self.data.winner = self.checkLine(
31 sp.record(winner=self.data.winner, line=self.data.deck[params.i])
32 )
33 self.data.winner = self.checkLine(
34 sp.record(
35 winner=self.data.winner,
36 line={
37 0: self.data.deck[0][params.j],
38 1: self.data.deck[1][params.j],
39 2: self.data.deck[2][params.j],
40 },
41 )
42 )
43 self.data.winner = self.checkLine(
44 sp.record(
45 winner=self.data.winner,
46 line={
47 0: self.data.deck[0][0],
48 1: self.data.deck[1][1],
49 2: self.data.deck[2][2],
50 },
51 )
52 )
53 self.data.winner = self.checkLine(
54 sp.record(
55 winner=self.data.winner,
56 line={
57 0: self.data.deck[0][2],
58 1: self.data.deck[1][1],
59 2: self.data.deck[2][0],
60 },
61 )
62 )
63 if self.data.nbMoves == 9 and self.data.winner == 0:
64 self.data.draw = True
65
66 @sp.private()
67 def checkLine(self, winner, line):
68 winner_ = winner
69 if line[0] != 0 and line[0] == line[1] and line[0] == line[2]:
70 winner_ = line[0]
71 return winner_
72
73
74# Tests
75if "main" in __name__:
76
77 @sp.add_test()
78 def test():
79 scenario = sp.test_scenario("TicTacToe", main)
80 scenario.h1("Tic-Tac-Toe")
81 # define a contract
82 c1 = main.TicTacToe()
83
84 # show its representation
85 scenario.h2("A sequence of interactions with a winner")
86 scenario += c1
87 scenario.h2("Message execution")
88 scenario.h3("A first move in the center")
89 c1.play(i=1, j=1, move=1)
90 scenario.h3("A forbidden move")
91 c1.play(i=1, j=1, move=2, _valid=False)
92 scenario.h3("A second move")
93 c1.play(i=1, j=2, move=2)
94 scenario.h3("Other moves")
95 c1.play(i=2, j=1, move=1)
96 c1.play(i=2, j=2, move=2)
97 scenario.verify(c1.data.winner == 0)
98 c1.play(i=0, j=1, move=1)
99 scenario.verify(c1.data.winner == 1)
100 scenario.p("Player1 has won")
101 c1.play(i=0, j=0, move=2, _valid=False)
102
103 c2 = main.TicTacToe()
104 scenario.h2("A sequence of interactions with a draw")
105 scenario += c2
106 scenario.h2("Message execution")
107 scenario.h3("A first move in the center")
108 c2.play(i=1, j=1, move=1)
109 scenario.h3("A forbidden move")
110 c2.play(i=1, j=1, move=2, _valid=False)
111 scenario.h3("A second move")
112 c2.play(i=1, j=2, move=2)
113 scenario.h3("Other moves")
114 c2.play(i=2, j=1, move=1)
115 c2.play(i=2, j=2, move=2)
116 c2.play(i=0, j=0, move=1)
117 c2.play(i=0, j=1, move=2)
118 c2.play(i=0, j=2, move=1)
119 c2.play(i=2, j=0, move=2)
120 c2.play(i=1, j=0, move=1)