TicTacToe / index.html
eva1267890's picture
Update index.html
0607104 verified
Raw
History Blame Contribute Delete
26.6 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Cyber Nexus // Tic-Tac-Toe</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
/* Custom Modern Core Animations */
@keyframes popIn {
0% { transform: scale(0.85); opacity: 0; filter: brightness(1.5); }
70% { transform: scale(1.05); }
100% { transform: scale(1); opacity: 1; filter: brightness(1); }
}
@keyframes strokeExtend {
0% { transform: scaleX(0); opacity: 0; }
100% { transform: scaleX(1); opacity: 1; }
}
@keyframes floatEffect {
0%, 100% { transform: translateY(0px); }
50% { transform: translateY(-6px); }
}
@keyframes particleFall {
0% { transform: translateY(-5vh) translateX(0) rotate(0deg); opacity: 1; }
100% { transform: translateY(105vh) translateX(100px) rotate(720deg); opacity: 0; }
}
@keyframes terminalShake {
0%, 100% { transform: translate(0, 0); }
10%, 30%, 50%, 70%, 90% { transform: translate(-4px, 2px); }
20%, 40%, 60%, 80% { transform: translate(4px, -2px); }
}
.shake-impact {
animation: terminalShake 0.4s cubic-bezier(.36,.07,.19,.97) both;
}
/* Utility System Classes */
.animate-pop { animation: popIn 0.25s cubic-bezier(0.175, 0.885, 0.32, 1.275) forwards; }
.animate-float { animation: floatEffect 4s ease-in-out infinite; }
.grid-cell {
position: relative;
background: rgba(30, 41, 59, 0.7);
border: 1px solid rgba(255, 255, 255, 0.05);
box-shadow: inset 0 4px 12px rgba(0, 0, 0, 0.2);
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.grid-cell:hover:empty {
background: rgba(51, 65, 85, 0.8);
border-color: rgba(255, 255, 255, 0.15);
transform: translateY(-2px);
box-shadow: 0 10px 20px -10px rgba(0, 0, 0, 0.5);
}
.win-vector {
position: absolute;
z-index: 20;
background: currentColor;
border-radius: 9999px;
transform-origin: left center;
animation: strokeExtend 0.4s cubic-bezier(0.4, 0, 0.2, 1) forwards;
box-shadow: 0 0 20px currentColor;
}
.fx-particle {
position: fixed;
pointer-events: none;
z-index: 50;
animation: particleFall 2.5s linear forwards;
}
/* Glassmorphism Panel Styling */
.panel-glass {
background: rgba(30, 41, 5slate9, 0.45);
backdrop-filter: blur(16px);
-webkit-backdrop-filter: blur(16px);
border: 1px solid rgba(255, 255, 255, 0.08);
}
.active-ring {
box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.1), 0 0 20px currentColor;
}
</style>
</head>
<body id="app-viewport" class="bg-slate-950 text-slate-100 min-h-screen flex flex-col items-center justify-center p-4 md:p-8 transition-all duration-700 font-sans selection:bg-purple-500/30">
<div class="max-w-5xl w-full space-y-8 relative z-10">
<header class="text-center space-y-2">
<h1 class="text-5xl md:text-6xl font-black tracking-tight uppercase bg-clip-text text-transparent bg-gradient-to-r from-cyan-400 via-indigo-400 to-fuchsia-500 animate-pulse">
Tic-Tac-Toe
</h1>
<div class="flex items-center justify-center gap-2 text-xs font-mono uppercase tracking-widest text-slate-400">
<span>Neural is active and ready to win! Good luck!</span>
<span class="w-1.5 h-1.5 rounded-full bg-emerald-400 inline-block animate-ping"></span>
</div>
</header>
<main class="grid grid-cols-1 lg:grid-cols-12 gap-8 items-start">
<section class="lg:col-span-7 xl:col-span-8 flex flex-col items-center">
<div class="w-full grid grid-cols-3 gap-3 mb-6 font-mono text-center">
<div class="panel-glass rounded-xl p-3 border-l-4 border-cyan-400">
<div class="text-xs uppercase text-slate-400 tracking-wider">User (X)</div>
<div id="stat-player" class="text-2xl font-bold text-cyan-400 mt-1">0</div>
</div>
<div class="panel-glass rounded-xl p-3 border-l-4 border-slate-400">
<div class="text-xs uppercase text-slate-400 tracking-wider">Ties</div>
<div id="stat-draws" class="text-2xl font-bold text-slate-300 mt-1">0</div>
</div>
<div class="panel-glass rounded-xl p-3 border-l-4 border-fuchsia-500">
<div class="text-xs uppercase text-slate-400 tracking-wider">Computer (O)</div>
<div id="stat-ai" class="text-2xl font-bold text-fuchsia-400 mt-1">0</div>
</div>
</div>
<div class="w-full relative panel-glass rounded-2xl p-4 shadow-2xl max-w-[480px] aspect-square group">
<div id="matrix-grid" class="grid grid-cols-3 gap-3 w-full h-full">
</div>
<div id="vector-plane" class="absolute inset-0 pointer-events-none overlay-container"></div>
</div>
</section>
<section class="lg:col-span-5 xl:col-span-4 space-y-6">
<div class="panel-glass rounded-2xl p-5 shadow-lg">
<h3 class="text-xs font-mono uppercase tracking-wider text-slate-400 mb-2">Diagnostic Output</h3>
<div class="bg-slate-900/60 rounded-xl p-4 border border-slate-800 flex items-center justify-center min-h-[72px]">
<p id="system-status" class="text-lg font-medium tracking-wide text-slate-200 text-center transition-all duration-200">
Awaiting user input...
</p>
</div>
</div>
<div class="panel-glass rounded-2xl p-5 shadow-lg space-y-3">
<h3 class="text-xs font-mono uppercase tracking-wider text-slate-400">Neural Intelligence Ceiling</h3>
<div class="grid grid-cols-3 gap-2 font-medium text-sm">
<button data-level="easy" class="diff-trigger py-2.5 px-3 rounded-xl bg-slate-800/80 border border-slate-700 hover:bg-slate-700/50 transition-all text-slate-300">Novice</button>
<button data-level="medium" class="diff-trigger py-2.5 px-3 rounded-xl bg-slate-800/80 border border-slate-700 hover:bg-slate-700/50 transition-all text-slate-300">Adaptive</button>
<button data-level="hard" class="diff-trigger py-2.5 px-3 rounded-xl bg-slate-800/80 border border-slate-700 hover:bg-slate-700/50 transition-all text-slate-300">Quantum</button>
</div>
</div>
<div class="panel-glass rounded-2xl p-5 shadow-lg space-y-3">
<h3 class="text-xs font-mono uppercase tracking-wider text-slate-400">Backgroud Color</h3>
<div class="grid grid-cols-6 gap-2">
<button data-palette="slate" class="theme-trigger aspect-square rounded-lg bg-slate-900 border border-slate-700 active-ring text-slate-400" title="Slate Void"></button>
<button data-palette="neon" class="theme-trigger aspect-square rounded-lg bg-gradient-to-br from-cyan-900 to-blue-900 border border-blue-700 text-cyan-400" title="Cyber Neon"></button>
<button data-palette="nebula" class="theme-trigger aspect-square rounded-lg bg-gradient-to-br from-purple-900 to-fuchsia-950 border border-purple-700 text-purple-400" title="Nebula Warp"></button>
<button data-palette="matrix" class="theme-trigger aspect-square rounded-lg bg-gradient-to-br from-emerald-950 to-slate-900 border border-emerald-800 text-emerald-400" title="Digital Grid"></button>
<button data-palette="magma" class="theme-trigger aspect-square rounded-lg bg-gradient-to-br from-rose-950 to-amber-950 border border-rose-800 text-rose-500" title="Magma Flare"></button>
<button data-palette="eclipse" class="theme-trigger aspect-square rounded-lg bg-gradient-to-br from-amber-950 to-zinc-900 border border-yellow-700 text-amber-500" title="Solar Eclipse"></button>
</div>
</div>
<button id="action-reset" class="w-full py-4 bg-gradient-to-r from-indigo-600 to-fuchsia-600 hover:from-indigo-500 hover:to-fuchsia-500 text-white font-bold rounded-xl shadow-lg shadow-indigo-500/20 transform hover:-translate-y-0.5 active:translate-y-0 transition-all tracking-wider text-sm uppercase font-mono">
<i class="fa-solid fa-rotate-right mr-2 text-xs"></i> Clear Playing Board
</button>
</section>
</main>
<footer class="text-center text-xs font-mono text-slate-600 pt-4">
© 2026 Eva Patel. Some Rights Reserved.
</footer>
</div>
<script>
document.addEventListener('DOMContentLoaded', () => {
// System Variables Space
let memoryCells = Array(9).fill('');
let activeEntity = 'X';
let matrixOperational = true;
let currentLevel = 'medium';
let activePalette = 'slate';
const registryScores = { user: 0, neural: 0, ties: 0 };
// Win Conditions Pattern Lookup Table
const winningVectors = [
{ pattern: [0, 1, 2], type: 'row', index: 0 },
{ pattern: [3, 4, 5], type: 'row', index: 1 },
{ pattern: [6, 7, 8], type: 'row', index: 2 },
{ pattern: [0, 3, 6], type: 'col', index: 0 },
{ pattern: [1, 4, 7], type: 'col', index: 1 },
{ pattern: [2, 5, 8], type: 'col', index: 2 },
{ pattern: [0, 4, 8], type: 'diag', index: 0 },
{ pattern: [2, 4, 6], type: 'diag', index: 1 }
];
// DOM Element Workspace Setup
const uiViewport = document.getElementById('app-viewport');
const uiGrid = document.getElementById('matrix-grid');
const uiVectorPlane = document.getElementById('vector-plane');
const uiStatusText = document.getElementById('system-status');
const uiBtnReset = document.getElementById('action-reset');
const uiScores = {
user: document.getElementById('stat-player'),
neural: document.getElementById('stat-ai'),
ties: document.getElementById('stat-draws')
};
const elementsDiff = document.querySelectorAll('.diff-trigger');
const elementsTheme = document.querySelectorAll('.theme-trigger');
// Theme Library Setup Config Configurations
const colorThemes = {
slate: { bg: 'bg-slate-950', panel: 'from-slate-900 to-slate-800', accent: 'text-slate-400' },
neon: { bg: 'bg-gradient-to-tr from-slate-950 via-blue-950 to-slate-950', panel: 'from-blue-900 to-indigo-950', accent: 'text-cyan-400' },
nebula: { bg: 'bg-gradient-to-tr from-slate-950 via-purple-950 to-slate-950', panel: 'from-purple-900 to-fuchsia-950', accent: 'text-fuchsia-400' },
matrix: { bg: 'bg-gradient-to-b from-black to-zinc-950', panel: 'from-zinc-900 to-emerald-950', accent: 'text-emerald-400' },
magma: { bg: 'bg-gradient-to-tr from-stone-950 via-rose-950 to-zinc-950', panel: 'from-rose-950 to-stone-900', accent: 'text-rose-500' },
eclipse: { bg: 'bg-gradient-to-br from-zinc-950 via-amber-950 to-neutral-950', panel: 'from-stone-900 to-amber-950', accent: 'text-amber-500' }
};
// Grid Layout Initialization Routine
function constructMatrixGrid() {
uiGrid.innerHTML = '';
for (let i = 0; i < 9; i++) {
const cellNode = document.createElement('button');
cellNode.className = 'grid-cell rounded-xl text-5xl font-extrabold flex items-center justify-center focus:outline-none focus:ring-2 focus:ring-indigo-500/40';
cellNode.dataset.cellIndex = i;
cellNode.addEventListener('click', () => triggerUserIntervention(i));
uiGrid.appendChild(cellNode);
}
}
// Engine Interactive Steps
function triggerUserIntervention(targetIndex) {
if (!matrixOperational || memoryCells[targetIndex] !== '' || activeEntity !== 'X') return;
commitMutationalMove(targetIndex, 'X');
if (evaluateMatrixState('X')) return;
activeEntity = 'O';
logDiagnosticMessage('Neural processing underway...', 'sync');
// UX Simulated Synaptic Latency Delayer
setTimeout(() => {
const computedMove = computeNeuralVector();
commitMutationalMove(computedMove, 'O');
if (evaluateMatrixState('O')) return;
activeEntity = 'X';
logDiagnosticMessage('Awaiting structural input...', 'user');
}, 400 + Math.random() * 300);
}
function commitMutationalMove(index, operator) {
memoryCells[index] = operator;
const domesticCell = uiGrid.children[index];
domesticCell.textContent = operator;
domesticCell.classList.add('animate-pop');
domesticCell.disabled = true;
if (operator === 'X') {
domesticCell.classList.add('text-cyan-400', 'shadow-[0_0_15px_rgba(34,211,238,0.2)]');
} else {
domesticCell.classList.add('text-fuchsia-400', 'shadow-[0_0_15px_rgba(232,121,249,0.2)]');
}
}
// Evaluation Engine Logic
function evaluateMatrixState(operator) {
const triumphantVector = verifyTriumph(memoryCells, operator);
if (triumphantVector) {
executeEndcycleProcedure(operator, triumphantVector);
return true;
}
if (memoryCells.every(c => c !== '')) {
executeEndcycleProcedure('draw');
return true;
}
return false;
}
function verifyTriumph(targetBoard, operator) {
return winningVectors.find(v => v.pattern.every(idx => targetBoard[idx] === operator)) || null;
}
// Algorithmic Artificial Intelligence Systems
function computeNeuralVector() {
if (currentLevel === 'easy') return extractRandomCell();
if (currentLevel === 'medium') {
if (Math.random() < 0.75) {
const directTriumph = discoverTerminalPath('O');
if (directTriumph !== -1) return directTriumph;
const defensiveBlock = discoverTerminalPath('X');
if (defensiveBlock !== -1) return defensiveBlock;
}
return extractRandomCell();
}
return processMinimaxAlgorithm();
}
function discoverTerminalPath(operator) {
for (let i = 0; i < 9; i++) {
if (memoryCells[i] === '') {
memoryCells[i] = operator;
const valid = verifyTriumph(memoryCells, operator);
memoryCells[i] = '';
if (valid) return i;
}
}
return -1;
}
function extractRandomCell() {
const clearIndices = memoryCells.map((val, idx) => val === '' ? idx : null).filter(v => v !== null);
return clearIndices[Math.floor(Math.random() * clearIndices.length)];
}
function processMinimaxAlgorithm() {
let supremeScore = -Infinity;
let tacticalIndex = 4; // Core element default priority placement optimization
if (memoryCells[4] === '') return 4;
for (let i = 0; i < 9; i++) {
if (memoryCells[i] === '') {
memoryCells[i] = 'O';
let dynamicScore = minimaxRecursion(memoryCells, 0, false);
memoryCells[i] = '';
if (dynamicScore > supremeScore) {
supremeScore = dynamicScore;
tacticalIndex = i;
}
}
}
return tacticalIndex;
}
function minimaxRecursion(virtualMatrix, runtimeDepth, searchingMax) {
if (verifyTriumph(virtualMatrix, 'O')) return 10 - runtimeDepth;
if (verifyTriumph(virtualMatrix, 'X')) return runtimeDepth - 10;
if (virtualMatrix.every(c => c !== '')) return 0;
if (searchingMax) {
let evaluationFloor = -Infinity;
for (let i = 0; i < 9; i++) {
if (virtualMatrix[i] === '') {
virtualMatrix[i] = 'O';
evaluationFloor = Math.max(evaluationFloor, minimaxRecursion(virtualMatrix, runtimeDepth + 1, false));
virtualMatrix[i] = '';
}
}
return evaluationFloor;
} else {
let evaluationCeiling = Infinity;
for (let i = 0; i < 9; i++) {
if (virtualMatrix[i] === '') {
virtualMatrix[i] = 'X';
evaluationCeiling = Math.min(evaluationCeiling, minimaxRecursion(virtualMatrix, runtimeDepth + 1, true));
virtualMatrix[i] = '';
}
}
return evaluationCeiling;
}
}
// Endcycle Processing Routines & Visual FX Rendering
function executeEndcycleProcedure(outcome, vectorContext = null) {
matrixOperational = false;
if (outcome === 'draw') {
registryScores.ties++;
uiScores.ties.textContent = registryScores.ties;
logDiagnosticMessage('Matrix Standoff. Paradox Locked.', 'stalemate');
} else {
const clientVictor = outcome === 'X';
if (clientVictor) {
registryScores.user++;
uiScores.user.textContent = registryScores.user;
logDiagnosticMessage('Human Intelligence Prevails.', 'win');
instantiateParticleCascade('#22d3ee');
} else {
registryScores.neural++;
uiScores.neural.textContent = registryScores.neural;
logDiagnosticMessage('Neural Array Dominance Certified.', 'lose');
instantiateParticleCascade('#e879f9');
}
renderVectorLine(vectorContext, clientVictor ? 'text-cyan-400' : 'text-fuchsia-400');
}
}
function renderVectorLine(vector, styleClass) {
const vectorLine = document.createElement('div');
vectorLine.className = `win-vector ${styleClass}`;
const factor = 100 / 3;
if (vector.type === 'row') {
vectorLine.style.top = `${(vector.index * factor) + (factor / 2)}%`;
vectorLine.style.left = '4%';
vectorLine.style.height = '6px';
vectorLine.style.width = '92%';
} else if (vector.type === 'col') {
vectorLine.style.left = `${(vector.index * factor) + (factor / 2)}%`;
vectorLine.style.top = '4%';
vectorLine.style.width = '6px';
vectorLine.style.height = '92%';
vectorLine.style.transformOrigin = 'center top';
vectorLine.style.transform = 'scaleY(0)';
vectorLine.style.animationName = 'strokeExtend';
} else if (vector.type === 'diag') {
vectorLine.style.height = '6px';
vectorLine.style.width = '124%';
if (vector.index === 0) {
vectorLine.style.top = '4%';
vectorLine.style.left = '4%';
vectorLine.style.transform = 'rotate(45deg)';
} else {
vectorLine.style.bottom = '4%';
vectorLine.style.left = '4%';
vectorLine.style.transformOrigin = 'left bottom';
vectorLine.style.transform = 'rotate(-45deg)';
}
}
uiVectorPlane.appendChild(vectorLine);
}
function instantiateParticleCascade(targetColor) {
for (let i = 0; i < 75; i++) {
const element = document.createElement('div');
element.className = 'fx-particle';
element.style.background = targetColor;
element.style.left = `${Math.random() * 100}vw`;
element.style.width = `${Math.random() * 8 + 4}px`;
element.style.height = element.style.width;
element.style.animationDelay = `${Math.random() * 1.5}s`;
element.style.boxShadow = `0 0 8px ${targetColor}`;
document.body.appendChild(element);
setTimeout(() => element.remove(), 4000);
}
}
// Diagnostic & Configuration Component Adjustments
function logDiagnosticMessage(msg, eventType) {
uiStatusText.textContent = msg;
uiStatusText.className = "text-lg font-medium tracking-wide text-center";
if (eventType === 'win') uiStatusText.classList.add('text-cyan-400', 'animate-bounce');
else if (eventType === 'lose') uiStatusText.classList.add('text-fuchsia-400', 'animate-pulse');
else if (eventType === 'sync') uiStatusText.classList.add('text-slate-400');
else uiStatusText.classList.add('text-slate-200');
}
function selectIntelligenceLevel(targetLevel) {
currentLevel = targetLevel;
elementsDiff.forEach(btn => {
if (btn.dataset.level === targetLevel) {
btn.className = "diff-trigger py-2.5 px-3 rounded-xl bg-gradient-to-r from-indigo-600 to-indigo-700 text-white shadow-md shadow-indigo-900/40 active-ring transition-all scale-105 font-semibold";
} else {
btn.className = "diff-trigger py-2.5 px-3 rounded-xl bg-slate-800/60 border border-slate-700/80 hover:bg-slate-700/50 text-slate-400 hover:text-slate-200 transition-all font-medium";
}
});
hardSystemPurge();
}
function deployScreenImpactShake() {
domStage.classList.add('shake-impact');
setTimeout(() => domStage.classList.remove('shake-impact'), 400);
}
function applyEnvironmentPalette(targetPalette) {
const selection = colorThemes[targetPalette];
uiViewport.className = `${selection.bg} text-slate-100 min-h-screen flex flex-col items-center justify-center p-4 md:p-8 transition-all duration-700 font-sans`;
elementsTheme.forEach(btn => {
if (btn.dataset.palette === targetPalette) btn.classList.add('active-ring');
else btn.classList.remove('active-ring');
});
}
function hardSystemPurge() {
memoryCells.fill('');
activeEntity = 'X';
matrixOperational = true;
uiVectorPlane.innerHTML = '';
Array.from(uiGrid.children).forEach(cell => {
cell.textContent = '';
cell.className = 'grid-cell rounded-xl text-5xl font-extrabold flex items-center justify-center focus:outline-none focus:ring-2 focus:ring-indigo-500/40';
cell.disabled = false;
});
logDiagnosticMessage('Awaiting structural input...', 'user');
}
// Event Bindings Initial Call
uiBtnReset.addEventListener('click', hardSystemPurge);
elementsDiff.forEach(btn => btn.addEventListener('click', () => selectIntelligenceLevel(btn.dataset.level)));
elementsTheme.forEach(btn => btn.addEventListener('click', () => applyEnvironmentPalette(btn.dataset.palette)));
// Master Initialization System Boot
constructMatrixGrid();
selectIntelligenceLevel('medium');
applyEnvironmentPalette('slate');
});
</script>
</body>
</html>