File size: 11,972 Bytes
d0a5785 6085efd |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 |
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Missing Values Tic-Tac-Toe</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="bg-gradient-to-br from-yellow-50 to-rose-100 min-h-screen flex items-center justify-center p-6">
<div class="w-full max-w-5xl bg-white rounded-2xl shadow-xl p-6">
<h1 class="text-3xl md:text-4xl font-extrabold text-center text-rose-700">Missing Values Tic-Tac-Toe</h1>
<p class="text-center text-sm text-gray-600 mt-2">
Source:
<a class="text-blue-600 underline" target="_blank" rel="noopener"
href="https://www.linkedin.com/pulse/creating-managing-missing-values-data-traditional-ai-driven-lively-eb3se/">
Creating and Managing Missing Values in Data — Michael Lively
</a>
</p>
<div id="banner" class="hidden bg-rose-100 border border-rose-300 text-rose-900 font-semibold text-center py-2 rounded mt-4"></div>
<div class="mt-6 flex flex-col md:flex-row md:space-x-6 space-y-4 md:space-y-0">
<!-- Board -->
<div id="board" class="grid grid-cols-3 gap-2 p-2 bg-gray-50 rounded-xl border-4 border-gray-200 mx-auto"></div>
<!-- Question Panel -->
<div id="questionPanel" class="md:w-1/2 w-full bg-gray-50 rounded-xl shadow-inner p-4">
<h2 id="panelQuestion" class="text-lg md:text-xl font-semibold text-gray-800">
Select a square to view the question
</h2>
<ul id="panelChoices" class="mt-4 space-y-2"></ul>
<p id="panelHint" class="mt-3 text-sm text-gray-600 hidden"></p>
<div class="mt-4 flex items-center space-x-2">
<button id="hintBtn" class="px-3 py-1.5 bg-gray-200 text-gray-700 rounded hover:bg-gray-300">Show Hint</button>
<button id="clearBtn" class="px-3 py-1.5 bg-white border rounded hover:bg-gray-100">Clear Panel</button>
</div>
</div>
</div>
<div class="flex flex-col md:flex-row md:items-center md:justify-between mt-6 space-y-3 md:space-y-0">
<p id="status" class="text-lg font-medium text-gray-800"></p>
<div class="flex items-center space-x-2">
<label class="text-sm text-gray-600">Mode:</label>
<select id="mode" class="border rounded px-2 py-1 text-sm">
<option value="two">Two Players (X vs O)</option>
<option value="solo">Solo (You are X)</option>
</select>
<button id="restartBtn" class="px-4 py-2 bg-rose-700 text-white rounded hover:bg-rose-800">Restart</button>
</div>
</div>
</div>
<script>
const randShuffle = (arr) => arr
.map(x => ({ x, r: Math.random() }))
.sort((a,b) => a.r - b.r)
.map(o => o.x);
// --- Question Bank (about Missing Values) ---
const QUESTION_BANK = [
{
question: 'Why do we sometimes create missing values deliberately?',
choices: [
'To corrupt the dataset permanently',
'To test imputation methods, stress-test models, and teach data handling',
'To hide sensitive features before analysis',
'To reduce dataset size'
],
answer: 2,
hint: 'Think about research, robustness, and teaching use cases.'
},
{
question: 'What does MCAR stand for?',
choices: [
'Missing Completely at Random',
'Managed Cases at Runtime',
'Mean Correction Algorithm Rule',
'Missing Computations in AI Regression'
],
answer: 1,
hint: 'It is the simplest type of missingness.'
},
{
question: 'Which traditional method is simplest but can distort variance?',
choices: [
'KNN Imputation',
'Mean/Median/Mode Imputation',
'Regression Imputation',
'GAN-based Imputation'
],
answer: 2,
hint: 'It just fills gaps with averages or modes.'
},
{
question: 'When is regression imputation best applied?',
choices: [
'When relationships are nonlinear',
'When values are missing completely at random',
'When strong linear correlations exist between variables',
'When text and tabular data are mixed'
],
answer: 3,
hint: 'Think straight-line relationships between variables.'
},
{
question: 'Which AI method iteratively predicts missing values for multiple variables?',
choices: ['Autoencoders', 'MICE', 'Bayesian Networks', 'GANs'],
answer: 2,
hint: 'Its name includes the word “Chained Equations”.'
},
{
question: 'Which deep learning model can reconstruct data by compressing and rebuilding inputs?',
choices: ['Decision Trees', 'Autoencoders', 'Support Vector Machines', 'Random Forests'],
answer: 2,
hint: 'It learns a latent representation of data.'
},
{
question: 'What makes GAN-based imputations (like GAIN) powerful?',
choices: [
'They always predict exact ground truth',
'They use adversarial training to generate realistic missing values',
'They only work for text data',
'They are deterministic and rule-based'
],
answer: 2,
hint: 'Think “generator vs. discriminator”.'
},
{
question: 'When is a Bayesian or EM approach most appropriate?',
choices: [
'When uncertainty must be quantified',
'When data is always complete',
'When no computation budget is available',
'When working only with images'
],
answer: 1,
hint: 'They provide distributions, not just point estimates.'
},
{
question: 'What type of data benefits most from Graph Neural Networks in imputation?',
choices: [
'Time series only',
'Graph-structured or relational data',
'Image pixel grids',
'Independent random samples'
],
answer: 2,
hint: 'Think networks: molecules, social media, transport.'
},
{
question: 'Which modern AI technique can handle hybrid text + tabular data?',
choices: [
'Self-supervised models and LLMs',
'Linear regression',
'Mode imputation',
'Support Vector Machines'
],
answer: 1,
hint: 'Think masked language models applied to structured data.'
}
];
// --- Game State ---
let currentPlayer, boardState, selectedCell, cellQuestions, mode;
const boardEl = document.getElementById('board');
const statusEl = document.getElementById('status');
const bannerEl = document.getElementById('banner');
const hintBtn = document.getElementById('hintBtn');
const clearBtn = document.getElementById('clearBtn');
const panelQuestion = document.getElementById('panelQuestion');
const panelChoices = document.getElementById('panelChoices');
const panelHint = document.getElementById('panelHint');
const restartBtn = document.getElementById('restartBtn');
const modeSel = document.getElementById('mode');
function initGame() {
mode = modeSel.value;
currentPlayer = 'X';
boardState = Array(9).fill('');
bannerEl.classList.add('hidden');
statusEl.innerText = '';
selectedCell = null;
const picked = randShuffle(QUESTION_BANK).slice(0, 9).map(q => {
const original = q.choices.map((c, i) => ({ text: c, idx: i + 1 }));
const shuffled = randShuffle(original);
const newChoices = shuffled.map(o => o.text);
const newAnswerIndex = shuffled.findIndex(o => o.idx === q.answer) + 1;
return {
question: q.question,
choices: newChoices,
answer: newAnswerIndex,
hint: q.hint || ''
};
});
cellQuestions = picked;
panelQuestion.innerText = 'Select a square to view the question';
panelChoices.innerHTML = '';
panelHint.classList.add('hidden');
panelHint.innerText = '';
renderBoard();
}
function renderBoard() {
boardEl.innerHTML = '';
boardState.forEach((mark, idx) => {
const btn = document.createElement('button');
let cls = 'bg-white h-24 w-24 md:h-28 md:w-28 flex items-center justify-center text-3xl font-extrabold rounded-xl shadow hover:bg-gray-100 transition';
if (mark === 'X') cls += ' text-rose-700';
if (mark === 'O') cls += ' text-sky-700';
btn.className = cls;
btn.innerText = mark;
btn.disabled = mark !== '';
btn.addEventListener('click', () => openQuestion(idx));
boardEl.appendChild(btn);
});
statusEl.innerText = `Current: ${currentPlayer}`;
}
function openQuestion(idx) {
selectedCell = idx;
const q = cellQuestions[idx];
panelQuestion.innerText = q.question;
panelChoices.innerHTML = '';
panelHint.classList.add('hidden');
panelHint.innerText = q.hint || '';
q.choices.forEach((c, i) => {
const li = document.createElement('li');
const btn = document.createElement('button');
btn.innerText = c;
btn.className = 'w-full text-left px-4 py-2 bg-gray-100 rounded hover:bg-gray-200';
btn.addEventListener('click', () => handleAnswer(i + 1));
li.appendChild(btn);
panelChoices.appendChild(li);
});
}
function handleAnswer(choice) {
const q = cellQuestions[selectedCell];
if (choice === q.answer) {
boardState[selectedCell] = currentPlayer;
renderBoard();
if (checkWin(currentPlayer)) return endGame(`${currentPlayer} wins!`);
if (boardState.every(c => c)) return endGame('Stalemate!');
currentPlayer = currentPlayer === 'X' ? 'O' : 'X';
statusEl.innerText = `Current: ${currentPlayer}`;
if (mode === 'solo' && currentPlayer === 'O') {
setTimeout(aiMove, 450);
}
} else {
alert('Incorrect! Turn missed.');
currentPlayer = currentPlayer === 'X' ? 'O' : 'X';
statusEl.innerText = `Current: ${currentPlayer}`;
if (mode === 'solo' && currentPlayer === 'O') {
setTimeout(aiMove, 450);
}
}
}
function checkWin(player) {
const wins = [
[0,1,2],[3,4,5],[6,7,8],
[0,3,6],[1,4,7],[2,5,8],
[0,4,8],[2,4,6]
];
return wins.some(combo => combo.every(i => boardState[i] === player));
}
function endGame(msg) {
bannerEl.innerText = `🎉 ${msg}`;
bannerEl.classList.remove('hidden');
document.querySelectorAll('#board button').forEach(b => b.disabled = true);
}
function aiMove() {
const open = boardState.map((v,i) => v === '' ? i : null).filter(v => v !== null);
if (open.length === 0) return;
const pick = open[Math.floor(Math.random() * open.length)];
const q = cellQuestions[pick];
const aiCorrect = Math.random() < 0.55;
if (aiCorrect) {
boardState[pick] = 'O';
renderBoard();
if (checkWin('O')) return endGame('O wins!');
if (boardState.every(c => c)) return endGame('Stalemate!');
currentPlayer = 'X';
statusEl.innerText = `Current: ${currentPlayer}`;
} else {
currentPlayer = 'X';
statusEl.innerText = `Current: ${currentPlayer}`;
}
}
hintBtn.addEventListener('click', () => panelHint.classList.toggle('hidden'));
clearBtn.addEventListener('click', () => {
panelQuestion.innerText = 'Select a square to view the question';
panelChoices.innerHTML = '';
panelHint.classList.add('hidden');
panelHint.innerText = '';
});
restartBtn.addEventListener('click', initGame);
modeSel.addEventListener('change', initGame);
initGame();
</script>
</body>
</html>
|