05/18/2026 Catchup - linksync project work and TicTacToe evaluations on different coding LLMs with OpenCode.
This commit is contained in:
300
TicTacToe-Compare/qwen3.6-27b/index.html
Normal file
300
TicTacToe-Compare/qwen3.6-27b/index.html
Normal file
@@ -0,0 +1,300 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Tic-Tac-Toe</title>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
|
||||
body {
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: #1a1a2e;
|
||||
color: #eee;
|
||||
font-family: 'Segoe UI', system-ui, sans-serif;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2.4rem;
|
||||
margin-bottom: 0.5rem;
|
||||
letter-spacing: 2px;
|
||||
}
|
||||
|
||||
#status {
|
||||
font-size: 1.2rem;
|
||||
min-height: 2rem;
|
||||
margin-bottom: 1rem;
|
||||
color: #aaa;
|
||||
}
|
||||
|
||||
#board {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 110px);
|
||||
grid-template-rows: repeat(3, 110px);
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.cell {
|
||||
width: 110px;
|
||||
height: 110px;
|
||||
background: #16213e;
|
||||
border: 2px solid #0f3460;
|
||||
border-radius: 8px;
|
||||
font-size: 3rem;
|
||||
font-weight: bold;
|
||||
color: #eee;
|
||||
cursor: pointer;
|
||||
transition: background 0.15s;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.cell:hover { background: #1a2a50; }
|
||||
.cell.taken { cursor: default; }
|
||||
.cell.x { color: #e94560; }
|
||||
.cell.o { color: #53d8fb; }
|
||||
|
||||
/* ---- overlays ---- */
|
||||
.overlay {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
background: rgba(10, 10, 30, 0.92);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.overlay.hidden { display: none; }
|
||||
|
||||
#coin {
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
border-radius: 50%;
|
||||
background: radial-gradient(circle at 40% 40%, #ffd700, #b8860b);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 2rem;
|
||||
font-weight: 800;
|
||||
color: #1a1a2e;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
#coin.flip {
|
||||
animation: coinFlip 0.8s ease-in-out;
|
||||
}
|
||||
|
||||
@keyframes coinFlip {
|
||||
0% { transform: scale(1) rotateY(0); }
|
||||
40% { transform: scale(1.3) rotateY(900deg); }
|
||||
60% { transform: scale(1.3) rotateY(1800deg); }
|
||||
100% { transform: scale(1) rotateY(3600deg); }
|
||||
}
|
||||
|
||||
#coin-text {
|
||||
font-size: 1.5rem;
|
||||
margin-bottom: 0.6rem;
|
||||
}
|
||||
|
||||
.result-title {
|
||||
font-size: 2.8rem;
|
||||
font-weight: 700;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.result-sub {
|
||||
font-size: 1.2rem;
|
||||
color: #aaa;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
button {
|
||||
padding: 0.7rem 2rem;
|
||||
font-size: 1.1rem;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
background: #e94560;
|
||||
color: #fff;
|
||||
cursor: pointer;
|
||||
transition: background 0.15s;
|
||||
}
|
||||
|
||||
button:hover { background: #c73a52; }
|
||||
|
||||
.win-line {
|
||||
background: #0a3d62 !important;
|
||||
border-color: #e94560 !important;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1>Tic-Tac-Toe</h1>
|
||||
<div id="status"></div>
|
||||
<div id="board"></div>
|
||||
|
||||
<!-- Coin flip overlay -->
|
||||
<div class="overlay" id="coinOverlay">
|
||||
<div id="coin">?</div>
|
||||
<div id="coin-text">Flipping a coin…</div>
|
||||
</div>
|
||||
|
||||
<!-- Game over overlay -->
|
||||
<div class="overlay hidden" id="endOverlay">
|
||||
<div class="result-title" id="endTitle"></div>
|
||||
<div class="result-sub" id="endSub"></div>
|
||||
<button id="restartBtn">Play Again</button>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const WIN_PATTERNS = [
|
||||
[0,1,2],[3,4,5],[6,7,8],
|
||||
[0,3,6],[1,4,7],[2,5,8],
|
||||
[0,4,8],[2,4,6]
|
||||
];
|
||||
|
||||
let board, playerMark, compMark, currentPlayer, gameOver;
|
||||
|
||||
const boardEl = document.getElementById('board');
|
||||
const statusEl = document.getElementById('status');
|
||||
const coinOverlay = document.getElementById('coinOverlay');
|
||||
const coinEl = document.getElementById('coin');
|
||||
const coinText = document.getElementById('coin-text');
|
||||
const endOverlay = document.getElementById('endOverlay');
|
||||
const endTitle = document.getElementById('endTitle');
|
||||
const endSub = document.getElementById('endSub');
|
||||
|
||||
// ---------- init ----------
|
||||
function init() {
|
||||
board = Array(9).fill(null);
|
||||
gameOver = false;
|
||||
endOverlay.classList.add('hidden');
|
||||
buildBoard();
|
||||
|
||||
coinText.textContent = 'Flipping a coin…';
|
||||
coinEl.textContent = '?';
|
||||
coinEl.classList.remove('flip');
|
||||
coinOverlay.classList.remove('hidden');
|
||||
|
||||
void coinEl.offsetWidth;
|
||||
coinEl.classList.add('flip');
|
||||
|
||||
setTimeout(() => {
|
||||
const heads = Math.random() < 0.5;
|
||||
coinEl.textContent = heads ? 'H' : 'T';
|
||||
|
||||
if (heads) {
|
||||
playerMark = 'X';
|
||||
compMark = 'O';
|
||||
currentPlayer = 'player';
|
||||
coinText.textContent = 'Heads! You go first as X.';
|
||||
} else {
|
||||
playerMark = 'O';
|
||||
compMark = 'X';
|
||||
currentPlayer = 'computer';
|
||||
coinText.textContent = 'Tails! Computer goes first as X.';
|
||||
}
|
||||
|
||||
statusEl.textContent = currentPlayer === 'player'
|
||||
? 'Your turn'
|
||||
: "Computer's turn";
|
||||
|
||||
setTimeout(() => {
|
||||
coinOverlay.classList.add('hidden');
|
||||
if (currentPlayer === 'computer') {
|
||||
setTimeout(compMove, 1000);
|
||||
}
|
||||
}, 1400);
|
||||
}, 850);
|
||||
}
|
||||
|
||||
function buildBoard() {
|
||||
boardEl.innerHTML = '';
|
||||
for (let i = 0; i < 9; i++) {
|
||||
const cell = document.createElement('div');
|
||||
cell.classList.add('cell');
|
||||
cell.dataset.index = i;
|
||||
cell.addEventListener('click', () => handleClick(i));
|
||||
boardEl.appendChild(cell);
|
||||
}
|
||||
}
|
||||
|
||||
function render() {
|
||||
const cells = boardEl.querySelectorAll('.cell');
|
||||
cells.forEach((c, i) => {
|
||||
c.textContent = board[i] || '';
|
||||
c.classList.remove('x', 'o', 'taken');
|
||||
if (board[i]) {
|
||||
c.classList.add(board[i], 'taken');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function handleClick(i) {
|
||||
if (gameOver || board[i] || currentPlayer !== 'player') return;
|
||||
board[i] = playerMark;
|
||||
render();
|
||||
if (checkEnd()) return;
|
||||
currentPlayer = 'computer';
|
||||
statusEl.textContent = "Computer's turn";
|
||||
setTimeout(compMove, 600);
|
||||
}
|
||||
|
||||
function compMove() {
|
||||
if (gameOver) return;
|
||||
const empties = board.map((v, i) => v === null ? i : -1).filter(i => i !== -1);
|
||||
if (!empties.length) return;
|
||||
board[empties[Math.floor(Math.random() * empties.length)]] = compMark;
|
||||
render();
|
||||
checkEnd();
|
||||
}
|
||||
|
||||
function checkEnd() {
|
||||
const winner = checkWinner();
|
||||
if (winner) {
|
||||
gameOver = true;
|
||||
const cells = boardEl.querySelectorAll('.cell');
|
||||
const line = WIN_PATTERNS.find(p => p.every(i => board[i] === winner));
|
||||
if (line) line.forEach(i => cells[i].classList.add('win-line'));
|
||||
|
||||
const isPlayer = winner === playerMark;
|
||||
endTitle.textContent = isPlayer ? 'You Win!' : 'Computer Wins!';
|
||||
endSub.textContent = isPlayer
|
||||
? 'Great job! Want to play again?'
|
||||
: 'Better luck next time. Play again?';
|
||||
setTimeout(() => endOverlay.classList.remove('hidden'), 700);
|
||||
return true;
|
||||
}
|
||||
if (board.every(c => c !== null)) {
|
||||
gameOver = true;
|
||||
endTitle.textContent = 'It\'s a Draw!';
|
||||
endSub.textContent = 'No winner this round. Try again?';
|
||||
setTimeout(() => endOverlay.classList.remove('hidden'), 700);
|
||||
return true;
|
||||
}
|
||||
if (!gameOver) {
|
||||
currentPlayer = (currentPlayer === 'player') ? 'computer' : 'player';
|
||||
statusEl.textContent = currentPlayer === 'player' ? 'Your turn' : "Computer's turn";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function checkWinner() {
|
||||
for (const [a, b, c] of WIN_PATTERNS) {
|
||||
if (board[a] && board[a] === board[b] && board[a] === board[c]) return board[a];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
document.getElementById('restartBtn').addEventListener('click', init);
|
||||
init();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user