Code viewer for World: what is love
const squareSize = 50;
let currentPlayer = "w";
let isGameOver = false;
let waitingForMove = false; // To prevent duplicate moves
let maxMoves = 50; // Maximum number of moves
let moveCount = 0;
let isSimulationOn = true; // Start simulation automatically

const aiWhite = "https://chess-stockfish-16-api.p.rapidapi.com/chess/api";
const aiBlack = "https://chess-move-maker.p.rapidapi.com/chess";

document.write(`
<head>
<title>Chess AI Tournament</title>
<script type="module">
    import { Chess } from "https://cdn.skypack.dev/chess.js";
    window.chess = new Chess();
</script>
</head>
<body>
    <button id="pauseBtn">Pause</button>
    <!-- Container for the canvas -->
    <div id="sketch"></div>
</body>
`);

function setup() {
    createCanvas(8 * squareSize, 8 * squareSize);
    console.log("Simulation started automatically on setup");
    runSimulation(); // Automatically start the simulation
}

function draw() {
    background(220);
    drawBoard();
    drawPieces();
}

function drawBoard() {
    for (let x = 0; x < 8; x++) {
        for (let y = 0; y < 8; y++) {
            fill((x + y) % 2 === 0 ? 215 : 100); // White and black squares
            rect(x * squareSize, y * squareSize, squareSize, squareSize);
        }
    }
}

function drawPieces() {
    const board = chess.board();
    textSize(squareSize * 0.8);
    textAlign(CENTER, CENTER);

    const pieceSymbols = {
        p: "♟", n: "♞", b: "♝", r: "♜", q: "♛", k: "♚", // Black pieces
        P: "♙", N: "♘", B: "♗", R: "♖", Q: "♕", K: "♔"  // White pieces
    };

    for (let y = 0; y < 8; y++) {
        for (let x = 0; x < 8; x++) {
            const piece = board[y][x];
            if (piece) {
                const symbol = pieceSymbols[piece.color === "w" ? piece.type.toUpperCase() : piece.type];
                fill(piece.color === "w" ? 255 : 0);
                text(
                    symbol,
                    x * squareSize + squareSize / 2,
                    y * squareSize + squareSize / 2
                );
            }
        }
    }
}

async function runSimulation() {
    while (isSimulationOn && !isGameOver) {
        if (!waitingForMove) {
            waitingForMove = true; // Lock moves until current move is processed
            await playTurn(); // Execute a move
        }
        await new Promise(r => setTimeout(r, 500)); // Add delay between moves
    }
}

async function playTurn() {
    const endpoint = currentPlayer === "w" ? aiWhite : aiBlack;
    const fen = chess.fen();

    try {
        const move = await getMove(fen, endpoint);

        if (!chess.move(move)) {
            throw new Error(`Invalid move from API: ${JSON.stringify(move)}`);
        }

        console.log(`Move ${moveCount}: ${currentPlayer} played from ${move.from} to ${move.to}`);
        moveCount++;

        if (moveCount >= maxMoves) {
            evaluateMaterialWinner();
            return;
        }

        if (chess.isGameOver()) {
            evaluateWinner();
            return;
        }

        currentPlayer = currentPlayer === "w" ? "b" : "w"; // Switch player
    } catch (error) {
        console.log("Error during API call:", error);
    } finally {
        waitingForMove = false; // Unlock for next move
    }
}

async function getMove(fen, url) {
    if (url === aiWhite) {
        return stockfishJS(fen);
    } else {
        return chessmovemakerJS(fen);
    }
}

async function chessmovemakerJS(fen) {
    const url = "https://chess-move-maker.p.rapidapi.com/chess";

    function fenToBoard(fen) {
        const pieceMap = {
            'p': 'bP', 'r': 'bR', 'n': 'bN', 'b': 'bB', 'q': 'bQ', 'k': 'bK',
            'P': 'wP', 'R': 'wR', 'N': 'wN', 'B': 'wB', 'Q': 'wQ', 'K': 'wK',
        };

        const rows = fen.split(' ')[0].split('/');
        return rows.map(row => {
            const expandedRow = [];
            for (const char of row) {
                if (isNaN(char)) {
                    expandedRow.push(pieceMap[char] || '');
                } else {
                    expandedRow.push(...Array(parseInt(char)).fill(''));
                }
            }
            return expandedRow;
        });
    }

    const options = {
        method: "POST",
        headers: {
            "x-rapidapi-key": "a4fef1ee6fmshb40f31ccdbfdd52p19565bjsn14ca66e0e06f",
            "x-rapidapi-host": "chess-move-maker.p.rapidapi.com",
            "Content-Type": "application/json",
        },
        body: JSON.stringify({
            color: currentPlayer === "w" ? "WHITE" : "BLACK",
            positions: fenToBoard(fen),
        }),
    };

    const response = await fetch(url, options);
    const moves = await response.json();

    if (moves.length > 0) {
        const { from, to } = moves[0];
        return { from, to };
    } else {
        throw new Error("No moves returned by the API");
    }
}

async function stockfishJS(fen) {
    const url = "https://chess-stockfish-16-api.p.rapidapi.com/chess/api";
    const data = new FormData();
    const apiKey = "b6afcf768dmsh065db0d82936420p13e2f4jsn04b3f64caa77";
    data.append("fen", fen);

    const options = {
        method: "POST",
        headers: {
            "x-rapidapi-key": apiKey,
            "x-rapidapi-host": "chess-stockfish-16-api.p.rapidapi.com",
        },
        body: data,
    };

    const response = await fetch(url, options);
    const dataBack = await response.json();
    const bestMove = dataBack.bestmove;
    const from = bestMove.slice(0, 2);
    const to = bestMove.slice(2, 4);

    return { from, to };
}

function evaluateWinner() {
    isGameOver = true;

    if (chess.isCheckmate()) {
        const winner = currentPlayer === "w" ? "Black" : "White";
        console.log(`Game over: ${winner} wins by checkmate`);
    } else if (chess.isDraw()) {
        console.log("Game over: Draw");
    } else {
        console.log("Game over: Strange condition");
    }

    console.log("PGN:", chess.pgn());
}

function evaluateMaterialWinner() {
    isGameOver = true;
    console.log("Game Over - Reached maximum number of moves");

    const board = chess.board();
    const material = { w: 0, b: 0 };
    const values = { p: 1, n: 3, b: 4, r: 5, q: 9, k: 0 };

    board.forEach(row => {
        row.forEach(piece => {
            if (piece) {
                material[piece.color] += values[piece.type];
            }
        });
    });

    console.log(`Material: White ${material.w}, Black ${material.b}`);
    if (material.w > material.b) {
        console.log("White wins");
    } else if (material.w < material.b) {
        console.log("Black wins");
    } else {
        console.log("Draw!");
    }

    console.log("PGN:", chess.pgn());
}

document.getElementById("pauseBtn").addEventListener("click", () => {
    if (isSimulationOn) {
        isSimulationOn = false;
        console.log("Simulation paused");
    }
});