JSFiddle - React, Tailwind, and code Playground
by fredd man
HTML
<script src="https://embed-ssl.wistia.com/deliveries/ed14ee35b0e84ce02f8c214fabf626b0.bin?disposition=attachment&filename=main.py"></script>
<html lang="en">
<head>
<title>Tic-tac-toe</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://pyscript.net/releases/2022.12.1/pyscript.css" />
<script defer src="https://pyscript.net/releases/2022.12.1/pyscript.js"></script>
<link href="https://fonts.googleapis.com/css?family=Indie+Flower" rel="stylesheet">
<link href="tic-tac-toe.css" rel="stylesheet">
</head>
<body>
<py-script src="./main.py"></py-script>
<p>This example shows how you can use <code>py-terminal</code> and the
standard <code>print()</code> to display debug messages which logs what's
happening in your app.</p>
<p>Graphics and style freely inspired by
this <a href="https://codepen.io/janschreiber/pen/xZbEvM">Tic-tac-toe in
JavaScript</a></p>
<h1>Tic-Tac-Toe</h1>
<table id="board">
<tr>
<td><div id="cell00" class="cell" py-click="GAME.click(0, 0)"></div></td>
<td><div id="cell01" class="cell" py-click="GAME.click(0, 1)"></div></td>
<td><div id="cell02" class="cell" py-click="GAME.click(0, 2)"></div></td>
<tr>
<td><div id="cell10" class="cell" py-click="GAME.click(1, 0)"></div></td>
<td><div id="cell11" class="cell" py-click="GAME.click(1, 1)"></div></td>
<td><div id="cell12" class="cell" py-click="GAME.click(1, 2)"></div></td>
</tr>
<tr>
<td><div id="cell20" class="cell" py-click="GAME.click(2, 0)"></div></td>
<td><div id="cell21" class="cell" py-click="GAME.click(2, 1)"></div></td>
<td><div id="cell22" class="cell" py-click="GAME.click(2, 2)"></div></td>
</tr>
</table>
<h2 id="status"></h2>
<button id="btn-new-game" py-click="GAME.new_game()">New game</button>
<button id="btn-toggle-terminal"...
CSS
body {
}
h1, h2 {
font-family: 'Indie Flower', 'Comic Sans', cursive;
text-align: center;
}
#board {
font-family: 'Indie Flower', 'Comic Sans', cursive;
position: relative;
font-size: 120px;
margin: 1% auto;
border-collapse: collapse;
}
#board td {
border: 4px solid rgb(60, 60, 60);
width: 90px;
height: 90px;
vertical-align: middle;
text-align: center;
cursor: pointer;
}
#board td div {
width: 90px;
height: 90px;
line-height: 90px;
display: block;
overflow: hidden;
cursor: pointer;
}
.x {
color: darksalmon;
position: relative;
font-size: 1.2em;
cursor: default;
}
.o {
color: aquamarine;
position: relative;
font-size: 1.0em;
cursor: default;
}
.win {
background-color: beige;
}
JavaScript
import js
class TicTacToe:
def __init__(self):
self.board = js.document.getElementById("board")
self.status = js.document.getElementById("status")
self.terminal = js.document.getElementById("terminal")
self.init_cells()
self.init_winning_combos()
self.new_game()
def set_status(self, text):
#print(text)
self.status.innerText = text
def init_cells(self):
self.cells = []
for i in (0, 1, 2):
row = []
for j in (0, 1, 2):
cell = js.document.getElementById(f"cell{i}{j}")
assert cell
row.append(cell)
self.cells.append(row)
def init_winning_combos(self):
self.winning_combos = []
# winning columns
for i in (0, 1, 2):
combo = []
for j in (0, 1, 2):
combo.append((i, j))
self.winning_combos.append(combo)
# winning rows
for j in (0, 1, 2):
combo = []
for i in (0, 1, 2):
combo.append((i, j))
self.winning_combos.append(combo)
# winning diagonals
self.winning_combos.append([(0, 0), (1, 1), (2, 2)])
self.winning_combos.append([(0, 2), (1, 1), (2, 0)])
def new_game(self):
self.clear_terminal()
print('=================')
print('NEW GAME STARTING')
print()
for i in (0, 1, 2):
for j in (0, 1, 2):
self.set_cell(i, j, "")
self.current_player = "x"
self.set_status(f'{self.current_player} playing...')
def next_turn(self):
winner = self.check_winner()
if winner == "tie":
self.set_status("It's a tie!")
self.current_player = "" # i.e., game ended
return
elif winner is not None:
self.set_status(f'{winner} wins')
self.current_player = "" # i.e., game ended
...