TicTacToe
Let's build a simple TicTacToe game using Pret. We will build a simple game where two players can play against each other.
from pret import proxy, component
from pret.ui.react import button, div
from pret.hooks import use_tracked
state = proxy({
"board": [0] * 9,
"turn": 1,
"winning_pattern": [],
})
winning_patterns = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
[0, 4, 8],
[6, 4, 2],
]
SQUARE_STYLE = {
"display": "flex",
"justifyContent": "center",
"alignItems": "center",
"width": "60px",
"height": "60px",
"margin": "2px",
"fontSize": "24px",
"padding": "0",
"appearance": "none",
"border": "1px solid grey",
}
WINNING_SQUARE_STYLE = {
**SQUARE_STYLE,
"background": "lightGreen",
}
GRID_STYLE = {
"display": "grid",
"gridTemplateColumns": "repeat(3, 66px)",
"gridGap": "2px",
}
@component
def TicTacToe():
tracked = use_tracked(state)
winning_pattern = tracked["winning_pattern"]
def on_click_square(idx):
# if the game is over, clean everything on click
if bool(state["winning_pattern"]) or 0 not in state["board"]:
state["board"][:] = [0 for _ in range(9)]
state["winning_pattern"] = []
return
# place a piece on the board
value = state["board"][idx]
if value == 0:
state["board"][idx] = state["turn"]
state["turn"] = 2 if state["turn"] == 1 else 1
# check for victory
for pattern in winning_patterns:
players = set(state["board"][i] for i in pattern)
if len(players) == 1 and 0 not in players:
state["winning_pattern"] = pattern
return div(
[
button(
"X" if square == 2 else "O" if square == 1 else "",
on_click=lambda event, idx=idx: on_click_square(idx),
style=(
WINNING_SQUARE_STYLE if idx in winning_pattern else SQUARE_STYLE
),
)
for idx, square in enumerate(tracked["board"])
],
style=GRID_STYLE,
)
TicTacToe()