<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
    <channel>
        <title>Маргарита - Блог3</title>
        <link>http://margo.mozello.shop/blog3/</link>
        <description>Маргарита - Блог3</description>
                    <item>
                <title>3</title>
                <link>http://margo.mozello.shop/blog3/params/post/5336838/3</link>
                <pubDate>Thu, 22 Oct 2026 21:05:00 +0000</pubDate>
                <description>33&lt;p&gt;&lt;br&gt;&lt;/p&gt;


    &lt;meta charset=&quot;UTF-8&quot;&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
    &lt;title&gt;2048 (8×8)&lt;/title&gt;
    &lt;style&gt;
        /* ===== СТИЛІ ТА ТЕМИ ===== */
        :root {
            --bg-color: #faf8ef;
            --wrapper-bg: #bbada0;
            --tile-empty: rgba(238, 228, 218, 0.35);
            --text-color: #776e65;
            --header-color: #776e65;
        }

        .game-theme-wrapper.dark {
            --bg-color: #121212;
            --wrapper-bg: #2d2a26;
            --tile-empty: #3d3a36;
            --text-color: #f9f6f2;
            --header-color: #e2d7cb;
        }

        body {
            background-color: var(--bg-color);
            font-family: &quot;Clear Sans&quot;, &quot;Helvetica Neue&quot;, Arial, sans-serif;
            margin: 0;
            padding: 10px;
            display: flex;
            justify-content: center;
            align-items: center;
            min-height: 95vh;
            transition: background-color 0.3s;
        }

        .game-theme-wrapper {
            text-align: center;
            max-width: 520px;
            width: 100%;
            position: relative;
        }

        .theme-toggle {
            cursor: pointer;
            padding: 8px 12px;
            background: #8f7a66;
            color: #fff;
            border-radius: 5px;
            display: inline-block;
            margin-bottom: 10px;
            font-weight: bold;
            user-select: none;
        }

        h1 {
            color: var(--header-color);
            margin: 5px 0;
            font-size: 38px;
        }

        .info-container {
            display: flex;
            justify-content: space-between;
            margin-bottom: 10px;
            gap: 5px;
        }

        .info {
            background: #bbada0;
            color: #fff;
            padding: 8px 10px;
            border-radius: 5px;
            font-weight: bold;
            font-size: 16px;
            min-width: 70px;
            flex: 1;
        }

        #restart {
            background: #8f7a66;
            color: #fff;
            border: none;
            padding: 8px 15px;
            border-radius: 5px;
            font-weight: bold;
            cursor: pointer;
            font-size: 16px;
            flex: 1;
        }

        #restart:hover {
            background: #9e8b78;
        }

        /* ІГРОВЕ ПОЛЕ 8х8 */
        #game-container {
            position: relative;
            width: 100%;
        }

        #game-board {
            width: 100%;
            aspect-ratio: 1;
            background: var(--wrapper-bg);
            border-radius: 6px;
            padding: 8px;
            box-sizing: border-box;
            display: grid;
            grid-template-columns: repeat(8, 1fr);
            grid-gap: 5px;
        }

        .tile {
            background: var(--tile-empty);
            border-radius: 4px;
            display: flex;
            justify-content: center;
            align-items: center;
            font-weight: bold;
            font-size: 16px;
            color: #776e65;
            user-select: none;
            aspect-ratio: 1;
        }

        /* Стилі плиток за значеннями */
        .tile[data-value=&quot;2&quot;] { background: #eee4da; color: #776e65; }
        .tile[data-value=&quot;4&quot;] { background: #ede0c8; color: #776e65; }
        .tile[data-value=&quot;8&quot;] { background: #f2b179; color: #f9f6f2; }
        .tile[data-value=&quot;16&quot;] { background: #f59563; color: #f9f6f2; }
        .tile[data-value=&quot;32&quot;] { background: #f67c5f; color: #f9f6f2; }
        .tile[data-value=&quot;64&quot;] { background: #f65e3b; color: #f9f6f2; }
        .tile[data-value=&quot;128&quot;] { background: #edcf72; color: #f9f6f2; font-size: 14px; }
        .tile[data-value=&quot;256&quot;] { background: #edcc61; color: #f9f6f2; font-size: 14px; }
        .tile[data-value=&quot;512&quot;] { background: #edc850; color: #f9f6f2; font-size: 14px; }
        .tile[data-value=&quot;1024&quot;] { background: #edc53f; color: #f9f6f2; font-size: 12px; }
        .tile[data-value=&quot;2048&quot;] { background: #edc22e; color: #f9f6f2; font-size: 12px; }
        .tile[data-value=&quot;4096&quot;], .tile[data-value=&quot;8192&quot;] { background: #3c3a32; color: #f9f6f2; font-size: 12px; }

        /* ВІКНО ПОВІДОМЛЕННЯ */
        #message {
            display: none;
            position: absolute;
            top: 0; left: 0; right: 0; bottom: 0;
            background: rgba(238, 228, 218, 0.73);
            z-index: 10;
            flex-direction: column;
            justify-content: center;
            align-items: center;
            border-radius: 6px;
        }

        .game-theme-wrapper.dark #message {
            background: rgba(45, 42, 38, 0.85);
        }

        #message-text {
            font-size: 36px;
            font-weight: bold;
            color: #776e65;
            margin-bottom: 20px;
        }

        .game-theme-wrapper.dark #message-text {
            color: #f9f6f2;
        }

        #continue {
            background: #8f7a66;
            color: #fff;
            border: none;
            padding: 10px 20px;
            border-radius: 5px;
            font-weight: bold;
            cursor: pointer;
            font-size: 18px;
        }

        /* ЕКРАННИЙ КУРСОР КЕРУВАННЯ */
        .controls {
            margin-top: 15px;
            display: grid;
            grid-template-areas: 
                &quot;. up .&quot;
                &quot;left down right&quot;;
            grid-gap: 8px;
            justify-content: center;
            width: 100%;
        }

        .control-btn {
            background: #8f7a66;
            color: #fff;
            border: none;
            width: 60px;
            height: 50px;
            border-radius: 5px;
            font-size: 24px;
            font-weight: bold;
            cursor: pointer;
            user-select: none;
            display: flex;
            justify-content: center;
            align-items: center;
            box-shadow: 0 3px 0 #6f5d4e;
        }

        .control-btn:active {
            transform: translateY(3px);
            box-shadow: none;
        }

        .btn-up { grid-area: up; }
        .btn-left { grid-area: left; }
        .btn-down { grid-area: down; }
        .btn-right { grid-area: right; }
    &lt;/style&gt;



&lt;div class=&quot;game-theme-wrapper light&quot; id=&quot;gameTheme&quot;&gt;
    &lt;div class=&quot;theme-toggle&quot; id=&quot;themeToggle&quot;&gt;🌙 Темна тема&lt;/div&gt;
    &lt;h1&gt;2048 (8×8)&lt;/h1&gt;
    
    &lt;div class=&quot;info-container&quot;&gt;
        &lt;div class=&quot;info&quot; id=&quot;score&quot;&gt;Очки: 0&lt;/div&gt;
        &lt;button id=&quot;restart&quot;&gt;Нова гра&lt;/button&gt;
        &lt;div class=&quot;info&quot; id=&quot;best&quot;&gt;Рекорд: 0&lt;/div&gt;
    &lt;/div&gt;

    &lt;div id=&quot;game-container&quot;&gt;
        &lt;div id=&quot;game-board&quot;&gt;&lt;/div&gt;
        &lt;div id=&quot;message&quot;&gt;
            &lt;div id=&quot;message-text&quot;&gt;&lt;/div&gt;
            &lt;button id=&quot;continue&quot;&gt;Продовжити&lt;/button&gt;
        &lt;/div&gt;
    &lt;/div&gt;

    &lt;!-- Екранні кнопки --&gt;
    &lt;div class=&quot;controls&quot;&gt;
        &lt;button class=&quot;control-btn btn-up&quot; data-dir=&quot;u&quot;&gt;↑&lt;/button&gt;
        &lt;button class=&quot;control-btn btn-left&quot; data-dir=&quot;l&quot;&gt;←&lt;/button&gt;
        &lt;button class=&quot;control-btn btn-down&quot; data-dir=&quot;d&quot;&gt;↓&lt;/button&gt;
        &lt;button class=&quot;control-btn btn-right&quot; data-dir=&quot;r&quot;&gt;→&lt;/button&gt;
    &lt;/div&gt;
&lt;/div&gt;

&lt;script&gt;
/* ===== ПЕРЕМИКАЧ ТЕМИ ===== */
(function () {
    const w = document.getElementById(&quot;gameTheme&quot;);
    const t = document.getElementById(&quot;themeToggle&quot;);
    const saved = localStorage.getItem(&quot;theme2048&quot;);

    if (saved === &quot;dark&quot;) {
        w.classList.replace(&quot;light&quot;, &quot;dark&quot;);
        t.textContent = &quot;☀️ Світла тема&quot;;
    }

    t.onclick = () =&gt; {
        if (w.classList.contains(&quot;dark&quot;)) {
            w.classList.replace(&quot;dark&quot;, &quot;light&quot;);
            t.textContent = &quot;🌙 Темна тема&quot;;
            localStorage.setItem(&quot;theme2048&quot;, &quot;light&quot;);
        } else {
            w.classList.replace(&quot;light&quot;, &quot;dark&quot;);
            t.textContent = &quot;☀️ Світла тема&quot;;
            localStorage.setItem(&quot;theme2048&quot;, &quot;dark&quot;);
        }
    };
})();
&lt;/script&gt;

&lt;script&gt;
/* ===== ГРА 2048 (8x8) ===== */
const board = document.getElementById(&#039;game-board&#039;),
scoreD = document.getElementById(&#039;score&#039;),
bestD = document.getElementById(&#039;best&#039;),
msg = document.getElementById(&#039;message&#039;),
msgT = document.getElementById(&#039;message-text&#039;),
cont = document.getElementById(&#039;continue&#039;);

const SIZE = 8;
const CELLS_COUNT = SIZE * SIZE;
let values = [], tiles = [], score = 0, best = 0;
let gameOver = false, allow = false;

best = +localStorage.getItem(&#039;best2048_8x8&#039;) || 0;
bestD.textContent = &#039;Рекорд: &#039; + best;

function save() {
    localStorage.setItem(&#039;g2048v_8x8&#039;, JSON.stringify(values));
    localStorage.setItem(&#039;g2048s_8x8&#039;, score);
    localStorage.setItem(&#039;g2048go_8x8&#039;, gameOver ? &#039;1&#039; : &#039;0&#039;);
    localStorage.setItem(&#039;g2048al_8x8&#039;, allow ? &#039;1&#039; : &#039;0&#039;);
}

function add() {
    const e = values.map((v, i) =&gt; v ? null : i).filter(v =&gt; v !== null);
    if (e.length) {
        values[e[Math.floor(Math.random() * e.length)]] = Math.random() &lt; .9 ? 2 : 4;
    }
}

function draw() {
    tiles.forEach((t, i) =&gt; {
        t.textContent = values[i] || &#039;&#039;;
        if (values[i]) {
            t.setAttribute(&#039;data-value&#039;, values[i]);
        } else {
            t.removeAttribute(&#039;data-value&#039;);
        }
    });
    scoreD.textContent = &#039;Очки: &#039; + score;
    if (score &gt; best) {
        best = score;
        bestD.textContent = &#039;Рекорд: &#039; + best;
        localStorage.setItem(&#039;best2048_8x8&#039;, best);
    }
    save();
}

function slide(r) {
    r = r.filter(v =&gt; v);
    for (let i = 0; i &lt; r.length - 1; i++) {
        if (r[i] === r[i + 1]) {
            r[i] *= 2;
            score += r[i];
            r[i + 1] = 0;
        }
    }
    r = r.filter(v =&gt; v);
    while (r.length &lt; SIZE) r.push(0);
    return r;
}

function move(d) {
    if (gameOver) return;
    let moved = false;

    for (let i = 0; i &lt; SIZE; i++) {
        let line = [];
        for (let j = 0; j &lt; SIZE; j++) {
            let x = d === &#039;l&#039; ? i * SIZE + j :
                    d === &#039;r&#039; ? i * SIZE + (SIZE - 1 - j) :
                    d === &#039;u&#039; ? j * SIZE + i :
                                (SIZE - 1 - j) * SIZE + i;
            line.push(values[x]);
        }

        let newLine = slide(line);

        for (let j = 0; j &lt; SIZE; j++) {
            let x = d === &#039;l&#039; ? i * SIZE + j :
                    d === &#039;r&#039; ? i * SIZE + (SIZE - 1 - j) :
                    d === &#039;u&#039; ? j * SIZE + i :
                                (SIZE - 1 - j) * SIZE + i;
            if (values[x] !== newLine[j]) {
                values[x] = newLine[j];
                moved = true;
            }
        }
    }

    if (moved) {
        add();
        draw();
        check();
    }
}

function hasMoves() {
    if (values.includes(0)) return true;
    for (let i = 0; i &lt; SIZE; i++) {
        for (let j = 0; j &lt; SIZE; j++) {
            let current = values[i * SIZE + j];
            if (j &lt; SIZE - 1 &amp;&amp; current === values[i * SIZE + j + 1]) return true;
            if (i &lt; SIZE - 1 &amp;&amp; current === values[(i + 1) * SIZE + j]) return true;
        }
    }
    return false;
}

function check() {
    if (!allow &amp;&amp; values.includes(2048)) {
        msgT.textContent = &#039;Ви виграли 🎉&#039;;
        msg.style.display = &#039;flex&#039;;
        gameOver = true;
        save();
    } else if (!hasMoves()) {
        msgT.textContent = &#039;Гру завершено&#039;;
        msg.style.display = &#039;flex&#039;;
        gameOver = true;
        save();
    }
}

function init() {
    board.innerHTML = &#039;&#039;;
    tiles = [];
    
    // Завантаження стану з LocalStorage
    const savedValues = localStorage.getItem(&#039;g2048v_8x8&#039;);
    values = savedValues ? JSON.parse(savedValues) : Array(CELLS_COUNT).fill(0);
    score = +localStorage.getItem(&#039;g2048s_8x8&#039;) || 0;
    gameOver = localStorage.getItem(&#039;g2048go_8x8&#039;) === &#039;1&#039;;
    allow = localStorage.getItem(&#039;g2048al_8x8&#039;) === &#039;1&#039;;

    for (let i = 0; i &lt; CELLS_COUNT; i++) {
        let d = document.createElement(&#039;div&#039;);
        d.className = &#039;tile&#039;;
        board.appendChild(d);
        tiles.push(d);
    }

    if (!savedValues &amp;&amp; !values.some(v =&gt; v)) { 
        add(); add(); 
    }
    
    draw();

    // Відновлення вікна повідомлення, якщо гра була завершена
    if (gameOver) {
        if (!allow &amp;&amp; values.includes(2048)) {
            msgT.textContent = &#039;Ви виграли 🎉&#039;;
            msg.style.display = &#039;flex&#039;;
        } else if (!hasMoves()) {
            msgT.textContent = &#039;Гру завершено&#039;;
            msg.style.display = &#039;flex&#039;;
        }
    }
}

/* Керування клавіатурою */
document.addEventListener(&#039;keydown&#039;, function (e) {
    const keys = {
        ArrowLeft: &#039;l&#039;,
        ArrowRight: &#039;r&#039;,
        ArrowUp: &#039;u&#039;,
        ArrowDown: &#039;d&#039;
    };
    if (keys[e.key]) {
        e.preventDefault();
        move(keys[e.key]);
    }
});

/* Керування екранними кнопками */
document.querySelectorAll(&#039;.control-btn&#039;).forEach(btn =&gt; {
    btn.onclick = () =&gt; {
        const dir = btn.getAttribute(&#039;data-dir&#039;);
        move(dir);
    };
});

document.getElementById(&#039;restart&#039;).onclick = () =&gt; {
    values = Array(CELLS_COUNT).fill(0);
    score = 0;
    gameOver = false;
    allow = false;
    add(); add();
    msg.style.display = &#039;none&#039;;
    draw();
};

cont.onclick = () =&gt; {
    gameOver = false;
    allow = true;
    msg.style.display = &#039;none&#039;;
    save();
};

init();
&lt;/script&gt;</description>
            </item>
                    <item>
                <title>2048 8 на 8</title>
                <link>http://margo.mozello.shop/blog3/params/post/5333940/2048-8-na-8</link>
                <pubDate>Sat, 17 Oct 2026 12:32:00 +0000</pubDate>
                <description>1&lt;p&gt;&lt;br&gt;&lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;



&lt;meta charset=&quot;UTF-8&quot;&gt;
&lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1&quot;&gt;
&lt;title&gt;2048 — поле 8×8&lt;/title&gt;
&lt;style&gt;
/* Усі стилі обмежені контейнером гри й не змінюють оформлення решти блогу. */
#game2048-app {
  --bg: #faf8ef;
  --board: #bbada0;
  --empty: rgba(238, 228, 218, .42);
  --text: #776e65;
  --accent: #8f7a66;
  max-width: 100%;
  margin: 18px auto;
  color: var(--text);
  font-family: Arial, Helvetica, sans-serif;
  box-sizing: border-box;
}
#game2048-app *, #game2048-app *::before, #game2048-app *::after { box-sizing: border-box; }
#game2048-app .g2048-shell {
  width: 100%;
  max-width: 900px;
  margin: auto;
  padding: clamp(10px, 2vw, 22px);
  border-radius: 16px;
  background: var(--bg);
  border: 1px solid #e8dfd4;
}
#game2048-app .g2048-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; flex-wrap: wrap; margin-bottom: 12px;
}
#game2048-app .g2048-title {
  margin: 0; font-size: clamp(28px, 5vw, 46px); line-height: 1;
  font-weight: 900; letter-spacing: -1px; color: #776e65;
}
#game2048-app .g2048-scores { display:flex; gap:8px; flex-wrap:wrap; }
#game2048-app .g2048-score {
  min-width: 82px; padding: 7px 12px; border-radius: 8px;
  background: #bbada0; color: #fff; text-align:center; font-weight:700;
}
#game2048-app .g2048-score small {
  display:block; font-size:10px; letter-spacing:1px; text-transform:uppercase;
  opacity:.9; margin-bottom:2px;
}
#game2048-app .g2048-score strong { font-size:18px; }
#game2048-app .g2048-actions {
  display:flex; flex-wrap:wrap; gap:8px; margin: 12px 0;
}
#game2048-app button {
  font: inherit; font-weight:700; border:0; border-radius:7px;
  padding:10px 14px; cursor:pointer; color:#fff; background:#8f7a66;
  touch-action: manipulation;
}
#game2048-app button:hover { filter:brightness(1.06); }
#game2048-app button:focus-visible { outline:3px solid #3c8d5a; outline-offset:2px; }
#game2048-app button:disabled { opacity:.45; cursor:not-allowed; }
#game2048-app .g2048-help { margin: 8px 0 12px; font-size:14px; line-height:1.45; }
#game2048-app .g2048-pad { display:grid; grid-template-columns:repeat(3, 48px); grid-template-rows:repeat(2, 42px); gap:5px; justify-content:center; margin:10px auto 12px; }
#game2048-app .g2048-pad button { padding:0; font-size:22px; line-height:1; border-radius:7px; background:#776e65; }
#game2048-app .g2048-pad .up { grid-column:2; grid-row:1; }
#game2048-app .g2048-pad .left { grid-column:1; grid-row:2; }
#game2048-app .g2048-pad .down { grid-column:2; grid-row:2; }
#game2048-app .g2048-pad .right { grid-column:3; grid-row:2; }

#game2048-app .g2048-board-wrap { width:100%; overflow-x:auto; padding-bottom:3px; }
#game2048-app .g2048-board {
  display:grid; grid-template-columns:repeat(8, minmax(0, 1fr));
  grid-template-rows:repeat(8, 48px); gap:5px;
  padding:7px; background:var(--board); border-radius:9px;
  width:100%; min-width:0; position:relative; isolation:isolate;
}
#game2048-app .g2048-cell {
  min-width:0; min-height:0; height:48px; border-radius:5px;
  background:var(--empty); display:flex; align-items:center; justify-content:center;
  font-weight:800; line-height:1; white-space:nowrap; overflow:hidden;
  padding:0 1px; user-select:none; font-variant-numeric:tabular-nums;
}
#game2048-app .g2048-cell.filled { animation:g2048-appear .12s ease-out; }
@keyframes g2048-appear { from { transform:scale(.88); } to { transform:scale(1); } }
#game2048-app .g2048-overlay {
  position:absolute; inset:7px; z-index:2; display:none; align-items:center;
  justify-content:center; flex-direction:column; gap:12px; text-align:center;
  border-radius:7px; background:rgba(250,248,239,.88); color:#776e65;
  font-size:clamp(24px,5vw,38px); font-weight:900;
}
#game2048-app .g2048-overlay.visible { display:flex; }
#game2048-app .g2048-overlay p { margin:0; }
#game2048-app .g2048-status { min-height:20px; margin-top:9px; font-size:13px; }
@media (max-width: 560px) {
  #game2048-app .g2048-shell { padding:8px; border-radius:10px; }
  #game2048-app .g2048-board { grid-template-rows:repeat(8, clamp(27px, 8.3vw, 42px)); gap:3px; padding:4px; }
  #game2048-app .g2048-cell { height:clamp(27px, 8.3vw, 42px); border-radius:3px; }
  #game2048-app .g2048-overlay { inset:4px; }
  #game2048-app button { padding:9px 11px; }
}
&lt;/style&gt;


&lt;div id=&quot;game2048-app&quot;&gt;
  &lt;section class=&quot;g2048-shell&quot; aria-label=&quot;Гра 2048 на полі 8 на 8&quot;&gt;
    &lt;div class=&quot;g2048-head&quot;&gt;
      &lt;h1 class=&quot;g2048-title&quot;&gt;2048&lt;/h1&gt;
      &lt;div class=&quot;g2048-scores&quot;&gt;
        &lt;div class=&quot;g2048-score&quot;&gt;&lt;small&gt;Рахунок&lt;/small&gt;&lt;b id=&quot;g2048-score&quot;&gt;0&lt;/b&gt;&lt;/div&gt;
        &lt;div class=&quot;g2048-score&quot;&gt;&lt;small&gt;Рекорд&lt;/small&gt;&lt;b id=&quot;g2048-best&quot;&gt;0&lt;/b&gt;&lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class=&quot;g2048-actions&quot;&gt;
      &lt;button type=&quot;button&quot; id=&quot;g2048-new&quot;&gt;Нова гра&lt;/button&gt;
      &lt;button type=&quot;button&quot; id=&quot;g2048-undo&quot;&gt;Скасувати хід&lt;/button&gt;
    &lt;/div&gt;
    &lt;p class=&quot;g2048-help&quot;&gt;Керування: &lt;b&gt;W A S D&lt;/b&gt; або &lt;b&gt;I J K L&lt;/b&gt;; також можна натискати екранні кнопки зі стрілками. На телефоні проведіть пальцем у потрібному напрямку. Однакові плитки зливаються, а після кожного результативного ходу з’являється нова плитка.&lt;/p&gt;
    &lt;div class=&quot;g2048-pad&quot; aria-label=&quot;Екранне керування&quot;&gt;
      &lt;button type=&quot;button&quot; class=&quot;up&quot; data-direction=&quot;up&quot; aria-label=&quot;Угору&quot;&gt;↑&lt;/button&gt;
      &lt;button type=&quot;button&quot; class=&quot;left&quot; data-direction=&quot;left&quot; aria-label=&quot;Ліворуч&quot;&gt;←&lt;/button&gt;
      &lt;button type=&quot;button&quot; class=&quot;down&quot; data-direction=&quot;down&quot; aria-label=&quot;Униз&quot;&gt;↓&lt;/button&gt;
      &lt;button type=&quot;button&quot; class=&quot;right&quot; data-direction=&quot;right&quot; aria-label=&quot;Праворуч&quot;&gt;→&lt;/button&gt;
    &lt;/div&gt;
    &lt;div class=&quot;g2048-board-wrap&quot;&gt;
      &lt;div class=&quot;g2048-board&quot; id=&quot;g2048-board&quot; role=&quot;grid&quot; aria-label=&quot;Ігрове поле 8 на 8&quot;&gt;&lt;/div&gt;
    &lt;/div&gt;
    &lt;div class=&quot;g2048-status&quot; id=&quot;g2048-status&quot; aria-live=&quot;polite&quot;&gt;Об’єднуйте плитки та збільшуйте рахунок.&lt;/div&gt;
  &lt;/section&gt;
&lt;/div&gt;
&lt;script&gt;
(() =&gt; {
  &#039;use strict&#039;;
  const SIZE = 8, CELLS = SIZE * SIZE, SAVE_KEY = &#039;blog2048_8x8_save_v1&#039;;
  const app = document.getElementById(&#039;game2048-app&#039;);
  const boardEl = app.querySelector(&#039;#g2048-board&#039;);
  const scoreEl = app.querySelector(&#039;#g2048-score&#039;);
  const bestEl = app.querySelector(&#039;#g2048-best&#039;);
  const undoBtn = app.querySelector(&#039;#g2048-undo&#039;);
  const statusEl = app.querySelector(&#039;#g2048-status&#039;);
  const newBtn = app.querySelector(&#039;#g2048-new&#039;);
  const overlay = document.createElement(&#039;div&#039;);
  overlay.className = &#039;g2048-overlay&#039;;
  overlay.innerHTML = &#039;&lt;p&gt;&lt;/p&gt;&lt;button type=&quot;button&quot;&gt;Грати ще&lt;/button&gt;&#039;;
  boardEl.appendChild(overlay);
  const overlayText = overlay.querySelector(&#039;p&#039;);
  const overlayButton = overlay.querySelector(&#039;button&#039;);

  let board = Array(CELLS).fill(0);
  let score = 0, best = 0, won = false, keepPlaying = false, over = false;
  let previous = null, touchStart = null;
  const cells = [];

  for (let i = 0; i &lt; CELLS; i++) {
    const cell = document.createElement(&#039;div&#039;);
    cell.className = &#039;g2048-cell&#039;;
    cell.setAttribute(&#039;role&#039;, &#039;gridcell&#039;);
    cells.push(cell);
    boardEl.insertBefore(cell, overlay);
  }

  function compactNumber(n) {
    // Степені двійки округлюємо до найближчого цілого для читабельного скорочення.
    if (n &lt; 1024) return String(n);
    if (n &lt; 1048576) return (n / 1024).toFixed(n &lt; 10240 ? 1 : 0).replace(/\.0$/, &#039;&#039;) + &#039;K&#039;;
    return (n / 1048576).toFixed(n &lt; 10485760 ? 1 : 0).replace(/\.0$/, &#039;&#039;) + &#039;M&#039;;
  }
  function tileColor(v) {
    const colors = {
      2:[&#039;#eee4da&#039;,&#039;#776e65&#039;], 4:[&#039;#ede0c8&#039;,&#039;#776e65&#039;], 8:[&#039;#f2b179&#039;,&#039;#fff&#039;],
      16:[&#039;#f59563&#039;,&#039;#fff&#039;], 32:[&#039;#f67c5f&#039;,&#039;#fff&#039;], 64:[&#039;#f65e3b&#039;,&#039;#fff&#039;],
      128:[&#039;#edcf72&#039;,&#039;#fff&#039;], 256:[&#039;#edcc61&#039;,&#039;#fff&#039;], 512:[&#039;#edc850&#039;,&#039;#fff&#039;],
      1024:[&#039;#edc53f&#039;,&#039;#fff&#039;], 2048:[&#039;#edc22e&#039;,&#039;#fff&#039;]
    };
    if (colors[v]) return colors[v];
    const hue = (Math.log2(v) * 31 + 35) % 360;
    return [`hsl(${hue} 58% 43%)`, &#039;#fff&#039;];
  }
  function render() {
    for (let i = 0; i &lt; CELLS; i++) {
      const v = board[i], el = cells[i];
      el.textContent = v ? compactNumber(v) : &#039;&#039;;
      el.classList.toggle(&#039;filled&#039;, !!v);
      el.style.background = v ? tileColor(v)[0] : &#039;&#039;;
      el.style.color = v ? tileColor(v)[1] : &#039;&#039;;
      // Довгі скорочення отримують менший шрифт, але не обрізаються.
      const len = el.textContent.length;
      el.style.fontSize = (v === 0 ? 16 : Math.max(10, Math.min(25, 25 - Math.max(0, len - 3) * 3))) + &#039;px&#039;;
      el.setAttribute(&#039;aria-label&#039;, v ? compactNumber(v) : &#039;порожня клітинка&#039;);
    }
    scoreEl.textContent = compactNumber(score);
    bestEl.textContent = compactNumber(best);
    undoBtn.disabled = !previous;
    overlay.classList.toggle(&#039;visible&#039;, over || (won &amp;&amp; !keepPlaying));
    if (over) { overlayText.textContent = &#039;Гру завершено&#039;; overlayButton.textContent = &#039;Спробувати знову&#039;; }
    else if (won &amp;&amp; !keepPlaying) { overlayText.textContent = &#039;2048 досягнуто!&#039;; overlayButton.textContent = &#039;Продовжити&#039;; }
    save();
  }
  function save() {
    try { localStorage.setItem(SAVE_KEY, JSON.stringify({board, score, best, won, keepPlaying, over, previous})); }
    catch (_) { /* Гра працює і без доступу до localStorage. */ }
  }
  function spawnTile() {
    // Без while: один прохід збирає всі порожні клітинки, далі обирається одна випадкова.
    const empty = [];
    for (let i = 0; i &lt; CELLS; i++) if (board[i] === 0) empty.push(i);
    if (empty.length === 0) return false;
    const index = empty[Math.floor(Math.random() * empty.length)];
    board[index] = Math.random() &lt; 0.9 ? 2 : 4;
    return true;
  }
  function snapshot() {
    return {board: board.slice(), score, won, keepPlaying, over};
  }
  function restore(s) {
    board = s.board.slice(); score = s.score; won = s.won;
    keepPlaying = s.keepPlaying; over = s.over;
  }
  function newGame() {
    board = Array(CELLS).fill(0); score = 0; won = false; keepPlaying = false; over = false; previous = null;
    spawnTile(); spawnTile();
    statusEl.textContent = &#039;Нова гра почалася. Успіхів!&#039;;
    render();
  }
  function lineIndices(direction, line) {
    const out = [];
    for (let step = 0; step &lt; SIZE; step++) {
      if (direction === &#039;left&#039;) out.push(line * SIZE + step);
      if (direction === &#039;right&#039;) out.push(line * SIZE + (SIZE - 1 - step));
      if (direction === &#039;up&#039;) out.push(step * SIZE + line);
      if (direction === &#039;down&#039;) out.push((SIZE - 1 - step) * SIZE + line);
    }
    return out;
  }
  function move(direction) {
    if (over || (won &amp;&amp; !keepPlaying)) return;
    const before = snapshot();
    let changed = false, gained = 0;
    for (let line = 0; line &lt; SIZE; line++) {
      const indices = lineIndices(direction, line);
      const values = indices.map(i =&gt; board[i]).filter(v =&gt; v !== 0);
      const merged = [];
      for (let i = 0; i &lt; values.length; i++) {
        if (values[i] === values[i + 1]) {
          const value = values[i] * 2;
          merged.push(value); gained += value; i++;
          if (value &gt;= 2048 &amp;&amp; !won) won = true;
        } else merged.push(values[i]);
      }
      while (merged.length &lt; SIZE) merged.push(0);
      indices.forEach((index, i) =&gt; {
        if (board[index] !== merged[i]) changed = true;
        board[index] = merged[i];
      });
    }
    if (!changed) return;
    previous = before;
    score += gained;
    if (score &gt; best) best = score;
    spawnTile();
    over = !canMove();
    if (over) statusEl.textContent = &#039;Немає доступних ходів. Почніть нову гру.&#039;;
    else if (won &amp;&amp; !keepPlaying) statusEl.textContent = &#039;Ви досягли 2048! Можна продовжити гру.&#039;;
    else statusEl.textContent = gained ? `Злиття додало ${compactNumber(gained)} очок.` : &#039;Хід виконано.&#039;;
    render();
  }
  function canMove() {
    if (board.some(v =&gt; v === 0)) return true;
    for (let r = 0; r &lt; SIZE; r++) for (let c = 0; c &lt; SIZE; c++) {
      const i = r * SIZE + c;
      if (c &lt; SIZE - 1 &amp;&amp; board[i] === board[i + 1]) return true;
      if (r &lt; SIZE - 1 &amp;&amp; board[i] === board[i + SIZE]) return true;
    }
    return false;
  }
  function undo() {
    if (!previous) return;
    const p = previous;
    previous = null;
    restore(p);
    statusEl.textContent = &#039;Попередній хід скасовано.&#039;;
    render();
  }
  function load() {
    try {
      const raw = localStorage.getItem(SAVE_KEY);
      if (!raw) return false;
      const s = JSON.parse(raw);
      if (!s || !Array.isArray(s.board) || s.board.length !== CELLS) return false;
      if (!s.board.every(v =&gt; Number.isSafeInteger(v) &amp;&amp; v &gt;= 0)) return false;
      board = s.board; score = Number(s.score) || 0; best = Number(s.best) || 0;
      won = !!s.won; keepPlaying = !!s.keepPlaying; over = !!s.over;
      previous = s.previous &amp;&amp; Array.isArray(s.previous.board) &amp;&amp; s.previous.board.length === CELLS ? s.previous : null;
      statusEl.textContent = &#039;Попередню гру відновлено.&#039;;
      return true;
    } catch (_) { return false; }
  }
  document.addEventListener(&#039;keydown&#039;, e =&gt; {
    if (!app.isConnected) return;
    const key = e.key.toLowerCase();
    const map = {
      arrowleft:&#039;left&#039;, a:&#039;left&#039;, j:&#039;left&#039;,
      arrowright:&#039;right&#039;, d:&#039;right&#039;, l:&#039;right&#039;,
      arrowup:&#039;up&#039;, w:&#039;up&#039;, i:&#039;up&#039;,
      arrowdown:&#039;down&#039;, s:&#039;down&#039;, k:&#039;down&#039;
    };
    if (map[key]) {
      e.preventDefault();
      move(map[key]);
    }
  });
  boardEl.addEventListener(&#039;touchstart&#039;, e =&gt; {
    if (e.touches.length !== 1) return;
    touchStart = {x:e.touches[0].clientX, y:e.touches[0].clientY};
  }, {passive:true});
  boardEl.addEventListener(&#039;touchend&#039;, e =&gt; {
    if (!touchStart || !e.changedTouches.length) return;
    const dx = e.changedTouches[0].clientX - touchStart.x;
    const dy = e.changedTouches[0].clientY - touchStart.y;
    touchStart = null;
    if (Math.max(Math.abs(dx), Math.abs(dy)) &lt; 24) return;
    move(Math.abs(dx) &gt; Math.abs(dy) ? (dx &gt; 0 ? &#039;right&#039; : &#039;left&#039;) : (dy &gt; 0 ? &#039;down&#039; : &#039;up&#039;));
  }, {passive:true});
  newBtn.addEventListener(&#039;click&#039;, () =&gt; {
    if (confirm(&#039;Почати нову гру? Поточний прогрес буде замінено.&#039;)) newGame();
  });
  app.querySelectorAll(&#039;[data-direction]&#039;).forEach(button =&gt; {
    button.addEventListener(&#039;click&#039;, () =&gt; move(button.dataset.direction));
  });
  undoBtn.addEventListener(&#039;click&#039;, undo);
  overlayButton.addEventListener(&#039;click&#039;, () =&gt; {
    if (over) newGame();
    else if (won) { keepPlaying = true; statusEl.textContent = &#039;Продовжуйте гру після 2048!&#039;; render(); }
  });
  if (!load()) newGame(); else render();
})();
&lt;/script&gt;</description>
            </item>
                    <item>
                <title>4</title>
                <link>http://margo.mozello.shop/blog3/params/post/5281636/4</link>
                <pubDate>Tue, 21 Jul 2026 09:55:00 +0000</pubDate>
                <description>ооооооооооооооооо&lt;hr class=&quot;moze-more-divider&quot;&gt;&lt;p&gt;4&lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;div id=&quot;game-container&quot; style=&quot;display:flex; flex-direction:column; align-items:center; font-family:sans-serif; padding:10px;&quot;&gt;
    &lt;div style=&quot;width:100%; max-width:800px; display:flex; justify-content:space-between; margin-bottom:10px;&quot;&gt;
        &lt;h2 style=&quot;margin:0;&quot;&gt;2048 - Eternal&lt;/h2&gt;
        &lt;div class=&quot;moze-right&quot;&gt;Score: &lt;span id=&quot;s-val&quot;&gt;0&lt;/span&gt;&lt;br&gt;Best: &lt;span id=&quot;b-val&quot;&gt;0&lt;/span&gt;&lt;/div&gt;
    &lt;/div&gt;
    
    &lt;div id=&quot;board&quot; style=&quot;display:grid; gap:8px; background:#bbada0; padding:8px; border-radius:6px; transition:grid-template-columns 0.1s linear;&quot;&gt;&lt;/div&gt;
    
    &lt;div style=&quot;margin-top:20px; display:flex; gap:10px;&quot;&gt;
        &lt;button onclick=&quot;game.reset()&quot;&gt;New Game&lt;/button&gt;
        &lt;button onclick=&quot;game.undo()&quot;&gt;Undo&lt;/button&gt;
    &lt;/div&gt;
&lt;/div&gt;

&lt;style&gt;
    .tile { 
        min-height: 50px; min-width: 50px; border-radius:4px; 
        display:flex; justify-content:center; align-items:center; 
        font-weight:bold; color:#fff; transition:all 0.1s;
        padding: 0 10px; white-space:nowrap;
    }
&lt;/style&gt;

&lt;script&gt;
class Game2048 {
    constructor() {
        this.size = 7;
        this.boardEl = document.getElementById(&#039;board&#039;);
        this.ctx = document.createElement(&#039;canvas&#039;).getContext(&#039;2d&#039;);
        this.loadGame();
        document.addEventListener(&#039;keydown&#039;, (e) =&gt; this.input(e));
        this.render();
    }

    saveGame() {
        localStorage.setItem(&#039;2048_eternal&#039;, JSON.stringify({
            board: this.board,
            score: this.score,
            history: this.history
        }));
    }

    loadGame() {
        const saved = localStorage.getItem(&#039;2048_eternal&#039;);
        if (saved) {
            const data = JSON.parse(saved);
            this.board = data.board;
            this.score = data.score;
            this.history = data.history;
        } else {
            this.board = Array(this.size).fill().map(() =&gt; Array(this.size).fill(0));
            this.score = 0;
            this.history = [];
            this.spawn(); this.spawn();
        }
    }

    input(e) {
        const keys = {ArrowUp:&#039;up&#039;, ArrowDown:&#039;down&#039;, ArrowLeft:&#039;left&#039;, ArrowRight:&#039;right&#039;, w:&#039;up&#039;, s:&#039;down&#039;, a:&#039;left&#039;, d:&#039;right&#039;};
        if (keys[e.key]) {
            e.preventDefault();
            this.move(keys[e.key]);
        }
    }

    move(dir) {
        let prevBoard = JSON.stringify(this.board);
        let moved = false;
        
        const rotate = () =&gt; {
            let next = Array(this.size).fill().map(() =&gt; Array(this.size).fill(0));
            for(let r=0; r&lt;this.size; r++) for(let c=0; c&lt;this.size; c++) next[c][this.size-1-r] = this.board[r][c];
            this.board = next;
        };

        const slide = () =&gt; {
            for(let r=0; r&lt;this.size; r++) {
                let row = this.board[r].filter(x =&gt; x);
                let newRow = [];
                for(let i=0; i&lt;row.length; i++) {
                    if(i + 1 &lt; row.length &amp;&amp; row[i] === row[i+1]) {
                        newRow.push(row[i]*2);
                        this.score += row[i]*2;
                        i++;
                        moved = true;
                    } else {
                        newRow.push(row[i]);
                    }
                }
                while(newRow.length &lt; this.size) newRow.push(0);
                if(this.board[r].join(&#039;,&#039;) !== newRow.join(&#039;,&#039;)) moved = true;
                this.board[r] = newRow;
            }
        };

        const dirs = {up:3, right:2, down:1, left:0};
        for(let i=0; i&lt;dirs[dir]; i++) rotate();
        slide();
        for(let i=0; i&lt;(4-dirs[dir])%4; i++) rotate();

        if(moved) {
            this.history.push(prevBoard);
            this.spawn();
            this.saveGame();
            this.render();
        }
    }

    spawn() {
        let empty = [];
        for(let r=0; r&lt;this.size; r++) for(let c=0; c&lt;this.size; c++) if(!this.board[r][c]) empty.push({r,c});
        if(empty.length) {
            let {r,c} = empty[Math.floor(Math.random()*empty.length)];
            this.board[r][c] = Math.random() &lt; 0.9 ? 2 : 4;
        }
    }

    render() {
        this.boardEl.innerHTML = &#039;&#039;;
        let colWidths = Array(this.size).fill(0);
        
        for(let c=0; c&lt;this.size; c++) {
            let max = 60;
            for(let r=0; r&lt;this.size; r++) {
                let val = this.board[r][c] ? this.board[r][c].toString() : &quot;0&quot;;
                let w = this.ctx.measureText(val).width + 30;
                if(w &gt; max) max = w;
            }
            colWidths[c] = max;
        }
        this.boardEl.style.gridTemplateColumns = colWidths.map(w =&gt; `${w}px`).join(&#039; &#039;);

        this.board.flat().forEach(val =&gt; {
            let t = document.createElement(&#039;div&#039;);
            t.className = &#039;tile&#039;;
            t.textContent = val || &#039;&#039;;
            t.style.background = val ? `hsl(${Math.log2(val)*20}, 70%, 45%)` : &#039;#cdc1b4&#039;;
            t.style.fontSize = val &gt; 100000 ? &#039;12px&#039; : &#039;18px&#039;;
            this.boardEl.appendChild(t);
        });

        document.getElementById(&#039;s-val&#039;).textContent = this.score;
        let best = Math.max(this.score, localStorage.getItem(&#039;best&#039;) || 0);
        localStorage.setItem(&#039;best&#039;, best);
        document.getElementById(&#039;b-val&#039;).textContent = best;
    }

    reset() { localStorage.removeItem(&#039;2048_eternal&#039;); location.reload(); }
    undo() { 
        if(this.history.length) {
            this.board = JSON.parse(this.history.pop());
            this.saveGame();
            this.render();
        }
    }
}
const game = new Game2048();
&lt;/script&gt;</description>
            </item>
                    <item>
                <title>3</title>
                <link>http://margo.mozello.shop/blog3/params/post/5279599/3</link>
                <pubDate>Wed, 15 Jul 2026 13:57:00 +0000</pubDate>
                <description>початок 16 липня 2026&amp;nbsp;&amp;nbsp;
&lt;span style=&quot;text-align: right; font-weight: 300; font-style: normal&quot;&gt;155232&lt;/span&gt;

&lt;hr class=&quot;moze-more-divider&quot;&gt;&lt;p&gt;3&lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;div id=&quot;game-container&quot; style=&quot;display:flex; flex-direction:column; align-items:center; font-family:sans-serif; padding:10px;&quot;&gt;
    &lt;div style=&quot;width:100%; max-width:800px; display:flex; justify-content:space-between; margin-bottom:10px;&quot;&gt;
        &lt;h2 style=&quot;margin:0;&quot;&gt;2048 - Eternal&lt;/h2&gt;
        &lt;div class=&quot;moze-right&quot;&gt;Score: &lt;span id=&quot;s-val&quot;&gt;0&lt;/span&gt;&lt;br&gt;Best: &lt;span id=&quot;b-val&quot;&gt;0&lt;/span&gt;&lt;/div&gt;
    &lt;/div&gt;
    
    &lt;div id=&quot;board&quot; style=&quot;display:grid; gap:8px; background:#bbada0; padding:8px; border-radius:6px; transition:grid-template-columns 0.1s linear;&quot;&gt;&lt;/div&gt;
    
    &lt;div style=&quot;margin-top:20px; display:flex; gap:10px;&quot;&gt;
        &lt;button onclick=&quot;game.reset()&quot; fdprocessedid=&quot;sq2gat&quot;&gt;New Game&lt;/button&gt;
        &lt;button onclick=&quot;game.undo()&quot; fdprocessedid=&quot;omrp2p&quot;&gt;Undo&lt;/button&gt;
    &lt;/div&gt;
&lt;/div&gt;

&lt;style&gt;
    .tile { 
        min-height: 50px; min-width: 50px; border-radius:4px; 
        display:flex; justify-content:center; align-items:center; 
        font-weight:bold; color:#fff; transition:all 0.1s;
        padding: 0 10px; white-space:nowrap;
    }
&lt;/style&gt;

&lt;script&gt;
class Game2048 {
    constructor() {
        this.size = 7;
        this.boardEl = document.getElementById(&#039;board&#039;);
        this.ctx = document.createElement(&#039;canvas&#039;).getContext(&#039;2d&#039;);
        this.loadGame();
        document.addEventListener(&#039;keydown&#039;, (e) =&gt; this.input(e));
        this.render();
    }

    saveGame() {
        localStorage.setItem(&#039;2048_eternal&#039;, JSON.stringify({
            board: this.board,
            score: this.score,
            history: this.history
        }));
    }

    loadGame() {
        const saved = localStorage.getItem(&#039;2048_eternal&#039;);
        if (saved) {
            const data = JSON.parse(saved);
            this.board = data.board;
            this.score = data.score;
            this.history = data.history;
        } else {
            this.board = Array(this.size).fill().map(() =&gt; Array(this.size).fill(0));
            this.score = 0;
            this.history = [];
            this.spawn(); this.spawn();
        }
    }

    input(e) {
        const keys = {ArrowUp:&#039;up&#039;, ArrowDown:&#039;down&#039;, ArrowLeft:&#039;left&#039;, ArrowRight:&#039;right&#039;, w:&#039;up&#039;, s:&#039;down&#039;, a:&#039;left&#039;, d:&#039;right&#039;};
        if (keys[e.key]) {
            e.preventDefault();
            this.move(keys[e.key]);
        }
    }

    move(dir) {
        let prevBoard = JSON.stringify(this.board);
        // Логіка зсуву (стандартна для 2048)
        let moved = false;
        // Тут реалізовано поворот для всіх 4 напрямків через одну функцію
        const rotate = () =&gt; {
            let next = Array(this.size).fill().map(() =&gt; Array(this.size).fill(0));
            for(let r=0; r&lt;this.size; r++) for(let c=0; c&lt;this.size; c++) next[c][this.size-1-r] = this.board[r][c];
            this.board = next;
        };

        const slide = () =&gt; {
            for(let r=0; r&lt;this.size; r++) {
                let row = this.board[r].filter(x =&gt; x);
                let newRow = [];
                for(let i=0; i&lt;row.length; i++) {
                    if(row[i] === row[i+1]) {
                        newRow.push(row[i]*2);
                        this.score += row[i]*2;
                        i++;
                        moved = true;
                    } else {
                        newRow.push(row[i]);
                    }
                }
                while(newRow.length &lt; this.size) newRow.push(0);
                if(this.board[r].join(&#039;,&#039;) !== newRow.join(&#039;,&#039;)) moved = true;
                this.board[r] = newRow;
            }
        };

        const dirs = {up:3, right:2, down:1, left:0};
        for(let i=0; i&lt;dirs[dir]; i++) rotate();
        slide();
        for(let i=0; i&lt;(4-dirs[dir])%4; i++) rotate();

        if(moved) {
            this.history.push(prevBoard);
            this.spawn();
            this.saveGame();
            this.render();
        }
    }

    spawn() {
        let empty = [];
        for(let r=0; r&lt;this.size; r++) for(let c=0; c&lt;this.size; c++) if(!this.board[r][c]) empty.push({r,c});
        if(empty.length) {
            let {r,c} = empty[Math.floor(Math.random()*empty.length)];
            this.board[r][c] = Math.random() &lt; 0.9 ? 2 : 4;
        }
    }

    render() {
        this.boardEl.innerHTML = &#039;&#039;;
        let colWidths = Array(this.size).fill(0);
        
        // Розрахунок ширини
        for(let c=0; c&lt;this.size; c++) {
            let max = 60;
            for(let r=0; r&lt;this.size; r++) {
                let val = this.board[r][c] ? this.board[r][c].toString() : &quot;0&quot;;
                let w = this.ctx.measureText(val).width + 30;
                if(w &gt; max) max = w;
            }
            colWidths[c] = max;
        }
        this.boardEl.style.gridTemplateColumns = colWidths.map(w =&gt; `${w}px`).join(&#039; &#039;);

        this.board.flat().forEach(val =&gt; {
            let t = document.createElement(&#039;div&#039;);
            t.className = &#039;tile&#039;;
            t.textContent = val || &#039;&#039;;
            t.style.background = val ? `hsl(${Math.log2(val)*20}, 70%, 45%)` : &#039;#cdc1b4&#039;;
            t.style.fontSize = val &gt; 100000 ? &#039;12px&#039; : &#039;18px&#039;;
            this.boardEl.appendChild(t);
        });

        document.getElementById(&#039;s-val&#039;).textContent = this.score;
        let best = Math.max(this.score, localStorage.getItem(&#039;best&#039;) || 0);
        localStorage.setItem(&#039;best&#039;, best);
        document.getElementById(&#039;b-val&#039;).textContent = best;
    }

    reset() { localStorage.removeItem(&#039;2048_eternal&#039;); location.reload(); }
    undo() { 
        if(this.history.length) {
            this.board = JSON.parse(this.history.pop());
            this.saveGame();
            this.render();
        }
    }
}
const game = new Game2048();
&lt;/script&gt;</description>
            </item>
                    <item>
                <title>2048 (7×7)</title>
                <link>http://margo.mozello.shop/blog3/params/post/5250004/10</link>
                <pubDate>Thu, 07 May 2026 15:54:00 +0000</pubDate>
                <description>10&amp;nbsp; 10&amp;nbsp; 10&amp;nbsp;&amp;nbsp;&lt;hr class=&quot;moze-more-divider&quot;&gt;&lt;p&gt;10&lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;


  &lt;meta charset=&quot;UTF-8&quot;&gt;
  &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
  &lt;title&gt;2048 (7×7) — Покращена версія&lt;/title&gt;

  &lt;style&gt;
    * {
      box-sizing: border-box;
    }

    body {
      font-family: Arial, sans-serif;
      background: linear-gradient(135deg, #faf8ef, #f3e5d0);
      margin: 0;
      padding: 15px;
      min-height: 100vh;
      display: flex;
      flex-direction: column;
      align-items: center;
    }

    h1 {
      font-size: 38px;
      margin: 10px 0 5px;
      color: #5c4033;
      text-align: center;
    }

    .subtitle {
      margin-bottom: 10px;
      color: #7a5c4b;
      font-size: 16px;
      text-align: center;
    }

    .stats {
      display: flex;
      gap: 15px;
      margin: 10px 0;
      flex-wrap: wrap;
      justify-content: center;
    }

    .info-box {
      background: #8f7a66;
      color: white;
      padding: 10px 18px;
      border-radius: 10px;
      min-width: 120px;
      text-align: center;
      box-shadow: 0 4px 10px rgba(0,0,0,0.15);
    }

    .label {
      font-size: 14px;
      opacity: 0.9;
    }

    .value {
      font-size: 24px;
      font-weight: bold;
      margin-top: 4px;
    }

    button {
      padding: 12px 22px;
      font-size: 18px;
      margin: 12px 0;
      border: none;
      border-radius: 10px;
      background: #6d4c41;
      color: white;
      cursor: pointer;
      transition: 0.2s;
      font-weight: bold;
    }

    button:hover {
      background: #5d4037;
      transform: scale(1.03);
    }

    #game-board {
      display: grid;
      grid-template-columns: repeat(7, 1fr);
      gap: 6px;
      background: #bbada0;
      padding: 8px;
      border-radius: 14px;
      width: 100%;
      max-width: 520px;
      box-shadow: 0 10px 30px rgba(0,0,0,0.2);
    }

    .tile {
      background: #cdc1b4;
      min-height: 62px;
      display: flex;
      align-items: center;
      justify-content: center;
      font-weight: bold;
      border-radius: 8px;
      font-size: 24px;
      transition: all 0.12s ease-in-out;
      user-select: none;
    }

    .tile:not(:empty) {
      animation: pop 0.15s ease;
    }

    @keyframes pop {
      0% { transform: scale(0.85); }
      100% { transform: scale(1); }
    }

    .tile[data-value=&quot;2&quot;]       { background: #eee4da; color: #776e65; }
    .tile[data-value=&quot;4&quot;]       { background: #ede0c8; color: #776e65; }
    .tile[data-value=&quot;8&quot;]       { background: #f2b179; color: white; }
    .tile[data-value=&quot;16&quot;]      { background: #f59563; color: white; }
    .tile[data-value=&quot;32&quot;]      { background: #f67c5f; color: white; }
    .tile[data-value=&quot;64&quot;]      { background: #f65e3b; color: white; }
    .tile[data-value=&quot;128&quot;]     { background: #edcf72; color: white; font-size: 22px; }
    .tile[data-value=&quot;256&quot;]     { background: #edcc61; color: white; font-size: 22px; }
    .tile[data-value=&quot;512&quot;]     { background: #edc850; color: white; font-size: 22px; }
    .tile[data-value=&quot;1024&quot;]    { background: #edc53f; color: white; font-size: 20px; }
    .tile[data-value=&quot;2048&quot;]    { background: #edc22e; color: white; font-size: 20px; }

    .tile[data-value=&quot;4096&quot;]    { background: #00b894; color: white; font-size: 20px; }
    .tile[data-value=&quot;8192&quot;]    { background: #00a8ff; color: white; font-size: 19px; }
    .tile[data-value=&quot;16384&quot;]   { background: #6c5ce7; color: white; font-size: 18px; }
    .tile[data-value=&quot;32768&quot;]   { background: #a55eea; color: white; font-size: 17px; }
    .tile[data-value=&quot;65536&quot;]   { background: #ff7675; color: white; font-size: 16px; }
    .tile[data-value=&quot;131072&quot;]  { background: #fd79a8; color: white; font-size: 15px; }
    .tile[data-value=&quot;262144&quot;]  { background: #feca57; color: #2d3436; font-size: 14px; }
    .tile[data-value=&quot;524288&quot;]  { background: #48dbfb; color: #1e272e; font-size: 13px; }
    .tile[data-value=&quot;1048576&quot;] { background: #ff9ff3; color: #1e272e; font-size: 12px; }

    .controls {
      margin-top: 15px;
      text-align: center;
      color: #6d4c41;
      font-size: 14px;
      max-width: 520px;
    }

    @media (max-width: 600px) {
      .tile {
        min-height: 44px;
        font-size: 18px;
      }

      h1 {
        font-size: 30px;
      }
    }
  &lt;/style&gt;



  &lt;h1&gt;2048 (7×7)&lt;/h1&gt;
  &lt;div class=&quot;subtitle&quot;&gt;Покращена версія з рекордом і плитками до 1048576&lt;/div&gt;

  &lt;div class=&quot;stats&quot;&gt;
    &lt;div class=&quot;info-box&quot;&gt;
      &lt;div class=&quot;label&quot;&gt;Очки&lt;/div&gt;
      &lt;div class=&quot;value&quot; id=&quot;score&quot;&gt;0&lt;/div&gt;
    &lt;/div&gt;

    &lt;div class=&quot;info-box&quot;&gt;
      &lt;div class=&quot;label&quot;&gt;Рекорд&lt;/div&gt;
      &lt;div class=&quot;value&quot; id=&quot;best&quot;&gt;0&lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;

  &lt;button id=&quot;restart&quot;&gt;Нова гра&lt;/button&gt;

  &lt;div id=&quot;game-board&quot;&gt;&lt;/div&gt;

  &lt;div class=&quot;controls&quot;&gt;
    Керування: ← ↑ → ↓ (стрілки клавіатури)
  &lt;/div&gt;

  &lt;script&gt;
    const SIZE = 7;
    const TOTAL = SIZE * SIZE;

    let values = new Array(TOTAL).fill(0);
    let score = 0;
    let best = parseInt(localStorage.getItem(&quot;best2048_7x7&quot;)) || 0;

    const board = document.getElementById(&quot;game-board&quot;);
    const scoreEl = document.getElementById(&quot;score&quot;);
    const bestEl = document.getElementById(&quot;best&quot;);

    function createBoard() {
      board.innerHTML = &quot;&quot;;

      for (let i = 0; i &lt; TOTAL; i++) {
        const tile = document.createElement(&quot;div&quot;);
        tile.className = &quot;tile&quot;;
        board.appendChild(tile);
      }
    }

    function updateBest() {
      if (score &gt; best) {
        best = score;
        localStorage.setItem(&quot;best2048_7x7&quot;, best);
      }
    }

    function updateBoard() {
      const tiles = board.children;

      for (let i = 0; i &lt; TOTAL; i++) {
        const val = values[i];
        tiles[i].textContent = val || &quot;&quot;;
        tiles[i].dataset.value = val || &quot;&quot;;
      }

      updateBest();

      scoreEl.textContent = score;
      bestEl.textContent = best;
    }

    function addTile() {
      const empty = [];

      for (let i = 0; i &lt; TOTAL; i++) {
        if (values[i] === 0) {
          empty.push(i);
        }
      }

      if (empty.length &gt; 0) {
        const randomIndex = Math.floor(Math.random() * empty.length);
        const pos = empty[randomIndex];

        values[pos] = Math.random() &lt; 0.9 ? 2 : 4;
      }
    }

    function slide(line) {
      let arr = line.filter(v =&gt; v !== 0);

      for (let i = 0; i &lt; arr.length - 1; i++) {
        if (arr[i] === arr[i + 1]) {
          arr[i] *= 2;
          score += arr[i];
          arr[i + 1] = 0;
        }
      }

      arr = arr.filter(v =&gt; v !== 0);

      while (arr.length &lt; SIZE) {
        arr.push(0);
      }

      return arr;
    }

    function move(direction) {
      let moved = false;

      for (let i = 0; i &lt; SIZE; i++) {
        let line = [];

        for (let j = 0; j &lt; SIZE; j++) {
          let idx;

          if (direction === &quot;left&quot;) idx = i * SIZE + j;
          if (direction === &quot;right&quot;) idx = i * SIZE + (SIZE - 1 - j);
          if (direction === &quot;up&quot;) idx = j * SIZE + i;
          if (direction === &quot;down&quot;) idx = (SIZE - 1 - j) * SIZE + i;

          line.push(values[idx]);
        }

        const newLine = slide(line);

        for (let j = 0; j &lt; SIZE; j++) {
          let idx;

          if (direction === &quot;left&quot;) idx = i * SIZE + j;
          if (direction === &quot;right&quot;) idx = i * SIZE + (SIZE - 1 - j);
          if (direction === &quot;up&quot;) idx = j * SIZE + i;
          if (direction === &quot;down&quot;) idx = (SIZE - 1 - j) * SIZE + i;

          if (values[idx] !== newLine[j]) {
            values[idx] = newLine[j];
            moved = true;
          }
        }
      }

      if (moved) {
        addTile();
        updateBoard();

        if (isGameOver()) {
          setTimeout(() =&gt; {
            alert(&quot;Гру завершено! Спробуй ще раз.&quot;);
          }, 100);
        }
      }
    }

    function isGameOver() {
      for (let i = 0; i &lt; TOTAL; i++) {
        if (values[i] === 0) return false;
      }

      for (let row = 0; row &lt; SIZE; row++) {
        for (let col = 0; col &lt; SIZE; col++) {
          const current = values[row * SIZE + col];

          if (col &lt; SIZE - 1 &amp;&amp; current === values[row * SIZE + col + 1]) {
            return false;
          }

          if (row &lt; SIZE - 1 &amp;&amp; current === values[(row + 1) * SIZE + col]) {
            return false;
          }
        }
      }

      return true;
    }

    function restart() {
      values = new Array(TOTAL).fill(0);
      score = 0;

      addTile();
      addTile();

      updateBoard();
    }

    document.addEventListener(&quot;keydown&quot;, (e) =&gt; {
      if ([&quot;ArrowLeft&quot;, &quot;ArrowRight&quot;, &quot;ArrowUp&quot;, &quot;ArrowDown&quot;].includes(e.key)) {
        e.preventDefault();

        if (e.key === &quot;ArrowLeft&quot;) move(&quot;left&quot;);
        if (e.key === &quot;ArrowRight&quot;) move(&quot;right&quot;);
        if (e.key === &quot;ArrowUp&quot;) move(&quot;up&quot;);
        if (e.key === &quot;ArrowDown&quot;) move(&quot;down&quot;);
      }
    });

    document.getElementById(&quot;restart&quot;).addEventListener(&quot;click&quot;, restart);

    createBoard();
    restart();
  &lt;/script&gt;</description>
            </item>
                    <item>
                <title>9</title>
                <link>http://margo.mozello.shop/blog3/params/post/5250000/9</link>
                <pubDate>Thu, 07 May 2026 15:43:00 +0000</pubDate>
                <description>9999999999999999999999999999&lt;hr class=&quot;moze-more-divider&quot;&gt;&lt;p&gt;0&lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;


  &lt;meta charset=&quot;UTF-8&quot;&gt;
  &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
  &lt;title&gt;2048 (7×7) — Красиві кольори&lt;/title&gt;
  &lt;style&gt;
    body {
      font-family: Arial, sans-serif;
      background: #faf8ef;
      margin: 0;
      padding: 10px;
      min-height: 100vh;
      display: flex;
      flex-direction: column;
      align-items: center;
    }
    h1 { font-size: 36px; margin: 10px 0 5px; }
    .info { font-size: 20px; margin: 5px 0; }
    button {
      padding: 10px 20px;
      font-size: 17px;
      margin: 10px 0;
      border: none;
      border-radius: 8px;
      background: #8f7a66;
      color: white;
      cursor: pointer;
    }
    #game-board {
      display: grid;
      grid-template-columns: repeat(7, 1fr);
      gap: 6px;
      background: #bbada0;
      padding: 8px;
      border-radius: 12px;
      width: 100%;
      max-width: 480px;
    }
    .tile {
      background: #cdc1b4;
      min-height: 58px;
      display: flex;
      align-items: center;
      justify-content: center;
      font-weight: bold;
      border-radius: 8px;
      font-size: 26px;
      transition: all 0.1s;
    }

    /* Основні кольори */
    .tile[data-value=&quot;2&quot;]    { background: #eee4da; color: #776e65; }
    .tile[data-value=&quot;4&quot;]    { background: #ede0c8; color: #776e65; }
    .tile[data-value=&quot;8&quot;]    { background: #f2b179; color: white; }
    .tile[data-value=&quot;16&quot;]   { background: #f59563; color: white; }
    .tile[data-value=&quot;32&quot;]   { background: #f67c5f; color: white; }
    .tile[data-value=&quot;64&quot;]   { background: #f65e3b; color: white; }
    .tile[data-value=&quot;128&quot;]  { background: #edcf72; color: white; }
    .tile[data-value=&quot;256&quot;]  { background: #edcc61; color: white; }
    .tile[data-value=&quot;512&quot;]  { background: #edc850; color: white; }
    .tile[data-value=&quot;1024&quot;] { background: #edc53f; color: white; }
    .tile[data-value=&quot;2048&quot;] { background: #edc22e; color: white; }

    /* Яскраві кольори для великих чисел */
    .tile[data-value=&quot;4096&quot;]  { background: #00b894; color: white; }
    .tile[data-value=&quot;8192&quot;]  { background: #00a8ff; color: white; }
    .tile[data-value=&quot;16384&quot;] { background: #6c5ce7; color: white; }
    .tile[data-value=&quot;32768&quot;] { background: #a55eea; color: white; }
    .tile[data-value=&quot;65536&quot;] { background: #ff7675; color: white; }
    .tile[data-value=&quot;131072&quot;]{ background: #fd79a8; color: white; }
    .tile[data-value^=&quot;262144&quot;]{ background: #feca57; color: #2d3436; font-size: 22px; }
  &lt;/style&gt;


  &lt;h1&gt;2048 (7×7) — Тест&lt;/h1&gt;
  &lt;div class=&quot;info&quot; id=&quot;score&quot;&gt;Очки: 0&lt;/div&gt;
  &lt;div class=&quot;info&quot; id=&quot;best&quot;&gt;Рекорд: 0&lt;/div&gt;
  &lt;button id=&quot;restart&quot; fdprocessedid=&quot;pxw4e9&quot;&gt;Нова гра&lt;/button&gt;

  &lt;div id=&quot;game-board&quot;&gt;&lt;/div&gt;

  &lt;script&gt;
    const SIZE = 7;
    const TOTAL = SIZE * SIZE;
    let values = new Array(TOTAL).fill(0);
    let score = 0;

    const board = document.getElementById(&#039;game-board&#039;);
    const scoreEl = document.getElementById(&#039;score&#039;);

    function createBoard() {
      board.innerHTML = &#039;&#039;;
      for (let i = 0; i &lt; TOTAL; i++) {
        const tile = document.createElement(&#039;div&#039;);
        tile.className = &#039;tile&#039;;
        board.appendChild(tile);
      }
    }

    function updateBoard() {
      const tiles = board.children;
      for (let i = 0; i &lt; TOTAL; i++) {
        const val = values[i];
        tiles[i].textContent = val || &#039;&#039;;
        tiles[i].dataset.value = val || &#039;&#039;;
      }
      scoreEl.textContent = &#039;Очки: &#039; + score;
    }

    function addTile() {
      const empty = [];
      for (let i = 0; i &lt; TOTAL; i++) if (values[i] === 0) empty.push(i);
      if (empty.length &gt; 0) {
        const pos = empty[Math.floor(Math.random() * empty.length)];
        values[pos] = Math.random() &lt; 0.9 ? 2 : 4;
      }
    }

    function slide(line) {
      let arr = line.filter(v =&gt; v);
      for (let i = 0; i &lt; arr.length - 1; i++) {
        if (arr[i] === arr[i + 1]) {
          arr[i] *= 2;
          score += arr[i];
          arr[i + 1] = 0;
        }
      }
      arr = arr.filter(v =&gt; v);
      while (arr.length &lt; SIZE) arr.push(0);
      return arr;
    }

    function move(dir) {
      let moved = false;

      for (let i = 0; i &lt; SIZE; i++) {
        let line = [];
        for (let j = 0; j &lt; SIZE; j++) {
          let idx = (dir === &#039;left&#039;) ? i*SIZE + j :
                    (dir === &#039;right&#039;) ? i*SIZE + (SIZE-1-j) :
                    (dir === &#039;up&#039;) ? j*SIZE + i :
                    (SIZE-1-j)*SIZE + i;
          line.push(values[idx]);
        }

        let newLine = slide(line);

        for (let j = 0; j &lt; SIZE; j++) {
          let idx = (dir === &#039;left&#039;) ? i*SIZE + j :
                    (dir === &#039;right&#039;) ? i*SIZE + (SIZE-1-j) :
                    (dir === &#039;up&#039;) ? j*SIZE + i :
                    (SIZE-1-j)*SIZE + i;
          if (values[idx] !== newLine[j]) {
            values[idx] = newLine[j];
            moved = true;
          }
        }
      }

      if (moved) {
        addTile();
        updateBoard();
      }
    }

    function restart() {
      values = new Array(TOTAL).fill(0);
      score = 0;
      addTile();
      addTile();
      updateBoard();
    }

    createBoard();
    restart();

    document.addEventListener(&#039;keydown&#039;, e =&gt; {
      if ([&quot;ArrowLeft&quot;,&quot;ArrowRight&quot;,&quot;ArrowUp&quot;,&quot;ArrowDown&quot;].includes(e.key)) {
        e.preventDefault();
        if (e.key === &quot;ArrowLeft&quot;) move(&quot;left&quot;);
        if (e.key === &quot;ArrowRight&quot;) move(&quot;right&quot;);
        if (e.key === &quot;ArrowUp&quot;) move(&quot;up&quot;);
        if (e.key === &quot;ArrowDown&quot;) move(&quot;down&quot;);
      }
    });

    document.getElementById(&#039;restart&#039;).onclick = restart;
  &lt;/script&gt;</description>
            </item>
                    <item>
                <title>Гра 2048 6 6 темна тема</title>
                <link>http://margo.mozello.shop/blog3/params/post/5198958/4</link>
                <pubDate>Fri, 23 Jan 2026 16:40:00 +0000</pubDate>
                <description>Початок 23 лютого 2026&lt;p&gt;3&amp;nbsp; &lt;span style=&quot;text-align: start; font-weight: 400; font-style: normal&quot;&gt;Початок
23 лютого 2026&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;text-align: start; font-weight: 400; font-style: normal&quot;&gt;3
2026&amp;nbsp; Початок 1 березня кінець 9 березня&lt;br&gt;
4 почоток 10 березня&amp;nbsp; кінець 12 березня 2 900
000&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;text-align: start; font-weight: 400; font-style: normal&quot;&gt;початок&amp;nbsp;
&amp;nbsp;26 03 2026&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;text-align: start; font-weight: 400; font-style: normal&quot;&gt;початок
31 березня 2026 року&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;text-align: start; font-weight: 400; font-style: normal&quot;&gt;&lt;img src=&quot;https://site-2669532.mozfiles.com/files/2669532/12__03_2026____2_900_000.jpg&quot; alt=&quot;12__03_2026____2_900_000.jpg&quot;&gt;&lt;br&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;meta charset=&quot;UTF-8&quot;&gt;
&lt;div class=&quot;game-theme-wrapper light&quot; id=&quot;gameTheme&quot;&gt;
&lt;div class=&quot;theme-toggle&quot; id=&quot;themeToggle&quot;&gt;🌙 Темна тема&lt;/div&gt;
&lt;h1&gt;2048 (6×6)&lt;/h1&gt;
&lt;div class=&quot;info&quot; id=&quot;score&quot;&gt;Очки: 0&lt;/div&gt;
&lt;div class=&quot;info&quot; id=&quot;best&quot;&gt;Рекорд: 0&lt;/div&gt;
&lt;button id=&quot;restart&quot; fdprocessedid=&quot;3y1n4&quot;&gt;Нова гра&lt;/button&gt;
&lt;div id=&quot;game-board&quot;&gt;&lt;/div&gt;
&lt;div id=&quot;message&quot;&gt;
&lt;div id=&quot;message-text&quot;&gt;&lt;/div&gt;
&lt;button id=&quot;continue&quot; fdprocessedid=&quot;xtnbda&quot;&gt;Продовжити&lt;/button&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;script&gt;
/* ===== ПЕРЕМИКАЧ ТЕМИ ===== */
(function () {
    const w = document.getElementById(&quot;gameTheme&quot;);
    const t = document.getElementById(&quot;themeToggle&quot;);
    const saved = localStorage.getItem(&quot;theme2048&quot;);

    if (saved === &quot;dark&quot;) {
        w.classList.replace(&quot;light&quot;, &quot;dark&quot;);
        t.textContent = &quot;☀️ Світла тема&quot;;
    }

    t.onclick = () =&gt; {
        if (w.classList.contains(&quot;dark&quot;)) {
            w.classList.replace(&quot;dark&quot;, &quot;light&quot;);
            t.textContent = &quot;🌙 Темна тема&quot;;
            localStorage.setItem(&quot;theme2048&quot;, &quot;light&quot;);
        } else {
            w.classList.replace(&quot;light&quot;, &quot;dark&quot;);
            t.textContent = &quot;☀️ Світла тема&quot;;
            localStorage.setItem(&quot;theme2048&quot;, &quot;dark&quot;);
        }
    };
})();
&lt;/script&gt;
&lt;script&gt;
/* ===== ГРА 2048 (6x6) ===== */
const board = document.getElementById(&#039;game-board&#039;),
scoreD = document.getElementById(&#039;score&#039;),
bestD = document.getElementById(&#039;best&#039;),
msg = document.getElementById(&#039;message&#039;),
msgT = document.getElementById(&#039;message-text&#039;),
cont = document.getElementById(&#039;continue&#039;);

const SIZE = 6;
let values = [], tiles = [], score = 0, best = 0;
let gameOver = false, allow = false;

best = +localStorage.getItem(&#039;best2048_6x6&#039;) || 0;
bestD.textContent = &#039;Рекорд: &#039; + best;

function save() {
    localStorage.setItem(&#039;g2048v&#039;, JSON.stringify(values));
    localStorage.setItem(&#039;g2048s&#039;, score);
}

function add() {
    const e = values.map((v, i) =&gt; v ? null : i).filter(v =&gt; v !== null);
    if (e.length) values[e[Math.random() * e.length | 0]] = Math.random() &lt; .9 ? 2 : 4;
}

function draw() {
    tiles.forEach((t, i) =&gt; {
        t.textContent = values[i] || &#039;&#039;;
        t.dataset.value = values[i];
    });
    scoreD.textContent = &#039;Очки: &#039; + score;
    if (score &gt; best) {
        best = score;
        bestD.textContent = &#039;Рекорд: &#039; + best;
        localStorage.setItem(&#039;best2048_6x6&#039;, best);
    }
    save();
}

function slide(r) {
    r = r.filter(v =&gt; v);
    for (let i = 0; i &lt; r.length - 1; i++) {
        if (r[i] === r[i + 1]) {
            r[i] *= 2;
            score += r[i];
            r[i + 1] = 0;
        }
    }
    r = r.filter(v =&gt; v);
    while (r.length &lt; SIZE) r.push(0);
    return r;
}

function move(d) {
    if (gameOver) return;
    let moved = false;

    for (let i = 0; i &lt; SIZE; i++) {
        let line = [];
        for (let j = 0; j &lt; SIZE; j++) {
            let x = d === &#039;l&#039; ? i * SIZE + j :
                    d === &#039;r&#039; ? i * SIZE + (SIZE - 1 - j) :
                    d === &#039;u&#039; ? j * SIZE + i :
                                (SIZE - 1 - j) * SIZE + i;
            line.push(values[x]);
        }

        let newLine = slide(line);

        for (let j = 0; j &lt; SIZE; j++) {
            let x = d === &#039;l&#039; ? i * SIZE + j :
                    d === &#039;r&#039; ? i * SIZE + (SIZE - 1 - j) :
                    d === &#039;u&#039; ? j * SIZE + i :
                                (SIZE - 1 - j) * SIZE + i;
            if (values[x] !== newLine[j]) {
                values[x] = newLine[j];
                moved = true;
            }
        }
    }

    if (moved) {
        add();
        draw();
        check();
    }
}

function check() {
    if (!allow &amp;&amp; values.includes(2048)) {
        msgT.textContent = &#039;Ви виграли 🎉&#039;;
        msg.style.display = &#039;block&#039;;
        gameOver = true;
    } else if (!values.includes(0)) {
        msgT.textContent = &#039;Гру завершено&#039;;
        msg.style.display = &#039;block&#039;;
        gameOver = true;
    }
}

function init() {
    board.innerHTML = &#039;&#039;;
    tiles = [];
    values = JSON.parse(localStorage.getItem(&#039;g2048v&#039;)) || Array(36).fill(0);
    score = +localStorage.getItem(&#039;g2048s&#039;) || 0;

    for (let i = 0; i &lt; 36; i++) {
        let d = document.createElement(&#039;div&#039;);
        d.className = &#039;tile&#039;;
        board.appendChild(d);
        tiles.push(d);
    }

    if (!values.some(v =&gt; v)) { add(); add(); }
    draw();
}

/* ⬇️ ВИПРАВЛЕННЯ: сторінка більше НЕ скролиться */
document.addEventListener(&#039;keydown&#039;, function (e) {
    const keys = {
        ArrowLeft: &#039;l&#039;,
        ArrowRight: &#039;r&#039;,
        ArrowUp: &#039;u&#039;,
        ArrowDown: &#039;d&#039;
    };
    if (keys[e.key]) {
        e.preventDefault();
        move(keys[e.key]);
    }
});

document.getElementById(&#039;restart&#039;).onclick = () =&gt; {
    values = Array(36).fill(0);
    score = 0;
    gameOver = false;
    allow = false;
    add(); add();
    msg.style.display = &#039;none&#039;;
    draw();
};

cont.onclick = () =&gt; {
    gameOver = false;
    allow = true;
    msg.style.display = &#039;none&#039;;
};

init();
&lt;/script&gt;</description>
            </item>
                    <item>
                <title>2048 6 6 ускладнена</title>
                <link>http://margo.mozello.shop/blog3/params/post/5190419/page</link>
                <pubDate>Sat, 03 Jan 2026 18:38:00 +0000</pubDate>
                <description>оооооооооооооооооооооооооооо&lt;hr class=&quot;moze-more-divider&quot;&gt;&lt;p&gt;2&lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;


  &lt;meta charset=&quot;UTF-8&quot;&gt;
  &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no&quot;&gt;
  &lt;meta name=&quot;apple-mobile-web-app-capable&quot; content=&quot;yes&quot;&gt;
  &lt;meta name=&quot;apple-mobile-web-app-status-bar-style&quot; content=&quot;black-translucent&quot;&gt;
  &lt;title&gt;2048 (6x6) Ускладнена&lt;/title&gt;
  &lt;style&gt;
    body {
      font-family: -apple-system, sans-serif;
      display: flex;
      flex-direction: column;
      align-items: center;
      background: #faf8ef;
      margin: 0;
      touch-action: none; /* Prevent iOS scrolling */
      -webkit-touch-callout: none; /* Disable iOS callouts */
      -webkit-user-select: none; /* Disable text selection */
      min-height: 80vh;
    }
    #game-board {
      display: grid;
      grid-template-columns: repeat(6, 10vw);
      gap: 2vw;
      margin: 4vw auto;
      max-width: 110vw;
    }
    .tile {
      width: 11vw;
      height: 5vw;
      background: #cdc1b4;
      font-size: calc(3vw);
      color: #776e65;
      display: flex;
      justify-content: center;
      align-items: center;
      font-weight: bold;
      border-radius: 3px;
      transition: transform 0.05s ease, background 0.05s ease; /* Прискорена анімація */
    }
    .tile[data-value=&quot;2&quot;]    { background: #eee4da; }
    .tile[data-value=&quot;4&quot;]    { background: #ede0c8; }
    .tile[data-value=&quot;8&quot;]    { background: #f2b179; color: #f9f6f2; }
    .tile[data-value=&quot;16&quot;]   { background: #f59563; color: #f9f6f2; }
    .tile[data-value=&quot;32&quot;]   { background: #f67c5f; color: #f9f6f2; }
    .tile[data-value=&quot;64&quot;]   { background: #f65e3b; color: #f9f6f2; }
    .tile[data-value=&quot;128&quot;]  { background: #edcf72; color: #f9f6f2; }
    .tile[data-value=&quot;256&quot;]  { background: #edcc61; color: #f9f6f2; }
    .tile[data-value=&quot;512&quot;]  { background: #edc850; color: #f9f6f2; }
    .tile[data-value=&quot;1024&quot;] { background: #edc53f; color: #f9f6f2; }
    .tile[data-value=&quot;2048&quot;] { background: #edc22e; color: #f9f6f2; }
    .tile[data-value=&quot;4096&quot;],
    .tile[data-value=&quot;8192&quot;],
    .tile[data-value=&quot;16384&quot;],
    .tile[data-value=&quot;32768&quot;] {
      background: #0000e6;
      color: #ffeb3b;
    }
    .tile[data-value=&quot;65536&quot;] { background: #DE3163; color: #f9f6f2; }
    .tile[data-value=&quot;131072&quot;] { background: #DE3163; color: #f9f6f2; }
    .tile.moved {
      transform: scale(1.1);
    }
    h1 {
      font-size: 8vw;
      margin: 4vw 0;
    }
    .info {
      font-size: 4vw;
      margin: 2vw 0;
    }
    #message {
      position: fixed;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      background: #ffffffdd;
      padding: 6vw;
      border-radius: 3vw;
      display: none;
      box-shadow: 0 0 10px rgba(0,0,0,0.3);
      text-align: center;
      z-index: 10;
      font-size: 5vw;
    }
    #message button {
      font-size: 4vw;
      padding: 2vw 4vw;
      margin-top: 2vw;
      border-radius: 2vw;
      min-width: 25vw;
    }
    #restart, #increase-level, #decrease-level {
      font-size: 4vw;
      padding: 2vw 4vw;
      border-radius: 2vw;
      min-width: 25vw;
      margin: 1vw;
    }
    .controls {
      display: flex;
      justify-content: center;
      margin: 2vw 0;
    }
    @media (max-width: 414px) {
      #game-board {
        grid-template-columns: repeat(6, 14vw);
        gap: 1vw;
      }
      .tile {
        width: 14vw;
        height: 14vw;
        font-size: calc(5vw);
      }
      h1 {
        font-size: 7vw;
      }
      .info {
        font-size: 3.5vw;
      }
    }
  &lt;/style&gt;


  &lt;h1&gt;2048 (6x6) Ускладнена&lt;/h1&gt;
  &lt;div class=&quot;info&quot; id=&quot;score&quot;&gt;бали : 0&lt;/div&gt;
  &lt;div class=&quot;info&quot; id=&quot;best&quot;&gt;Рекорд: 0&lt;/div&gt;
  &lt;div class=&quot;info&quot; id=&quot;level&quot;&gt;Рівень: 1&lt;/div&gt;
  &lt;div class=&quot;controls&quot;&gt;
    &lt;button id=&quot;restart&quot; fdprocessedid=&quot;8y4t5&quot;&gt;Нова гра&lt;/button&gt;
    &lt;button id=&quot;increase-level&quot; fdprocessedid=&quot;kejura&quot;&gt;Підвищити рівень&lt;/button&gt;
    &lt;button id=&quot;decrease-level&quot; fdprocessedid=&quot;hmsjo&quot;&gt;Понизити рівень&lt;/button&gt;
  &lt;/div&gt;
  &lt;div id=&quot;game-board&quot;&gt;&lt;/div&gt;
  &lt;div id=&quot;message&quot;&gt;
    &lt;div id=&quot;message-text&quot;&gt;&lt;/div&gt;
    &lt;button id=&quot;continue&quot;&gt;Продовжити&lt;/button&gt;
  &lt;/div&gt;

  &lt;script&gt;
    const GRID_SIZE = 6;
    const TOTAL_TILES = GRID_SIZE * GRID_SIZE;
    const board = document.getElementById(&#039;game-board&#039;);
    const scoreEl = document.getElementById(&#039;score&#039;);
    const bestEl = document.getElementById(&#039;best&#039;);
    const levelEl = document.getElementById(&#039;level&#039;);
    const message = document.getElementById(&#039;message&#039;);
    const messageText = document.getElementById(&#039;message-text&#039;);
    const continueBtn = document.getElementById(&#039;continue&#039;);
    const increaseLevelBtn = document.getElementById(&#039;increase-level&#039;);
    const decreaseLevelBtn = document.getElementById(&#039;decrease-level&#039;);
    let tiles, values, score, best, gameOver, allowContinue;
    let tilesToAdd = 1;
    let level = 1;

    function slide(line) {
      let newLine = line.filter(v =&gt; v !== 0);
      for (let i = 0; i &lt; newLine.length - 1; i++) {
        if (newLine[i] === newLine[i + 1]) {
          newLine[i] *= 2;
          score += newLine[i];
          newLine[i + 1] = 0;
        }
      }
      newLine = newLine.filter(v =&gt; v !== 0);
      while (newLine.length &lt; GRID_SIZE) newLine.push(0);
      return newLine;
    }

    function updateBoard() {
      for (let i = 0; i &lt; TOTAL_TILES; i++) {
        const v = values[i];
        tiles[i].dataset.value = v || &#039;&#039;;
        tiles[i].textContent = v || &#039;&#039;;
      }
    }

    function updateScore() {
      scoreEl.textContent = `Окуляри: ${score}`;
      best = Math.max(best, score);
      bestEl.textContent = `Рекорд: ${best}`;
      localStorage.setItem(&#039;game2048_best_6x6&#039;, best);

      // Оновлення рівня на основі очок (автоматично, якщо потрібно)
      if (score &gt; 1000 * level) {
        level++;
        tilesToAdd = Math.min(level, 3);
        levelEl.textContent = `Рівень: ${level}`;
      }
    }

    function addTile() {
      const empty = values.reduce((acc, v, i) =&gt; { if (!v) acc.push(i); return acc; }, []);
      if (empty.length) {
        const idx = empty[Math.floor(Math.random() * empty.length)];
        values[idx] = Math.random() &lt; 0.9 ? 2 : 4;
      }
    }

    function move(direction) {
      if (gameOver) return;
      let moved = false;
      for (let i = 0; i &lt; GRID_SIZE; i++) {
        let line = [];
        for (let j = 0; j &lt; GRID_SIZE; j++) {
          let idx = direction === &#039;left&#039;  ? i * GRID_SIZE + j :
                    direction === &#039;right&#039; ? i * GRID_SIZE + (GRID_SIZE - 1 - j) :
                    direction === &#039;up&#039;    ? j * GRID_SIZE + i :
                                            (GRID_SIZE - 1 - j) * GRID_SIZE + i;
          line.push(values[idx]);
        }

        const newLine = slide(line);

        for (let j = 0; j &lt; GRID_SIZE; j++) {
          let idx = direction === &#039;left&#039;  ? i * GRID_SIZE + j :
                    direction === &#039;right&#039; ? i * GRID_SIZE + (GRID_SIZE - 1 - j) :
                    direction === &#039;up&#039;    ? j * GRID_SIZE + i :
                                            (GRID_SIZE - 1 - j) * GRID_SIZE + i;
          if (values[idx] !== newLine[j]) {
            values[idx] = newLine[j];
            moved = true;
            tiles[idx].classList.add(&#039;moved&#039;);
            setTimeout(() =&gt; tiles[idx].classList.remove(&#039;moved&#039;), 50);
          }
        }
      }

      if (moved) {
        for (let k = 0; k &lt; tilesToAdd; k++) {
          addTile();
        }
        updateBoard();
        updateScore();
        checkWinLose();
        if (navigator.vibrate) navigator.vibrate(10);
      }
    }

    function checkWinLose() {
      if (!allowContinue &amp;&amp; values.includes(2048)) {
        showMessage(&#039;Ви виграли! 🎉&#039;);
        gameOver = true;
      } else if (!canMove()) {
        showMessage(&#039;Гру завершено!&#039;);
        gameOver = true;
      }
    }

    function showMessage(text) {
      messageText.textContent = text;
      message.style.display = &#039;block&#039;;
    }

    function restartGame() {
      values = new Array(TOTAL_TILES).fill(0);
      score = 0;
      level = 1;
      tilesToAdd = 1;
      gameOver = false;
      allowContinue = false;
      addTile(); addTile();
      updateBoard();
      updateScore();
      levelEl.textContent = `Рівень: ${level}`;
      message.style.display = &#039;none&#039;;
      saveGame();
    }

    function increaseLevel() {
      level = Math.min(level + 1, 10); // Max level 10, for example
      tilesToAdd = Math.min(level, 3);
      levelEl.textContent = `Рівень: ${level}`;
      saveGame();
    }

    function decreaseLevel() {
      level = Math.max(level - 1, 1); // Min level 1
      tilesToAdd = Math.min(level, 3);
      levelEl.textContent = `Рівень: ${level}`;
      saveGame();
    }

    function canMove() {
      if (values.includes(0)) return true;
      for (let i = 0; i &lt; GRID_SIZE; i++) {
        for (let j = 0; j &lt; GRID_SIZE - 1; j++) {
          if (values[i * GRID_SIZE + j] === values[i * GRID_SIZE + j + 1] ||
              values[j * GRID_SIZE + i] === values[(j + 1) * GRID_SIZE + i]) return true;
        }
      }
      return false;
    }

    function saveGame() {
      localStorage.setItem(&#039;game2048_values_6x6&#039;, JSON.stringify(values));
      localStorage.setItem(&#039;game2048_score_6x6&#039;, score);
      localStorage.setItem(&#039;game2048_level_6x6&#039;, level);
      localStorage.setItem(&#039;game2048_tilesToAdd_6x6&#039;, tilesToAdd);
    }

    function loadGame() {
      const savedValues = localStorage.getItem(&#039;game2048_values_6x6&#039;);
      const savedScore = localStorage.getItem(&#039;game2048_score_6x6&#039;);
      const savedLevel = localStorage.getItem(&#039;game2048_level_6x6&#039;);
      const savedTilesToAdd = localStorage.getItem(&#039;game2048_tilesToAdd_6x6&#039;);
      if (savedValues) {
        values = JSON.parse(savedValues);
        score = parseInt(savedScore) || 0;
        level = parseInt(savedLevel) || 1;
        tilesToAdd = parseInt(savedTilesToAdd) || 1;
      } else {
        values = new Array(TOTAL_TILES).fill(0);
        addTile(); addTile();
      }
      updateBoard();
      updateScore();
      levelEl.textContent = `Рівень: ${level}`;
    }

    function loadBest() {
      best = parseInt(localStorage.getItem(&#039;game2048_best_6x6&#039;)) || 0;
      bestEl.textContent = `Рекорд: ${best}`;
    }

    function init() {
      tiles = [];
      board.innerHTML = &#039;&#039;;
      for (let i = 0; i &lt; TOTAL_TILES; i++) {
        const tile = document.createElement(&#039;div&#039;);
        tile.className = &#039;tile&#039;;
        board.appendChild(tile);
        tiles.push(tile);
      }
      loadGame();
    }

    document.addEventListener(&#039;keydown&#039;, e =&gt; {
      if ([&quot;ArrowUp&quot;, &quot;ArrowDown&quot;, &quot;ArrowLeft&quot;, &quot;ArrowRight&quot;].includes(e.key)) {
        e.preventDefault();
        move({
          ArrowLeft: &#039;left&#039;,
          ArrowRight: &#039;right&#039;,
          ArrowUp: &#039;up&#039;,
          ArrowDown: &#039;down&#039;
        }[e.key]);
      }
    });

    let startX, startY;
    board.addEventListener(&#039;touchstart&#039;, e =&gt; {
      e.preventDefault();
      const t = e.touches[0];
      startX = t.clientX;
      startY = t.clientY;
    });

    board.addEventListener(&#039;touchend&#039;, e =&gt; {
      e.preventDefault();
      const t = e.changedTouches[0];
      const dx = t.clientX - startX;
      const dy = t.clientY - startY;
      if (Math.abs(dx) &gt; Math.abs(dy)) {
        if (dx &gt; 20) move(&#039;right&#039;);
        else if (dx &lt; -20) move(&#039;left&#039;);
      } else {
        if (dy &gt; 20) move(&#039;down&#039;);
        else if (dy &lt; -20) move(&#039;up&#039;);
      }
    });

    document.getElementById(&#039;restart&#039;).addEventListener(&#039;click&#039;, restartGame);
    increaseLevelBtn.addEventListener(&#039;click&#039;, increaseLevel);
    decreaseLevelBtn.addEventListener(&#039;click&#039;, decreaseLevel);
    continueBtn.addEventListener(&#039;click&#039;, () =&gt; {
      gameOver = false;
      allowContinue = true;
      message.style.display = &#039;none&#039;;
      saveGame();
    });

    loadBest();
    init();
  &lt;/script&gt;</description>
            </item>
                    <item>
                <title>кубік рубіка 3 на 3</title>
                <link>http://margo.mozello.shop/blog3/params/post/5185431/kr3</link>
                <pubDate>Thu, 18 Dec 2025 17:15:00 +0000</pubDate>
                <description>дддддддддддддддддддддд&lt;hr class=&quot;moze-more-divider&quot;&gt;&lt;p&gt;1&lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;&lt;div class=&quot;rubik-cube-wrapper&quot; style=&quot;display: flex; justify-content: center; align-items: center; margin: 20px 0; position: relative; height: auto; min-height: 400px;&quot;&gt;
    &lt;style&gt;
        .rubik-cube-container {
            width: 400px; /* Змініть цей розмір для збільшення/зменшення */
            height: 419px; /* Висота повинна бути width + 19px для кнопок */
            background-color: #f0f0f0;
            border: 1px solid #ccc;
            padding: 10px;
            box-sizing: border-box;
        }
    &lt;/style&gt;
    &lt;script src=&quot;https://animcubejs.cubing.net/AnimCube3.js&quot;&gt;&lt;/script&gt;
    &lt;div class=&quot;rubik-cube-container&quot;&gt;
        &lt;script&gt;
            AnimCube3(&quot;move=RUR&#039;URU2R&#039;U2&amp;initrevmove=#&amp;edit=1&amp;demo=1&quot;);
        &lt;/script&gt;
    &lt;/div&gt;
&lt;/div&gt;</description>
            </item>
                    <item>
                <title>Лінії 098</title>
                <link>http://margo.mozello.shop/blog3/params/post/5164939/page</link>
                <pubDate>Mon, 03 Nov 2025 12:18:00 +0000</pubDate>
                <description>лллллллллллллллллллллллллллл&lt;hr class=&quot;moze-more-divider&quot;&gt;&lt;p&gt;98 2&lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;&lt;title&gt;Lines 98 - Smaller Field for iOS&lt;/title&gt;
  &lt;meta charset=&quot;UTF-8&quot;&gt;
  &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0, user-scalable=no, maximum-scale=1.0&quot;&gt;
  &lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.2/p5.min.js&quot; onerror=&quot;loadBackupP5()&quot;&gt;&lt;/script&gt;
  &lt;script&gt;
    function loadBackupP5() {
      console.log(&quot;Failed to load p5.js from primary CDN, trying backup...&quot;);
      let script = document.createElement(&#039;script&#039;);
      script.src = &#039;https://unpkg.com/p5@1.4.2/lib/p5.min.js&#039;;
      script.onload = () =&gt; console.log(&quot;Backup p5.js loaded&quot;);
      script.onerror = () =&gt; console.log(&quot;Failed to load p5.js&quot;);
      document.head.appendChild(script);
    }
  &lt;/script&gt;
  &lt;style&gt;
    body { margin: 0; padding: 0; background: linear-gradient(to bottom, #e0f7fa, #b3e5fc); font-family: Arial, sans-serif; -webkit-user-select: none; user-select: none; display: flex; flex-direction: column; align-items: center; }
    #game-container { max-width: 100%; width: 100%; margin: 0 auto; padding: 5px; background: #fff; border-radius: 10px; box-shadow: 0 4px 12px rgba(0,0,0,0.3); text-align: center; box-sizing: border-box; position: relative; }
    canvas { display: block; margin: 0 auto; border-radius: 8px; touch-action: none; cursor: pointer; width: 100%; max-height: 100vh; }
    .bottom-controls { display: flex; gap: 10px; margin-top: 10px; }
    button { padding: 6px 12px; background: #0288d1; color: white; border: none; border-radius: 5px; cursor: pointer; font-size: 12px; z-index: 10; }
    button:hover, button:active { background: #0277bd; }
    @media (max-width: 400px) { 
      #game-container { padding: 3px; } 
      button { padding: 5px 10px; font-size: 10px; } 
      canvas { max-width: 100%; max-height: calc(100vh - 10px); }
    }
  &lt;/style&gt;



  &lt;div id=&quot;game-container&quot;&gt;
  &lt;/div&gt;
  &lt;div class=&quot;bottom-controls&quot;&gt;
    &lt;button id=&quot;restart&quot; onclick=&quot;restartGame()&quot;&gt;Restart&lt;/button&gt;
    &lt;button id=&quot;hint&quot; onclick=&quot;showHint()&quot;&gt;Hint&lt;/button&gt;
  &lt;/div&gt;
    &lt;script&gt;
      let grid;
      let cellSize;
      let gridSize = 9;
      let colors = [&#039;#f44336&#039;, &#039;#2196f3&#039;, &#039;#4caf50&#039;, &#039;#ffeb3b&#039;, &#039;#9c27b0&#039;, &#039;#00bcd4&#039;, &#039;#ff9800&#039;];
      let selectedBall = null;
      let score = 0;
      let gameOver = false;
      let nextBalls = [];
      let animation = null;
      let moveCount = 0;
  
      function setup() {
        console.log(&quot;p5.js setup started&quot;);
        pixelDensity(2); // Support Retina display on iPhone 7
        let maxWidth = Math.min(window.innerWidth - 10, 320); // Smaller width for iPhone 7
        let maxHeight = Math.min(window.innerHeight - 10, 480); // Fit iPhone 7 height
        cellSize = Math.floor(maxWidth / gridSize);
        let canvasHeight = Math.min(maxHeight, gridSize * cellSize + 100); // Reduced extra height
        let canvas = createCanvas(maxWidth, canvasHeight);
        canvas.parent(&#039;game-container&#039;);
        canvas.style(&#039;touch-action&#039;, &#039;none&#039;);
        console.log(`Canvas size: ${maxWidth}x${canvasHeight}, cellSize: ${cellSize}`);
        resetGame();
        console.log(&quot;p5.js setup completed&quot;);
      }
  
      function windowResized() {
        let maxWidth = Math.min(window.innerWidth - 10, 320);
        let maxHeight = Math.min(window.innerHeight - 10, 480);
        cellSize = Math.floor(maxWidth / gridSize);
        let canvasHeight = Math.min(maxHeight, gridSize * cellSize + 100);
        resizeCanvas(maxWidth, canvasHeight);
        console.log(`Resized canvas: ${maxWidth}x${canvasHeight}`);
      }
  
      function resetGame() {
        grid = Array(gridSize).fill().map(() =&gt; Array(gridSize).fill(null));
        nextBalls = generateBalls(3);
        spawnBalls(nextBalls);
        nextBalls = generateBalls(3);
        score = 0;
        gameOver = false;
        animation = null;
        selectedBall = null;
        moveCount = 0;
        console.log(&quot;Game reset&quot;);
      }
  
      function draw() {
        if (gameOver) {
          background(255);
          drawGrid();
          drawBalls();
          textAlign(CENTER);
          textSize(cellSize * 0.8);
          fill(255, 0, 0);
          text(&quot;Game Over!&quot;, width / 2, height / 2);
          return;
        }
  
        background(255);
        drawGrid();
        drawBalls();
        drawNextBalls();
        drawScore();
  
        if (animation) {
          let { startX, startY, endX, endY, color, progress } = animation;
          let x = lerp(startX, endX, progress);
          let y = lerp(startY, endY, progress);
          drawBall(x, y, color);
          animation.progress += 0.05;
          if (animation.progress &gt;= 1) animation = null;
        }
      }
  
      function drawGrid() {
        stroke(200);
        for (let i = 0; i &lt;= gridSize; i++) {
          line(i * cellSize, 0, i * cellSize, gridSize * cellSize);
          line(0, i * cellSize, gridSize * cellSize, i * cellSize);
        }
      }
  
      function drawBalls() {
        for (let i = 0; i &lt; gridSize; i++) {
          for (let j = 0; j &lt; gridSize; j++) {
            if (grid[i][j]) {
              drawBall(j * cellSize + cellSize / 2, i * cellSize + cellSize / 2, grid[i][j]);
            }
          }
        }
        if (selectedBall) {
          noFill();
          stroke(0);
          strokeWeight(2);
          rect(selectedBall.j * cellSize, selectedBall.i * cellSize, cellSize, cellSize);
        }
      }
  
      function drawBall(x, y, color) {
        fill(color);
        noStroke();
        ellipse(x, y, cellSize * 0.8);
      }
  
      function drawNextBalls() {
        textAlign(LEFT);
        textSize(14);
        fill(0);
        text(&quot;Next:&quot;, 10, gridSize * cellSize + 20);
        for (let i = 0; i &lt; nextBalls.length; i++) {
          drawBall(60 + i * cellSize / 2, gridSize * cellSize + 20, nextBalls[i]);
        }
      }
  
      function drawScore() {
        textAlign(RIGHT);
        textSize(14);
        fill(0);
        text(`Score: ${score}`, width - 10, gridSize * cellSize + 20);
      }
  
      function generateBalls(count) {
        return Array(count).fill().map(() =&gt; random(colors));
      }
  
      function spawnBalls(balls) {
        for (let color of balls) {
          let emptyCells = getEmptyCells();
          if (emptyCells.length === 0) {
            gameOver = true;
            return;
          }
          let pos = random(emptyCells);
          grid[pos.i][pos.j] = color;
        }
      }

      function getEmptyCells() {
        let emptyCells = [];
        for (let i = 0; i &lt; gridSize; i++) {
          for (let j = 0; j &lt; gridSize; j++) {
            if (!grid[i][j]) emptyCells.push({ i, j });
          }
        }
        return emptyCells;
      }
  
      function mousePressed() {
        if (gameOver || animation) return;
        let i = floor(mouseY / cellSize);
        let j = floor(mouseX / cellSize);
        if (i &gt;= 0 &amp;&amp; i &lt; gridSize &amp;&amp; j &gt;= 0 &amp;&amp; j &lt; gridSize) {
          if (grid[i][j]) {
            selectedBall = { i, j };
          } else if (selectedBall) {
            if (canMove(selectedBall.i, selectedBall.j, i, j)) {
              animateMove(selectedBall.i, selectedBall.j, i, j);
              moveBall(selectedBall.i, selectedBall.j, i, j);
              let lines = checkLines();
              if (lines.length &gt; 0) {
                removeLines(lines);
              } else {
                spawnBalls(nextBalls);
                nextBalls = generateBalls(3);
              }
              selectedBall = null;
              moveCount++;
              if (isGridFull()) gameOver = true;
            }
          }
        }
      }
  
      function animateMove(startI, startJ, endI, endJ) {
        animation = {
          startX: startJ * cellSize + cellSize / 2,
          startY: startI * cellSize + cellSize / 2,
          endX: endJ * cellSize + cellSize / 2,
          endY: endI * cellSize + cellSize / 2,
          color: grid[startI][startJ],
          progress: 0
        };
      }
  
      function canMove(startI, startJ, endI, endJ) {
        if (startI === endI &amp;&amp; startJ === endJ) return false;
        let queue = [{ i: startI, j: startJ }];
        let visited = Array(gridSize).fill().map(() =&gt; Array(gridSize).fill(false));
        visited[startI][startJ] = true;
        let maxIterations = gridSize * gridSize;
        let iterations = 0;
  
        while (queue.length &gt; 0) {
          iterations++;
          if (iterations &gt; maxIterations) {
            console.log(&quot;canMove: Max iterations reached&quot;);
            return false;
          }
          let { i, j } = queue.shift();
          if (i === endI &amp;&amp; j === endJ) return true;
  
          let neighbors = [
            { ni: i + 1, nj: j }, { ni: i - 1, nj: j },
            { ni: i, nj: j + 1 }, { ni: i, nj: j - 1 }
          ];
  
          for (let { ni, nj } of neighbors) {
            if (ni &gt;= 0 &amp;&amp; ni &lt; gridSize &amp;&amp; nj &gt;= 0 &amp;&amp; nj &lt; gridSize &amp;&amp; !visited[ni][nj] &amp;&amp; !grid[ni][nj]) {
              queue.push({ i: ni, j: nj });
              visited[ni][nj] = true;
            }
          }
        }
        return false;
      }
  
      function isAnyMovePossible() {
        for (let si = 0; si &lt; gridSize; si++) {
          for (let sj = 0; sj &lt; gridSize; sj++) {
            if (grid[si][sj]) {
              let visited = Array(gridSize).fill().map(() =&gt; Array(gridSize).fill(false));
              let queue = [{ i: si, j: sj }];
              visited[si][sj] = true;
              while (queue.length &gt; 0) {
                let { i, j } = queue.shift();
                let neighbors = [
                  { ni: i + 1, nj: j }, { ni: i - 1, nj: j },
                  { ni: i, nj: j + 1 }, { ni: i, nj: j - 1 }
                ];
                for (let { ni, nj } of neighbors) {
                  if (ni &gt;= 0 &amp;&amp; ni &lt; gridSize &amp;&amp; nj &gt;= 0 &amp;&amp; nj &lt; gridSize &amp;&amp; !visited[ni][nj] &amp;&amp; !grid[ni][nj]) {
                    return true;
                  }
                }
              }
            }
          }
        }
        return false;
      }
  
      function moveBall(startI, startJ, endI, endJ) {
        grid[endI][endJ] = grid[startI][startJ];
        grid[startI][startJ] = null;
      }
  
      function copyGrid(g) {
        return g.map(row =&gt; row.slice());
      }

      function checkLine(startI, startJ, di, dj, customGrid = grid) {
        let line = [{ i: startI, j: startJ }];
        let color = customGrid[startI][startJ];
        let i = startI + di;
        let j = startJ + dj;
        let iterations = 0;
        let maxIterations = gridSize;
        while (i &gt;= 0 &amp;&amp; i &lt; gridSize &amp;&amp; j &gt;= 0 &amp;&amp; j &lt; gridSize &amp;&amp; customGrid[i][j] === color) {
          iterations++;
          if (iterations &gt; maxIterations) {
            console.log(&quot;checkLine: Max iterations reached&quot;);
            break;
          }
          line.push({ i, j });
          i += di;
          j += dj;
        }
        return line;
      }

      function checkLines(customGrid = grid) {
        let lines = [];
        for (let i = 0; i &lt; gridSize; i++) {
          for (let j = 0; j &lt; gridSize; j++) {
            if (customGrid[i][j]) {
              let hLine = checkLine(i, j, 0, 1, customGrid);
              if (hLine.length &gt;= 5) lines.push(hLine);
              let vLine = checkLine(i, j, 1, 0, customGrid);
              if (vLine.length &gt;= 5) lines.push(vLine);
              let d1Line = checkLine(i, j, 1, -1, customGrid);
              if (d1Line.length &gt;= 5) lines.push(d1Line);
              let d2Line = checkLine(i, j, 1, 1, customGrid);
              if (d2Line.length &gt;= 5) lines.push(d2Line);
            }
          }
        }
        let uniqueLines = [];
        let removed = new Set();
        for (let line of lines) {
          let positions = line.map(p =&gt; `${p.i},${p.j}`);
          if (!positions.some(pos =&gt; removed.has(pos))) {
            uniqueLines.push(line);
            positions.forEach(pos =&gt; removed.add(pos));
          }
        }
        return uniqueLines;
      }
  
      function removeLines(lines) {
        for (let line of lines) {
          for (let { i, j } of line) {
            grid[i][j] = null;
          }
          score += line.length * 2;
        }
      }
  
      function isGridFull() {
        for (let i = 0; i &lt; gridSize; i++) {
          for (let j = 0; j &lt; gridSize; j++) {
            if (!grid[i][j]) return false;
          }
        }
        return true;
      }

      function findHelpfulMove() {
        for (let si = 0; si &lt; gridSize; si++) {
          for (let sj = 0; sj &lt; gridSize; sj++) {
            if (grid[si][sj]) {
              for (let ei = 0; ei &lt; gridSize; ei++) {
                for (let ej = 0; ej &lt; gridSize; ej++) {
                  if (!grid[ei][ej] &amp;&amp; canMove(si, sj, ei, ej)) {
                    let tempGrid = copyGrid(grid);
                    tempGrid[ei][ej] = tempGrid[si][sj];
                    tempGrid[si][sj] = null;
                    let lines = checkLines(tempGrid);
                    if (lines.length &gt; 0) {
                      return { from: { i: si, j: sj }, to: { i: ei, j: ej } };
                    }
                  }
                }
              }
            }
          }
        }
        return null;
      }

      function showHint() {
        if (gameOver) {
          alert(&quot;Game is over!&quot;);
          return;
        }
        let move = findHelpfulMove();
        if (move) {
          alert(`Move ball from row ${move.from.i + 1}, col ${move.from.j + 1} to row ${move.to.i + 1}, col ${move.to.j + 1}`);
        } else {
          alert(&quot;No immediate line-forming move found.&quot;);
        }
      }
  
      function restartGame() {
        resetGame();
        console.log(&quot;Game restarted via button&quot;);
      }
    &lt;/script&gt;</description>
            </item>
            </channel>
</rss>