417 lines
21 KiB
HTML
417 lines
21 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="ru" data-theme="dark">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||
<title>Космический сканворд — разгадай и победь</title>
|
||
<meta name="description" content="Интерактивный сканворд на тему Космос: 12 слов, подсказки, проверка ответов и звёздное поле.">
|
||
<link rel="icon" href="design-system/brand/kazakhtelecom-logo.png">
|
||
<link rel="stylesheet" href="design-system/kt-ai-fonts.css">
|
||
<link rel="stylesheet" href="design-system/kt-ai-tokens.css">
|
||
<link rel="stylesheet" href="design-system/kt-ai-components.css">
|
||
<link rel="stylesheet" href="design-system/kt-ai-page.css">
|
||
<style>
|
||
* { box-sizing: border-box; }
|
||
a.kt-ai-btn { text-decoration: none; }
|
||
.stars { position: fixed; inset: 0; pointer-events: none; z-index: -1; }
|
||
.star { position: absolute; border-radius: 50%; background: var(--kt-ai-fg); opacity: .35; animation: twinkle 3s ease-in-out infinite; }
|
||
@keyframes twinkle { 0%,100% { opacity: .15; } 50% { opacity: .7; } }
|
||
.hud { display: flex; align-items: center; gap: var(--kt-ai-space-6); flex-wrap: wrap; margin-top: var(--kt-ai-space-7); }
|
||
.hud .stat b { font-size: var(--kt-ai-text-3xl); font-family: var(--kt-ai-font-mono); }
|
||
.hud .stat span { font-size: var(--kt-ai-text-xs); color: var(--kt-ai-fg-faint); }
|
||
.progress { flex: 1; min-width: 140px; height: 10px; border-radius: var(--kt-ai-radius-full); overflow: hidden; background: color-mix(in srgb, var(--kt-ai-fg) 10%, transparent); }
|
||
.progress i { display: block; height: 100%; background: var(--kt-ai-primary); transition: width .4s ease; border-radius: var(--kt-ai-radius-full); }
|
||
.game-layout { display: grid; grid-template-columns: minmax(0,1fr) 330px; gap: var(--kt-ai-space-9); align-items: start; margin-top: var(--kt-ai-space-9); }
|
||
@media (max-width: 920px) { .game-layout { grid-template-columns: 1fr; } }
|
||
.board-scroll { overflow-x: auto; padding-bottom: var(--kt-ai-space-2); }
|
||
.board { display: grid; grid-template-columns: repeat(11, var(--cell, 44px)); grid-auto-rows: var(--cell, 44px); gap: 7px; width: max-content; margin: 0 auto; }
|
||
.cell { position: relative; display: grid; place-items: center; border-radius: var(--kt-ai-radius-md); background: var(--kt-ai-card-bg); border: 1px solid var(--kt-ai-card-border); cursor: pointer; }
|
||
.cell.block { background: color-mix(in srgb, var(--kt-ai-fg) 6%, transparent); border-color: transparent; cursor: default; }
|
||
.cell .num { position: absolute; top: 3px; left: 5px; font-size: var(--kt-ai-text-xs); color: var(--kt-ai-fg-faint); font-weight: var(--kt-ai-weight-medium); }
|
||
.cell input { pointer-events: none; width: 100%; height: 100%; border: 0; background: none; outline: none; text-align: center; font-family: var(--kt-ai-font-mono); font-size: calc(var(--cell, 44px) * .5); font-weight: var(--kt-ai-weight-bold); color: var(--kt-ai-fg); text-transform: uppercase; }
|
||
.cell.sel { border-color: var(--kt-ai-primary); box-shadow: 0 0 0 2px color-mix(in srgb, var(--kt-ai-primary) 45%, transparent); }
|
||
.cell.ok { background: color-mix(in srgb, var(--kt-ai-primary) 16%, var(--kt-ai-card-bg)); border-color: color-mix(in srgb, var(--kt-ai-primary) 55%, var(--kt-ai-card-border)); }
|
||
.cell.bad { border-color: var(--kt-ai-danger); }
|
||
.cell.pop { animation: pop .3s ease; }
|
||
@keyframes pop { 0% { transform: scale(1); } 50% { transform: scale(1.18); } 100% { transform: scale(1); } }
|
||
.clues-box { background: var(--kt-ai-card-bg); border: 1px solid var(--kt-ai-card-border); border-radius: var(--kt-ai-radius-2xl); padding: var(--kt-ai-space-5); }
|
||
.clues-box h3 { margin: 0 0 var(--kt-ai-space-3); font-size: var(--kt-ai-text-lg); display: flex; gap: var(--kt-ai-space-2); align-items: center; }
|
||
.clue { display: flex; gap: var(--kt-ai-space-3); padding: var(--kt-ai-space-3); border-radius: var(--kt-ai-radius-lg); cursor: pointer; border: 1px solid transparent; align-items: flex-start; }
|
||
.clue:hover { background: color-mix(in srgb, var(--kt-ai-fg) 5%, transparent); }
|
||
.clue .n { font-weight: var(--kt-ai-weight-bold); font-family: var(--kt-ai-font-mono); min-width: 22px; color: var(--kt-ai-primary); }
|
||
.clue .t { color: var(--kt-ai-fg-muted); font-size: var(--kt-ai-text-sm); }
|
||
.clue .w { color: var(--kt-ai-fg-faint); font-size: var(--kt-ai-text-xs); white-space: nowrap; }
|
||
.clue.done { opacity: .5; }
|
||
.clue.done .t { text-decoration: line-through; }
|
||
.clue.sel { border-color: var(--kt-ai-primary); }
|
||
.win-banner { margin: var(--kt-ai-space-7) 0 0; padding: var(--kt-ai-space-7); border-radius: var(--kt-ai-radius-2xl); background: color-mix(in srgb, var(--kt-ai-primary) 12%, var(--kt-ai-card-bg)); border: 1px solid color-mix(in srgb, var(--kt-ai-primary) 45%, transparent); text-align: center; }
|
||
.board-foot { display: flex; justify-content: center; gap: var(--kt-ai-space-3); flex-wrap: wrap; margin-top: var(--kt-ai-space-6); }
|
||
.toast { position: fixed; left: 50%; transform: translateX(-50%); bottom: 24px; background: var(--kt-ai-card-bg); border: 1px solid var(--kt-ai-card-border); border-radius: var(--kt-ai-radius-full); padding: var(--kt-ai-space-3) var(--kt-ai-space-6); z-index: 10; font-size: var(--kt-ai-text-sm); box-shadow: 0 8px 24px rgba(0,0,0,.35); opacity: 0; transition: opacity .3s; }
|
||
</style>
|
||
</head>
|
||
<body>
|
||
|
||
<div class="stars" id="stars"></div>
|
||
|
||
<section class="kt-ai-hero" data-align="center">
|
||
<div class="kt-ai-wrap">
|
||
<div class="kt-ai-hero-actions" style="justify-content:center;margin-bottom:var(--kt-ai-space-4)">
|
||
<span class="kt-ai-chip"><svg class="kt-icon" aria-hidden="true"><use href="#rocket"></use></svg> Космос · 12 слов</span>
|
||
</div>
|
||
<h1>Сканворд «Космос»</h1>
|
||
<p class="kt-ai-hero-sub">Выбери слово в списке подсказок, вводи буквы с клавиатуры — собранные слова подсвечиваются сами. Заполни весь космос, чтобы победить!</p>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="kt-ai-section" data-divider="true">
|
||
<div class="kt-ai-wrap">
|
||
<div class="hud">
|
||
<div class="stat"><b id="progressWords">0/12</b><span>слов разгадано</span></div>
|
||
<div class="progress"><i id="progressBar" style="width:0%"></i></div>
|
||
<div class="stat"><b id="timer">0:00</b><span>время</span></div>
|
||
</div>
|
||
|
||
<div class="board-foot">
|
||
<button class="kt-ai-btn" data-variant="ghost" data-size="sm" id="btnHint">Подсказать букву</button>
|
||
<button class="kt-ai-btn" data-size="sm" id="btnCheck">Проверить</button>
|
||
<button class="kt-ai-btn" data-variant="ghost" data-size="sm" id="btnReset">Сбросить</button>
|
||
</div>
|
||
|
||
<div class="win-banner" id="winBanner" hidden>
|
||
<div style="display:flex;align-items:center;justify-content:center;gap:var(--kt-ai-space-3)">
|
||
<svg class="kt-icon kt-icon-lg" aria-hidden="true"><use href="#trophy"></use></svg>
|
||
<h2 style="margin:0">Победа! Космос разгадан за <b id="winTime"></b></h2>
|
||
</div>
|
||
<p style="margin-top:var(--kt-ai-space-4)">Ты настоящий космонавт. Попробуй ещё раз?</p>
|
||
<div class="kt-ai-hero-actions" style="justify-content:center;margin-top:var(--kt-ai-space-5)"><button class="kt-ai-btn" data-variant="primary" id="btnAgain" data-size="lg">Сыграть ещё раз</button></div>
|
||
</div>
|
||
|
||
<div class="game-layout">
|
||
<div class="board-scroll"><div class="board" id="board"></div></div>
|
||
<aside class="clues-box">
|
||
<h3><svg class="kt-icon" aria-hidden="true"><use href="#book"></use></svg> Подсказки</h3>
|
||
<div id="clues"></div>
|
||
</aside>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<footer class="kt-ai-wrap kt-ai-pagefoot">
|
||
<span>© 2026 Космический сканворд</span>
|
||
<span class="kt-ai-spacer"></span>
|
||
<span>12 слов о Вселенной</span>
|
||
</footer>
|
||
|
||
<script src="design-system/icons/kt-ai-icons.js"></script>
|
||
<script>
|
||
"use strict";
|
||
|
||
var ACROSS = {
|
||
2: {answer:"КОСМОС", clue:"Слово, с которого началась наша Вселенная"},
|
||
4: {answer:"ЛУНА", clue:"Единственный естественный спутник Земли"},
|
||
5: {answer:"ЗЕМЛЯ", clue:"Её называют «голубой планетой»"},
|
||
6: {answer:"СОЛНЦЕ", clue:"Оно находится в центре нашей системы"},
|
||
9: {answer:"ТЕЛЕСКОП", clue:"Прибор для наблюдения за далёкими звёздами"},
|
||
10: {answer:"ГРАВИТАЦИЯ", clue:"Сила, которая держит Луну рядом с Землёй"}
|
||
};
|
||
var DOWN = {
|
||
1: {answer:"ЗВЕЗДА", clue:"Вечный огонь, горящий в небе"},
|
||
3: {answer:"МЕРКУРИЙ", clue:"Самая близкая к Солнцу планета"},
|
||
5: {answer:"ПРИВОЗ", clue:"Пустое место-ловушка в кроссворде"},
|
||
8: {answer:"МЕТЕЛЬ", clue:"Она кружит в атмосфере, а в космосе её нет"}
|
||
};
|
||
var START = {
|
||
A: {2:[2,2], 4:[4,4], 5:[6,3], 6:[8,4], 9:[10,1], 10:[10,4]},
|
||
D: {1:[2,1], 3:[2,5], 5:[5,6], 8:[6,8]}
|
||
};
|
||
var TOTAL = 12;
|
||
var LETTERS = "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ";
|
||
var R = 11, C = 11;
|
||
|
||
/* ---- сетка ---- */
|
||
var grid = [];
|
||
for (var gr = 0; gr < R; gr++) { grid[gr] = []; for (var gc = 0; gc < C; gc++) grid[gr][gc] = null; }
|
||
function place(dir, id, word, r0, c0) {
|
||
for (var i = 0; i < word.length; i++) {
|
||
var r = r0 + (dir === "A" ? 0 : i);
|
||
var c = c0 + (dir === "A" ? i : 0);
|
||
var ch = word[i];
|
||
var cell = grid[r][c];
|
||
if (!cell) cell = grid[r][c] = {A:null, iA:-1, D:null, iD:-1, ch:""};
|
||
if (dir === "A") cell.A = id, cell.iA = i; else cell.D = id, cell.iD = i;
|
||
if (cell.ch && cell.ch !== ch) document.body.textContent = "КОЛЛИЗИЯ на " + r + "," + c;
|
||
cell.ch = ch;
|
||
}
|
||
}
|
||
for (var ka in ACROSS) place("A", +ka, ACROSS[+ka].answer, START.A[+ka][0], START.A[+ka][1]);
|
||
for (var kd in DOWN) place("D", +kd, DOWN[+kd].answer, START.D[+kd][0], START.D[+kd][1]);
|
||
|
||
/* строка сетки для слова */
|
||
function cellsOf(dir, id) {
|
||
var w = (dir === "A" ? ACROSS : DOWN)[id];
|
||
var s = START[dir][id];
|
||
var out = [];
|
||
for (var i = 0; i < w.answer.length; i++) out.push({r: s[0] + (dir === "D" ? i : 0), c: s[1] + (dir === "A" ? i : 0)});
|
||
return out;
|
||
}
|
||
|
||
/* ---- state ---- */
|
||
var letters = {}; // "r_c" -> строка буквы
|
||
var selDir = "A", selId = null, selIdx = 0;
|
||
var solved = new Set();
|
||
var start = Date.now(), timerH = null, won = false, toastH = null;
|
||
|
||
/* ---- DOM ---- */
|
||
var boardEl = document.getElementById("board");
|
||
function buildBoard() {
|
||
boardEl.innerHTML = "";
|
||
for (var r = 0; r < R; r++) for (var c = 0; c < C; c++) {
|
||
var d = document.createElement("div");
|
||
var cell = grid[r][c];
|
||
if (!cell) { d.className = "cell block"; boardEl.appendChild(d); continue; }
|
||
d.className = "cell";
|
||
d.setAttribute("data-r", r); d.setAttribute("data-c", c);
|
||
var numId = null;
|
||
if (cell.A !== null && START.A[cell.A][0] === r && START.A[cell.A][1] === c) numId = cell.A;
|
||
if (numId === null && cell.D !== null && START.D[cell.D][0] === r && START.D[cell.D][1] === c) numId = cell.D;
|
||
if (numId !== null) {
|
||
var n = document.createElement("span"); n.className = "num"; n.textContent = numId; d.appendChild(n);
|
||
}
|
||
var inp = document.createElement("input");
|
||
inp.maxLength = 1; inp.setAttribute("data-r", r); inp.setAttribute("data-c", c);
|
||
d.appendChild(inp);
|
||
d.addEventListener("click", function() { cellClick(+this.getAttribute("data-r"), +this.getAttribute("data-c")); });
|
||
boardEl.appendChild(d);
|
||
}
|
||
}
|
||
function id0(cell) { return cell.A !== null ? cell.A : cell.D; }
|
||
function cellEl(r, c) { return boardEl.querySelector('.cell[data-r="' + r + '"][data-c="' + c + '"]'); }
|
||
function inpEl(r, c) { var e = cellEl(r, c); return e && e.querySelector("input"); }
|
||
|
||
function selectWord(dir, id, idx) {
|
||
selDir = dir; selId = id; selIdx = idx || 0;
|
||
document.querySelectorAll(".cell.sel").forEach(function(e){ e.classList.remove("sel"); });
|
||
var list = cellsOf(dir, id);
|
||
list.forEach(function(p){ cellEl(p.r, p.c).classList.add("sel"); });
|
||
renderClues();
|
||
}
|
||
function cellClick(r, c) {
|
||
var cell = grid[r][c]; if (!cell) return;
|
||
var dir, id, idx;
|
||
if (selDir === "A" && cell.A !== null) { dir = "A"; id = cell.A; idx = cell.iA; }
|
||
else if (selDir === "D" && cell.D !== null) { dir = "D"; id = cell.D; idx = cell.iD; }
|
||
else if (cell.A !== null) { dir = "A"; id = cell.A; idx = cell.iA; }
|
||
else { dir = "D"; id = cell.D; idx = cell.iD; }
|
||
selectWord(dir, id, idx);
|
||
}
|
||
function focusIdx(dir, id, idx) {
|
||
selIdx = idx;
|
||
var list = cellsOf(dir, id);
|
||
var p = list[idx];
|
||
document.querySelectorAll(".cell.sel").forEach(function(e){ e.classList.remove("sel"); });
|
||
list.forEach(function(q){ cellEl(q.r, q.c).classList.add("sel"); });
|
||
var i = inpEl(p.r, p.c); if (i) i.focus();
|
||
}
|
||
|
||
function onInput(e) {
|
||
var inp = e.target; if (inp.tagName !== "INPUT") return;
|
||
var r = +inp.getAttribute("data-r"), c = +inp.getAttribute("data-c");
|
||
v = (v || "").toUpperCase().replace(/Ё/g, "Е");
|
||
if (v.length > 1) v = v.slice(-1);
|
||
if (v && LETTERS.indexOf(v) === -1) v = "";
|
||
inp.value = v;
|
||
letters[r + "_" + c] = v;
|
||
if (v && selIdx < cellsOf(selDir, selId).length - 1) focusIdx(selDir, selId, selIdx + 1);
|
||
refresh();
|
||
}
|
||
|
||
function refresh() {
|
||
var done = solvedWords();
|
||
solved = done;
|
||
document.querySelectorAll(".cell.ok").forEach(function(e){ e.classList.remove("ok"); });
|
||
done.forEach(function(key) {
|
||
var dir = key[0], id = +key.slice(1);
|
||
cellsOf(dir, id).forEach(function(p){ cellEl(p.r, p.c).classList.add("ok"); });
|
||
});
|
||
document.getElementById("progressWords").textContent = done.size + "/" + TOTAL;
|
||
document.getElementById("progressBar").style.width = (done.size / TOTAL * 100) + "%";
|
||
renderClues();
|
||
if (done.size === TOTAL && !won) win();
|
||
}
|
||
function solvedWords() {
|
||
var done = new Set();
|
||
for (var id in ACROSS) {
|
||
var w = ACROSS[+id].answer, s = START.A[+id];
|
||
if (w.split("").every(function(ch, i){ return letters[s[0] + "_" + (s[1] + i)] === ch; })) done.add("A" + id);
|
||
}
|
||
for (var id2 in DOWN) {
|
||
var w2 = DOWN[+id2].answer, s2 = START.D[+id2];
|
||
if (w2.split("").every(function(ch, i){ return letters[(s2[0] + i) + "_" + s2[1]] === ch; })) done.add("D" + id2);
|
||
}
|
||
return done;
|
||
}
|
||
|
||
function checkBoard() {
|
||
var bad = 0;
|
||
document.querySelectorAll(".cell.bad").forEach(function(e){ e.classList.remove("bad"); });
|
||
for (var id in ACROSS) {
|
||
var w = ACROSS[+id].answer, s = START.A[+id];
|
||
for (var i = 0; i < w.length; i++) {
|
||
var r = s[0], c = s[1] + i; var v = letters[r + "_" + c];
|
||
if (v && v !== w[i]) { cellEl(r, c).classList.add("bad"); bad++; }
|
||
}
|
||
}
|
||
for (var id2 in DOWN) {
|
||
var w2 = DOWN[+id2].answer, s2 = START.D[+id2];
|
||
for (var i2 = 0; i2 < w2.length; i2++) {
|
||
var r2 = s2[0] + i2, c2 = s2[1]; var v2 = letters[r2 + "_" + c2];
|
||
if (v2 && v2 !== w2[i2]) { cellEl(r2, c2).classList.add("bad"); bad++; }
|
||
}
|
||
}
|
||
setTimeout(function(){ document.querySelectorAll(".cell.bad").forEach(function(e){ e.classList.remove("bad"); }); }, 1200);
|
||
toast(bad === 0 ? "Ошибок нет — так держать!" : "Не сойдётся: " + bad + " букв(ы)");
|
||
refresh();
|
||
}
|
||
|
||
function hint() {
|
||
if (selId === null) { toast("Выбери слово из подсказок"); return; }
|
||
var list = cellsOf(selDir, selId);
|
||
var w = (selDir === "A" ? ACROSS : DOWN)[selId].answer;
|
||
for (var i = 0; i < list.length; i++) {
|
||
var p = list[i];
|
||
if (!letters[p.r + "_" + p.c]) {
|
||
letters[p.r + "_" + p.c] = w[i];
|
||
var e = inpEl(p.r, p.c); if (e) e.value = w[i];
|
||
cellEl(p.r, p.c).classList.add("pop");
|
||
refresh();
|
||
toast("Подсказка открыта");
|
||
return;
|
||
}
|
||
}
|
||
toast("Это слово уже готово");
|
||
}
|
||
|
||
function win() {
|
||
won = true; clearInterval(timerH);
|
||
var s = Math.floor((Date.now() - start) / 1000);
|
||
document.getElementById("winTime").textContent = Math.floor(s/60) + " мин " + (s % 60) + " с";
|
||
document.getElementById("winBanner").hidden = false;
|
||
}
|
||
function reset() {
|
||
letters = {}; solved = new Set(); won = false;
|
||
start = Date.now(); document.getElementById("timer").textContent = "0:00";
|
||
document.querySelectorAll(".cell").forEach(function(e){ e.classList.remove("ok","bad","sel","win"); });
|
||
document.querySelectorAll(".cell input").forEach(function(i){ i.value = ""; });
|
||
document.getElementById("winBanner").hidden = true;
|
||
clearInterval(timerH); timerH = setInterval(tick, 1000);
|
||
refresh(); toast("Заново! Удачи");
|
||
}
|
||
function tick() {
|
||
var s = Math.floor((Date.now() - start) / 1000);
|
||
document.getElementById("timer").textContent = Math.floor(s/60) + ":" + (s % 60 < 10 ? "0" : "") + (s % 60);
|
||
}
|
||
function toast(msg) {
|
||
var t = document.querySelector(".toast");
|
||
if (!t) { t = document.createElement("div"); t.className = "toast"; document.body.appendChild(t); }
|
||
t.textContent = msg; t.style.opacity = "1";
|
||
clearTimeout(toastH); toastH = setTimeout(function(){ t.style.opacity = "0"; }, 2200);
|
||
}
|
||
|
||
function renderClues() {
|
||
var box = document.getElementById("clues");
|
||
box.innerHTML = "";
|
||
var done = solvedWords();
|
||
function block(dir, map, label) {
|
||
var head = document.createElement("div");
|
||
head.style.cssText = "font-size:var(--kt-ai-text-xs);color:var(--kt-ai-fg-faint);margin:var(--kt-ai-space-3) 0 var(--kt-ai-space-2);text-transform:uppercase;letter-spacing:.05em";
|
||
head.textContent = label; box.appendChild(head);
|
||
Object.keys(map).map(Number).sort(function(a,b){return a-b;}).forEach(function(id) {
|
||
var key = dir + id;
|
||
var el = document.createElement("div");
|
||
el.className = "clue" + (done.has(key) ? " done" : "") + (selDir === dir && selId === id ? " sel" : "");
|
||
el.innerHTML = '<span class="n">' + id + '</span><div><div class="t">' + map[id].clue + '</div><div class="w">' + map[id].answer.length + ' букв</div></div>';
|
||
el.addEventListener("click", function(){ selectWord(dir, id, 0); var l = cellsOf(dir, id); focusIdx(dir, id, 0); var i = inpEl(l[0].r, l[0].c); if (i) i.focus(); });
|
||
box.appendChild(el);
|
||
});
|
||
}
|
||
block("A", ACROSS, "Горизонталь");
|
||
block("D", DOWN, "Вертикаль");
|
||
}
|
||
|
||
function onKey(e) {
|
||
var inp = document.activeElement;
|
||
if (inp && inp.tagName !== "INPUT") return;
|
||
if (selId === null) return;
|
||
var list = cellsOf(selDir, selId);
|
||
var w = (selDir === "A" ? ACROSS : DOWN)[selId].answer;
|
||
if (e.key === "ArrowRight" && selDir === "A" && selIdx < list.length - 1) { e.preventDefault(); focusIdx("A", selId, selIdx + 1); }
|
||
else if (e.key === "ArrowLeft" && selDir === "A" && selIdx > 0) { e.preventDefault(); focusIdx("A", selId, selIdx - 1); }
|
||
else if (e.key === "ArrowDown") {
|
||
e.preventDefault();
|
||
var r = list[selIdx].r, c = list[selIdx].c; var cell = grid[r][c];
|
||
if (cell.D !== null) { selectWord("D", cell.D, cell.iD); focusIdx("D", cell.D, cell.iD); }
|
||
}
|
||
else if (e.key === "ArrowUp") {
|
||
e.preventDefault();
|
||
var r2 = list[selIdx].r, c2 = list[selIdx].c; var cell2 = grid[r2][c2];
|
||
if (cell2.A !== null) { selectWord("A", cell2.A, cell2.iA); focusIdx("A", cell2.A, cell2.iA); }
|
||
}
|
||
else if (e.key === "Backspace" && !inp.value) {
|
||
e.preventDefault();
|
||
if (selIdx > 0) {
|
||
var p = list[selIdx - 1];
|
||
letters[p.r + "_" + p.c] = "";
|
||
var i = inpEl(p.r, p.c); if (i) i.value = "";
|
||
focusIdx(selDir, selId, selIdx - 1);
|
||
refresh();
|
||
}
|
||
}
|
||
}
|
||
|
||
function buildStars() {
|
||
var box = document.getElementById("stars");
|
||
for (var i = 0; i < 70; i++) {
|
||
var s = document.createElement("span"); s.className = "star";
|
||
var sz = Math.random() * 3 + 1;
|
||
s.style.width = sz + "px"; s.style.height = sz + "px";
|
||
s.style.left = Math.random() * 100 + "%"; s.style.top = Math.random() * 100 + "%";
|
||
s.style.animationDelay = (Math.random() * 3) + "s";
|
||
s.style.animationDuration = (2 + Math.random() * 3) + "s";
|
||
box.appendChild(s);
|
||
}
|
||
}
|
||
|
||
function boot() {
|
||
buildBoard();
|
||
buildStars();
|
||
renderClues();
|
||
document.querySelectorAll(".cell").forEach(function(d) {
|
||
var inp = d.querySelector("input"); if (!inp) return;
|
||
inp.addEventListener("input", onInput);
|
||
inp.addEventListener("focus", function(){
|
||
var r = +inp.getAttribute("data-r"), c = +inp.getAttribute("data-c");
|
||
var cell = grid[r][c]; if (!cell) return;
|
||
if (selDir === "A" && cell.A !== null) selectWord("A", cell.A, cell.iA);
|
||
else if (selDir === "D" && cell.D !== null) selectWord("D", cell.D, cell.iD);
|
||
else if (cell.A !== null) selectWord("A", cell.A, cell.iA);
|
||
else selectWord("D", cell.D, cell.iD);
|
||
});
|
||
});
|
||
document.addEventListener("keydown", onKey);
|
||
document.getElementById("btnHint").addEventListener("click", hint);
|
||
document.getElementById("btnCheck").addEventListener("click", checkBoard);
|
||
document.getElementById("btnReset").addEventListener("click", reset);
|
||
document.getElementById("btnAgain").addEventListener("click", reset);
|
||
document.addEventListener("click", function(e) {
|
||
if (e.target.closest(".clues-box") || e.target.closest(".board") || e.target.closest(".kt-ai-btn")) return;
|
||
document.querySelectorAll(".cell.sel").forEach(function(x){ x.classList.remove("sel"); });
|
||
});
|
||
timerH = setInterval(tick, 1000); tick();
|
||
var l0 = cellsOf("A", 2); focusIdx("A", 2, 0);
|
||
}
|
||
boot();
|
||
</script>
|
||
|
||
</body>
|
||
</html>
|