JSFiddle - React, Tailwind, and code Playground

by fredd man

HTML

<script src="https://embed-ssl.wistia.com/deliveries/ed14ee35b0e84ce02f8c214fabf626b0.bin?disposition=attachment&amp;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
           ...