Revised and reskinned Martian chess

https://svonberg.org/wp-content/uploads/2025/11/martianchessai3.html

https://svonberg.org/wp-content/uploads/2025/11/starcitychessv1.html

https://svonberg.org/wp-content/uploads/2025/11/moonchess1.html


<!DOCTYPE html>
<html lang=”en”>
<head>
    <meta charset=”UTF-8″>
    <meta name=”viewport” content=”width=device-width, initial-scale=1.0″>
    <title>Roanoke: Star City vs Blue Ridge</title>
    <script src=”https://cdn.tailwindcss.com”></script>
    <style>
        /* Custom Animations */
        @keyframes slideIn {
            from { transform: translateY(10px); opacity: 0; }
            to { transform: translateY(0); opacity: 1; }
        }
        .animate-slide-in {
            animation: slideIn 0.3s ease-out forwards;
        }
        /* Prevent touch scrolling/zooming on board */
        .board-container {
            touch-action: none;
        }
        /* Disable interaction during AI turn */
        .ai-thinking {
            pointer-events: none;
            opacity: 0.9;
            cursor: wait;
        }
    </style>
</head>
<body class=”bg-slate-900 text-slate-200 font-sans min-h-screen flex flex-col items-center justify-center p-4″>

    <div class=”max-w-2xl w-full bg-slate-800 shadow-2xl rounded-xl overflow-hidden flex flex-col border border-slate-700″>
       
        <!– Header & Settings –>
        <div class=”bg-slate-950 text-white p-4 border-b border-slate-700″>
            <div class=”flex justify-between items-center mb-4″>
                <div>
                    <h1 class=”text-xl font-bold text-slate-100 tracking-wider”>ROANOKE <span class=”text-slate-500 text-sm”>VA</span></h1>
                    <p class=”text-xs text-slate-400″>Star City vs. Blue Ridge (Martian Chess Rules)</p>
                </div>
                <button onclick=”game.resetGame()” class=”bg-blue-900 hover:bg-blue-800 text-white px-4 py-2 rounded text-sm font-bold transition shadow-md border border-blue-700″>
                    Reset Game
                </button>
            </div>
           
            <!– Player Setup –>
            <div class=”flex gap-4 text-sm bg-slate-900 p-2 rounded-lg justify-center border border-slate-800″>
                <div class=”flex flex-col items-center”>
                    <label class=”text-xs text-red-400 mb-1 uppercase tracking-widest font-bold”>Star City</label>
                    <select id=”p2-type” class=”bg-slate-800 text-slate-200 rounded px-2 py-1 border border-slate-600 focus:outline-none focus:border-red-400″>
                        <option value=”human”>Human</option>
                        <option value=”ai” selected>AI (The Star)</option>
                    </select>
                </div>
                <div class=”flex items-center text-slate-600 font-bold text-xs”>VS</div>
                <div class=”flex flex-col items-center”>
                    <label class=”text-xs text-emerald-500 mb-1 uppercase tracking-widest font-bold”>Blue Ridge</label>
                    <select id=”p1-type” class=”bg-slate-800 text-slate-200 rounded px-2 py-1 border border-slate-600 focus:outline-none focus:border-emerald-500″>
                        <option value=”human” selected>Human</option>
                        <option value=”ai”>AI (The Valley)</option>
                    </select>
                </div>
            </div>
        </div>

        <!– Game Info Bar –>
        <div class=”bg-slate-800 p-3 text-sm font-medium border-b border-slate-700 grid grid-cols-3 items-center”>
            <div id=”p2-score” class=”flex flex-col items-start pl-2″>
                <span class=”text-xs uppercase tracking-wider text-red-400″>Star City</span>
                <span class=”text-2xl font-bold text-white leading-none drop-shadow-lg” id=”score-p2″>0</span>
            </div>
           
            <div class=”flex flex-col items-center gap-1″>
                <div id=”turn-indicator” class=”bg-slate-900 px-4 py-1 rounded-full shadow-inner border border-slate-700 text-emerald-400 font-bold transition-colors duration-300 whitespace-nowrap”>
                    Blue Ridge Turn
                </div>
                <!– Deadlock Counter –>
                <div class=”text-xs text-slate-500 font-mono bg-slate-900 px-2 py-0.5 rounded border border-slate-800″ title=”Game ends at 27 moves without capture”>
                    Peaceful Moves: <span id=”deadlock-counter” class=”font-bold text-slate-300″>0</span>/27
                </div>
            </div>

            <div id=”p1-score” class=”flex flex-col items-end pr-2″>
                <span class=”text-xs uppercase tracking-wider text-emerald-500″>Blue Ridge</span>
                <span class=”text-2xl font-bold text-white leading-none drop-shadow-lg” id=”score-p1″>0</span>
            </div>
        </div>

        <!– Game Board Area –>
        <div class=”flex-1 bg-slate-900 p-4 flex justify-center items-center overflow-hidden relative”>
           
            <div id=”board” class=”board-container grid grid-cols-4 gap-0 bg-black border-4 border-black shadow-2xl select-none relative transition-opacity duration-200 ring-1 ring-slate-700″>
                <!– Cells generated by JS –>
            </div>
        </div>

        <!– Instructions / Status –>
        <div class=”p-4 bg-slate-800 border-t border-slate-700 text-sm text-slate-400″>
            <p id=”status-text” class=”font-medium text-center text-slate-300″>Select a piece in your region to move.</p>
            <div class=”mt-2 flex gap-4 text-xs text-slate-500 justify-center”>
                <span class=”flex items-center gap-1″><div class=”w-2 h-2 bg-slate-400 rounded-full”></div> Pawn (1)</span>
                <span class=”flex items-center gap-1″><div class=”w-3 h-3 bg-slate-400 rounded-full”></div> Drone (2)</span>
                <span class=”flex items-center gap-1″><div class=”w-4 h-4 bg-slate-400 rounded-full”></div> Queen (3)</span>
            </div>
        </div>
    </div>

    <!– Game Logic –>
    <script>
        // — Constants & Config —
        const ROWS = 8;
        const COLS = 4;
        const MAX_MOVES_WITHOUT_CAPTURE = 27;
        const PIECE_TYPES = {
            PAWN: { id: ‘pawn’, name: ‘Pawn’, points: 1, size: ‘small’ },
            DRONE: { id: ‘drone’, name: ‘Drone’, points: 2, size: ‘medium’ },
            QUEEN: { id: ‘queen’, name: ‘Queen’, points: 3, size: ‘large’ }
        };
       
        const PLAYERS = {
            TOP: 0,    // Star City
            BOTTOM: 1  // Blue Ridge
        };

        class MartianChess {
            constructor() {
                this.board = [];
                this.turn = PLAYERS.BOTTOM;
                this.scores = { [PLAYERS.TOP]: 0, [PLAYERS.BOTTOM]: 0 };
                this.selectedCell = null;
                this.validMoves = [];
                this.gameActive = false;
                this.movesWithoutCapture = 0;
                this.lastMove = null;
               
                this.playerTypes = {
                    [PLAYERS.TOP]: ‘ai’,
                    [PLAYERS.BOTTOM]: ‘human’
                };

                // Bind UI selectors
                document.getElementById(‘p2-type’).addEventListener(‘change’, (e) => {
                    this.playerTypes[PLAYERS.TOP] = e.target.value;
                    if(this.gameActive && this.turn === PLAYERS.TOP && e.target.value === ‘ai’) {
                        this.playAITurn();
                    }
                });
                document.getElementById(‘p1-type’).addEventListener(‘change’, (e) => {
                    this.playerTypes[PLAYERS.BOTTOM] = e.target.value;
                    if(this.gameActive && this.turn === PLAYERS.BOTTOM && e.target.value === ‘ai’) {
                        this.playAITurn();
                    }
                });

                this.initBoard();
            }

            initBoard() {
                this.board = Array(ROWS).fill(null).map(() => Array(COLS).fill(null));
                this.gameActive = true;
                this.movesWithoutCapture = 0;
                this.lastMove = null;

                // Setup Top Player (Star City)
                this.placePiece(0, 0, PIECE_TYPES.QUEEN);
                this.placePiece(0, 1, PIECE_TYPES.QUEEN);
                this.placePiece(1, 0, PIECE_TYPES.QUEEN);
                this.placePiece(0, 2, PIECE_TYPES.DRONE);
                this.placePiece(1, 1, PIECE_TYPES.DRONE);
                this.placePiece(2, 0, PIECE_TYPES.DRONE);
                this.placePiece(1, 2, PIECE_TYPES.PAWN);
                this.placePiece(2, 1, PIECE_TYPES.PAWN);
                this.placePiece(2, 2, PIECE_TYPES.PAWN);

                // Setup Bottom Player (Blue Ridge)
                this.placePiece(7, 3, PIECE_TYPES.QUEEN);
                this.placePiece(7, 2, PIECE_TYPES.QUEEN);
                this.placePiece(6, 3, PIECE_TYPES.QUEEN);
                this.placePiece(7, 1, PIECE_TYPES.DRONE);
                this.placePiece(6, 2, PIECE_TYPES.DRONE);
                this.placePiece(5, 3, PIECE_TYPES.DRONE);
                this.placePiece(6, 1, PIECE_TYPES.PAWN);
                this.placePiece(5, 2, PIECE_TYPES.PAWN);
                this.placePiece(5, 1, PIECE_TYPES.PAWN);

                this.turn = PLAYERS.BOTTOM;
                this.scores = { 0: 0, 1: 0 };
                this.selectedCell = null;
                this.validMoves = [];
               
                this.playerTypes[PLAYERS.TOP] = document.getElementById(‘p2-type’).value;
                this.playerTypes[PLAYERS.BOTTOM] = document.getElementById(‘p1-type’).value;

                this.updateUI();
                this.render();
                this.checkAI();
            }

            placePiece(r, c, type) {
                this.board[r][c] = { …type };
            }

            getOwner(row) {
                return row < 4 ? PLAYERS.TOP : PLAYERS.BOTTOM;
            }

            checkAI() {
                if (!this.gameActive) return;
                const currentPlayerType = this.playerTypes[this.turn];
                const boardEl = document.getElementById(‘board’);

                if (currentPlayerType === ‘ai’) {
                    boardEl.classList.add(‘ai-thinking’);
                    this.updateStatus(`${this.turn === PLAYERS.TOP ? “Star City” : “Blue Ridge”} AI is thinking…`);
                   
                    setTimeout(() => {
                        this.playAITurn();
                    }, 800);
                } else {
                    boardEl.classList.remove(‘ai-thinking’);
                    this.updateStatus(`${this.turn === PLAYERS.TOP ? “Star City’s” : “Blue Ridge’s”} Turn`);
                }
            }

            // — AI Logic —

            playAITurn() {
                if (!this.gameActive) return;

                const allMoves = this.getAllValidMoves(this.turn);
                if (allMoves.length === 0) {
                    return;
                }

                let bestMove = null;
                let bestScore = -Infinity;
                allMoves.sort(() => Math.random() – 0.5);

                for (const move of allMoves) {
                    const score = this.evaluateMove(move);
                    if (score > bestScore) {
                        bestScore = score;
                        bestMove = move;
                    }
                }

                if (bestMove) {
                    this.executeMove(bestMove);
                }
            }

            getAllValidMoves(player) {
                const moves = [];
                for (let r = 0; r < ROWS; r++) {
                    for (let c = 0; c < COLS; c++) {
                        if (this.board[r][c] && this.getOwner(r) === player) {
                            const pieceMoves = this.calculateMoves(r, c);
                            pieceMoves.forEach(m => {
                                m.fromR = r;
                                m.fromC = c;
                                m.piece = this.board[r][c];
                            });
                            moves.push(…pieceMoves);
                        }
                    }
                }
                return moves;
            }

            evaluateMove(move) {
                let score = 0;
               
                if (move.isCapture) {
                    const targetPiece = this.board[move.r][move.c];
                    score += (targetPiece.points * 10);
                }

                const fromOwner = this.getOwner(move.fromR);
                const toOwner = this.getOwner(move.r);
               
                if (fromOwner !== toOwner) {
                    const pieceValue = move.piece.points;
                    score -= (pieceValue * 8);
                } else {
                    score += 1;
                }

                let myPiecesCount = 0;
                for(let r=0; r<ROWS; r++) {
                    for(let c=0; c<COLS; c++) {
                        if(this.board[r][c] && this.getOwner(r) === this.turn) {
                            myPiecesCount++;
                        }
                    }
                }
               
                const willEmptyZone = (fromOwner !== toOwner) && (myPiecesCount === 1);
                const myCurrentScore = this.scores[this.turn];
                const opp = this.turn === PLAYERS.TOP ? PLAYERS.BOTTOM : PLAYERS.TOP;
                const oppScore = this.scores[opp];

                if (willEmptyZone) {
                    let finalMyScore = myCurrentScore;
                    if (move.isCapture) {
                         const target = this.board[move.r][move.c];
                         finalMyScore += target.points;
                    }

                    if (finalMyScore > oppScore) {
                        score += 1000;
                    } else {
                        score -= 1000;
                    }
                } else {
                     if (myCurrentScore > oppScore + 3 && fromOwner !== toOwner) {
                         score += 5;
                     }
                }

                if (this.movesWithoutCapture > 20 && myCurrentScore > oppScore) {
                    if (fromOwner !== toOwner) score += 50;
                }

                return score;
            }

            // — Core Logic —

            isValidSelection(r, c) {
                const piece = this.board[r][c];
                if (!piece) return false;
                return this.getOwner(r) === this.turn && this.playerTypes[this.turn] === ‘human’;
            }

            calculateMoves(r, c) {
                const piece = this.board[r][c];
                if (!piece) return [];

                const moves = [];
               
                if (piece.id === ‘pawn’) {
                    [[1,1], [1,-1], [-1,1], [-1,-1]].forEach(([dr, dc]) => {
                        this.addMoveIfValid(r, c, dr, dc, 1, moves);
                    });
                } else if (piece.id === ‘drone’) {
                    [[0,1], [0,-1], [1,0], [-1,0]].forEach(([dr, dc]) => {
                        this.addMoveIfValid(r, c, dr, dc, 2, moves);
                    });
                } else if (piece.id === ‘queen’) {
                    [[0,1], [0,-1], [1,0], [-1,0], [1,1], [1,-1], [-1,1], [-1,-1]].forEach(([dr, dc]) => {
                        this.addMoveIfValid(r, c, dr, dc, 8, moves);
                    });
                }
                return moves;
            }

            addMoveIfValid(startR, startC, dr, dc, maxSteps, moves) {
                for (let i = 1; i <= maxSteps; i++) {
                    const nr = startR + (dr * i);
                    const nc = startC + (dc * i);

                    if (nr < 0 || nr >= ROWS || nc < 0 || nc >= COLS) break;

                    const targetPiece = this.board[nr][nc];
                    const currentOwner = this.getOwner(startR);
                   
                    if (!targetPiece) {
                        moves.push({ r: nr, c: nc });
                    } else {
                        const targetZoneOwner = this.getOwner(nr);
                        if (targetZoneOwner !== currentOwner) {
                            moves.push({ r: nr, c: nc, isCapture: true });
                        }
                        break;
                    }
                }
            }

            handleCellClick(r, c) {
                if (!this.gameActive) return;
                if (this.playerTypes[this.turn] === ‘ai’) return;

                const move = this.validMoves.find(m => m.r === r && m.c === c);
                if (move) {
                    this.executeMove(move);
                    return;
                }

                if (this.isValidSelection(r, c)) {
                    this.selectedCell = { r, c };
                    this.validMoves = this.calculateMoves(r, c);
                    this.render();
                    this.updateStatus(“Unit selected.”);
                } else {
                    this.selectedCell = null;
                    this.validMoves = [];
                    this.render();
                }
            }

            executeMove(move) {
                const fromR = move.fromR !== undefined ? move.fromR : this.selectedCell.r;
                const fromC = move.fromC !== undefined ? move.fromC : this.selectedCell.c;
               
                const piece = this.board[fromR][fromC];
               
                this.lastMove = {
                    from: { r: fromR, c: fromC },
                    to: { r: move.r, c: move.c }
                };

                if (move.isCapture) {
                    const targetPiece = this.board[move.r][move.c];
                    this.scores[this.turn] += targetPiece.points;
                    this.movesWithoutCapture = 0;
                } else {
                    this.movesWithoutCapture++;
                }

                this.board[move.r][move.c] = piece;
                this.board[fromR][fromC] = null;

                this.selectedCell = null;
                this.validMoves = [];
               
                this.render();
                this.updateUI();

                if (this.checkWinCondition()) {
                    this.gameActive = false;
                    document.getElementById(‘board’).classList.remove(‘ai-thinking’);
                    return;
                }

                this.toggleTurn();
                this.render();
                this.updateUI();
                this.checkAI();
            }

            toggleTurn() {
                this.turn = this.turn === PLAYERS.BOTTOM ? PLAYERS.TOP : PLAYERS.BOTTOM;
            }

            checkWinCondition() {
                if (this.movesWithoutCapture >= MAX_MOVES_WITHOUT_CAPTURE) {
                    const winner = this.scores[PLAYERS.BOTTOM] > this.scores[PLAYERS.TOP] ? “Blue Ridge” :
                                   this.scores[PLAYERS.BOTTOM] < this.scores[PLAYERS.TOP] ? “Star City” : “Tie”;
                   
                    const msg = `Stalemate (27 moves)! \n\nWinner: ${winner}\n\nBlue Ridge: ${this.scores[PLAYERS.BOTTOM]}\nStar City: ${this.scores[PLAYERS.TOP]}`;
                   
                    setTimeout(() => alert(msg), 100);
                    this.updateStatus(“Game Over: Stalemate Limit Reached”);
                    return true;
                }

                let topPieces = 0;
                let bottomPieces = 0;

                for(let r=0; r<ROWS; r++) {
                    for(let c=0; c<COLS; c++) {
                        if (this.board[r][c]) {
                            if (r < 4) topPieces++;
                            else bottomPieces++;
                        }
                    }
                }

                if (topPieces === 0 || bottomPieces === 0) {
                    const winner = this.scores[PLAYERS.BOTTOM] > this.scores[PLAYERS.TOP] ? “Blue Ridge” :
                                   this.scores[PLAYERS.BOTTOM] < this.scores[PLAYERS.TOP] ? “Star City” : “Tie”;
                   
                    const msg = `Game Over! ${winner} Wins!\n\nFinal Score:\nBlue Ridge: ${this.scores[PLAYERS.BOTTOM]}\nStar City: ${this.scores[PLAYERS.TOP]}`;
                   
                    setTimeout(() => alert(msg), 100);
                    this.updateStatus(msg);
                    return true;
                }
                return false;
            }

            resetGame() {
                this.initBoard();
            }

            updateUI() {
                document.getElementById(‘score-p1’).textContent = this.scores[PLAYERS.BOTTOM];
                document.getElementById(‘score-p2’).textContent = this.scores[PLAYERS.TOP];
               
                const counterEl = document.getElementById(‘deadlock-counter’);
                counterEl.textContent = this.movesWithoutCapture;
                if (this.movesWithoutCapture > 20) {
                    counterEl.className = “font-bold text-red-500 animate-pulse”;
                } else {
                    counterEl.className = “font-bold text-slate-300”;
                }

                const turnInd = document.getElementById(‘turn-indicator’);
                const pType = this.playerTypes[this.turn] === ‘ai’ ? ‘(AI)’ : ”;
               
                if (this.turn === PLAYERS.BOTTOM) {
                    turnInd.textContent = `Blue Ridge Turn ${pType}`;
                    turnInd.className = `px-4 py-1 rounded-full shadow-inner font-bold whitespace-nowrap bg-emerald-950 text-emerald-400 border border-emerald-900`;
                } else {
                    turnInd.textContent = `Star City Turn ${pType}`;
                    turnInd.className = `px-4 py-1 rounded-full shadow-inner font-bold whitespace-nowrap bg-red-950 text-red-400 border border-red-900`;
                }
            }

            updateStatus(msg) {
                document.getElementById(‘status-text’).textContent = msg;
            }

            render() {
                const boardEl = document.getElementById(‘board’);
                boardEl.innerHTML = ”;

                for(let r=0; r<ROWS; r++) {
                    for(let c=0; c<COLS; c++) {
                        const cell = document.createElement(‘div’);
                        let classes = “w-16 h-16 flex items-center justify-center relative transition-all duration-200 “;
                       
                        // Theme Coloring
                        const isDark = (r + c) % 2 === 1;
                        let bgColor = “”;
                       
                        if (r < 4) {
                            // Star City Zone (Top) – Dark Night Sky / Mill Mountain
                            bgColor = isDark ? “bg-slate-900” : “bg-slate-800”;
                        } else {
                            // Blue Ridge Zone (Bottom) – Misty Valley
                            bgColor = isDark ? “bg-slate-700” : “bg-slate-600”;
                        }

                        // Last Move Highlight (Sunrise Yellow)
                        const isLastMoveFrom = this.lastMove && this.lastMove.from.r === r && this.lastMove.from.c === c;
                        const isLastMoveTo = this.lastMove && this.lastMove.to.r === r && this.lastMove.to.c === c;

                        if (isLastMoveFrom || isLastMoveTo) {
                            bgColor = “bg-yellow-500/20”;
                        }

                        classes += bgColor;

                        // Canal (The Railroad Tracks line?)
                        if (r === 3) classes += ” border-b-4 border-black”;

                        const isSelected = this.selectedCell && this.selectedCell.r === r && this.selectedCell.c === c;
                        const isValidMove = this.validMoves.find(m => m.r === r && m.c === c);
                        const isCapture = isValidMove && isValidMove.isCapture;

                        if (isSelected) classes += ” ring-4 ring-yellow-400 z-10 shadow-lg”;
                       
                        if (isValidMove) {
                            if (isCapture) classes += ” ring-4 ring-red-500 bg-red-900/40 cursor-pointer”;
                            else classes += ” ring-4 ring-emerald-400/50 bg-emerald-900/20 cursor-pointer”;
                        } else if (this.board[r][c] && this.isValidSelection(r, c)) {
                            classes += ” cursor-pointer hover:brightness-110″;
                        }

                        cell.className = classes;
                        cell.onclick = () => this.handleCellClick(r, c);

                        const piece = this.board[r][c];
                        if (piece) {
                            cell.innerHTML = this.getPieceSVG(piece, r);
                        } else if (isValidMove && !isCapture) {
                            cell.innerHTML = `<div class=”w-2 h-2 bg-emerald-400 rounded-full opacity-50″></div>`;
                        }

                        boardEl.appendChild(cell);
                    }
                }
            }

            getPieceSVG(piece, row) {
                const owner = this.getOwner(row);
               
                // — VISUALS —
                // Star City (Top): The Roanoke Star. Neon Red body, White Pips.
                // Blue Ridge (Bottom): The Mountains. Forest Green body, White/Sky Blue Pips.
               
                let fill = “”;
                let stroke = “”;
                let pipColor = “”;
               
                let scale = 0.9;
                if (piece.size === ‘small’) scale = 0.55;
                if (piece.size === ‘medium’) scale = 0.75;
                const transform = `transform: scale(${scale}); transform-origin: center;`;

                // — SHAPES —
               
                if (owner === PLAYERS.TOP) {
                    // THE STAR
                    fill = “fill-red-500”;
                    stroke = “stroke-white”;
                    pipColor = “fill-white”;
                   
                    // 5-Point Star Path
                    const starPath = “M 50 10 L 61 35 L 88 35 L 66 50 L 75 75 L 50 60 L 25 75 L 34 50 L 12 35 L 39 35 Z”;
                   
                    // Star Pips (Center cluster)
                    let pips = “”;
                    if (piece.id === ‘pawn’) pips = `<circle cx=”50″ cy=”50″ r=”6″ class=”${pipColor}” />`;
                    else if (piece.id === ‘drone’) pips = `<circle cx=”42″ cy=”50″ r=”5″ class=”${pipColor}” /><circle cx=”58″ cy=”50″ r=”5″ class=”${pipColor}” />`;
                    else if (piece.id === ‘queen’) pips = `<circle cx=”50″ cy=”40″ r=”5″ class=”${pipColor}” /><circle cx=”40″ cy=”55″ r=”5″ class=”${pipColor}” /><circle cx=”60″ cy=”55″ r=”5″ class=”${pipColor}” />`;

                    return `
                    <svg viewBox=”0 0 100 100″ class=”w-full h-full animate-slide-in drop-shadow-lg” style=”${transform}”>
                        <path d=”${starPath}” class=”${fill} ${stroke}” stroke-width=”4″ stroke-linejoin=”round”/>
                        ${pips}
                    </svg>
                    `;

                } else {
                    // THE MOUNTAIN
                    fill = “fill-emerald-700”;
                    stroke = “stroke-emerald-300”;
                    pipColor = “fill-white”;

                    // Mountain/Triangle shape with snowcap hint style
                    const mountainPath = “M 50 10 L 90 90 L 10 90 Z”;
                   
                    // Snowcap detail (optional visual flair)
                    const snowCap = “M 50 10 L 65 40 L 50 30 L 35 40 Z”;

                    // Mountain Pips (Lower center)
                    let pips = “”;
                    if (piece.id === ‘pawn’) pips = `<circle cx=”50″ cy=”70″ r=”7″ class=”${pipColor}” />`;
                    else if (piece.id === ‘drone’) pips = `<circle cx=”40″ cy=”70″ r=”6″ class=”${pipColor}” /><circle cx=”60″ cy=”70″ r=”6″ class=”${pipColor}” />`;
                    else if (piece.id === ‘queen’) pips = `<circle cx=”50″ cy=”55″ r=”6″ class=”${pipColor}” /><circle cx=”35″ cy=”75″ r=”6″ class=”${pipColor}” /><circle cx=”65″ cy=”75″ r=”6″ class=”${pipColor}” />`;

                    return `
                    <svg viewBox=”0 0 100 100″ class=”w-full h-full animate-slide-in drop-shadow-lg” style=”${transform}”>
                        <path d=”${mountainPath}” class=”${fill} ${stroke}” stroke-width=”4″ stroke-linejoin=”round”/>
                        <path d=”${snowCap}” class=”fill-emerald-100 opacity-30″ />
                        ${pips}
                    </svg>
                    `;
                }
            }
        }

        const game = new MartianChess();

    </script>
</body>
</html>

Leave a Reply