<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
    <channel>
        <title>Маргарита - Ігри</title>
        <link>http://margo.mozello.shop/gry/</link>
        <description>Маргарита - Ігри</description>
                    <item>
                <title>2048 6 6</title>
                <link>http://margo.mozello.shop/gry/params/post/5199027/2048-6-6</link>
                <pubDate>Fri, 23 Jan 2026 22:22: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;meta charset=&quot;UTF-8&quot;&gt;

&lt;style&gt;
/* ===== ОБГОРТКА З ТЕМАМИ ===== */
.game-theme-wrapper {
    padding: 25px 20px;
    border-radius: 14px;
    font-family: sans-serif;
    text-align: center;
    transition: background-color .3s, color .3s;
}

/* Світла тема */
.game-theme-wrapper.light {
    background: #faf8ef;
    color: #333;
}

/* Темна ЗЕЛЕНА тема */
.game-theme-wrapper.dark {
    background: #0f1f1a;
    color: #e0f2ea;
}

/* Кнопка теми */
.theme-toggle {
    display: inline-block;
    margin-bottom: 15px;
    padding: 8px 16px;
    background: #2d6a4f;
    color: #fff;
    border-radius: 20px;
    cursor: pointer;
    font-size: 14px;
}
.theme-toggle:hover { background: #40916c; }

/* Заголовки */
.game-theme-wrapper.dark h1,
.game-theme-wrapper.dark .info {
    color: #b7e4c7;
}

/* Кнопка нової гри */
#restart {
    margin: 10px 0;
    padding: 8px 16px;
    border-radius: 6px;
    border: none;
    cursor: pointer;
}

/* ===== ДОШКА ГРИ ===== */
#game-board {
    display: grid;
    grid-template-columns: repeat(6, 80px);
    gap: 8px;
    justify-content: center;
    margin: 20px auto;
    padding: 10px;
    border-radius: 10px;
}

/* Темна тема — фон дошки */
.game-theme-wrapper.dark #game-board {
    background: #1b3a2f;
}

/* Клітинки */
.tile {
    width: 110px;
    height: 40px;
    background: #cdc1b4;
    font-size: 24px;
    color: #776e65;
    display: flex;
    justify-content: center;
    align-items: center;
    font-weight: bold;
    border-radius: 5px;
}

/* Кольори плиток */
.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: #fff; }
.tile[data-value=&quot;16&quot;]   { background: #f59563; color: #fff; }
.tile[data-value=&quot;32&quot;]   { background: #f67c5f; color: #fff; }
.tile[data-value=&quot;64&quot;]   { background: #f65e3b; color: #fff; }
.tile[data-value=&quot;128&quot;]  { background: #edcf72; color: #fff; }
.tile[data-value=&quot;256&quot;]  { background: #edcc61; color: #fff; }
.tile[data-value=&quot;512&quot;]  { background: #edc850; color: #fff; }
.tile[data-value=&quot;1024&quot;] { background: #edc53f; color: #fff; }
.tile[data-value=&quot;2048&quot;] { background: #edc22e; color: #fff; }

/* Повідомлення */
#message {
    position: fixed;
    top: 40%;
    left: 50%;
    transform: translate(-50%, -50%);
    background: #ffffffee;
    padding: 25px;
    border-radius: 10px;
    display: none;
    z-index: 10;
}
&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 (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;&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>реверсі</title>
                <link>http://margo.mozello.shop/gry/params/post/5144256/revers</link>
                <pubDate>Sat, 04 Oct 2025 19:55:00 +0000</pubDate>
                <description>&lt;img src=&quot;https://site-2669532.mozfiles.com/files/2669532/medium/gra_revers.jpg&quot; style=&quot;width: 189px;&quot;&gt;У світі настільних ігор є одна, яка поєднує простоту правил і глибину стратегії — це Реверсі. Вона не потребує складного обладнання, але здатна захопити на години. У цій бесіді ми розглянемо, чому Реверсі варта вашої уваги, як у неї грати, і що вона дає гравцеві.

&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;p&gt;&lt;br&gt;&lt;/p&gt;



  &lt;meta charset=&quot;UTF-8&quot;&gt;
  &lt;title&gt;Реверсі: Гравець vs Комп&#039;ютер&lt;/title&gt;
  &lt;style&gt;
    canvas { background: #0a0; display: block; margin: 20px auto; }
    body { text-align: center; font-family: sans-serif; }
    details { margin: 20px auto; width: 80%; text-align: left; }
    summary { font-weight: bold; cursor: pointer; }
  &lt;/style&gt;


  &lt;h1&gt;Гра Реверсі&lt;/h1&gt;
  &lt;canvas id=&quot;board&quot; width=&quot;320&quot; height=&quot;320&quot;&gt;&lt;/canvas&gt;
  &lt;p&gt;Поточний гравець: &lt;span id=&quot;player&quot;&gt;Гравець (Чорний)&lt;/span&gt;&lt;/p&gt;

  &lt;details&gt;
    &lt;summary&gt;📘 Правила гри та інструкція&lt;/summary&gt;
    &lt;p&gt;&lt;b&gt;Мета гри:&lt;/b&gt; захопити більше клітинок, ніж суперник, перетворюючи його фішки на свої.&lt;/p&gt;
    &lt;p&gt;&lt;b&gt;Початок:&lt;/b&gt; гра починається з 4 фішками в центрі дошки. Гравець — чорний, комп’ютер — білий.&lt;/p&gt;
    &lt;p&gt;&lt;b&gt;Хід:&lt;/b&gt; фішка ставиться так, щоб між новою фішкою і вже наявною була хоча б одна фішка суперника. Всі такі фішки перевертаються.&lt;/p&gt;
    &lt;p&gt;&lt;b&gt;Коли немає ходів:&lt;/b&gt; якщо гравець не має допустимих ходів — хід переходить супернику.&lt;/p&gt;
    &lt;p&gt;&lt;b&gt;Завершення гри:&lt;/b&gt; коли дошка заповнена або жоден гравець не має ходів. Перемагає той, у кого більше фішок.&lt;/p&gt;
  &lt;/details&gt;

  &lt;script&gt;
    const canvas = document.getElementById(&quot;board&quot;);
    const ctx = canvas.getContext(&quot;2d&quot;);
    const size = 8;
    const cell = canvas.width / size;
    let board = Array(size).fill().map(() =&gt; Array(size).fill(null));
    board[3][3] = board[4][4] = &quot;W&quot;;
    board[3][4] = board[4][3] = &quot;B&quot;;
    let current = &quot;B&quot;;

    function drawBoard() {
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      for (let x = 0; x &lt; size; x++) {
        for (let y = 0; y &lt; size; y++) {
          ctx.strokeRect(x * cell, y * cell, cell, cell);
          if (board[x][y]) {
            ctx.beginPath();
            ctx.arc(x * cell + cell / 2, y * cell + cell / 2, cell / 2 - 4, 0, Math.PI * 2);
            ctx.fillStyle = board[x][y] === &quot;B&quot; ? &quot;black&quot; : &quot;white&quot;;
            ctx.fill();
          }
        }
      }
    }

    function isValid(x, y, player) {
      if (board[x][y]) return false;
      const opp = player === &quot;B&quot; ? &quot;W&quot; : &quot;B&quot;;
      const dirs = [[-1,-1],[-1,0],[-1,1],[0,-1],[0,1],[1,-1],[1,0],[1,1]];
      for (let [dx, dy] of dirs) {
        let nx = x + dx, ny = y + dy, found = false;
        while (nx &gt;= 0 &amp;&amp; ny &gt;= 0 &amp;&amp; nx &lt; size &amp;&amp; ny &lt; size) {
          if (board[nx][ny] === opp) found = true;
          else if (board[nx][ny] === player &amp;&amp; found) return true;
          else break;
          nx += dx; ny += dy;
        }
      }
      return false;
    }

    function flip(x, y, player) {
      board[x][y] = player;
      const opp = player === &quot;B&quot; ? &quot;W&quot; : &quot;B&quot;;
      const dirs = [[-1,-1],[-1,0],[-1,1],[0,-1],[0,1],[1,-1],[1,0],[1,1]];
      for (let [dx, dy] of dirs) {
        let nx = x + dx, ny = y + dy, path = [];
        while (nx &gt;= 0 &amp;&amp; ny &gt;= 0 &amp;&amp; nx &lt; size &amp;&amp; ny &lt; size) {
          if (board[nx][ny] === opp) path.push([nx, ny]);
          else if (board[nx][ny] === player) {
            for (let [px, py] of path) board[px][py] = player;
            break;
          } else break;
          nx += dx; ny += dy;
        }
      }
    }

    function getValidMoves(player) {
      let moves = [];
      for (let x = 0; x &lt; size; x++) {
        for (let y = 0; y &lt; size; y++) {
          if (isValid(x, y, player)) moves.push([x, y]);
        }
      }
      return moves;
    }

    function countDiscs() {
      let black = 0, white = 0;
      for (let row of board) {
        for (let cell of row) {
          if (cell === &quot;B&quot;) black++;
          if (cell === &quot;W&quot;) white++;
        }
      }
      return { black, white };
    }

    function checkEndGame() {
      const movesB = getValidMoves(&quot;B&quot;);
      const movesW = getValidMoves(&quot;W&quot;);
      const full = board.flat().every(cell =&gt; cell !== null);
      if ((movesB.length === 0 &amp;&amp; movesW.length === 0) || full) {
        const { black, white } = countDiscs();
        let result = &quot;&quot;;
        if (black &gt; white) result = &quot;Ви перемогли!&quot;;
        else if (white &gt; black) result = &quot;Комп’ютер переміг!&quot;;
        else result = &quot;Нічия!&quot;;
        alert(`${result}\nЧорних: ${black}\nБілих: ${white}`);
      }
    }

    function checkTurn() {
      let moves = getValidMoves(current);
      if (moves.length === 0) {
        alert(&quot;Ходів немає. Хід переходить супернику.&quot;);
        current = current === &quot;B&quot; ? &quot;W&quot; : &quot;B&quot;;
        document.getElementById(&quot;player&quot;).textContent =
          current === &quot;B&quot; ? &quot;Гравець (Чорний)&quot; : &quot;Комп&#039;ютер (Білий)&quot;;
        drawBoard();
        if (current === &quot;W&quot;) {
          setTimeout(computerMove, 500);
        }
      }
    }

    function computerMove() {
      let moves = getValidMoves(&quot;W&quot;);
      if (moves.length &gt; 0) {
        let [x, y] = moves[0];
        flip(x, y, &quot;W&quot;);
        current = &quot;B&quot;;
        document.getElementById(&quot;player&quot;).textContent = &quot;Гравець (Чорний)&quot;;
        drawBoard();
        checkEndGame();
        checkTurn();
      } else {
        alert(&quot;Комп&#039;ютер не має ходів. Хід переходить гравцю.&quot;);
        current = &quot;B&quot;;
        document.getElementById(&quot;player&quot;).textContent = &quot;Гравець (Чорний)&quot;;
        drawBoard();
        checkEndGame();
        checkTurn();
      }
    }

    canvas.addEventListener(&quot;click&quot;, e =&gt; {
      if (current !== &quot;B&quot;) return;
      const x = Math.floor(e.offsetX / cell);
      const y = Math.floor(e.offsetY / cell);
      if (isValid(x, y, &quot;B&quot;)) {
        flip(x, y, &quot;B&quot;);
        current = &quot;W&quot;;
        document.getElementById(&quot;player&quot;).textContent = &quot;Комп&#039;ютер (Білий)&quot;;
        drawBoard();
        checkEndGame();
        setTimeout(computerMove, 500);
      } else {
        checkTurn();
      }
    });

    drawBoard();
  &lt;/script&gt;</description>
            </item>
                    <item>
                <title>Мозаїка майстрів 7</title>
                <link>http://margo.mozello.shop/gry/params/post/5141570/mozaka-majstrv-7</link>
                <pubDate>Thu, 02 Oct 2025 14:15:00 +0000</pubDate>
                <description>&lt;span style=&quot;text-align: start; font-weight: 400; font-style: normal&quot;&gt;Права кнопка миші — поворот блоку, Середня кнопка/подвійне торкання — перевертання, Кнопка &quot;Скасувати&quot; — скасування ходу&lt;br&gt;на телефоні поворот блоку інший. Гра поводитися трохи дивно і треба призвичаїтись., але кмітлива дитина розбереться&lt;br&gt;&lt;/span&gt;

&lt;hr class=&quot;moze-more-divider&quot;&gt;&lt;p&gt;2 жовтня 2025&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;Мозаїка Майстрів — Версія 1.9&lt;/title&gt;
    &lt;style&gt;
        body {
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            min-height: 100vh;
            margin: 0;
            padding: 10px;
            background-color: #8A2BE2; /* Фіолетовий фон сторінки */
            font-family: Arial, sans-serif;
            overflow: auto;
        }

        #mainGameContainer {
            display: flex;
            align-items: flex-start;
            justify-content: center;
            gap: 20px;
            margin-top: 20px;
        }

        #gridContainer {
            display: flex;
            flex-direction: column;
            align-items: center;
        }

        #gameCanvas {
            border: 2px solid #333;
            background-color: #98FF98; /* Салатовий фон гри */
            max-width: 100%;
            height: auto;
        }

        #nextBlocks {
            display: flex;
            flex-direction: column;
            justify-content: flex-start;
            margin-top: 0;
            flex-wrap: nowrap;
            width: auto;
            max-width: 100px;
            gap: 10px;
        }

        .blockCanvas {
            border: 1px solid #ccc;
            cursor: grab;
            width: 80px;
            height: 80px;
            margin: 0;
        }

        .blockCanvas.dragging {
            opacity: 0.5;
            cursor: grabbing;
        }

        #score, #highScore {
            font-size: 20px;
            margin-top: 10px;
        }

        #bonusMessage {
            display: none;
            position: fixed;
            top: 20%;
            left: 50%;
            transform: translateX(-50%);
            background-color: rgba(0, 128, 0, 0.8);
            color: white;
            padding: 10px 20px;
            border-radius: 5px;
            z-index: 1000;
            font-size: 18px;
        }

        #gameOver, #pauseOverlay {
            display: none;
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            background-color: rgba(0, 0, 0, 0.8);
            color: white;
            padding: 15px;
            border-radius: 10px;
            text-align: center;
            z-index: 1000;
        }

        button {
            margin-top: 10px;
            padding: 8px 16px;
            font-size: 14px;
            cursor: pointer;
        }

        h2 {
            margin: 10px 0;
        }

        p {
            margin: 5px 0;
        }

        .accordion {
            width: 100%;
            max-width: 500px;
            margin-top: 20px;
        }

        .accordion-item {
            border: 1px solid #333;
            margin-bottom: 5px;
            border-radius: 5px;
        }

        .accordion-header {
            background-color: #ddd;
            padding: 10px;
            cursor: pointer;
            font-size: 18px;
            font-weight: bold;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }

        .accordion-header::after {
            content: &#039;▼&#039;;
            font-size: 14px;
        }

        .accordion-header.active::after {
            content: &#039;▲&#039;;
        }

        .accordion-content {
            display: none;
            padding: 10px;
            background-color: #fff;
        }

        .accordion-content.active {
            display: block;
        }

        .accordion-content table {
            width: 100%;
            border-collapse: collapse;
            margin-bottom: 15px;
        }

        .accordion-content th, .accordion-content td {
            border: 1px solid #333;
            padding: 8px;
            text-align: center;
        }

        .accordion-content th {
            background-color: #ddd;
        }

        .accordion-content pre {
            margin: 0;
            font-size: 12px;
        }

        .accordion-content canvas {
            border: 1px solid #ccc;
        }
    &lt;/style&gt;


    &lt;h2&gt;Мозаїка Майстрів — Версія 1.9&lt;/h2&gt;
    &lt;p&gt;Права кнопка миші — поворот блоку, Середня кнопка/подвійне торкання — перевертання, Кнопка &quot;Скасувати&quot; — скасування ходу&lt;/p&gt;

    &lt;div id=&quot;mainGameContainer&quot;&gt;
        &lt;div id=&quot;gridContainer&quot;&gt;
            &lt;canvas id=&quot;gameCanvas&quot; width=&quot;300&quot; height=&quot;300&quot;&gt;&lt;/canvas&gt;
            &lt;button id=&quot;pauseButton&quot; fdprocessedid=&quot;rcbg5m&quot;&gt;Пауза&lt;/button&gt;
            &lt;button id=&quot;undoButton&quot; disabled=&quot;&quot;&gt;Скасувати&lt;/button&gt;
            &lt;div id=&quot;score&quot;&gt;Очки: 0&lt;/div&gt;
            &lt;div id=&quot;highScore&quot;&gt;Рекорд: 0&lt;/div&gt;
        &lt;/div&gt;
        &lt;div id=&quot;nextBlocks&quot;&gt;
            &lt;canvas id=&quot;block1&quot; class=&quot;blockCanvas&quot; width=&quot;80&quot; height=&quot;80&quot; draggable=&quot;true&quot;&gt;&lt;/canvas&gt;
            &lt;canvas id=&quot;block2&quot; class=&quot;blockCanvas&quot; width=&quot;80&quot; height=&quot;80&quot; draggable=&quot;true&quot;&gt;&lt;/canvas&gt;
            &lt;canvas id=&quot;block3&quot; class=&quot;blockCanvas&quot; width=&quot;80&quot; height=&quot;80&quot; draggable=&quot;true&quot;&gt;&lt;/canvas&gt;
        &lt;/div&gt;
    &lt;/div&gt;

    &lt;div id=&quot;bonusMessage&quot;&gt;&lt;/div&gt;
    &lt;div id=&quot;gameOver&quot;&gt;
        &lt;h2&gt;Гра закінчена!&lt;/h2&gt;
        &lt;p id=&quot;finalScore&quot;&gt;&lt;/p&gt;
        &lt;button onclick=&quot;restartGame()&quot;&gt;Грати знову&lt;/button&gt;
    &lt;/div&gt;
    &lt;div id=&quot;pauseOverlay&quot;&gt;
        &lt;h2&gt;Гра на паузі&lt;/h2&gt;
        &lt;button onclick=&quot;togglePause()&quot;&gt;Відновити&lt;/button&gt;
    &lt;/div&gt;

    &lt;div class=&quot;accordion&quot;&gt;
        &lt;div class=&quot;accordion-item&quot;&gt;
            &lt;div class=&quot;accordion-header&quot; onclick=&quot;toggleAccordion(this)&quot;&gt;Таблиця блоків&lt;/div&gt;
            &lt;div class=&quot;accordion-content&quot;&gt;
                &lt;table&gt;
                    &lt;thead&gt;
                        &lt;tr&gt;
                            &lt;th&gt;Назва&lt;/th&gt;
                            &lt;th&gt;Зображення&lt;/th&gt;
                            &lt;th&gt;Структура&lt;/th&gt;
                            &lt;th&gt;Використання&lt;/th&gt;
                        &lt;/tr&gt;
                    &lt;/thead&gt;
                    &lt;tbody&gt;
                        &lt;tr&gt;
                            &lt;td&gt;Одинарний&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeSingle&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для заповнення окремих клітинок&lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;tr&gt;
                            &lt;td&gt;L-форма&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeL&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1, 1],&lt;br&gt;[1, 0]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для кутів або вузьких просторів&lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;tr&gt;
                            &lt;td&gt;T-форма&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeT&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1, 1, 1],&lt;br&gt;[0, 1, 0]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для горизонтальних ліній з виступом&lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;tr&gt;
                            &lt;td&gt;I-форма (4)&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeI4&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1, 1, 1, 1]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для заповнення рядків/стовпців&lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;tr&gt;
                            &lt;td&gt;Квадрат&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeSquare&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1, 1],&lt;br&gt;[1, 1]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для компактних квадратних просторів&lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;tr&gt;
                            &lt;td&gt;Z-форма&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeZ&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1, 1, 0],&lt;br&gt;[0, 1, 1]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для зміщених &quot;змійок&quot;&lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;tr&gt;
                            &lt;td&gt;I-форма (5)&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeI5&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1, 1, 1, 1, 1]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для довгих рядків/стовпців&lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;tr&gt;
                            &lt;td&gt;I-форма (3)&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeI3&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1, 1, 1]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для середніх рядків/стовпців&lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;tr&gt;
                            &lt;td&gt;I-форма (2)&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeI2&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1, 1]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для коротких рядків/стовпців&lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;tr&gt;
                            &lt;td&gt;Діагональ 2x2&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeDiagonal2&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1, 0],&lt;br&gt;[0, 1]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для заповнення діагональних просторів&lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;tr&gt;
                            &lt;td&gt;Діагональ 3x3&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeDiagonal3&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1, 0, 0],&lt;br&gt;[0, 1, 0],&lt;br&gt;[0, 0, 1]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для довгих діагональних ліній&lt;/td&gt;
                        &lt;/tr&gt;
                    &lt;/tbody&gt;
                &lt;/table&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;accordion-item&quot;&gt;
            &lt;div class=&quot;accordion-header&quot; onclick=&quot;toggleAccordion(this)&quot;&gt;Інструкція&lt;/div&gt;
            &lt;div class=&quot;accordion-content&quot;&gt;
                &lt;h3&gt;Мета гри&lt;/h3&gt;
                &lt;p&gt;&quot;Мозаїка Майстрів&quot; — це головоломка, де гравець розміщує блоки на сітці 10x10, щоб очищати цілі рядки або стовпці. Мета — набрати якомога більше очок і встановити рекорд. Гра закінчується, коли жоден блок не можна розмістити.&lt;/p&gt;
                
                &lt;h3&gt;Правила гри&lt;/h3&gt;
                &lt;ul&gt;
                    &lt;li&gt;&lt;b&gt;Ігрове поле&lt;/b&gt;: Сітка 10x10, де клітинки можуть бути порожніми або заповненими.&lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Черга блоків&lt;/b&gt;: До трьох блоків відображаються справа для розміщення.&lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Розміщення&lt;/b&gt;: Перетягуйте блоки на сітку. Розміщення можливе лише у вільних місцях.&lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Очищення ліній&lt;/b&gt;:
                        &lt;ul&gt;
                            &lt;li&gt;Повний рядок або стовпець очищається.&lt;/li&gt;
                            &lt;li&gt;1 лінія: 100 очок.&lt;/li&gt;
                            &lt;li&gt;2+ ліній: 100 + 50 за кожну додаткову (наприклад, 2 лінії = 150 очок).&lt;/li&gt;
                        &lt;/ul&gt;
                    &lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Бонус за очищення поля&lt;/b&gt;: 25% від суми очок, якщо поле порожнє.&lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Рекорд&lt;/b&gt;: Зберігається у браузері, відображається під час гри та після завершення.&lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Кінець гри&lt;/b&gt;: Гра закінчується, якщо блоки неможливо розмістити.&lt;/li&gt;
                &lt;/ul&gt;

                &lt;h3&gt;Дії гравця&lt;/h3&gt;
                &lt;ul&gt;
                    &lt;li&gt;&lt;b&gt;Перетягування&lt;/b&gt;:
                        &lt;ul&gt;
                            &lt;li&gt;ПК: Лівою кнопкою миші.&lt;/li&gt;
                            &lt;li&gt;Сенсорні пристрої: Торкніться та перетягніть.&lt;/li&gt;
                        &lt;/ul&gt;
                    &lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Поворот&lt;/b&gt;: Права кнопка миші або довге натискання (300мс).&lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Перевертання&lt;/b&gt;:
                        &lt;ul&gt;
                            &lt;li&gt;ПК: Середня кнопка миші або подвійне клацання.&lt;/li&gt;
                            &lt;li&gt;Сенсорні пристрої: Двохпальцевий тап.&lt;/li&gt;
                        &lt;/ul&gt;
                    &lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Скасування ходу&lt;/b&gt;: Кнопка &quot;Скасувати&quot; для останнього ходу.&lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Пауза&lt;/b&gt;: Кнопка &quot;Пауза&quot;/&quot;Відновити&quot;.&lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Перезапуск&lt;/b&gt;: Кнопка &quot;Грати знову&quot; на екрані &quot;Гра закінчена&quot;.&lt;/li&gt;
                &lt;/ul&gt;

                &lt;h3&gt;Поради&lt;/h3&gt;
                &lt;ul&gt;
                    &lt;li&gt;Плануйте ходи, щоб створювати повні лінії.&lt;/li&gt;
                    &lt;li&gt;Використовуйте одинарний блок для прогалин.&lt;/li&gt;
                    &lt;li&gt;Скасовуйте невдалі ходи.&lt;/li&gt;
                    &lt;li&gt;Намагайтеся очищати кілька ліній для бонусів.&lt;/li&gt;
                    &lt;li&gt;Експериментуйте з діагональними блоками для унікальних комбінацій.&lt;/li&gt;
                &lt;/ul&gt;
            &lt;/div&gt;
        &lt;/div&gt;
    &lt;/div&gt;

    &lt;script&gt;
        function toggleAccordion(header) {
            const content = header.nextElementSibling;
            const isActive = content.classList.contains(&#039;active&#039;);
            document.querySelectorAll(&#039;.accordion-content&#039;).forEach(c =&gt; c.classList.remove(&#039;active&#039;));
            document.querySelectorAll(&#039;.accordion-header&#039;).forEach(h =&gt; h.classList.remove(&#039;active&#039;));
            if (!isActive) {
                content.classList.add(&#039;active&#039;);
                header.classList.add(&#039;active&#039;);
            }
        }

        const shapes = {
            single: [[1]],
            l: [[1, 1], [1, 0]],
            t: [[1, 1, 1], [0, 1, 0]],
            i4: [[1, 1, 1, 1]],
            square: [[1, 1], [1, 1]],
            z: [[1, 1, 0], [0, 1, 1]],
            i5: [[1, 1, 1, 1, 1]],
            i3: [[1, 1, 1]],
            i2: [[1, 1]],
            diagonal2: [[1, 0], [0, 1]],
            diagonal3: [[1, 0, 0], [0, 1, 0], [0, 0, 1]]
        };

        const colors = [&#039;#FF0000&#039;, &#039;#FFA500&#039;, &#039;#FFFF00&#039;, &#039;#008000&#039;, &#039;#00CED1&#039;, &#039;#0000FF&#039;, &#039;#800080&#039;]; // Веселка: червоний, оранжевий, жовтий, зелений, блакитний, синій, фіолетовий

        const cellSize = 30;
        const gridSize = 10;

        let grid = Array(gridSize).fill().map(() =&gt; Array(gridSize).fill(null));
        let currentBlocks = [];
        let selectedBlock = null;
        let score = 0;
        let highScore = localStorage.getItem(&#039;blockLegendHighScore&#039;) || 0;
        let gameActive = true;
        let gamePaused = false;
        let lastMove = null;

        const gameCanvas = document.getElementById(&#039;gameCanvas&#039;);
        const ctx = gameCanvas.getContext(&#039;2d&#039;);
        const scoreElement = document.getElementById(&#039;score&#039;);
        const highScoreElement = document.getElementById(&#039;highScore&#039;);
        const bonusMessageElement = document.getElementById(&#039;bonusMessage&#039;);
        const gameOverElement = document.getElementById(&#039;gameOver&#039;);
        const finalScoreElement = document.getElementById(&#039;finalScore&#039;);
        const pauseButton = document.getElementById(&#039;pauseButton&#039;);
        const undoButton = document.getElementById(&#039;undoButton&#039;);
        const pauseOverlay = document.getElementById(&#039;pauseOverlay&#039;);

        highScoreElement.textContent = `Рекорд: ${highScore}`;

        function drawGrid() {
            ctx.clearRect(0, 0, gameCanvas.width, gameCanvas.height);
            for (let y = 0; y &lt; gridSize; y++) {
                for (let x = 0; x &lt; gridSize; x++) {
                    ctx.strokeStyle = &#039;#ddd&#039;;
                    ctx.strokeRect(x * cellSize, y * cellSize, cellSize, cellSize);
                    if (grid[y][x]) {
                        ctx.fillStyle = grid[y][x];
                        ctx.fillRect(x * cellSize, y * cellSize, cellSize, cellSize);
                    }
                }
            }
        }

        function drawPreview(shape, x, y, valid) {
            drawGrid();
            for (let sy = 0; sy &lt; shape.length; sy++) {
                for (let sx = 0; sx &lt; shape[sy].length; sx++) {
                    if (shape[sy][sx]) {
                        ctx.fillStyle = valid ? &#039;rgba(0, 255, 0, 0.5)&#039; : &#039;rgba(255, 0, 0, 0.5)&#039;;
                        ctx.fillRect((x + sx) * cellSize, (y + sy) * cellSize, cellSize, cellSize);
                    }
                }
            }
        }

        function canPlaceBlock(shape, x, y) {
            for (let sy = 0; sy &lt; shape.length; sy++) {
                for (let sx = 0; sx &lt; shape[sy].length; sx++) {
                    if (shape[sy][sx]) {
                        if (x + sx &lt; 0 || x + sx &gt;= gridSize || y + sy &lt; 0 || y + sy &gt;= gridSize || grid[y + sy][x + sx]) {
                            return false;
                        }
                    }
                }
            }
            return true;
        }

        function placeBlock(shape, color, x, y, blockIndex) {
            lastMove = {
                grid: grid.map(row =&gt; [...row]),
                score,
                block: { shape, color },
                blockIndex
            };
            undoButton.disabled = false;
            for (let sy = 0; sy &lt; shape.length; sy++) {
                for (let sx = 0; sx &lt; shape[sy].length; sx++) {
                    if (shape[sy][sx]) {
                        grid[y + sy][x + sx] = color;
                    }
                }
            }
            drawGrid();
            checkLines();
        }

        function rotateShape(shape) {
            return shape[0].map((_, col) =&gt; shape.map(row =&gt; row[col]).reverse());
        }

        function flipShape(shape) {
            return shape.map(row =&gt; row.reverse());
        }

        function generateBlock() {
            const shapeKeys = Object.keys(shapes);
            const randomShapeKey = shapeKeys[Math.floor(Math.random() * shapeKeys.length)];
            const shape = shapes[randomShapeKey];
            const color = colors[Math.floor(Math.random() * colors.length)];
            return { shape, color };
        }

        function generateBlocks() {
            while (currentBlocks.length &lt; 3) {
                currentBlocks.push(generateBlock());
            }
            for (let i = 0; i &lt; 3; i++) {
                drawBlock(i, currentBlocks[i].shape, currentBlocks[i].color);
            }
        }

        function drawBlock(index, shape, color) {
            const blockCanvas = document.getElementById(`block${index + 1}`);
            const bctx = blockCanvas.getContext(&#039;2d&#039;);
            bctx.clearRect(0, 0, blockCanvas.width, blockCanvas.height);
            const blockSize = 20;
            const offsetX = (blockCanvas.width - shape[0].length * blockSize) / 2;
            const offsetY = (blockCanvas.height - shape.length * blockSize) / 2;
            const gradient = bctx.createLinearGradient(0, 0, 0, blockSize * shape.length);
            gradient.addColorStop(0, color);
            gradient.addColorStop(1, lightenColor(color, 0.3)); // Світлий градієнт для огранки
            for (let sy = 0; sy &lt; shape.length; sy++) {
                for (let sx = 0; sx &lt; shape[sy].length; sx++) {
                    if (shape[sy][sx]) {
                        bctx.fillStyle = gradient;
                        bctx.fillRect(offsetX + sx * blockSize, offsetY + sy * blockSize, blockSize, blockSize);
                        bctx.strokeStyle = lightenColor(color, 0.6); // Світлий контур
                        bctx.lineWidth = 2;
                        bctx.strokeRect(offsetX + sx * blockSize, offsetY + sy * blockSize, blockSize, blockSize);
                    }
                }
            }
        }

        // Функція для освітлення кольору
        function lightenColor(color, percent) {
            const num = parseInt(color.replace(&quot;#&quot;, &quot;&quot;), 16);
            const r = Math.min(255, Math.floor((num &gt;&gt; 16) * (1 + percent)));
            const g = Math.min(255, Math.floor(((num &gt;&gt; 8) &amp; 0x00FF) * (1 + percent)));
            const b = Math.min(255, Math.floor((num &amp; 0x0000FF) * (1 + percent)));
            return `#${(r &lt;&lt; 16 | g &lt;&lt; 8 | b).toString(16).padStart(6, &#039;0&#039;)}`;
        }

        function drawShapePreview(id, shape, color) {
            const canvas = document.getElementById(id);
            const ctx = canvas.getContext(&#039;2d&#039;);
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            const blockSize = 15;
            const offsetX = (canvas.width - shape[0].length * blockSize) / 2;
            const offsetY = (canvas.height - shape.length * blockSize) / 2;
            const gradient = ctx.createLinearGradient(0, 0, 0, blockSize * shape.length);
            gradient.addColorStop(0, color);
            gradient.addColorStop(1, lightenColor(color, 0.3));
            for (let sy = 0; sy &lt; shape.length; sy++) {
                for (let sx = 0; sx &lt; shape[sy].length; sx++) {
                    if (shape[sy][sx]) {
                        ctx.fillStyle = gradient;
                        ctx.fillRect(offsetX + sx * blockSize, offsetY + sy * blockSize, blockSize, blockSize);
                        ctx.strokeStyle = lightenColor(color, 0.6);
                        ctx.lineWidth = 1;
                        ctx.strokeRect(offsetX + sx * blockSize, offsetY + sy * blockSize, blockSize, blockSize);
                    }
                }
            }
        }

        function showBonusMessage(message) {
            bonusMessageElement.textContent = message;
            bonusMessageElement.style.display = &#039;block&#039;;
            setTimeout(() =&gt; {
                bonusMessageElement.style.display = &#039;none&#039;;
            }, 2000);
        }

        function checkLines() {
            let linesCleared = 0;
            for (let i = 0; i &lt; gridSize; i++) {
                if (grid[i].every(cell =&gt; cell)) {
                    grid[i] = Array(gridSize).fill(null);
                    linesCleared++;
                }
                let colFull = true;
                for (let j = 0; j &lt; gridSize; j++) {
                    if (!grid[j][i]) {
                        colFull = false;
                        break;
                    }
                }
                if (colFull) {
                    for (let j = 0; j &lt; gridSize; j++) {
                        grid[j][i] = null;
                    }
                    linesCleared++;
                }
            }
            if (linesCleared &gt; 0) {
                let lineBonus = linesCleared === 1 ? 100 : 100 + (linesCleared - 1) * 50;
                score += lineBonus;
                if (linesCleared &gt; 1) {
                    showBonusMessage(`Бонус за ${linesCleared} лінії: +${lineBonus} очок`);
                }
                const isGridEmpty = grid.every(row =&gt; row.every(cell =&gt; !cell));
                if (isGridEmpty &amp;&amp; score &gt; 0) {
                    const clearBonus = Math.floor(score * 0.25);
                    score += clearBonus;
                    showBonusMessage(`Бонус за повне очищення поля: +${clearBonus} очок`);
                }
                scoreElement.textContent = `Очки: ${score}`;
                if (score &gt; highScore) {
                    highScore = score;
                    localStorage.setItem(&#039;blockLegendHighScore&#039;, highScore);
                    highScoreElement.textContent = `Рекорд: ${highScore}`;
                }
            }
            drawGrid();
            checkGameOver();
        }

        function checkGameOver() {
            console.log(&#039;Перевірка стану гри. Кількість блоків:&#039;, currentBlocks.length, &#039;Блоки:&#039;, JSON.stringify(currentBlocks.map(b =&gt; ({ shape: b.shape, color: b.color }))));
            if (currentBlocks.length === 0) {
                console.log(&#039;Черга порожня, генеруємо нові блоки&#039;);
                setTimeout(() =&gt; {
                    generateBlocks();
                    console.log(&#039;Нові блоки згенеровано, нова черга:&#039;, JSON.stringify(currentBlocks.map(b =&gt; ({ shape: b.shape, color: b.color }))));
                }, 0);
                return;
            }
            let canPlaceAny = false;
            for (let block of currentBlocks) {
                for (let y = 0; y &lt; gridSize; y++) {
                    for (let x = 0; x &lt; gridSize; x++) {
                        if (canPlaceBlock(block.shape, x, y)) {
                            canPlaceAny = true;
                            break;
                        }
                    }
                    if (canPlaceAny) break;
                }
                if (canPlaceAny) break;
            }
            console.log(&#039;Чи можна розмістити блок:&#039;, canPlaceAny);
            if (!canPlaceAny) {
                gameActive = false;
                if (score &gt; highScore) {
                    highScore = score;
                    localStorage.setItem(&#039;blockLegendHighScore&#039;, highScore);
                    console.log(&#039;Новий рекорд на кінці гри:&#039;, highScore);
                }
                finalScoreElement.textContent = `Ваш рахунок: ${score}\nРекорд: ${highScore}`;
                gameOverElement.style.display = &#039;block&#039;;
                console.log(&#039;Гра закінчена. Рахунок:&#039;, score, &#039;Рекорд:&#039;, highScore);
            }
        }

        function restartGame() {
            grid = Array(gridSize).fill().map(() =&gt; Array(gridSize).fill(null));
            score = 0;
            scoreElement.textContent = `Очки: ${score}`;
            highScoreElement.textContent = `Рекорд: ${highScore}`;
            gameOverElement.style.display = &#039;none&#039;;
            gamePaused = false;
            pauseButton.textContent = &#039;Пауза&#039;;
            pauseOverlay.style.display = &#039;none&#039;;
            undoButton.disabled = true;
            lastMove = null;
            gameActive = true;
            currentBlocks = [];
            generateBlocks();
            drawGrid();
            console.log(&#039;Гра перезапущена. Рахунок:&#039;, score, &#039;Рекорд:&#039;, highScore);
        }

        function undoMove() {
            if (!lastMove || !gameActive || gamePaused) return;
            grid = lastMove.grid.map(row =&gt; [...row]);
            score = lastMove.score;
            currentBlocks.splice(lastMove.blockIndex, 0, lastMove.block);
            scoreElement.textContent = `Очки: ${score}`;
            undoButton.disabled = true;
            lastMove = null;
            for (let i = 0; i &lt; 3; i++) {
                const blockCanvas = document.getElementById(`block${i + 1}`);
                blockCanvas.getContext(&#039;2d&#039;).clearRect(0, 0, blockCanvas.width, blockCanvas.height);
                if (i &lt; currentBlocks.length) {
                    drawBlock(i, currentBlocks[i].shape, currentBlocks[i].color);
                }
            }
            drawGrid();
            console.log(&#039;Хід скасовано. Поточна черга:&#039;, JSON.stringify(currentBlocks.map(b =&gt; ({ shape: b.shape, color: b.color }))));
        }

        function togglePause() {
            if (!gameActive) return;
            gamePaused = !gamePaused;
            pauseButton.textContent = gamePaused ? &#039;Відновити&#039; : &#039;Пауза&#039;;
            pauseOverlay.style.display = gamePaused ? &#039;block&#039; : &#039;none&#039;;
            console.log(&#039;Гра на паузі:&#039;, gamePaused);
        }

        pauseButton.addEventListener(&#039;click&#039;, togglePause);
        undoButton.addEventListener(&#039;click&#039;, undoMove);

        let touchStartX = 0;
        let touchStartY = 0;
        const blockCanvases = document.querySelectorAll(&#039;.blockCanvas&#039;);
        blockCanvases.forEach(canvas =&gt; {
            canvas.addEventListener(&#039;dragstart&#039;, (e) =&gt; {
                if (!gameActive || gamePaused) return;
                const index = parseInt(canvas.id.replace(&#039;block&#039;, &#039;&#039;)) - 1;
                selectedBlock = currentBlocks[index];
                canvas.classList.add(&#039;dragging&#039;);
                e.dataTransfer.setData(&#039;text/plain&#039;, index);
                console.log(&#039;Початок перетягування блоку:&#039;, index, &#039;Блок:&#039;, JSON.stringify(selectedBlock));
            });

            canvas.addEventListener(&#039;dragend&#039;, (e) =&gt; {
                canvas.classList.remove(&#039;dragging&#039;);
                drawGrid();
                console.log(&#039;Кінець перетягування&#039;);
            });

            canvas.addEventListener(&#039;contextmenu&#039;, (e) =&gt; {
                e.preventDefault();
                if (!gameActive || gamePaused) return;
                const index = parseInt(canvas.id.replace(&#039;block&#039;, &#039;&#039;)) - 1;
                currentBlocks[index].shape = rotateShape(currentBlocks[index].shape);
                drawBlock(index, currentBlocks[index].shape, currentBlocks[index].color);
                console.log(&#039;Блок повернуто:&#039;, index, &#039;Нова форма:&#039;, JSON.stringify(currentBlocks[index].shape));
            });

            canvas.addEventListener(&#039;mousedown&#039;, (e) =&gt; {
                if (e.button === 1) {
                    e.preventDefault();
                    if (!gameActive || gamePaused) return;
                    const index = parseInt(canvas.id.replace(&#039;block&#039;, &#039;&#039;)) - 1;
                    currentBlocks[index].shape = flipShape(currentBlocks[index].shape);
                    drawBlock(index, currentBlocks[index].shape, currentBlocks[index].color);
                    console.log(&#039;Блок перевернуто (середня кнопка):&#039;, index, &#039;Нова форма:&#039;, JSON.stringify(currentBlocks[index].shape));
                }
            });

            canvas.addEventListener(&#039;dblclick&#039;, (e) =&gt; {
                e.preventDefault();
                if (!gameActive || gamePaused) return;
                const index = parseInt(canvas.id.replace(&#039;block&#039;, &#039;&#039;)) - 1;
                if (index &gt;= 0 &amp;&amp; index &lt; currentBlocks.length) {
                    currentBlocks[index].shape = flipShape(currentBlocks[index].shape);
                    drawBlock(index, currentBlocks[index].shape, currentBlocks[index].color);
                    console.log(&#039;Блок перевернуто (подвійне клацання):&#039;, index, &#039;Нова форма:&#039;, JSON.stringify(currentBlocks[index].shape));
                }
            });

            canvas.addEventListener(&#039;touchstart&#039;, (e) =&gt; {
                if (!gameActive || gamePaused) return;
                const index = parseInt(canvas.id.replace(&#039;block&#039;, &#039;&#039;)) - 1;
                if (index &gt;= 0 &amp;&amp; index &lt; currentBlocks.length) {
                    selectedBlock = currentBlocks[index];
                    canvas.classList.add(&#039;dragging&#039;);

                    // Record initial touch position for movement tolerance
                    const touch = e.touches[0];
                    touchStartX = touch.clientX;
                    touchStartY = touch.clientY;

                    // Two-finger tap detection for flipping
                    if (e.touches.length === 2) {
                        const touch1 = e.touches[0];
                        const touch2 = e.touches[1];
                        const moveTolerance = 10; // Pixels of movement allowed
                        const dx1 = Math.abs(touch1.clientX - touchStartX);
                        const dy1 = Math.abs(touch1.clientY - touchStartY);
                        const dx2 = Math.abs(touch2.clientX - touchStartX);
                        const dy2 = Math.abs(touch2.clientY - touchStartY);
                        if (dx1 &lt; moveTolerance &amp;&amp; dy1 &lt; moveTolerance &amp;&amp; dx2 &lt; moveTolerance &amp;&amp; dy2 &lt; moveTolerance) {
                            currentBlocks[index].shape = flipShape(currentBlocks[index].shape);
                            drawBlock(index, currentBlocks[index].shape, currentBlocks[index].color);
                            console.log(&#039;Блок перевернуто (двохпальцевий тап):&#039;, index, &#039;Нова форма:&#039;, JSON.stringify(currentBlocks[index].shape));
                            e.preventDefault(); // Prevent default behavior (e.g., zoom)
                        }
                        return; // Exit early to avoid long-press interference
                    }

                    // Long-press detection for rotation
                    let touchStartTime = Date.now();
                    const touchHoldTimeout = setTimeout(() =&gt; {
                        if (Date.now() - touchStartTime &gt;= 300 &amp;&amp; e.touches.length === 1) { // Reduced to 300ms
                            currentBlocks[index].shape = rotateShape(currentBlocks[index].shape);
                            drawBlock(index, currentBlocks[index].shape, currentBlocks[index].color);
                            console.log(&#039;Блок повернуто (довге натискання):&#039;, index, &#039;Нова форма:&#039;, JSON.stringify(currentBlocks[index].shape));
                        }
                    }, 300);

                    // Cancel timeout on touchend or touchmove
                    const touchEndOrMove = (event) =&gt; {
                        const currentTouch = event.touches[0] || event.changedTouches[0];
                        const dx = Math.abs(currentTouch.clientX - touchStartX);
                        const dy = Math.abs(currentTouch.clientY - touchStartY);
                        if (dx &gt; 10 || dy &gt; 10) { // Cancel if significant movement
                            clearTimeout(touchHoldTimeout);
                        }
                    };
                    canvas.addEventListener(&#039;touchend&#039;, touchEndOrMove, { once: true });
                    canvas.addEventListener(&#039;touchmove&#039;, touchEndOrMove, { once: true });

                    console.log(&#039;Початок сенсорного перетягування блоку:&#039;, index, &#039;Блок:&#039;, JSON.stringify(selectedBlock));
                } else {
                    console.error(&#039;Помилка: невалідний індекс блоку на touchstart&#039;, index);
                }
            });

            canvas.addEventListener(&#039;touchmove&#039;, (e) =&gt; {
                e.preventDefault();
                if (!gameActive || !selectedBlock || gamePaused) return;
                const touch = e.touches[0];
                const rect = gameCanvas.getBoundingClientRect();
                const x = Math.floor((touch.clientX - rect.left) / cellSize);
                const y = Math.floor((touch.clientY - rect.top) / cellSize);
                const valid = canPlaceBlock(selectedBlock.shape, x, y);
                drawPreview(selectedBlock.shape, x, y, valid);
            });

            canvas.addEventListener(&#039;touchend&#039;, (e) =&gt; {
                if (!gameActive || !selectedBlock || gamePaused) return;
                const touch = e.changedTouches[0];
                const rect = gameCanvas.getBoundingClientRect();
                const x = Math.floor((touch.clientX - rect.left) / cellSize);
                const y = Math.floor((touch.clientY - rect.top) / cellSize);
                const index = parseInt(canvas.id.replace(&#039;block&#039;, &#039;&#039;)) - 1;
                console.log(`Сенсорне розміщення: координати (${x}, ${y}), індекс: ${index}, блок:`, JSON.stringify(selectedBlock));
                if (index &gt;= 0 &amp;&amp; index &lt; currentBlocks.length) {
                    if (canPlaceBlock(selectedBlock.shape, x, y)) {
                        placeBlock(selectedBlock.shape, selectedBlock.color, x, y, index);
                        currentBlocks.splice(index, 1);
                        console.log(&#039;Блок видалено з черги. Залишилося:&#039;, currentBlocks.length, &#039;Блоки:&#039;, JSON.stringify(currentBlocks.map(b =&gt; ({ shape: b.shape, color: b.color }))));
                        for (let i = 0; i &lt; 3; i++) {
                            const blockCanvas = document.getElementById(`block${i + 1}`);
                            blockCanvas.getContext(&#039;2d&#039;).clearRect(0, 0, blockCanvas.width, blockCanvas.height);
                            if (i &lt; currentBlocks.length) {
                                drawBlock(i, currentBlocks[i].shape, currentBlocks[i].color);
                            }
                        }
                        checkGameOver();
                        selectedBlock = null;
                    } else {
                        console.log(&#039;Неможливо розмістити блок на позиції:&#039;, x, y);
                    }
                } else {
                    console.error(&#039;Помилка: невалідний індекс блоку на touchend&#039;, index);
                }
                canvas.classList.remove(&#039;dragging&#039;);
                drawGrid();
                console.log(&#039;Сенсорне розміщення завершено&#039;);
            });
        });

        gameCanvas.addEventListener(&#039;dragover&#039;, (e) =&gt; {
            e.preventDefault();
            if (!gameActive || !selectedBlock || gamePaused) return;
            const rect = gameCanvas.getBoundingClientRect();
            const x = Math.floor((e.clientX - rect.left) / cellSize);
            const y = Math.floor((e.clientY - rect.top) / cellSize);
            const valid = canPlaceBlock(selectedBlock.shape, x, y);
            drawPreview(selectedBlock.shape, x, y, valid);
        });

        gameCanvas.addEventListener(&#039;drop&#039;, (e) =&gt; {
            e.preventDefault();
            if (!gameActive || !selectedBlock || gamePaused) return;
            const rect = gameCanvas.getBoundingClientRect();
            const x = Math.floor((e.clientX - rect.left) / cellSize);
            const y = Math.floor((e.clientY - rect.top) / cellSize);
            const index = parseInt(e.dataTransfer.getData(&#039;text/plain&#039;));
            console.log(`Розміщення через drag: координати (${x}, ${y}), індекс: ${index}, блок:`, JSON.stringify(selectedBlock));
            if (index &gt;= 0 &amp;&amp; index &lt; currentBlocks.length) {
                if (canPlaceBlock(selectedBlock.shape, x, y)) {
                    placeBlock(selectedBlock.shape, selectedBlock.color, x, y, index);
                    currentBlocks.splice(index, 1);
                    console.log(&#039;Блок видалено з черги. Залишилося:&#039;, currentBlocks.length, &#039;Блоки:&#039;, JSON.stringify(currentBlocks.map(b =&gt; ({ shape: b.shape, color: b.color }))));
                    for (let i = 0; i &lt; 3; i++) {
                        const blockCanvas = document.getElementById(`block${i + 1}`);
                        blockCanvas.getContext(&#039;2d&#039;).clearRect(0, 0, blockCanvas.width, blockCanvas.height);
                        if (i &lt; currentBlocks.length) {
                            drawBlock(i, currentBlocks[i].shape, currentBlocks[i].color);
                        }
                    }
                    checkGameOver();
                    selectedBlock = null;
                } else {
                    console.log(&#039;Неможливо розмістити блок на позиції:&#039;, x, y);
                }
            } else {
                console.error(&#039;Помилка: невалідний індекс блоку на drop&#039;, index);
            }
            drawGrid();
        });

        // Ініціалізація попередніх зображень блоків
        drawShapePreview(&#039;shapeSingle&#039;, shapes.single, colors[0]);
        drawShapePreview(&#039;shapeL&#039;, shapes.l, colors[1]);
        drawShapePreview(&#039;shapeT&#039;, shapes.t, colors[2]);
        drawShapePreview(&#039;shapeI4&#039;, shapes.i4, colors[3]);
        drawShapePreview(&#039;shapeSquare&#039;, shapes.square, colors[4]);
        drawShapePreview(&#039;shapeZ&#039;, shapes.z, colors[5]);
        drawShapePreview(&#039;shapeI5&#039;, shapes.i5, colors[0]);
        drawShapePreview(&#039;shapeI3&#039;, shapes.i3, colors[1]);
        drawShapePreview(&#039;shapeI2&#039;, shapes.i2, colors[2]);
        drawShapePreview(&#039;shapeDiagonal2&#039;, shapes.diagonal2, colors[3]);
        drawShapePreview(&#039;shapeDiagonal3&#039;, shapes.diagonal3, colors[4]);

        generateBlocks();
        drawGrid();
        console.log(&#039;Гра ініціалізована — Мозаїка Майстрів Версія 1.9&#039;);
    &lt;/script&gt;</description>
            </item>
                    <item>
                <title>мм6</title>
                <link>http://margo.mozello.shop/gry/params/post/5141394/mm6</link>
                <pubDate>Thu, 02 Oct 2025 10:30:00 +0000</pubDate>
                <description>рррррррррррррррррррррр&lt;hr class=&quot;moze-more-divider&quot;&gt;&lt;p&gt;6&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;Мозаїка Майстрів — Версія 1.9&lt;/title&gt;
    &lt;style&gt;
        body {
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            min-height: 100vh;
            margin: 0;
            padding: 10px;
            background-color: #f0f0f0;
            font-family: Arial, sans-serif;
            overflow: auto;
        }

        #mainGameContainer {
            display: flex;
            align-items: flex-start;
            justify-content: center;
            gap: 20px;
            margin-top: 20px;
        }

        #gridContainer {
            display: flex;
            flex-direction: column;
            align-items: center;
        }

        #gameCanvas {
            border: 2px solid #333;
            background-color: #e3f1c6;
            max-width: 100%;
            height: auto;
        }

        #nextBlocks {
            display: flex;
            flex-direction: column;
            justify-content: flex-start;
            margin-top: 0;
            flex-wrap: nowrap;
            width: auto;
            max-width: 100px;
            gap: 10px;
        }

        .blockCanvas {
            border: 1px solid #ccc;
            cursor: grab;
            width: 80px;
            height: 80px;
            margin: 0;
        }

        .blockCanvas.dragging {
            opacity: 0.5;
            cursor: grabbing;
        }

        #score, #highScore {
            font-size: 20px;
            margin-top: 10px;
        }

        #bonusMessage {
            display: none;
            position: fixed;
            top: 20%;
            left: 50%;
            transform: translateX(-50%);
            background-color: rgba(0, 128, 0, 0.8);
            color: white;
            padding: 10px 20px;
            border-radius: 5px;
            z-index: 1000;
            font-size: 18px;
        }

        #gameOver, #pauseOverlay {
            display: none;
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            background-color: rgba(0, 0, 0, 0.8);
            color: white;
            padding: 15px;
            border-radius: 10px;
            text-align: center;
            z-index: 1000;
        }

        button {
            margin-top: 10px;
            padding: 8px 16px;
            font-size: 14px;
            cursor: pointer;
        }

        h2 {
            margin: 10px 0;
        }

        p {
            margin: 5px 0;
        }

        .accordion {
            width: 100%;
            max-width: 500px;
            margin-top: 20px;
        }

        .accordion-item {
            border: 1px solid #333;
            margin-bottom: 5px;
            border-radius: 5px;
        }

        .accordion-header {
            background-color: #ddd;
            padding: 10px;
            cursor: pointer;
            font-size: 18px;
            font-weight: bold;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }

        .accordion-header::after {
            content: &#039;▼&#039;;
            font-size: 14px;
        }

        .accordion-header.active::after {
            content: &#039;▲&#039;;
        }

        .accordion-content {
            display: none;
            padding: 10px;
            background-color: #fff;
        }

        .accordion-content.active {
            display: block;
        }

        .accordion-content table {
            width: 100%;
            border-collapse: collapse;
            margin-bottom: 15px;
        }

        .accordion-content th, .accordion-content td {
            border: 1px solid #333;
            padding: 8px;
            text-align: center;
        }

        .accordion-content th {
            background-color: #ddd;
        }

        .accordion-content pre {
            margin: 0;
            font-size: 12px;
        }

        .accordion-content canvas {
            border: 1px solid #ccc;
        }
    &lt;/style&gt;


    &lt;h2&gt;Мозаїка Майстрів — Версія 1.9&lt;/h2&gt;
    &lt;p&gt;Права кнопка миші — поворот блоку, Середня кнопка/подвійне торкання — перевертання, Кнопка &quot;Скасувати&quot; — скасування ходу&lt;/p&gt;

    &lt;div id=&quot;mainGameContainer&quot;&gt;
        &lt;div id=&quot;gridContainer&quot;&gt;
            &lt;canvas id=&quot;gameCanvas&quot; width=&quot;300&quot; height=&quot;300&quot;&gt;&lt;/canvas&gt;
            &lt;button id=&quot;pauseButton&quot; fdprocessedid=&quot;62619d&quot;&gt;Пауза&lt;/button&gt;
            &lt;button id=&quot;undoButton&quot; disabled=&quot;&quot;&gt;Скасувати&lt;/button&gt;
            &lt;div id=&quot;score&quot;&gt;Очки: 0&lt;/div&gt;
            &lt;div id=&quot;highScore&quot;&gt;Рекорд: 0&lt;/div&gt;
        &lt;/div&gt;
        &lt;div id=&quot;nextBlocks&quot;&gt;
            &lt;canvas id=&quot;block1&quot; class=&quot;blockCanvas&quot; width=&quot;80&quot; height=&quot;80&quot; draggable=&quot;true&quot;&gt;&lt;/canvas&gt;
            &lt;canvas id=&quot;block2&quot; class=&quot;blockCanvas&quot; width=&quot;80&quot; height=&quot;80&quot; draggable=&quot;true&quot;&gt;&lt;/canvas&gt;
            &lt;canvas id=&quot;block3&quot; class=&quot;blockCanvas&quot; width=&quot;80&quot; height=&quot;80&quot; draggable=&quot;true&quot;&gt;&lt;/canvas&gt;
        &lt;/div&gt;
    &lt;/div&gt;

    &lt;div id=&quot;bonusMessage&quot;&gt;&lt;/div&gt;
    &lt;div id=&quot;gameOver&quot;&gt;
        &lt;h2&gt;Гра закінчена!&lt;/h2&gt;
        &lt;p id=&quot;finalScore&quot;&gt;&lt;/p&gt;
        &lt;button onclick=&quot;restartGame()&quot;&gt;Грати знову&lt;/button&gt;
    &lt;/div&gt;
    &lt;div id=&quot;pauseOverlay&quot;&gt;
        &lt;h2&gt;Гра на паузі&lt;/h2&gt;
        &lt;button onclick=&quot;togglePause()&quot;&gt;Відновити&lt;/button&gt;
    &lt;/div&gt;

    &lt;div class=&quot;accordion&quot;&gt;
        &lt;div class=&quot;accordion-item&quot;&gt;
            &lt;div class=&quot;accordion-header&quot; onclick=&quot;toggleAccordion(this)&quot;&gt;Таблиця блоків&lt;/div&gt;
            &lt;div class=&quot;accordion-content&quot;&gt;
                &lt;table&gt;
                    &lt;thead&gt;
                        &lt;tr&gt;
                            &lt;th&gt;Назва&lt;/th&gt;
                            &lt;th&gt;Зображення&lt;/th&gt;
                            &lt;th&gt;Структура&lt;/th&gt;
                            &lt;th&gt;Використання&lt;/th&gt;
                        &lt;/tr&gt;
                    &lt;/thead&gt;
                    &lt;tbody&gt;
                        &lt;tr&gt;
                            &lt;td&gt;Одинарний&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeSingle&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для заповнення окремих клітинок&lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;tr&gt;
                            &lt;td&gt;L-форма&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeL&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1, 1],&lt;br&gt;[1, 0]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для кутів або вузьких просторів&lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;tr&gt;
                            &lt;td&gt;T-форма&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeT&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1, 1, 1],&lt;br&gt;[0, 1, 0]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для горизонтальних ліній з виступом&lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;tr&gt;
                            &lt;td&gt;I-форма (4)&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeI4&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1, 1, 1, 1]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для заповнення рядків/стовпців&lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;tr&gt;
                            &lt;td&gt;Квадрат&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeSquare&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1, 1],&lt;br&gt;[1, 1]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для компактних квадратних просторів&lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;tr&gt;
                            &lt;td&gt;Z-форма&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeZ&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1, 1, 0],&lt;br&gt;[0, 1, 1]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для зміщених &quot;змійок&quot;&lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;tr&gt;
                            &lt;td&gt;I-форма (5)&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeI5&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1, 1, 1, 1, 1]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для довгих рядків/стовпців&lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;tr&gt;
                            &lt;td&gt;I-форма (3)&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeI3&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1, 1, 1]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для середніх рядків/стовпців&lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;tr&gt;
                            &lt;td&gt;I-форма (2)&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeI2&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1, 1]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для коротких рядків/стовпців&lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;tr&gt;
                            &lt;td&gt;Діагональ 2x2&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeDiagonal2&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1, 0],&lt;br&gt;[0, 1]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для заповнення діагональних просторів&lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;tr&gt;
                            &lt;td&gt;Діагональ 3x3&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeDiagonal3&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1, 0, 0],&lt;br&gt;[0, 1, 0],&lt;br&gt;[0, 0, 1]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для довгих діагональних ліній&lt;/td&gt;
                        &lt;/tr&gt;
                    &lt;/tbody&gt;
                &lt;/table&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;accordion-item&quot;&gt;
            &lt;div class=&quot;accordion-header&quot; onclick=&quot;toggleAccordion(this)&quot;&gt;Інструкція&lt;/div&gt;
            &lt;div class=&quot;accordion-content&quot;&gt;
                &lt;h3&gt;Мета гри&lt;/h3&gt;
                &lt;p&gt;&quot;Мозаїка Майстрів&quot; — це головоломка, де гравець розміщує блоки на сітці 10x10, щоб очищати цілі рядки або стовпці. Мета — набрати якомога більше очок і встановити рекорд. Гра закінчується, коли жоден блок не можна розмістити.&lt;/p&gt;
                
                &lt;h3&gt;Правила гри&lt;/h3&gt;
                &lt;ul&gt;
                    &lt;li&gt;&lt;b&gt;Ігрове поле&lt;/b&gt;: Сітка 10x10, де клітинки можуть бути порожніми або заповненими.&lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Черга блоків&lt;/b&gt;: До трьох блоків відображаються справа для розміщення.&lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Розміщення&lt;/b&gt;: Перетягуйте блоки на сітку. Розміщення можливе лише у вільних місцях.&lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Очищення ліній&lt;/b&gt;:
                        &lt;ul&gt;
                            &lt;li&gt;Повний рядок або стовпець очищається.&lt;/li&gt;
                            &lt;li&gt;1 лінія: 100 очок.&lt;/li&gt;
                            &lt;li&gt;2+ ліній: 100 + 50 за кожну додаткову (наприклад, 2 лінії = 150 очок).&lt;/li&gt;
                        &lt;/ul&gt;
                    &lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Бонус за очищення поля&lt;/b&gt;: 25% від суми очок, якщо поле порожнє.&lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Рекорд&lt;/b&gt;: Зберігається у браузері, відображається під час гри та після завершення.&lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Кінець гри&lt;/b&gt;: Гра закінчується, якщо блоки неможливо розмістити.&lt;/li&gt;
                &lt;/ul&gt;

                &lt;h3&gt;Дії гравця&lt;/h3&gt;
                &lt;ul&gt;
                    &lt;li&gt;&lt;b&gt;Перетягування&lt;/b&gt;:
                        &lt;ul&gt;
                            &lt;li&gt;ПК: Лівою кнопкою миші.&lt;/li&gt;
                            &lt;li&gt;Сенсорні пристрої: Торкніться та перетягніть.&lt;/li&gt;
                        &lt;/ul&gt;
                    &lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Поворот&lt;/b&gt;: Права кнопка миші або довге натискання (300мс).&lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Перевертання&lt;/b&gt;:
                        &lt;ul&gt;
                            &lt;li&gt;ПК: Середня кнопка миші або подвійне клацання.&lt;/li&gt;
                            &lt;li&gt;Сенсорні пристрої: Двохпальцевий тап.&lt;/li&gt;
                        &lt;/ul&gt;
                    &lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Скасування ходу&lt;/b&gt;: Кнопка &quot;Скасувати&quot; для останнього ходу.&lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Пауза&lt;/b&gt;: Кнопка &quot;Пауза&quot;/&quot;Відновити&quot;.&lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Перезапуск&lt;/b&gt;: Кнопка &quot;Грати знову&quot; на екрані &quot;Гра закінчена&quot;.&lt;/li&gt;
                &lt;/ul&gt;

                &lt;h3&gt;Поради&lt;/h3&gt;
                &lt;ul&gt;
                    &lt;li&gt;Плануйте ходи, щоб створювати повні лінії.&lt;/li&gt;
                    &lt;li&gt;Використовуйте одинарний блок для прогалин.&lt;/li&gt;
                    &lt;li&gt;Скасовуйте невдалі ходи.&lt;/li&gt;
                    &lt;li&gt;Намагайтеся очищати кілька ліній для бонусів.&lt;/li&gt;
                    &lt;li&gt;Експериментуйте з діагональними блоками для унікальних комбінацій.&lt;/li&gt;
                &lt;/ul&gt;
            &lt;/div&gt;
        &lt;/div&gt;
    &lt;/div&gt;

    &lt;script&gt;
        // Акордеон-меню
        function toggleAccordion(header) {
            const content = header.nextElementSibling;
            const isActive = content.classList.contains(&#039;active&#039;);
            document.querySelectorAll(&#039;.accordion-content&#039;).forEach(item =&gt; {
                item.classList.remove(&#039;active&#039;);
                item.previousElementSibling.classList.remove(&#039;active&#039;);
            });
            if (!isActive) {
                content.classList.add(&#039;active&#039;);
                header.classList.add(&#039;active&#039;);
            }
        }

        // Ігрова логіка
        const gameCanvas = document.getElementById(&#039;gameCanvas&#039;);
        const ctx = gameCanvas.getContext(&#039;2d&#039;);
        const gridSize = 10;
        const cellSize = gameCanvas.width / gridSize;
        const scoreElement = document.getElementById(&#039;score&#039;);
        const highScoreElement = document.getElementById(&#039;highScore&#039;);
        const bonusMessageElement = document.getElementById(&#039;bonusMessage&#039;);
        const gameOverElement = document.getElementById(&#039;gameOver&#039;);
        const finalScoreElement = document.getElementById(&#039;finalScore&#039;);
        const pauseButton = document.getElementById(&#039;pauseButton&#039;);
        const undoButton = document.getElementById(&#039;undoButton&#039;);
        const pauseOverlay = document.getElementById(&#039;pauseOverlay&#039;);

        let grid = Array(gridSize).fill().map(() =&gt; Array(gridSize).fill(null));
        let score = 0;
        let highScore = parseInt(localStorage.getItem(&#039;blockLegendHighScore&#039;)) || 0;
        let currentBlocks = [];
        let selectedBlock = null;
        let gameActive = true;
        let gamePaused = false;
        let lastMove = null;

        highScoreElement.textContent = `Рекорд: ${highScore}`;
        console.log(&#039;Завантажено рекорд:&#039;, highScore);

        const blockShapes = [
            [[1]], // Одинарний (1x1)
            [[1]], // Одинарний (збільшена ймовірність)
            [[1, 1], [1, 0]], // L-форма
            [[1, 1, 1], [0, 1, 0]], // T-форма
            [[1, 1, 1, 1]], // I-форма (4)
            [[1, 1], [1, 1]], // Квадрат
            [[1, 1, 0], [0, 1, 1]], // Z-форма
            [[1, 1, 1, 1, 1]], // I-форма (5)
            [[1, 1, 1]], // I-форма (3)
            [[1, 1]], // I-форма (2)
            [[1, 0], [0, 1]], // Діагональ 2x2
            [[1, 0, 0], [0, 1, 0], [0, 0, 1]] // Діагональ 3x3
        ];

        const colors = [&#039;#FF0000&#039;, &#039;#00FF00&#039;, &#039;#0000FF&#039;, &#039;#FFFF00&#039;, &#039;#FF00FF&#039;, &#039;#FFA500&#039;, &#039;#800080&#039;, &#039;#00FFFF&#039;, &#039;#FF4500&#039;, &#039;#2E8B57&#039;, &#039;#DAA520&#039;, &#039;#8A2BE2&#039;];

        // Малювання блоків у таблиці
        function drawTableBlock(canvasId, shape, color) {
            const canvas = document.getElementById(canvasId);
            const ctx = canvas.getContext(&#039;2d&#039;);
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            const maxSize = Math.max(shape.length, shape[0].length);
            const blockCellSize = canvas.width / maxSize;
            shape.forEach((row, y) =&gt; {
                row.forEach((cell, x) =&gt; {
                    if (cell) {
                        ctx.fillStyle = color;
                        ctx.fillRect(x * blockCellSize + 2, y * blockCellSize + 2, blockCellSize - 4, blockCellSize - 4);
                        ctx.strokeStyle = &#039;#000&#039;;
                        ctx.strokeRect(x * blockCellSize + 2, y * blockCellSize + 2, blockCellSize - 4, blockCellSize - 4);
                    }
                });
            });
        }

        // Ініціалізація малюнків у таблиці
        drawTableBlock(&#039;shapeSingle&#039;, blockShapes[0], colors[0]);
        drawTableBlock(&#039;shapeL&#039;, blockShapes[2], colors[1]);
        drawTableBlock(&#039;shapeT&#039;, blockShapes[3], colors[2]);
        drawTableBlock(&#039;shapeI4&#039;, blockShapes[4], colors[3]);
        drawTableBlock(&#039;shapeSquare&#039;, blockShapes[5], colors[4]);
        drawTableBlock(&#039;shapeZ&#039;, blockShapes[6], colors[0]);
        drawTableBlock(&#039;shapeI5&#039;, blockShapes[7], colors[5]);
        drawTableBlock(&#039;shapeI3&#039;, blockShapes[8], colors[6]);
        drawTableBlock(&#039;shapeI2&#039;, blockShapes[9], colors[1]);
        drawTableBlock(&#039;shapeDiagonal2&#039;, blockShapes[10], colors[10]);
        drawTableBlock(&#039;shapeDiagonal3&#039;, blockShapes[11], colors[11]);

        function generateBlocks() {
            currentBlocks = [];
            for (let i = 0; i &lt; 3; i++) {
                const shapeIndex = Math.floor(Math.random() * blockShapes.length);
                const shape = blockShapes[shapeIndex];
                const colorIndex = Math.floor(Math.random() * colors.length);
                currentBlocks.push({ shape: shape, color: colors[colorIndex] });
                drawBlock(i, shape, colors[colorIndex]);
            }
        }

        function drawBlock(index, shape, color) {
            const canvas = document.getElementById(`block${index + 1}`);
            const blockCtx = canvas.getContext(&#039;2d&#039;);
            blockCtx.clearRect(0, 0, canvas.width, canvas.height);
            const maxSize = Math.max(shape.length, shape[0].length);
            const blockCellSize = canvas.width / maxSize;
            const offsetX = (canvas.width - (shape[0].length * blockCellSize)) / 2;
            const offsetY = (canvas.height - (shape.length * blockCellSize)) / 2;
            shape.forEach((row, y) =&gt; {
                row.forEach((cell, x) =&gt; {
                    if (cell) {
                        blockCtx.fillStyle = color;
                        blockCtx.fillRect(offsetX + x * blockCellSize + 2, offsetY + y * blockCellSize + 2, blockCellSize - 4, blockCellSize - 4);
                        blockCtx.strokeStyle = &#039;#000&#039;;
                        blockCtx.strokeRect(offsetX + x * blockCellSize + 2, offsetY + y * blockCellSize + 2, blockCellSize - 4, blockCellSize - 4);
                    }
                });
            });
        }

        function rotateShape(shape) {
            const rows = shape.length;
            const cols = shape[0].length;
            const rotated = Array(cols).fill().map(() =&gt; Array(rows).fill(0));
            for (let y = 0; y &lt; rows; y++) {
                for (let x = 0; x &lt; cols; x++) {
                    rotated[x][rows - 1 - y] = shape[y][x];
                }
            }
            return rotated;
        }

        function flipShape(shape) {
            return shape.map(row =&gt; [...row].reverse());
        }

        function showBonusMessage(message) {
            bonusMessageElement.textContent = message;
            bonusMessageElement.style.display = &#039;block&#039;;
            setTimeout(() =&gt; bonusMessageElement.style.display = &#039;none&#039;, 2000);
        }

        function drawGrid() {
            ctx.clearRect(0, 0, gameCanvas.width, gameCanvas.height);
            for (let y = 0; y &lt; gridSize; y++) {
                for (let x = 0; x &lt; gridSize; x++) {
                    ctx.strokeStyle = &#039;#000&#039;;
                    ctx.strokeRect(x * cellSize, y * cellSize, cellSize, cellSize);
                    if (grid[y][x]) {
                        ctx.fillStyle = grid[y][x];
                        ctx.fillRect(x * cellSize + 2, y * cellSize + 2, cellSize - 4, cellSize - 4);
                    }
                }
            }
        }

        function drawPreview(shape, x, y, valid) {
            drawGrid();
            if (shape &amp;&amp; x &gt;= 0 &amp;&amp; y &gt;= 0) {
                ctx.globalAlpha = 0.5;
                for (let sy = 0; sy &lt; shape.length; sy++) {
                    for (let sx = 0; sx &lt; shape[sy].length; sx++) {
                        if (shape[sy][sx]) {
                            ctx.fillStyle = valid ? selectedBlock.color : &#039;#FF0000&#039;;
                            ctx.fillRect((x + sx) * cellSize + 2, (y + sy) * cellSize + 2, cellSize - 4, cellSize - 4);
                            ctx.strokeStyle = &#039;#000&#039;;
                            ctx.strokeRect((x + sx) * cellSize + 2, (y + sy) * cellSize + 2, cellSize - 4, cellSize - 4);
                        }
                    }
                }
                ctx.globalAlpha = 1.0;
            }
        }

        function canPlaceBlock(shape, x, y) {
            for (let sy = 0; sy &lt; shape.length; sy++) {
                for (let sx = 0; sx &lt; shape[sy].length; sx++) {
                    if (shape[sy][sx]) {
                        const gridX = x + sx;
                        const gridY = y + sy;
                        if (gridX &lt; 0 || gridX &gt;= gridSize || gridY &lt; 0 || gridY &gt;= gridSize || grid[gridY][gridX]) {
                            return false;
                        }
                    }
                }
            }
            return true;
        }

        function placeBlock(shape, color, x, y, blockIndex) {
            console.log(`Розміщення блоку на позиції (${x}, ${y}), індекс: ${blockIndex}, форма:`, JSON.stringify(shape));
            lastMove = {
                grid: grid.map(row =&gt; [...row]),
                score,
                block: { shape, color },
                blockIndex
            };
            undoButton.disabled = false;
            for (let sy = 0; sy &lt; shape.length; sy++) {
                for (let sx = 0; sx &lt; shape[sy].length; sx++) {
                    if (shape[sy][sx]) {
                        grid[y + sy][x + sx] = color;
                    }
                }
            }
            console.log(&#039;Блок розміщено, викликаємо checkLines&#039;);
            checkLines();
            console.log(&#039;checkLines завершено, викликаємо checkGameOver&#039;);
            checkGameOver();
            drawGrid();
            console.log(&#039;Розміщення завершено, поточна черга:&#039;, JSON.stringify(currentBlocks.map(b =&gt; ({ shape: b.shape, color: b.color }))));
        }

        function checkLines() {
            let linesCleared = 0;
            for (let y = gridSize - 1; y &gt;= 0; y--) {
                if (grid[y].every(cell =&gt; cell)) {
                    grid.splice(y, 1);
                    grid.unshift(Array(gridSize).fill(null));
                    linesCleared++;
                    y++;
                }
            }
            for (let x = gridSize - 1; x &gt;= 0; x--) {
                let isFull = true;
                for (let y = 0; y &lt; gridSize; y++) {
                    if (!grid[y][x]) {
                        isFull = false;
                        break;
                    }
                }
                if (isFull) {
                    for (let y = 0; y &lt; gridSize; y++) {
                        grid[y].splice(x, 1);
                        grid[y].push(null);
                    }
                    linesCleared++;
                    x++;
                }
            }
            if (linesCleared &gt; 0) {
                let lineBonus = linesCleared === 1 ? 100 : 100 + (linesCleared - 1) * 50;
                score += lineBonus;
                if (linesCleared &gt; 1) {
                    showBonusMessage(`Бонус за ${linesCleared} лінії: +${lineBonus} очок`);
                    console.log(`Бонус за очищення ${linesCleared} ліній: +${lineBonus} очок`);
                }
                const isGridEmpty = grid.every(row =&gt; row.every(cell =&gt; !cell));
                if (isGridEmpty &amp;&amp; score &gt; 0) {
                    const clearBonus = Math.floor(score * 0.25);
                    score += clearBonus;
                    showBonusMessage(`Бонус за повне очищення поля: +${clearBonus} очок`);
                    console.log(`Бонус за повне очищення поля: +${clearBonus} очок`);
                }
                scoreElement.textContent = `Очки: ${score}`;
                if (score &gt; highScore) {
                    highScore = score;
                    localStorage.setItem(&#039;blockLegendHighScore&#039;, highScore);
                    highScoreElement.textContent = `Рекорд: ${highScore}`;
                    console.log(&#039;Новий рекорд:&#039;, highScore);
                }
            }
            console.log(&#039;Очищено ліній:&#039;, linesCleared, &#039;Очки:&#039;, score, &#039;Рекорд:&#039;, highScore);
        }

        function checkGameOver() {
            console.log(&#039;Перевірка стану гри. Кількість блоків:&#039;, currentBlocks.length, &#039;Блоки:&#039;, JSON.stringify(currentBlocks.map(b =&gt; ({ shape: b.shape, color: b.color }))));
            if (currentBlocks.length === 0) {
                console.log(&#039;Черга порожня, генеруємо нові блоки&#039;);
                setTimeout(() =&gt; {
                    generateBlocks();
                    console.log(&#039;Нові блоки згенеровано, нова черга:&#039;, JSON.stringify(currentBlocks.map(b =&gt; ({ shape: b.shape, color: b.color }))));
                }, 0);
                return;
            }
            let canPlaceAny = false;
            for (let block of currentBlocks) {
                for (let y = 0; y &lt; gridSize; y++) {
                    for (let x = 0; x &lt; gridSize; x++) {
                        if (canPlaceBlock(block.shape, x, y)) {
                            canPlaceAny = true;
                            break;
                        }
                    }
                    if (canPlaceAny) break;
                }
                if (canPlaceAny) break;
            }
            console.log(&#039;Чи можна розмістити блок:&#039;, canPlaceAny);
            if (!canPlaceAny) {
                gameActive = false;
                if (score &gt; highScore) {
                    highScore = score;
                    localStorage.setItem(&#039;blockLegendHighScore&#039;, highScore);
                    console.log(&#039;Новий рекорд на кінці гри:&#039;, highScore);
                }
                finalScoreElement.textContent = `Ваш рахунок: ${score}\nРекорд: ${highScore}`;
                gameOverElement.style.display = &#039;block&#039;;
                console.log(&#039;Гра закінчена. Рахунок:&#039;, score, &#039;Рекорд:&#039;, highScore);
            }
        }

        function restartGame() {
            grid = Array(gridSize).fill().map(() =&gt; Array(gridSize).fill(null));
            score = 0;
            scoreElement.textContent = `Очки: ${score}`;
            highScoreElement.textContent = `Рекорд: ${highScore}`;
            gameOverElement.style.display = &#039;none&#039;;
            gamePaused = false;
            pauseButton.textContent = &#039;Пауза&#039;;
            pauseOverlay.style.display = &#039;none&#039;;
            undoButton.disabled = true;
            lastMove = null;
            gameActive = true;
            currentBlocks = [];
            generateBlocks();
            drawGrid();
            console.log(&#039;Гра перезапущена. Рахунок:&#039;, score, &#039;Рекорд:&#039;, highScore);
        }

        function undoMove() {
            if (!lastMove || !gameActive || gamePaused) return;
            grid = lastMove.grid.map(row =&gt; [...row]);
            score = lastMove.score;
            currentBlocks.splice(lastMove.blockIndex, 0, lastMove.block);
            scoreElement.textContent = `Очки: ${score}`;
            undoButton.disabled = true;
            lastMove = null;
            for (let i = 0; i &lt; 3; i++) {
                const blockCanvas = document.getElementById(`block${i + 1}`);
                blockCanvas.getContext(&#039;2d&#039;).clearRect(0, 0, blockCanvas.width, blockCanvas.height);
                if (i &lt; currentBlocks.length) {
                    drawBlock(i, currentBlocks[i].shape, currentBlocks[i].color);
                }
            }
            drawGrid();
            console.log(&#039;Хід скасовано. Поточна черга:&#039;, JSON.stringify(currentBlocks.map(b =&gt; ({ shape: b.shape, color: b.color }))));
        }

        function togglePause() {
            if (!gameActive) return;
            gamePaused = !gamePaused;
            pauseButton.textContent = gamePaused ? &#039;Відновити&#039; : &#039;Пауза&#039;;
            pauseOverlay.style.display = gamePaused ? &#039;block&#039; : &#039;none&#039;;
            console.log(&#039;Гра на паузі:&#039;, gamePaused);
        }

        pauseButton.addEventListener(&#039;click&#039;, togglePause);
        undoButton.addEventListener(&#039;click&#039;, undoMove);

        let touchStartX = 0;
        let touchStartY = 0;
        const blockCanvases = document.querySelectorAll(&#039;.blockCanvas&#039;);
        blockCanvases.forEach(canvas =&gt; {
            canvas.addEventListener(&#039;dragstart&#039;, (e) =&gt; {
                if (!gameActive || gamePaused) return;
                const index = parseInt(canvas.id.replace(&#039;block&#039;, &#039;&#039;)) - 1;
                selectedBlock = currentBlocks[index];
                canvas.classList.add(&#039;dragging&#039;);
                e.dataTransfer.setData(&#039;text/plain&#039;, index);
                console.log(&#039;Початок перетягування блоку:&#039;, index, &#039;Блок:&#039;, JSON.stringify(selectedBlock));
            });

            canvas.addEventListener(&#039;dragend&#039;, (e) =&gt; {
                canvas.classList.remove(&#039;dragging&#039;);
                drawGrid();
                console.log(&#039;Кінець перетягування&#039;);
            });

            canvas.addEventListener(&#039;contextmenu&#039;, (e) =&gt; {
                e.preventDefault();
                if (!gameActive || gamePaused) return;
                const index = parseInt(canvas.id.replace(&#039;block&#039;, &#039;&#039;)) - 1;
                currentBlocks[index].shape = rotateShape(currentBlocks[index].shape);
                drawBlock(index, currentBlocks[index].shape, currentBlocks[index].color);
                console.log(&#039;Блок повернуто:&#039;, index, &#039;Нова форма:&#039;, JSON.stringify(currentBlocks[index].shape));
            });

            canvas.addEventListener(&#039;mousedown&#039;, (e) =&gt; {
                if (e.button === 1) {
                    e.preventDefault();
                    if (!gameActive || gamePaused) return;
                    const index = parseInt(canvas.id.replace(&#039;block&#039;, &#039;&#039;)) - 1;
                    currentBlocks[index].shape = flipShape(currentBlocks[index].shape);
                    drawBlock(index, currentBlocks[index].shape, currentBlocks[index].color);
                    console.log(&#039;Блок перевернуто (середня кнопка):&#039;, index, &#039;Нова форма:&#039;, JSON.stringify(currentBlocks[index].shape));
                }
            });

            canvas.addEventListener(&#039;dblclick&#039;, (e) =&gt; {
                e.preventDefault();
                if (!gameActive || gamePaused) return;
                const index = parseInt(canvas.id.replace(&#039;block&#039;, &#039;&#039;)) - 1;
                if (index &gt;= 0 &amp;&amp; index &lt; currentBlocks.length) {
                    currentBlocks[index].shape = flipShape(currentBlocks[index].shape);
                    drawBlock(index, currentBlocks[index].shape, currentBlocks[index].color);
                    console.log(&#039;Блок перевернуто (подвійне клацання):&#039;, index, &#039;Нова форма:&#039;, JSON.stringify(currentBlocks[index].shape));
                }
            });

            canvas.addEventListener(&#039;touchstart&#039;, (e) =&gt; {
                if (!gameActive || gamePaused) return;
                const index = parseInt(canvas.id.replace(&#039;block&#039;, &#039;&#039;)) - 1;
                if (index &gt;= 0 &amp;&amp; index &lt; currentBlocks.length) {
                    selectedBlock = currentBlocks[index];
                    canvas.classList.add(&#039;dragging&#039;);

                    // Record initial touch position for movement tolerance
                    const touch = e.touches[0];
                    touchStartX = touch.clientX;
                    touchStartY = touch.clientY;

                    // Two-finger tap detection for flipping
                    if (e.touches.length === 2) {
                        const touch1 = e.touches[0];
                        const touch2 = e.touches[1];
                        const moveTolerance = 10; // Pixels of movement allowed
                        const dx1 = Math.abs(touch1.clientX - touchStartX);
                        const dy1 = Math.abs(touch1.clientY - touchStartY);
                        const dx2 = Math.abs(touch2.clientX - touchStartX);
                        const dy2 = Math.abs(touch2.clientY - touchStartY);
                        if (dx1 &lt; moveTolerance &amp;&amp; dy1 &lt; moveTolerance &amp;&amp; dx2 &lt; moveTolerance &amp;&amp; dy2 &lt; moveTolerance) {
                            currentBlocks[index].shape = flipShape(currentBlocks[index].shape);
                            drawBlock(index, currentBlocks[index].shape, currentBlocks[index].color);
                            console.log(&#039;Блок перевернуто (двохпальцевий тап):&#039;, index, &#039;Нова форма:&#039;, JSON.stringify(currentBlocks[index].shape));
                            e.preventDefault(); // Prevent default behavior (e.g., zoom)
                        }
                        return; // Exit early to avoid long-press interference
                    }

                    // Long-press detection for rotation
                    let touchStartTime = Date.now();
                    const touchHoldTimeout = setTimeout(() =&gt; {
                        if (Date.now() - touchStartTime &gt;= 300 &amp;&amp; e.touches.length === 1) { // Reduced to 300ms
                            currentBlocks[index].shape = rotateShape(currentBlocks[index].shape);
                            drawBlock(index, currentBlocks[index].shape, currentBlocks[index].color);
                            console.log(&#039;Блок повернуто (довге натискання):&#039;, index, &#039;Нова форма:&#039;, JSON.stringify(currentBlocks[index].shape));
                        }
                    }, 300);

                    // Cancel timeout on touchend or touchmove
                    const touchEndOrMove = (event) =&gt; {
                        const currentTouch = event.touches[0] || event.changedTouches[0];
                        const dx = Math.abs(currentTouch.clientX - touchStartX);
                        const dy = Math.abs(currentTouch.clientY - touchStartY);
                        if (dx &gt; 10 || dy &gt; 10) { // Cancel if significant movement
                            clearTimeout(touchHoldTimeout);
                        }
                    };
                    canvas.addEventListener(&#039;touchend&#039;, touchEndOrMove, { once: true });
                    canvas.addEventListener(&#039;touchmove&#039;, touchEndOrMove, { once: true });

                    console.log(&#039;Початок сенсорного перетягування блоку:&#039;, index, &#039;Блок:&#039;, JSON.stringify(selectedBlock));
                } else {
                    console.error(&#039;Помилка: невалідний індекс блоку на touchstart&#039;, index);
                }
            });

            canvas.addEventListener(&#039;touchmove&#039;, (e) =&gt; {
                e.preventDefault();
                if (!gameActive || !selectedBlock || gamePaused) return;
                const touch = e.touches[0];
                const rect = gameCanvas.getBoundingClientRect();
                const x = Math.floor((touch.clientX - rect.left) / cellSize);
                const y = Math.floor((touch.clientY - rect.top) / cellSize);
                const valid = canPlaceBlock(selectedBlock.shape, x, y);
                drawPreview(selectedBlock.shape, x, y, valid);
            });

            canvas.addEventListener(&#039;touchend&#039;, (e) =&gt; {
                if (!gameActive || !selectedBlock || gamePaused) return;
                const touch = e.changedTouches[0];
                const rect = gameCanvas.getBoundingClientRect();
                const x = Math.floor((touch.clientX - rect.left) / cellSize);
                const y = Math.floor((touch.clientY - rect.top) / cellSize);
                const index = parseInt(canvas.id.replace(&#039;block&#039;, &#039;&#039;)) - 1;
                console.log(`Сенсорне розміщення: координати (${x}, ${y}), індекс: ${index}, блок:`, JSON.stringify(selectedBlock));
                if (index &gt;= 0 &amp;&amp; index &lt; currentBlocks.length) {
                    if (canPlaceBlock(selectedBlock.shape, x, y)) {
                        placeBlock(selectedBlock.shape, selectedBlock.color, x, y, index);
                        currentBlocks.splice(index, 1);
                        console.log(&#039;Блок видалено з черги. Залишилося:&#039;, currentBlocks.length, &#039;Блоки:&#039;, JSON.stringify(currentBlocks.map(b =&gt; ({ shape: b.shape, color: b.color }))));
                        for (let i = 0; i &lt; 3; i++) {
                            const blockCanvas = document.getElementById(`block${i + 1}`);
                            blockCanvas.getContext(&#039;2d&#039;).clearRect(0, 0, blockCanvas.width, blockCanvas.height);
                            if (i &lt; currentBlocks.length) {
                                drawBlock(i, currentBlocks[i].shape, currentBlocks[i].color);
                            }
                        }
                        checkGameOver();
                        selectedBlock = null;
                    } else {
                        console.log(&#039;Неможливо розмістити блок на позиції:&#039;, x, y);
                    }
                } else {
                    console.error(&#039;Помилка: невалідний індекс блоку на touchend&#039;, index);
                }
                canvas.classList.remove(&#039;dragging&#039;);
                drawGrid();
                console.log(&#039;Сенсорне розміщення завершено&#039;);
            });
        });

        generateBlocks();
        drawGrid();
        console.log(&#039;Гра ініціалізована — Мозаїка Майстрів Версія 1.9&#039;);
    &lt;/script&gt;</description>
            </item>
                    <item>
                <title>Мозаїка Майстрів</title>
                <link>http://margo.mozello.shop/gry/params/post/5141333/mozaka-majstrv</link>
                <pubDate>Thu, 02 Oct 2025 09:25:00 +0000</pubDate>
                <description>ооооооооооооооооооооооооо&lt;hr class=&quot;moze-more-divider&quot;&gt;&lt;p&gt;15&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;Мозаїка Майстрів — Версія 1.9&lt;/title&gt;
    &lt;style&gt;
        body {
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            min-height: 100vh;
            margin: 0;
            padding: 10px;
            background-color: #f0f0f0;
            font-family: Arial, sans-serif;
            overflow: auto;
        }

        #mainGameContainer {
            display: flex;
            align-items: flex-start;
            justify-content: center;
            gap: 20px;
            margin-top: 20px;
        }

        #gridContainer {
            display: flex;
            flex-direction: column;
            align-items: center;
        }

        #gameCanvas {
            border: 2px solid #333;
            background-color: #e3f1c6;
            max-width: 100%;
            height: auto;
        }

        #nextBlocks {
            display: flex;
            flex-direction: column;
            justify-content: flex-start;
            margin-top: 0;
            flex-wrap: nowrap;
            width: auto;
            max-width: 100px;
            gap: 10px;
        }

        .blockCanvas {
            border: 1px solid #ccc;
            cursor: grab;
            width: 80px;
            height: 80px;
            margin: 0;
        }

        .blockCanvas.dragging {
            opacity: 0.5;
            cursor: grabbing;
        }

        #score, #highScore {
            font-size: 20px;
            margin-top: 10px;
        }

        #bonusMessage {
            display: none;
            position: fixed;
            top: 20%;
            left: 50%;
            transform: translateX(-50%);
            background-color: rgba(0, 128, 0, 0.8);
            color: white;
            padding: 10px 20px;
            border-radius: 5px;
            z-index: 1000;
            font-size: 18px;
        }

        #gameOver, #pauseOverlay {
            display: none;
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            background-color: rgba(0, 0, 0, 0.8);
            color: white;
            padding: 15px;
            border-radius: 10px;
            text-align: center;
            z-index: 1000;
        }

        button {
            margin-top: 10px;
            padding: 8px 16px;
            font-size: 14px;
            cursor: pointer;
        }

        h2 {
            margin: 10px 0;
        }

        p {
            margin: 5px 0;
        }

        .accordion {
            width: 100%;
            max-width: 500px;
            margin-top: 20px;
        }

        .accordion-item {
            border: 1px solid #333;
            margin-bottom: 5px;
            border-radius: 5px;
        }

        .accordion-header {
            background-color: #ddd;
            padding: 10px;
            cursor: pointer;
            font-size: 18px;
            font-weight: bold;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }

        .accordion-header::after {
            content: &#039;▼&#039;;
            font-size: 14px;
        }

        .accordion-header.active::after {
            content: &#039;▲&#039;;
        }

        .accordion-content {
            display: none;
            padding: 10px;
            background-color: #fff;
        }

        .accordion-content.active {
            display: block;
        }

        .accordion-content table {
            width: 100%;
            border-collapse: collapse;
            margin-bottom: 15px;
        }

        .accordion-content th, .accordion-content td {
            border: 1px solid #333;
            padding: 8px;
            text-align: center;
        }

        .accordion-content th {
            background-color: #ddd;
        }

        .accordion-content pre {
            margin: 0;
            font-size: 12px;
        }

        .accordion-content canvas {
            border: 1px solid #ccc;
        }
    &lt;/style&gt;


    &lt;h2&gt;Мозаїка Майстрів — Версія 1.9&lt;/h2&gt;
    &lt;p&gt;Права кнопка миші — поворот блоку, Середня кнопка/подвійне торкання — перевертання, Кнопка &quot;Скасувати&quot; — скасування ходу&lt;/p&gt;

    &lt;div id=&quot;mainGameContainer&quot; style=&quot;display: flex; align-items: flex-start; justify-content: center; gap: 20px;&quot;&gt;
        &lt;div id=&quot;gridContainer&quot;&gt;
            &lt;canvas id=&quot;gameCanvas&quot; width=&quot;300&quot; height=&quot;300&quot;&gt;&lt;/canvas&gt;
            &lt;button id=&quot;pauseButton&quot;&gt;Пауза&lt;/button&gt;
            &lt;button id=&quot;undoButton&quot; disabled=&quot;&quot;&gt;Скасувати&lt;/button&gt;
            &lt;div id=&quot;score&quot;&gt;Очки: 0&lt;/div&gt;
            &lt;div id=&quot;highScore&quot;&gt;Рекорд: 0&lt;/div&gt;
        &lt;/div&gt;
        &lt;div id=&quot;nextBlocks&quot;&gt;
            &lt;canvas id=&quot;block1&quot; class=&quot;blockCanvas&quot; width=&quot;80&quot; height=&quot;80&quot; draggable=&quot;true&quot;&gt;&lt;/canvas&gt;
            &lt;canvas id=&quot;block2&quot; class=&quot;blockCanvas&quot; width=&quot;80&quot; height=&quot;80&quot; draggable=&quot;true&quot;&gt;&lt;/canvas&gt;
            &lt;canvas id=&quot;block3&quot; class=&quot;blockCanvas&quot; width=&quot;80&quot; height=&quot;80&quot; draggable=&quot;true&quot;&gt;&lt;/canvas&gt;
        &lt;/div&gt;
    &lt;/div&gt;

    &lt;div id=&quot;bonusMessage&quot;&gt;&lt;/div&gt;
    &lt;div id=&quot;gameOver&quot;&gt;
        &lt;h2&gt;Гра закінчена!&lt;/h2&gt;
        &lt;p id=&quot;finalScore&quot;&gt;&lt;/p&gt;
        &lt;button onclick=&quot;restartGame()&quot;&gt;Грати знову&lt;/button&gt;
    &lt;/div&gt;
    &lt;div id=&quot;pauseOverlay&quot;&gt;
        &lt;h2&gt;Гра на паузі&lt;/h2&gt;
        &lt;button onclick=&quot;togglePause()&quot;&gt;Відновити&lt;/button&gt;
    &lt;/div&gt;

    &lt;div class=&quot;accordion&quot;&gt;
        &lt;div class=&quot;accordion-item&quot;&gt;
            &lt;div class=&quot;accordion-header&quot; onclick=&quot;toggleAccordion(this)&quot;&gt;Таблиця блоків&lt;/div&gt;
            &lt;div class=&quot;accordion-content&quot;&gt;
                &lt;table&gt;
                    &lt;thead&gt;
                        &lt;tr&gt;
                            &lt;th&gt;Назва&lt;/th&gt;
                            &lt;th&gt;Зображення&lt;/th&gt;
                            &lt;th&gt;Структура&lt;/th&gt;
                            &lt;th&gt;Використання&lt;/th&gt;
                        &lt;/tr&gt;
                    &lt;/thead&gt;
                    &lt;tbody&gt;
                        &lt;tr&gt;
                            &lt;td&gt;Одинарний&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeSingle&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для заповнення окремих клітинок&lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;tr&gt;
                            &lt;td&gt;L-форма&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeL&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1, 1],&lt;br&gt;[1, 0]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для кутів або вузьких просторів&lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;tr&gt;
                            &lt;td&gt;T-форма&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeT&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1, 1, 1],&lt;br&gt;[0, 1, 0]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для горизонтальних ліній з виступом&lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;tr&gt;
                            &lt;td&gt;I-форма (4)&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeI4&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1, 1, 1, 1]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для заповнення рядків/стовпців&lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;tr&gt;
                            &lt;td&gt;Квадрат&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeSquare&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1, 1],&lt;br&gt;[1, 1]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для компактних квадратних просторів&lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;tr&gt;
                            &lt;td&gt;Z-форма&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeZ&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1, 1, 0],&lt;br&gt;[0, 1, 1]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для зміщених &quot;змійок&quot;&lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;tr&gt;
                            &lt;td&gt;I-форма (5)&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeI5&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1, 1, 1, 1, 1]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для довгих рядків/стовпців&lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;tr&gt;
                            &lt;td&gt;I-форма (3)&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeI3&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1, 1, 1]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для середніх рядків/стовпців&lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;tr&gt;
                            &lt;td&gt;I-форма (2)&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeI2&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1, 1]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для коротких рядків/стовпців&lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;tr&gt;
                            &lt;td&gt;Діагональ 2x2&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeDiagonal2&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1, 0],&lt;br&gt;[0, 1]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для заповнення діагональних просторів&lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;tr&gt;
                            &lt;td&gt;Діагональ 3x3&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeDiagonal3&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1, 0, 0],&lt;br&gt;[0, 1, 0],&lt;br&gt;[0, 0, 1]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для довгих діагональних ліній&lt;/td&gt;
                        &lt;/tr&gt;
                    &lt;/tbody&gt;
                &lt;/table&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;accordion-item&quot;&gt;
            &lt;div class=&quot;accordion-header&quot; onclick=&quot;toggleAccordion(this)&quot;&gt;Інструкція&lt;/div&gt;
            &lt;div class=&quot;accordion-content&quot;&gt;
                &lt;h3&gt;Мета гри&lt;/h3&gt;
                &lt;p&gt;&quot;Мозаїка Майстрів&quot; — це головоломка, де гравець розміщує блоки на сітці 10x10, щоб очищати цілі рядки або стовпці. Мета — набрати якомога більше очок і встановити рекорд. Гра закінчується, коли жоден блок не можна розмістити.&lt;/p&gt;
                
                &lt;h3&gt;Правила гри&lt;/h3&gt;
                &lt;ul&gt;
                    &lt;li&gt;&lt;b&gt;Ігрове поле&lt;/b&gt;: Сітка 10x10, де клітинки можуть бути порожніми або заповненими.&lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Черга блоків&lt;/b&gt;: До трьох блоків відображаються справа для розміщення.&lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Розміщення&lt;/b&gt;: Перетягуйте блоки на сітку. Розміщення можливе лише у вільних місцях.&lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Очищення ліній&lt;/b&gt;:
                        &lt;ul&gt;
                            &lt;li&gt;Повний рядок або стовпець очищається.&lt;/li&gt;
                            &lt;li&gt;1 лінія: 100 очок.&lt;/li&gt;
                            &lt;li&gt;2+ ліній: 100 + 50 за кожну додаткову (наприклад, 2 лінії = 150 очок).&lt;/li&gt;
                        &lt;/ul&gt;
                    &lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Бонус за очищення поля&lt;/b&gt;: 25% від суми очок, якщо поле порожнє.&lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Рекорд&lt;/b&gt;: Зберігається у браузері, відображається під час гри та після завершення.&lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Кінець гри&lt;/b&gt;: Гра закінчується, якщо блоки неможливо розмістити.&lt;/li&gt;
                &lt;/ul&gt;

                &lt;h3&gt;Дії гравця&lt;/h3&gt;
                &lt;ul&gt;
                    &lt;li&gt;&lt;b&gt;Перетягування&lt;/b&gt;:
                        &lt;ul&gt;
                            &lt;li&gt;ПК: Лівою кнопкою миші.&lt;/li&gt;
                            &lt;li&gt;Сенсорні пристрої: Торкніться та перетягніть.&lt;/li&gt;
                        &lt;/ul&gt;
                    &lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Поворот&lt;/b&gt;: Права кнопка миші (90°).&lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Перевертання&lt;/b&gt;:
                        &lt;ul&gt;
                            &lt;li&gt;ПК: Середня кнопка миші або подвійне клацання.&lt;/li&gt;
                            &lt;li&gt;Сенсорні пристрої: Подвійне торкання.&lt;/li&gt;
                        &lt;/ul&gt;
                    &lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Скасування ходу&lt;/b&gt;: Кнопка &quot;Скасувати&quot; для останнього ходу.&lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Пауза&lt;/b&gt;: Кнопка &quot;Пауза&quot;/&quot;Відновити&quot;.&lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Перезапуск&lt;/b&gt;: Кнопка &quot;Грати знову&quot; на екрані &quot;Гра закінчена&quot;.&lt;/li&gt;
                &lt;/ul&gt;

                &lt;h3&gt;Поради&lt;/h3&gt;
                &lt;ul&gt;
                    &lt;li&gt;Плануйте ходи, щоб створювати повні лінії.&lt;/li&gt;
                    &lt;li&gt;Використовуйте одинарний блок для прогалин.&lt;/li&gt;
                    &lt;li&gt;Скасовуйте невдалі ходи.&lt;/li&gt;
                    &lt;li&gt;Намагайтеся очищати кілька ліній для бонусів.&lt;/li&gt;
                    &lt;li&gt;Експериментуйте з діагональними блоками для унікальних комбінацій.&lt;/li&gt;
                &lt;/ul&gt;
            &lt;/div&gt;
        &lt;/div&gt;
    &lt;/div&gt;

    &lt;script&gt;
        // Акордеон-меню
        function toggleAccordion(header) {
            const content = header.nextElementSibling;
            const isActive = content.classList.contains(&#039;active&#039;);
            document.querySelectorAll(&#039;.accordion-content&#039;).forEach(item =&gt; {
                item.classList.remove(&#039;active&#039;);
                item.previousElementSibling.classList.remove(&#039;active&#039;);
            });
            if (!isActive) {
                content.classList.add(&#039;active&#039;);
                header.classList.add(&#039;active&#039;);
            }
        }

        // Ігрова логіка
        const gameCanvas = document.getElementById(&#039;gameCanvas&#039;);
        const ctx = gameCanvas.getContext(&#039;2d&#039;);
        const gridSize = 10;
        const cellSize = gameCanvas.width / gridSize;
        const scoreElement = document.getElementById(&#039;score&#039;);
        const highScoreElement = document.getElementById(&#039;highScore&#039;);
        const bonusMessageElement = document.getElementById(&#039;bonusMessage&#039;);
        const gameOverElement = document.getElementById(&#039;gameOver&#039;);
        const finalScoreElement = document.getElementById(&#039;finalScore&#039;);
        const pauseButton = document.getElementById(&#039;pauseButton&#039;);
        const undoButton = document.getElementById(&#039;undoButton&#039;);
        const pauseOverlay = document.getElementById(&#039;pauseOverlay&#039;);

        let grid = Array(gridSize).fill().map(() =&gt; Array(gridSize).fill(null));
        let score = 0;
        let highScore = parseInt(localStorage.getItem(&#039;blockLegendHighScore&#039;)) || 0;
        let currentBlocks = [];
        let selectedBlock = null;
        let gameActive = true;
        let gamePaused = false;
        let lastMove = null;

        highScoreElement.textContent = `Рекорд: ${highScore}`;
        console.log(&#039;Завантажено рекорд:&#039;, highScore);

        const blockShapes = [
            [[1]], // Одинарний (1x1)
            [[1]], // Одинарний (збільшена ймовірність)
            [[1, 1], [1, 0]], // L-форма
            [[1, 1, 1], [0, 1, 0]], // T-форма
            [[1, 1, 1, 1]], // I-форма (4)
            [[1, 1], [1, 1]], // Квадрат
            [[1, 1, 0], [0, 1, 1]], // Z-форма
            [[1, 1, 1, 1, 1]], // I-форма (5)
            [[1, 1, 1]], // I-форма (3)
            [[1, 1]], // I-форма (2)
            [[1, 0], [0, 1]], // Діагональ 2x2
            [[1, 0, 0], [0, 1, 0], [0, 0, 1]] // Діагональ 3x3
        ];

        const colors = [&#039;#FF0000&#039;, &#039;#00FF00&#039;, &#039;#0000FF&#039;, &#039;#FFFF00&#039;, &#039;#FF00FF&#039;, &#039;#FFA500&#039;, &#039;#800080&#039;, &#039;#00FFFF&#039;, &#039;#FF4500&#039;, &#039;#2E8B57&#039;, &#039;#DAA520&#039;, &#039;#8A2BE2&#039;];

        // Малювання блоків у таблиці
        function drawTableBlock(canvasId, shape, color) {
            const canvas = document.getElementById(canvasId);
            const ctx = canvas.getContext(&#039;2d&#039;);
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            const maxSize = Math.max(shape.length, shape[0].length);
            const blockCellSize = canvas.width / maxSize;
            shape.forEach((row, y) =&gt; {
                row.forEach((cell, x) =&gt; {
                    if (cell) {
                        ctx.fillStyle = color;
                        ctx.fillRect(x * blockCellSize + 2, y * blockCellSize + 2, blockCellSize - 4, blockCellSize - 4);
                        ctx.strokeStyle = &#039;#000&#039;;
                        ctx.strokeRect(x * blockCellSize + 2, y * blockCellSize + 2, blockCellSize - 4, blockCellSize - 4);
                    }
                });
            });
        }

        // Ініціалізація малюнків у таблиці
        drawTableBlock(&#039;shapeSingle&#039;, blockShapes[0], colors[0]);
        drawTableBlock(&#039;shapeL&#039;, blockShapes[2], colors[1]);
        drawTableBlock(&#039;shapeT&#039;, blockShapes[3], colors[2]);
        drawTableBlock(&#039;shapeI4&#039;, blockShapes[4], colors[3]);
        drawTableBlock(&#039;shapeSquare&#039;, blockShapes[5], colors[4]);
        drawTableBlock(&#039;shapeZ&#039;, blockShapes[6], colors[0]);
        drawTableBlock(&#039;shapeI5&#039;, blockShapes[7], colors[5]);
        drawTableBlock(&#039;shapeI3&#039;, blockShapes[8], colors[6]);
        drawTableBlock(&#039;shapeI2&#039;, blockShapes[9], colors[1]);
        drawTableBlock(&#039;shapeDiagonal2&#039;, blockShapes[10], colors[10]);
        drawTableBlock(&#039;shapeDiagonal3&#039;, blockShapes[11], colors[11]);

        function generateBlocks() {
            currentBlocks = [];
            for (let i = 0; i &lt; 3; i++) {
                const shapeIndex = Math.floor(Math.random() * blockShapes.length);
                const shape = blockShapes[shapeIndex];
                const colorIndex = Math.floor(Math.random() * colors.length);
                currentBlocks.push({ shape: shape, color: colors[colorIndex] });
                drawBlock(i, shape, colors[colorIndex]);
            }
        }

        function drawBlock(index, shape, color) {
            const canvas = document.getElementById(`block${index + 1}`);
            const blockCtx = canvas.getContext(&#039;2d&#039;);
            blockCtx.clearRect(0, 0, canvas.width, canvas.height);
            const maxSize = Math.max(shape.length, shape[0].length);
            const blockCellSize = canvas.width / maxSize;
            const offsetX = (canvas.width - (shape[0].length * blockCellSize)) / 2;
            const offsetY = (canvas.height - (shape.length * blockCellSize)) / 2;
            shape.forEach((row, y) =&gt; {
                row.forEach((cell, x) =&gt; {
                    if (cell) {
                        blockCtx.fillStyle = color;
                        blockCtx.fillRect(offsetX + x * blockCellSize + 2, offsetY + y * blockCellSize + 2, blockCellSize - 4, blockCellSize - 4);
                        blockCtx.strokeStyle = &#039;#000&#039;;
                        blockCtx.strokeRect(offsetX + x * blockCellSize + 2, offsetY + y * blockCellSize + 2, blockCellSize - 4, blockCellSize - 4);
                    }
                });
            });
        }

        function rotateShape(shape) {
            const rows = shape.length;
            const cols = shape[0].length;
            const rotated = Array(cols).fill().map(() =&gt; Array(rows).fill(0));
            for (let y = 0; y &lt; rows; y++) {
                for (let x = 0; x &lt; cols; x++) {
                    rotated[x][rows - 1 - y] = shape[y][x];
                }
            }
            return rotated;
        }

        function flipShape(shape) {
            return shape.map(row =&gt; [...row].reverse());
        }

        function showBonusMessage(message) {
            bonusMessageElement.textContent = message;
            bonusMessageElement.style.display = &#039;block&#039;;
            setTimeout(() =&gt; bonusMessageElement.style.display = &#039;none&#039;, 2000);
        }

        function drawGrid() {
            ctx.clearRect(0, 0, gameCanvas.width, gameCanvas.height);
            for (let y = 0; y &lt; gridSize; y++) {
                for (let x = 0; x &lt; gridSize; x++) {
                    ctx.strokeStyle = &#039;#000&#039;;
                    ctx.strokeRect(x * cellSize, y * cellSize, cellSize, cellSize);
                    if (grid[y][x]) {
                        ctx.fillStyle = grid[y][x];
                        ctx.fillRect(x * cellSize + 2, y * cellSize + 2, cellSize - 4, cellSize - 4);
                    }
                }
            }
        }

        function drawPreview(shape, x, y, valid) {
            drawGrid();
            if (shape &amp;&amp; x &gt;= 0 &amp;&amp; y &gt;= 0) {
                ctx.globalAlpha = 0.5;
                for (let sy = 0; sy &lt; shape.length; sy++) {
                    for (let sx = 0; sx &lt; shape[sy].length; sx++) {
                        if (shape[sy][sx]) {
                            ctx.fillStyle = valid ? selectedBlock.color : &#039;#FF0000&#039;;
                            ctx.fillRect((x + sx) * cellSize + 2, (y + sy) * cellSize + 2, cellSize - 4, cellSize - 4);
                            ctx.strokeStyle = &#039;#000&#039;;
                            ctx.strokeRect((x + sx) * cellSize + 2, (y + sy) * cellSize + 2, cellSize - 4, cellSize - 4);
                        }
                    }
                }
                ctx.globalAlpha = 1.0;
            }
        }

        function canPlaceBlock(shape, x, y) {
            for (let sy = 0; sy &lt; shape.length; sy++) {
                for (let sx = 0; sx &lt; shape[sy].length; sx++) {
                    if (shape[sy][sx]) {
                        const gridX = x + sx;
                        const gridY = y + sy;
                        if (gridX &lt; 0 || gridX &gt;= gridSize || gridY &lt; 0 || gridY &gt;= gridSize || grid[gridY][gridX]) {
                            return false;
                        }
                    }
                }
            }
            return true;
        }

        function placeBlock(shape, color, x, y, blockIndex) {
            console.log(`Розміщення блоку на позиції (${x}, ${y}), індекс: ${blockIndex}, форма:`, JSON.stringify(shape));
            lastMove = {
                grid: grid.map(row =&gt; [...row]),
                score,
                block: { shape, color },
                blockIndex
            };
            undoButton.disabled = false;
            for (let sy = 0; sy &lt; shape.length; sy++) {
                for (let sx = 0; sx &lt; shape[sy].length; sx++) {
                    if (shape[sy][sx]) {
                        grid[y + sy][x + sx] = color;
                    }
                }
            }
            console.log(&#039;Блок розміщено, викликаємо checkLines&#039;);
            checkLines();
            console.log(&#039;checkLines завершено, викликаємо checkGameOver&#039;);
            checkGameOver();
            drawGrid();
            console.log(&#039;Розміщення завершено, поточна черга:&#039;, JSON.stringify(currentBlocks.map(b =&gt; ({ shape: b.shape, color: b.color }))));
        }

        function checkLines() {
            let linesCleared = 0;
            for (let y = gridSize - 1; y &gt;= 0; y--) {
                if (grid[y].every(cell =&gt; cell)) {
                    grid.splice(y, 1);
                    grid.unshift(Array(gridSize).fill(null));
                    linesCleared++;
                    y++;
                }
            }
            for (let x = gridSize - 1; x &gt;= 0; x--) {
                let isFull = true;
                for (let y = 0; y &lt; gridSize; y++) {
                    if (!grid[y][x]) {
                        isFull = false;
                        break;
                    }
                }
                if (isFull) {
                    for (let y = 0; y &lt; gridSize; y++) {
                        grid[y].splice(x, 1);
                        grid[y].push(null);
                    }
                    linesCleared++;
                    x++;
                }
            }
            if (linesCleared &gt; 0) {
                let lineBonus = linesCleared === 1 ? 100 : 100 + (linesCleared - 1) * 50;
                score += lineBonus;
                if (linesCleared &gt; 1) {
                    showBonusMessage(`Бонус за ${linesCleared} лінії: +${lineBonus} очок`);
                    console.log(`Бонус за очищення ${linesCleared} ліній: +${lineBonus} очок`);
                }
                const isGridEmpty = grid.every(row =&gt; row.every(cell =&gt; !cell));
                if (isGridEmpty &amp;&amp; score &gt; 0) {
                    const clearBonus = Math.floor(score * 0.25);
                    score += clearBonus;
                    showBonusMessage(`Бонус за повне очищення поля: +${clearBonus} очок`);
                    console.log(`Бонус за повне очищення поля: +${clearBonus} очок`);
                }
                scoreElement.textContent = `Очки: ${score}`;
                if (score &gt; highScore) {
                    highScore = score;
                    localStorage.setItem(&#039;blockLegendHighScore&#039;, highScore);
                    highScoreElement.textContent = `Рекорд: ${highScore}`;
                    console.log(&#039;Новий рекорд:&#039;, highScore);
                }
            }
            console.log(&#039;Очищено ліній:&#039;, linesCleared, &#039;Очки:&#039;, score, &#039;Рекорд:&#039;, highScore);
        }

        function checkGameOver() {
            console.log(&#039;Перевірка стану гри. Кількість блоків:&#039;, currentBlocks.length, &#039;Блоки:&#039;, JSON.stringify(currentBlocks.map(b =&gt; ({ shape: b.shape, color: b.color }))));
            if (currentBlocks.length === 0) {
                console.log(&#039;Черга порожня, генеруємо нові блоки&#039;);
                setTimeout(() =&gt; {
                    generateBlocks();
                    console.log(&#039;Нові блоки згенеровано, нова черга:&#039;, JSON.stringify(currentBlocks.map(b =&gt; ({ shape: b.shape, color: b.color }))));
                }, 0);
                return;
            }
            let canPlaceAny = false;
            for (let block of currentBlocks) {
                for (let y = 0; y &lt; gridSize; y++) {
                    for (let x = 0; x &lt; gridSize; x++) {
                        if (canPlaceBlock(block.shape, x, y)) {
                            canPlaceAny = true;
                            break;
                        }
                    }
                    if (canPlaceAny) break;
                }
                if (canPlaceAny) break;
            }
            console.log(&#039;Чи можна розмістити блок:&#039;, canPlaceAny);
            if (!canPlaceAny) {
                gameActive = false;
                if (score &gt; highScore) {
                    highScore = score;
                    localStorage.setItem(&#039;blockLegendHighScore&#039;, highScore);
                    console.log(&#039;Новий рекорд на кінці гри:&#039;, highScore);
                }
                finalScoreElement.textContent = `Ваш рахунок: ${score}\nРекорд: ${highScore}`;
                gameOverElement.style.display = &#039;block&#039;;
                console.log(&#039;Гра закінчена. Рахунок:&#039;, score, &#039;Рекорд:&#039;, highScore);
            }
        }

        function restartGame() {
            grid = Array(gridSize).fill().map(() =&gt; Array(gridSize).fill(null));
            score = 0;
            scoreElement.textContent = `Очки: ${score}`;
            highScoreElement.textContent = `Рекорд: ${highScore}`;
            gameOverElement.style.display = &#039;none&#039;;
            gamePaused = false;
            pauseButton.textContent = &#039;Пауза&#039;;
            pauseOverlay.style.display = &#039;none&#039;;
            undoButton.disabled = true;
            lastMove = null;
            gameActive = true;
            currentBlocks = [];
            generateBlocks();
            drawGrid();
            console.log(&#039;Гра перезапущена. Рахунок:&#039;, score, &#039;Рекорд:&#039;, highScore);
        }

        function undoMove() {
            if (!lastMove || !gameActive || gamePaused) return;
            grid = lastMove.grid.map(row =&gt; [...row]);
            score = lastMove.score;
            currentBlocks.splice(lastMove.blockIndex, 0, lastMove.block);
            scoreElement.textContent = `Очки: ${score}`;
            undoButton.disabled = true;
            lastMove = null;
            for (let i = 0; i &lt; 3; i++) {
                const blockCanvas = document.getElementById(`block${i + 1}`);
                blockCanvas.getContext(&#039;2d&#039;).clearRect(0, 0, blockCanvas.width, blockCanvas.height);
                if (i &lt; currentBlocks.length) {
                    drawBlock(i, currentBlocks[i].shape, currentBlocks[i].color);
                }
            }
            drawGrid();
            console.log(&#039;Хід скасовано. Поточна черга:&#039;, JSON.stringify(currentBlocks.map(b =&gt; ({ shape: b.shape, color: b.color }))));
        }

        function togglePause() {
            if (!gameActive) return;
            gamePaused = !gamePaused;
            pauseButton.textContent = gamePaused ? &#039;Відновити&#039; : &#039;Пауза&#039;;
            pauseOverlay.style.display = gamePaused ? &#039;block&#039; : &#039;none&#039;;
            console.log(&#039;Гра на паузі:&#039;, gamePaused);
        }

        pauseButton.addEventListener(&#039;click&#039;, togglePause);
        undoButton.addEventListener(&#039;click&#039;, undoMove);

        const blockCanvases = document.querySelectorAll(&#039;.blockCanvas&#039;);
        blockCanvases.forEach(canvas =&gt; {
            canvas.addEventListener(&#039;dragstart&#039;, (e) =&gt; {
                if (!gameActive || gamePaused) return;
                const index = parseInt(canvas.id.replace(&#039;block&#039;, &#039;&#039;)) - 1;
                selectedBlock = currentBlocks[index];
                canvas.classList.add(&#039;dragging&#039;);
                e.dataTransfer.setData(&#039;text/plain&#039;, index);
                console.log(&#039;Початок перетягування блоку:&#039;, index, &#039;Блок:&#039;, JSON.stringify(selectedBlock));
            });

            canvas.addEventListener(&#039;dragend&#039;, (e) =&gt; {
                canvas.classList.remove(&#039;dragging&#039;);
                drawGrid();
                console.log(&#039;Кінець перетягування&#039;);
            });

            canvas.addEventListener(&#039;contextmenu&#039;, (e) =&gt; {
                e.preventDefault();
                if (!gameActive || gamePaused) return;
                const index = parseInt(canvas.id.replace(&#039;block&#039;, &#039;&#039;)) - 1;
                currentBlocks[index].shape = rotateShape(currentBlocks[index].shape);
                drawBlock(index, currentBlocks[index].shape, currentBlocks[index].color);
                console.log(&#039;Блок повернуто:&#039;, index, &#039;Нова форма:&#039;, JSON.stringify(currentBlocks[index].shape));
            });

            canvas.addEventListener(&#039;mousedown&#039;, (e) =&gt; {
                if (e.button === 1) {
                    e.preventDefault();
                    if (!gameActive || gamePaused) return;
                    const index = parseInt(canvas.id.replace(&#039;block&#039;, &#039;&#039;)) - 1;
                    currentBlocks[index].shape = flipShape(currentBlocks[index].shape);
                    drawBlock(index, currentBlocks[index].shape, currentBlocks[index].color);
                    console.log(&#039;Блок перевернуто (середня кнопка):&#039;, index, &#039;Нова форма:&#039;, JSON.stringify(currentBlocks[index].shape));
                }
            });

            canvas.addEventListener(&#039;dblclick&#039;, (e) =&gt; {
                e.preventDefault();
                if (!gameActive || gamePaused) return;
                const index = parseInt(canvas.id.replace(&#039;block&#039;, &#039;&#039;)) - 1;
                if (index &gt;= 0 &amp;&amp; index &lt; currentBlocks.length) {
                    currentBlocks[index].shape = flipShape(currentBlocks[index].shape);
                    drawBlock(index, currentBlocks[index].shape, currentBlocks[index].color);
                    console.log(&#039;Блок перевернуто (подвійне клацання):&#039;, index, &#039;Нова форма:&#039;, JSON.stringify(currentBlocks[index].shape));
                }
            });

            canvas.addEventListener(&#039;touchstart&#039;, (e) =&gt; {
                if (!gameActive || gamePaused) return;
                const index = parseInt(canvas.id.replace(&#039;block&#039;, &#039;&#039;)) - 1;
                if (index &gt;= 0 &amp;&amp; index &lt; currentBlocks.length) {
                    selectedBlock = currentBlocks[index];
                    canvas.classList.add(&#039;dragging&#039;);
                    console.log(&#039;Початок сенсорного перетягування блоку:&#039;, index, &#039;Блок:&#039;, JSON.stringify(selectedBlock));
                } else {
                    console.error(&#039;Помилка: невалідний індекс блоку на touchstart&#039;, index);
                }
            });

            canvas.addEventListener(&#039;touchmove&#039;, (e) =&gt; {
                e.preventDefault();
                if (!gameActive || !selectedBlock || gamePaused) return;
                const touch = e.touches[0];
                const rect = gameCanvas.getBoundingClientRect();
                const x = Math.floor((touch.clientX - rect.left) / cellSize);
                const y = Math.floor((touch.clientY - rect.top) / cellSize);
                const valid = canPlaceBlock(selectedBlock.shape, x, y);
                drawPreview(selectedBlock.shape, x, y, valid);
            });

            canvas.addEventListener(&#039;touchend&#039;, (e) =&gt; {
                if (!gameActive || !selectedBlock || gamePaused) return;
                const touch = e.changedTouches[0];
                const rect = gameCanvas.getBoundingClientRect();
                const x = Math.floor((touch.clientX - rect.left) / cellSize);
                const y = Math.floor((touch.clientY - rect.top) / cellSize);
                const index = parseInt(canvas.id.replace(&#039;block&#039;, &#039;&#039;)) - 1;
                console.log(`Сенсорне розміщення: координати (${x}, ${y}), індекс: ${index}, блок:`, JSON.stringify(selectedBlock));
                if (index &gt;= 0 &amp;&amp; index &lt; currentBlocks.length) {
                    if (canPlaceBlock(selectedBlock.shape, x, y)) {
                        placeBlock(selectedBlock.shape, selectedBlock.color, x, y, index);
                        currentBlocks.splice(index, 1);
                        console.log(&#039;Блок видалено з черги. Залишилося:&#039;, currentBlocks.length, &#039;Блоки:&#039;, JSON.stringify(currentBlocks.map(b =&gt; ({ shape: b.shape, color: b.color }))));
                        for (let i = 0; i &lt; 3; i++) {
                            const blockCanvas = document.getElementById(`block${i + 1}`);
                            blockCanvas.getContext(&#039;2d&#039;).clearRect(0, 0, blockCanvas.width, blockCanvas.height);
                            if (i &lt; currentBlocks.length) {
                                drawBlock(i, currentBlocks[i].shape, currentBlocks[i].color);
                            }
                        }
                        checkGameOver();
                        selectedBlock = null;
                    } else {
                        console.log(&#039;Неможливо розмістити блок на позиції:&#039;, x, y);
                    }
                } else {
                    console.error(&#039;Помилка: невалідний індекс блоку на touchend&#039;, index);
                }
                canvas.classList.remove(&#039;dragging&#039;);
                drawGrid();
                console.log(&#039;Сенсорне розміщення завершено&#039;);
            });
        });

        gameCanvas.addEventListener(&#039;dragover&#039;, (e) =&gt; {
            e.preventDefault();
            if (!gameActive || !selectedBlock || gamePaused) return;
            const rect = gameCanvas.getBoundingClientRect();
            const x = Math.floor((e.clientX - rect.left) / cellSize);
            const y = Math.floor((e.clientY - rect.top) / cellSize);
            const valid = canPlaceBlock(selectedBlock.shape, x, y);
            drawPreview(selectedBlock.shape, x, y, valid);
        });

        gameCanvas.addEventListener(&#039;drop&#039;, (e) =&gt; {
            e.preventDefault();
            if (!gameActive || !selectedBlock || gamePaused) return;
            const rect = gameCanvas.getBoundingClientRect();
            const x = Math.floor((e.clientX - rect.left) / cellSize);
            const y = Math.floor((e.clientY - rect.top) / cellSize);
            const index = parseInt(e.dataTransfer.getData(&#039;text/plain&#039;));
            console.log(`Розміщення через drag: координати (${x}, ${y}), індекс: ${index}, блок:`, JSON.stringify(selectedBlock));
            if (index &gt;= 0 &amp;&amp; index &lt; currentBlocks.length) {
                if (canPlaceBlock(selectedBlock.shape, x, y)) {
                    placeBlock(selectedBlock.shape, selectedBlock.color, x, y, index);
                    currentBlocks.splice(index, 1);
                    console.log(&#039;Блок видалено з черги. Залишилося:&#039;, currentBlocks.length, &#039;Блоки:&#039;, JSON.stringify(currentBlocks.map(b =&gt; ({ shape: b.shape, color: b.color }))));
                    for (let i = 0; i &lt; 3; i++) {
                        const blockCanvas = document.getElementById(`block${i + 1}`);
                        blockCanvas.getContext(&#039;2d&#039;).clearRect(0, 0, blockCanvas.width, blockCanvas.height);
                        if (i &lt; currentBlocks.length) {
                            drawBlock(i, currentBlocks[i].shape, currentBlocks[i].color);
                        }
                    }
                    checkGameOver();
                    selectedBlock = null;
                } else {
                    console.log(&#039;Неможливо розмістити блок на позиції:&#039;, x, y);
                }
            } else {
                console.error(&#039;Помилка: невалідний індекс блоку на drop&#039;, index);
            }
        });

        generateBlocks();
        drawGrid();
        console.log(&#039;Гра ініціалізована — Мозаїка Майстрів Версія 1.9&#039;);
    &lt;/script&gt;</description>
            </item>
                    <item>
                <title>мм3</title>
                <link>http://margo.mozello.shop/gry/params/post/5140019/mm3</link>
                <pubDate>Tue, 30 Sep 2025 14:12:00 +0000</pubDate>
                <description>оооооооооооооооооооооооооооо&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;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;Мозаїка Майстрів — Версія 1.9 (Виправлена)&lt;/title&gt;
    &lt;style&gt;
        body {
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            min-height: 100vh;
            margin: 0;
            padding: 10px;
            background-color: #f0f0f0;
            font-family: Arial, sans-serif;
            overflow: auto;
        }
        #gameCanvas {
            border: 2px solid #333;
            background-color: #e3f1c6;
            max-width: 100%;
            height: auto;
            margin-top: 20px;
        }
        #nextBlocks {
            display: flex;
            justify-content: center;
            margin-top: 10px;
            flex-wrap: wrap;
            width: 100%;
            max-width: 260px;
            gap: 1px;
        }
        .blockCanvas {
            border: 1px solid #ccc;
            cursor: grab;
            width: 80px;
            height: 80px;
            margin: 2px;
        }
        .blockCanvas.dragging {
            opacity: 0.5;
            cursor: grabbing;
        }
        #score, #highScore {
            font-size: 20px;
            margin-top: 10px;
        }
        #bonusMessage {
            display: none;
            position: fixed;
            top: 20%;
            left: 50%;
            transform: translateX(-50%);
            background-color: rgba(0, 128, 0, 0.8);
            color: white;
            padding: 10px 20px;
            border-radius: 5px;
            z-index: 1000;
            font-size: 18px;
        }
        #gameOver, #pauseOverlay {
            display: none;
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            background-color: rgba(0, 0, 0, 0.8);
            color: white;
            padding: 15px;
            border-radius: 10px;
            text-align: center;
            z-index: 1000;
        }
        button {
            margin-top: 10px;
            padding: 8px 16px;
            font-size: 14px;
            cursor: pointer;
            background-color: #4CAF50;
            color: white;
            border: none;
            border-radius: 5px;
        }
        #rotateButtons {
            margin-top: 10px;
            display: flex;
            gap: 5px;
        }
        h2 {
            margin: 10px 0;
        }
        p {
            margin: 5px 0;
        }
        .accordion {
            width: 100%;
            max-width: 500px;
            margin-top: 20px;
        }
        .accordion-item {
            border: 1px solid #333;
            margin-bottom: 5px;
            border-radius: 5px;
        }
        .accordion-header {
            background-color: #ddd;
            padding: 10px;
            cursor: pointer;
            font-size: 18px;
            font-weight: bold;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }
        .accordion-header::after {
            content: &#039;▼&#039;;
            font-size: 14px;
        }
        .accordion-header.active::after {
            content: &#039;▲&#039;;
        }
        .accordion-content {
            display: none;
            padding: 10px;
            background-color: #fff;
        }
        .accordion-content.active {
            display: block;
        }
        .accordion-content table {
            width: 100%;
            border-collapse: collapse;
            margin-bottom: 15px;
        }
        .accordion-content th, .accordion-content td {
            border: 1px solid #333;
            padding: 8px;
            text-align: center;
        }
        .accordion-content th {
            background-color: #ddd;
        }
        .accordion-content pre {
            margin: 0;
            font-size: 12px;
        }
        .accordion-content canvas {
            border: 1px solid #ccc;
        }
    &lt;/style&gt;


    &lt;h2&gt;Мозаїка Майстрів — Версія 1.9 (Виправлена)&lt;/h2&gt;
    &lt;p&gt;Права кнопка миші — поворот блоку на 90°, Жест двома пальцями — поворот на кут, Кнопка &quot;Скасувати&quot; — скасування ходу&lt;/p&gt;
    &lt;canvas id=&quot;gameCanvas&quot; width=&quot;300&quot; height=&quot;300&quot;&gt;&lt;/canvas&gt;
    &lt;button id=&quot;pauseButton&quot; fdprocessedid=&quot;imgj4r&quot;&gt;Пауза&lt;/button&gt;
    &lt;button id=&quot;undoButton&quot; disabled=&quot;&quot;&gt;Скасувати&lt;/button&gt;
    &lt;div id=&quot;nextBlocks&quot;&gt;
        &lt;canvas id=&quot;block1&quot; class=&quot;blockCanvas&quot; width=&quot;80&quot; height=&quot;80&quot; draggable=&quot;true&quot;&gt;&lt;/canvas&gt;
        &lt;canvas id=&quot;block2&quot; class=&quot;blockCanvas&quot; width=&quot;80&quot; height=&quot;80&quot; draggable=&quot;true&quot;&gt;&lt;/canvas&gt;
        &lt;canvas id=&quot;block3&quot; class=&quot;blockCanvas&quot; width=&quot;80&quot; height=&quot;80&quot; draggable=&quot;true&quot;&gt;&lt;/canvas&gt;
    &lt;/div&gt;
    &lt;div id=&quot;score&quot;&gt;Очки: 0&lt;/div&gt;
    &lt;div id=&quot;highScore&quot;&gt;Рекорд: 0&lt;/div&gt;
    &lt;div id=&quot;bonusMessage&quot;&gt;&lt;/div&gt;
    &lt;div id=&quot;gameOver&quot;&gt;
        &lt;h2&gt;Гра закінчена!&lt;/h2&gt;
        &lt;p id=&quot;finalScore&quot;&gt;&lt;/p&gt;
        &lt;button onclick=&quot;restartGame()&quot;&gt;Грати знову&lt;/button&gt;
    &lt;/div&gt;
    &lt;div id=&quot;pauseOverlay&quot;&gt;
        &lt;h2&gt;Гра на паузі&lt;/h2&gt;
        &lt;button onclick=&quot;togglePause()&quot;&gt;Відновити&lt;/button&gt;
    &lt;/div&gt;
    &lt;div id=&quot;rotateButtons&quot;&gt;
        &lt;button onclick=&quot;rotateSelectedBlock(90)&quot;&gt;90°&lt;/button&gt;
        &lt;button onclick=&quot;rotateSelectedBlock(180)&quot;&gt;180°&lt;/button&gt;
        &lt;button onclick=&quot;rotateSelectedBlock(270)&quot;&gt;270°&lt;/button&gt;
    &lt;/div&gt;

    &lt;div class=&quot;accordion&quot;&gt;
        &lt;div class=&quot;accordion-item&quot;&gt;
            &lt;div class=&quot;accordion-header&quot; onclick=&quot;toggleAccordion(this)&quot;&gt;Таблиця блоків&lt;/div&gt;
            &lt;div class=&quot;accordion-content&quot;&gt;
                &lt;table&gt;
                    &lt;thead&gt;
                        &lt;tr&gt;
                            &lt;th&gt;Назва&lt;/th&gt;
                            &lt;th&gt;Зображення&lt;/th&gt;
                            &lt;th&gt;Структура&lt;/th&gt;
                            &lt;th&gt;Використання&lt;/th&gt;
                        &lt;/tr&gt;
                    &lt;/thead&gt;
                    &lt;tbody&gt;
                        &lt;tr&gt;
                            &lt;td&gt;Одинарний&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeSingle&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для заповнення окремих клітинок&lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;tr&gt;
                            &lt;td&gt;L-форма&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeL&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1, 1],&lt;br&gt;[1, 0]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для кутів або вузьких просторів&lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;tr&gt;
                            &lt;td&gt;T-форма&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeT&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1, 1, 1],&lt;br&gt;[0, 1, 0]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для горизонтальних ліній з виступом&lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;tr&gt;
                            &lt;td&gt;I-форма (4)&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeI4&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1, 1, 1, 1]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для заповнення рядків/стовпців&lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;tr&gt;
                            &lt;td&gt;Квадрат&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeSquare&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1, 1],&lt;br&gt;[1, 1]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для компактних квадратних просторів&lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;tr&gt;
                            &lt;td&gt;Z-форма&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeZ&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1, 1, 0],&lt;br&gt;[0, 1, 1]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для зміщених &quot;змійок&quot;&lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;tr&gt;
                            &lt;td&gt;I-форма (5)&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeI5&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1, 1, 1, 1, 1]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для довгих рядків/стовпців&lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;tr&gt;
                            &lt;td&gt;I-форма (3)&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeI3&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1, 1, 1]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для середніх рядків/стовпців&lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;tr&gt;
                            &lt;td&gt;I-форма (2)&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeI2&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1, 1]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для коротких рядків/стовпців&lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;tr&gt;
                            &lt;td&gt;Діагональ 2x2&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeDiagonal2&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1, 0],&lt;br&gt;[0, 1]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для заповнення діагональних просторів&lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;tr&gt;
                            &lt;td&gt;Діагональ 3x3&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeDiagonal3&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1, 0, 0],&lt;br&gt;[0, 1, 0],&lt;br&gt;[0, 0, 1]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для довгих діагональних ліній&lt;/td&gt;
                        &lt;/tr&gt;
                    &lt;/tbody&gt;
                &lt;/table&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;accordion-item&quot;&gt;
            &lt;div class=&quot;accordion-header&quot; onclick=&quot;toggleAccordion(this)&quot;&gt;Інструкція&lt;/div&gt;
            &lt;div class=&quot;accordion-content&quot;&gt;
                &lt;h3&gt;Мета гри&lt;/h3&gt;
                &lt;p&gt;&quot;Мозаїка Майстрів&quot; — це головоломка, де гравець розміщує блоки на сітці 10x10, щоб очищати цілі рядки або стовпці. Мета — набрати якомога більше очок і встановити рекорд. Гра закінчується, коли жоден блок не можна розмістити.&lt;/p&gt;
                
                &lt;h3&gt;Правила гри&lt;/h3&gt;
                &lt;ul&gt;
                    &lt;li&gt;&lt;b&gt;Ігрове поле&lt;/b&gt;: Сітка 10x10, де клітинки можуть бути порожніми або заповненими.&lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Черга блоків&lt;/b&gt;: До трьох блоків відображаються знизу для розміщення.&lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Розміщення&lt;/b&gt;: Перетягуйте блоки на сітку. Розміщення можливе лише у вільних місцях.&lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Очищення ліній&lt;/b&gt;:
                        &lt;ul&gt;
                            &lt;li&gt;Повний рядок або стовпець очищається.&lt;/li&gt;
                            &lt;li&gt;1 лінія: 100 очок.&lt;/li&gt;
                            &lt;li&gt;2+ ліній: 100 + 50 за кожну додаткову (наприклад, 2 лінії = 150 очок).&lt;/li&gt;
                        &lt;/ul&gt;
                    &lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Бонус за очищення поля&lt;/b&gt;: 25% від суми очок, якщо поле порожнє.&lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Рекорд&lt;/b&gt;: Зберігається у браузері, відображається під час гри та після завершення.&lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Кінець гри&lt;/b&gt;: Гра закінчується, якщо блоки неможливо розмістити.&lt;/li&gt;
                &lt;/ul&gt;

                &lt;h3&gt;Дії гравця&lt;/h3&gt;
                &lt;ul&gt;
                    &lt;li&gt;&lt;b&gt;Перетягування&lt;/b&gt;:
                        &lt;ul&gt;
                            &lt;li&gt;ПК: Лівою кнопкою миші.&lt;/li&gt;
                            &lt;li&gt;Сенсорні пристрої: Торкніться та перетягніть.&lt;/li&gt;
                        &lt;/ul&gt;
                    &lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Поворот&lt;/b&gt;: Кнопки 90°/180°/270° або жест двома пальцями.&lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Скасування ходу&lt;/b&gt;: Кнопка &quot;Скасувати&quot; для останнього ходу.&lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Пауза&lt;/b&gt;: Кнопка &quot;Пауза&quot;/&quot;Відновити&quot;.&lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Перезапуск&lt;/b&gt;: Кнопка &quot;Грати знову&quot; на екрані &quot;Гра закінчена&quot;.&lt;/li&gt;
                &lt;/ul&gt;

                &lt;h3&gt;Поради&lt;/h3&gt;
                &lt;ul&gt;
                    &lt;li&gt;Плануйте ходи, щоб створювати повні лінії.&lt;/li&gt;
                    &lt;li&gt;Використовуйте одинарний блок для прогалин.&lt;/li&gt;
                    &lt;li&gt;Скасовуйте невдалі ходи.&lt;/li&gt;
                    &lt;li&gt;Намагайтеся очищати кілька ліній для бонусів.&lt;/li&gt;
                    &lt;li&gt;Експериментуйте з діагональними блоками для унікальних комбінацій.&lt;/li&gt;
                &lt;/ul&gt;
            &lt;/div&gt;
        &lt;/div&gt;
    &lt;/div&gt;

    &lt;script&gt;
        // Акордеон-меню
        function toggleAccordion(header) {
            const content = header.nextElementSibling;
            const isActive = content.classList.contains(&#039;active&#039;);
            document.querySelectorAll(&#039;.accordion-content&#039;).forEach(item =&gt; {
                item.classList.remove(&#039;active&#039;);
                item.previousElementSibling.classList.remove(&#039;active&#039;);
            });
            if (!isActive) {
                content.classList.add(&#039;active&#039;);
                header.classList.add(&#039;active&#039;);
            }
        }

        // Ігрова логіка
        const gameCanvas = document.getElementById(&#039;gameCanvas&#039;);
        const ctx = gameCanvas.getContext(&#039;2d&#039;);
        const gridSize = 10;
        const cellSize = gameCanvas.width / gridSize; // 30px
        const scoreElement = document.getElementById(&#039;score&#039;);
        const highScoreElement = document.getElementById(&#039;highScore&#039;);
        const bonusMessageElement = document.getElementById(&#039;bonusMessage&#039;);
        const gameOverElement = document.getElementById(&#039;gameOver&#039;);
        const finalScoreElement = document.getElementById(&#039;finalScore&#039;);
        const pauseButton = document.getElementById(&#039;pauseButton&#039;);
        const undoButton = document.getElementById(&#039;undoButton&#039;);
        const pauseOverlay = document.getElementById(&#039;pauseOverlay&#039;);

        let grid = Array(gridSize).fill().map(() =&gt; Array(gridSize).fill(null));
        let score = 0;
        let highScore = parseInt(localStorage.getItem(&#039;blockLegendHighScore&#039;)) || 0;
        let currentBlocks = [];
        let selectedBlock = null;
        let selectedBlockIndex = -1;
        let gameActive = true;
        let gamePaused = false;
        let lastMove = null;

        highScoreElement.textContent = `Рекорд: ${highScore}`;
        console.log(&#039;Завантажено рекорд:&#039;, highScore);

        const blockShapes = [
            [[1]], // Одинарний
            [[1, 1], [1, 0]], // L-форма
            [[1, 1, 1], [0, 1, 0]], // T-форма
            [[1, 1, 1, 1]], // I-форма (4)
            [[1, 1], [1, 1]], // Квадрат
            [[1, 1, 0], [0, 1, 1]], // Z-форма
            [[1, 1, 1, 1, 1]], // I-форма (5)
            [[1, 1, 1]], // I-форма (3)
            [[1, 1]], // I-форма (2)
            [[1, 0], [0, 1]], // Діагональ 2x2
            [[1, 0, 0], [0, 1, 0], [0, 0, 1]] // Діагональ 3x3
        ];

        const colors = [&#039;#FF0000&#039;, &#039;#00FF00&#039;, &#039;#0000FF&#039;, &#039;#FFFF00&#039;, &#039;#FF00FF&#039;, &#039;#FFA500&#039;, &#039;#800080&#039;, &#039;#00FFFF&#039;, &#039;#FF4500&#039;, &#039;#2E8B57&#039;, &#039;#DAA520&#039;, &#039;#8A2BE2&#039;];

        // Малювання блоків у таблиці
        function drawTableBlock(canvasId, shape, color) {
            const canvas = document.getElementById(canvasId);
            const ctx = canvas.getContext(&#039;2d&#039;);
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            const maxSize = Math.max(shape.length, shape[0].length);
            const blockCellSize = canvas.width / maxSize;
            shape.forEach((row, y) =&gt; {
                row.forEach((cell, x) =&gt; {
                    if (cell) {
                        ctx.fillStyle = color;
                        ctx.fillRect(x * blockCellSize + 2, y * blockCellSize + 2, blockCellSize - 4, blockCellSize - 4);
                        ctx.strokeStyle = &#039;#000&#039;;
                        ctx.strokeRect(x * blockCellSize + 2, y * blockCellSize + 2, blockCellSize - 4, blockCellSize - 4);
                    }
                });
            });
        }

        // Ініціалізація малюнків у таблиці
        drawTableBlock(&#039;shapeSingle&#039;, blockShapes[0], colors[0]);
        drawTableBlock(&#039;shapeL&#039;, blockShapes[1], colors[1]);
        drawTableBlock(&#039;shapeT&#039;, blockShapes[2], colors[2]);
        drawTableBlock(&#039;shapeI4&#039;, blockShapes[3], colors[3]);
        drawTableBlock(&#039;shapeSquare&#039;, blockShapes[4], colors[4]);
        drawTableBlock(&#039;shapeZ&#039;, blockShapes[5], colors[0]);
        drawTableBlock(&#039;shapeI5&#039;, blockShapes[6], colors[5]);
        drawTableBlock(&#039;shapeI3&#039;, blockShapes[7], colors[6]);
        drawTableBlock(&#039;shapeI2&#039;, blockShapes[8], colors[1]);
        drawTableBlock(&#039;shapeDiagonal2&#039;, blockShapes[9], colors[10]);
        drawTableBlock(&#039;shapeDiagonal3&#039;, blockShapes[10], colors[11]);

        function showBonusMessage(message) {
            bonusMessageElement.textContent = message;
            bonusMessageElement.style.display = &#039;block&#039;;
            setTimeout(() =&gt; bonusMessageElement.style.display = &#039;none&#039;, 2000);
        }

        function drawGrid() {
            ctx.clearRect(0, 0, gameCanvas.width, gameCanvas.height);
            for (let y = 0; y &lt; gridSize; y++) {
                for (let x = 0; x &lt; gridSize; x++) {
                    ctx.strokeStyle = &#039;#000&#039;;
                    ctx.strokeRect(x * cellSize, y * cellSize, cellSize, cellSize);
                    if (grid[y][x]) {
                        ctx.fillStyle = grid[y][x];
                        ctx.fillRect(x * cellSize + 2, y * cellSize + 2, cellSize - 4, cellSize - 4);
                    }
                }
            }
        }

        function drawPreview(shape, x, y, valid) {
            drawGrid();
            if (shape &amp;&amp; x &gt;= 0 &amp;&amp; y &gt;= 0) {
                ctx.globalAlpha = 0.5;
                for (let sy = 0; sy &lt; shape.length; sy++) {
                    for (let sx = 0; sx &lt; shape[sy].length; sx++) {
                        if (shape[sy][sx]) {
                            ctx.fillStyle = valid ? selectedBlock.color : &#039;#FF0000&#039;;
                            ctx.fillRect((x + sx) * cellSize + 2, (y + sy) * cellSize + 2, cellSize - 4, cellSize - 4);
                            ctx.strokeStyle = &#039;#000&#039;;
                            ctx.strokeRect((x + sx) * cellSize + 2, (y + sy) * cellSize + 2, cellSize - 4, cellSize - 4);
                        }
                    }
                }
                ctx.globalAlpha = 1.0;
            }
        }

        function canPlaceBlock(shape, x, y) {
            for (let sy = 0; sy &lt; shape.length; sy++) {
                for (let sx = 0; sx &lt; shape[sy].length; sx++) {
                    if (shape[sy][sx]) {
                        const gridX = x + sx;
                        const gridY = y + sy;
                        if (gridX &lt; 0 || gridX &gt;= gridSize || gridY &lt; 0 || gridY &gt;= gridSize || grid[gridY][gridX]) {
                            return false;
                        }
                    }
                }
            }
            return true;
        }

        function placeBlock(shape, color, x, y, blockIndex) {
            console.log(`Розміщення блоку на позиції (${x}, ${y}), індекс: ${blockIndex}, форма:`, JSON.stringify(shape));
            lastMove = {
                grid: grid.map(row =&gt; [...row]),
                score,
                block: { shape, color },
                blockIndex
            };
            undoButton.disabled = false;
            for (let sy = 0; sy &lt; shape.length; sy++) {
                for (let sx = 0; sx &lt; shape[sy].length; sx++) {
                    if (shape[sy][sx]) {
                        grid[y + sy][x + sx] = color;
                    }
                }
            }
            console.log(&#039;Блок розміщено, викликаємо checkLines&#039;);
            checkLines();
            console.log(&#039;checkLines завершено, викликаємо checkGameOver&#039;);
            checkGameOver();
            drawGrid();
            console.log(&#039;Розміщення завершено, поточна черга:&#039;, JSON.stringify(currentBlocks.map(b =&gt; ({ shape: b.shape, color: b.color }))));
        }

        function checkLines() {
            let linesCleared = 0;
            for (let y = gridSize - 1; y &gt;= 0; y--) {
                if (grid[y].every(cell =&gt; cell)) {
                    grid.splice(y, 1);
                    grid.unshift(Array(gridSize).fill(null));
                    linesCleared++;
                    y++;
                }
            }
            for (let x = gridSize - 1; x &gt;= 0; x--) {
                let isFull = true;
                for (let y = 0; y &lt; gridSize; y++) {
                    if (!grid[y][x]) {
                        isFull = false;
                        break;
                    }
                }
                if (isFull) {
                    for (let y = 0; y &lt; gridSize; y++) {
                        grid[y].splice(x, 1);
                        grid[y].push(null);
                    }
                    linesCleared++;
                    x++;
                }
            }
            if (linesCleared &gt; 0) {
                let lineBonus = linesCleared === 1 ? 100 : 100 + (linesCleared - 1) * 50;
                score += lineBonus;
                if (linesCleared &gt; 1) {
                    showBonusMessage(`Бонус за ${linesCleared} лінії: +${lineBonus} очок`);
                    console.log(`Бонус за очищення ${linesCleared} ліній: +${lineBonus} очок`);
                }
                const isGridEmpty = grid.every(row =&gt; row.every(cell =&gt; !cell));
                if (isGridEmpty &amp;&amp; score &gt; 0) {
                    const clearBonus = Math.floor(score * 0.25);
                    score += clearBonus;
                    showBonusMessage(`Бонус за повне очищення поля: +${clearBonus} очок`);
                    console.log(`Бонус за повне очищення поля: +${clearBonus} очок`);
                }
                scoreElement.textContent = `Очки: ${score}`;
                if (score &gt; highScore) {
                    highScore = score;
                    localStorage.setItem(&#039;blockLegendHighScore&#039;, highScore);
                    highScoreElement.textContent = `Рекорд: ${highScore}`;
                    console.log(&#039;Новий рекорд:&#039;, highScore);
                }
            }
            console.log(&#039;Очищено ліній:&#039;, linesCleared, &#039;Очки:&#039;, score, &#039;Рекорд:&#039;, highScore);
        }

        function checkGameOver() {
            console.log(&#039;Перевірка стану гри. Кількість блоків:&#039;, currentBlocks.length, &#039;Блоки:&#039;, JSON.stringify(currentBlocks.map(b =&gt; ({ shape: b.shape, color: b.color }))));
            if (currentBlocks.length === 0) {
                console.log(&#039;Черга порожня, генеруємо нові блоки&#039;);
                setTimeout(() =&gt; {
                    generateBlocks();
                    console.log(&#039;Нові блоки згенеровано, нова черга:&#039;, JSON.stringify(currentBlocks.map(b =&gt; ({ shape: b.shape, color: b.color }))));
                }, 0);
                return;
            }
            let canPlaceAny = false;
            for (let block of currentBlocks) {
                for (let y = 0; y &lt; gridSize; y++) {
                    for (let x = 0; x &lt; gridSize; x++) {
                        if (canPlaceBlock(block.shape, x, y)) {
                            canPlaceAny = true;
                            break;
                        }
                    }
                    if (canPlaceAny) break;
                }
                if (canPlaceAny) break;
            }
            console.log(&#039;Чи можна розмістити блок:&#039;, canPlaceAny);
            if (!canPlaceAny) {
                gameActive = false;
                if (score &gt; highScore) {
                    highScore = score;
                    localStorage.setItem(&#039;blockLegendHighScore&#039;, highScore);
                    console.log(&#039;Новий рекорд на кінці гри:&#039;, highScore);
                }
                finalScoreElement.textContent = `Ваш рахунок: ${score}\nРекорд: ${highScore}`;
                gameOverElement.style.display = &#039;block&#039;;
                console.log(&#039;Гра закінчена. Рахунок:&#039;, score, &#039;Рекорд:&#039;, highScore);
            }
        }

        function restartGame() {
            grid = Array(gridSize).fill().map(() =&gt; Array(gridSize).fill(null));
            score = 0;
            scoreElement.textContent = `Очки: ${score}`;
            highScoreElement.textContent = `Рекорд: ${highScore}`;
            gameOverElement.style.display = &#039;none&#039;;
            gamePaused = false;
            pauseButton.textContent = &#039;Пауза&#039;;
            pauseOverlay.style.display = &#039;none&#039;;
            undoButton.disabled = true;
            lastMove = null;
            gameActive = true;
            currentBlocks = [];
            generateBlocks();
            drawGrid();
            console.log(&#039;Гра перезапущена. Рахунок:&#039;, score, &#039;Рекорд:&#039;, highScore);
        }

        function togglePause() {
            if (!gameActive) return;
            gamePaused = !gamePaused;
            pauseButton.textContent = gamePaused ? &#039;Відновити&#039; : &#039;Пауза&#039;;
            pauseOverlay.style.display = gamePaused ? &#039;block&#039; : &#039;none&#039;;
            console.log(&#039;Гра на паузі:&#039;, gamePaused);
        }

        pauseButton.addEventListener(&#039;click&#039;, togglePause);
        undoButton.addEventListener(&#039;click&#039;, undoMove);

        const blockCanvases = document.querySelectorAll(&#039;.blockCanvas&#039;);
        let touchStart = { x1: 0, y1: 0, x2: 0, y2: 0, time: 0 };

        blockCanvases.forEach(canvas =&gt; {
            canvas.addEventListener(&#039;dragstart&#039;, (e) =&gt; {
                if (!gameActive || gamePaused) return;
                const index = parseInt(canvas.id.replace(&#039;block&#039;, &#039;&#039;)) - 1;
                selectedBlock = currentBlocks[index];
                selectedBlockIndex = index;
                canvas.classList.add(&#039;dragging&#039;);
                e.dataTransfer.setData(&#039;text/plain&#039;, index);
                console.log(&#039;Початок перетягування блоку:&#039;, index, &#039;Блок:&#039;, JSON.stringify(selectedBlock));
            });

            canvas.addEventListener(&#039;dragend&#039;, (e) =&gt; {
                canvas.classList.remove(&#039;dragging&#039;);
                selectedBlock = null;
                selectedBlockIndex = -1;
                drawGrid();
                console.log(&#039;Кінець перетягування&#039;);
            });

            canvas.addEventListener(&#039;contextmenu&#039;, (e) =&gt; {
                e.preventDefault();
                if (!gameActive || gamePaused) return;
                const index = parseInt(canvas.id.replace(&#039;block&#039;, &#039;&#039;)) - 1;
                rotateSelectedBlock(90, index);
                drawBlock(index, currentBlocks[index].shape, currentBlocks[index].color);
                console.log(&#039;Блок повернуто на 90°:&#039;, index, &#039;Нова форма:&#039;, JSON.stringify(currentBlocks[index].shape));
            });

            canvas.addEventListener(&#039;touchstart&#039;, (e) =&gt; {
                if (!gameActive || gamePaused || e.touches.length &lt; 1) return;
                const index = parseInt(canvas.id.replace(&#039;block&#039;, &#039;&#039;)) - 1;
                selectedBlock = currentBlocks[index];
                selectedBlockIndex = index;
                canvas.classList.add(&#039;dragging&#039;);
                if (e.touches.length === 1) {
                    touchStart = { x1: e.touches[0].clientX, y1: e.touches[0].clientY, time: Date.now() };
                } else if (e.touches.length === 2) {
                    touchStart = { x1: e.touches[0].clientX, y1: e.touches[0].clientY, x2: e.touches[1].clientX, y2: e.touches[1].clientY, time: Date.now() };
                }
                console.log(&#039;Початок сенсорного перетягування/ротації блоку:&#039;, index, &#039;Блок:&#039;, JSON.stringify(selectedBlock));
            });

            canvas.addEventListener(&#039;touchmove&#039;, (e) =&gt; {
                e.preventDefault();
                if (!gameActive || gamePaused || e.touches.length !== 2 || selectedBlockIndex === -1) return;
                const touch1 = e.touches[0];
                const touch2 = e.touches[1];
                const dx = touch2.clientX - touch1.clientX;
                const dy = touch2.clientY - touch1.clientY;
                const startDx = touchStart.x2 - touchStart.x1;
                const startDy = touchStart.y2 - touchStart.y1;
                let angle = Math.atan2(dy, dx) - Math.atan2(startDy, startDx);
                angle = Math.round(degrees(angle) / 90) * 90; // Округлення до найближчих 90°
                rotateSelectedBlock(angle, selectedBlockIndex);
                drawBlock(selectedBlockIndex, currentBlocks[selectedBlockIndex].shape, currentBlocks[selectedBlockIndex].color);
                touchStart = { x1: touch1.clientX, y1: touch1.clientY, x2: touch2.clientX, y2: touch2.clientY, time: Date.now() };
            });

            canvas.addEventListener(&#039;touchend&#039;, (e) =&gt; {
                if (!gameActive || !selectedBlock || gamePaused) return;
                const touch = e.changedTouches[0];
                const rect = gameCanvas.getBoundingClientRect();
                const x = Math.floor((touch.clientX - rect.left) / cellSize);
                const y = Math.floor((touch.clientY - rect.top) / cellSize);
                console.log(`Сенсорне розміщення: координати (${x}, ${y}), індекс: ${selectedBlockIndex}, блок:`, JSON.stringify(selectedBlock));
                if (selectedBlockIndex &gt;= 0 &amp;&amp; selectedBlockIndex &lt; currentBlocks.length) {
                    if (canPlaceBlock(selectedBlock.shape, x, y)) {
                        placeBlock(selectedBlock.shape, selectedBlock.color, x, y, selectedBlockIndex);
                        currentBlocks.splice(selectedBlockIndex, 1);
                        console.log(&#039;Блок видалено з черги. Залишилося:&#039;, currentBlocks.length);
                        for (let i = 0; i &lt; 3; i++) {
                            const blockCanvas = document.getElementById(`block${i + 1}`);
                            blockCanvas.getContext(&#039;2d&#039;).clearRect(0, 0, blockCanvas.width, blockCanvas.height);
                            if (i &lt; currentBlocks.length) {
                                drawBlock(i, currentBlocks[i].shape, currentBlocks[i].color);
                            }
                        }
                        checkGameOver();
                        selectedBlock = null;
                        selectedBlockIndex = -1;
                    } else {
                        console.log(&#039;Неможливо розмістити блок на позиції:&#039;, x, y);
                    }
                }
                canvas.classList.remove(&#039;dragging&#039;);
                drawGrid();
                console.log(&#039;Сенсорне розміщення завершено&#039;);
                touchStart = null;
            });

            canvas.addEventListener(&#039;mousedown&#039;, (e) =&gt; {
                if (e.button === 1) {
                    e.preventDefault();
                    if (!gameActive || gamePaused) return;
                    const index = parseInt(canvas.id.replace(&#039;block&#039;, &#039;&#039;)) - 1;
                    currentBlocks[index].shape = flipShape(currentBlocks[index].shape);
                    drawBlock(index, currentBlocks[index].shape, currentBlocks[index].color);
                    console.log(&#039;Блок перевернуто (середня кнопка):&#039;, index, &#039;Нова форма:&#039;, JSON.stringify(currentBlocks[index].shape));
                }
            });
        });

        gameCanvas.addEventListener(&#039;dragover&#039;, (e) =&gt; {
            e.preventDefault();
            if (!gameActive || !selectedBlock || gamePaused) return;
            const rect = gameCanvas.getBoundingClientRect();
            const x = Math.floor((e.clientX - rect.left) / cellSize);
            const y = Math.floor((e.clientY - rect.top) / cellSize);
            const valid = canPlaceBlock(selectedBlock.shape, x, y);
            drawPreview(selectedBlock.shape, x, y, valid);
        });

        gameCanvas.addEventListener(&#039;drop&#039;, (e) =&gt; {
            e.preventDefault();
            if (!gameActive || !selectedBlock || gamePaused) return;
            const rect = gameCanvas.getBoundingClientRect();
            const x = Math.floor((e.clientX - rect.left) / cellSize);
            const y = Math.floor((e.clientY - rect.top) / cellSize);
            const index = parseInt(e.dataTransfer.getData(&#039;text/plain&#039;));
            console.log(`Розміщення через drag: координати (${x}, ${y}), індекс: ${index}, блок:`, JSON.stringify(selectedBlock));
            if (index &gt;= 0 &amp;&amp; index &lt; currentBlocks.length) {
                if (canPlaceBlock(selectedBlock.shape, x, y)) {
                    placeBlock(selectedBlock.shape, selectedBlock.color, x, y, index);
                    currentBlocks.splice(index, 1);
                    console.log(&#039;Блок видалено з черги. Залишилося:&#039;, currentBlocks.length);
                    for (let i = 0; i &lt; 3; i++) {
                        const blockCanvas = document.getElementById(`block${i + 1}`);
                        blockCanvas.getContext(&#039;2d&#039;).clearRect(0, 0, blockCanvas.width, blockCanvas.height);
                        if (i &lt; currentBlocks.length) {
                            drawBlock(i, currentBlocks[i].shape, currentBlocks[i].color);
                        }
                    }
                    checkGameOver();
                    selectedBlock = null;
                    selectedBlockIndex = -1;
                } else {
                    console.log(&#039;Неможливо розмістити блок на позиції:&#039;, x, y);
                }
            } else {
                console.error(&#039;Помилка: невалідний індекс блоку на drop&#039;, index);
            }
        });

        function generateBlocks() {
            currentBlocks = [];
            for (let i = 0; i &lt; 3; i++) {
                const shapeIndex = Math.floor(Math.random() * blockShapes.length);
                const colorIndex = Math.floor(Math.random() * colors.length);
                currentBlocks.push({ shape: blockShapes[shapeIndex], color: colors[colorIndex] });
                drawBlock(i, currentBlocks[i].shape, currentBlocks[i].color);
            }
        }

        function drawBlock(index, shape, color) {
            const canvas = document.getElementById(`block${index + 1}`);
            const blockCtx = canvas.getContext(&#039;2d&#039;);
            blockCtx.clearRect(0, 0, canvas.width, canvas.height);
            const maxSize = Math.max(shape.length, shape[0].length);
            const blockCellSize = canvas.width / maxSize;
            const offsetX = (canvas.width - maxSize * blockCellSize) / 2;
            const offsetY = (canvas.height - maxSize * blockCellSize) / 2;
            for (let y = 0; y &lt; shape.length; y++) {
                for (let x = 0; x &lt; shape[y].length; x++) {
                    if (shape[y][x]) {
                        blockCtx.fillStyle = color;
                        blockCtx.fillRect(offsetX + x * blockCellSize + 2, offsetY + y * blockCellSize + 2, blockCellSize - 4, blockCellSize - 4);
                        blockCtx.strokeStyle = &#039;#000&#039;;
                        blockCtx.strokeRect(offsetX + x * blockCellSize + 2, offsetY + y * blockCellSize + 2, blockCellSize - 4, blockCellSize - 4);
                    }
                }
            }
        }

        function rotateSelectedBlock(angle, index) {
            if (index === undefined || index &lt; 0 || index &gt;= currentBlocks.length) {
                console.error(&#039;Невірний індекс блоку для ротації:&#039;, index);
                return;
            }
            let shape = currentBlocks[index].shape;
            let newShape = Array(shape[0].length).fill().map(() =&gt; Array(shape.length).fill(0));
            for (let y = 0; y &lt; shape.length; y++) {
                for (let x = 0; x &lt; shape[y].length; x++) {
                    let newX, newY;
                    if (angle === 90) {
                        newX = shape.length - 1 - y;
                        newY = x;
                    } else if (angle === 180) {
                        newX = shape[y].length - 1 - x;
                        newY = shape.length - 1 - y;
                    } else if (angle === 270) {
                        newX = y;
                        newY = shape[0].length - 1 - x;
                    } else {
                        return; // Нічого не робимо для інших кутів
                    }
                    newShape[newY][newX] = shape[y][x];
                }
            }
            currentBlocks[index].shape = newShape;
            drawBlock(index, currentBlocks[index].shape, currentBlocks[index].color);
            console.log(`Блок повернуто на ${angle}°:`, index, &#039;Нова форма:&#039;, JSON.stringify(currentBlocks[index].shape));
        }

        function flipShape(shape) {
            return shape[0].map((_, col) =&gt; shape.map(row =&gt; row[col]).reverse());
        }

        function undoMove() {
            if (lastMove) {
                grid = lastMove.grid;
                score = lastMove.score;
                currentBlocks[lastMove.blockIndex] = lastMove.block;
                scoreElement.textContent = `Очки: ${score}`;
                drawGrid();
                drawBlock(lastMove.blockIndex, currentBlocks[lastMove.blockIndex].shape, currentBlocks[lastMove.blockIndex].color);
                lastMove = null;
                undoButton.disabled = true;
                console.log(&#039;Хід скасовано&#039;);
            }
        }

        generateBlocks();
        drawGrid();
        console.log(&#039;Гра ініціалізована — Мозаїка Майстрів Версія 1.9&#039;);
    &lt;/script&gt;</description>
            </item>
                    <item>
                <title>мм2</title>
                <link>http://margo.mozello.shop/gry/params/post/5139951/mm2</link>
                <pubDate>Tue, 30 Sep 2025 11:51:00 +0000</pubDate>
                <description>ооооооооооооооооооооооооооооооооооооо&lt;hr class=&quot;moze-more-divider&quot;&gt;&lt;p&gt;1&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;Мозаїка Майстрів — Версія 1.9&lt;/title&gt;
    &lt;style&gt;
        body {
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            min-height: 100vh;
            margin: 0;
            padding: 10px;
            background-color: #f0f0f0;
            font-family: Arial, sans-serif;
            overflow: auto;
        }
        #gameCanvas {
            border: 2px solid #333;
            background-color: #e3f1c6;
            max-width: 100%;
            height: auto;
            margin-top: 20px;
        }
        #nextBlocks {
            display: flex;
            justify-content: center;
            margin-top: 10px;
            flex-wrap: wrap;
            width: 100%;
            max-width: 260px;
            gap: 1px;
        }
        .blockCanvas {
            border: 1px solid #ccc;
            cursor: grab;
            width: 80px;
            height: 80px;
            margin: 2px;
        }
        .blockCanvas.dragging {
            opacity: 0.5;
            cursor: grabbing;
        }
        #score, #highScore {
            font-size: 20px;
            margin-top: 10px;
        }
        #bonusMessage {
            display: none;
            position: fixed;
            top: 20%;
            left: 50%;
            transform: translateX(-50%);
            background-color: rgba(0, 128, 0, 0.8);
            color: white;
            padding: 10px 20px;
            border-radius: 5px;
            z-index: 1000;
            font-size: 18px;
        }
        #gameOver, #pauseOverlay {
            display: none;
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            background-color: rgba(0, 0, 0, 0.8);
            color: white;
            padding: 15px;
            border-radius: 10px;
            text-align: center;
            z-index: 1000;
        }
        button {
            margin-top: 10px;
            padding: 8px 16px;
            font-size: 14px;
            cursor: pointer;
        }
        h2 {
            margin: 10px 0;
        }
        p {
            margin: 5px 0;
        }
        .accordion {
            width: 100%;
            max-width: 500px;
            margin-top: 20px;
        }
        .accordion-item {
            border: 1px solid #333;
            margin-bottom: 5px;
            border-radius: 5px;
        }
        .accordion-header {
            background-color: #ddd;
            padding: 10px;
            cursor: pointer;
            font-size: 18px;
            font-weight: bold;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }
        .accordion-header::after {
            content: &#039;▼&#039;;
            font-size: 14px;
        }
        .accordion-header.active::after {
            content: &#039;▲&#039;;
        }
        .accordion-content {
            display: none;
            padding: 10px;
            background-color: #fff;
        }
        .accordion-content.active {
            display: block;
        }
        .accordion-content table {
            width: 100%;
            border-collapse: collapse;
            margin-bottom: 15px;
        }
        .accordion-content th, .accordion-content td {
            border: 1px solid #333;
            padding: 8px;
            text-align: center;
        }
        .accordion-content th {
            background-color: #ddd;
        }
        .accordion-content pre {
            margin: 0;
            font-size: 12px;
        }
        .accordion-content canvas {
            border: 1px solid #ccc;
        }
    &lt;/style&gt;


    &lt;h2&gt;Мозаїка Майстрів — Версія 1.9&lt;/h2&gt;
    &lt;p&gt;Права кнопка миші — поворот блоку, Середня кнопка/подвійне торкання — перевертання, Кнопка &quot;Скасувати&quot; — скасування ходу&lt;/p&gt;
    &lt;canvas id=&quot;gameCanvas&quot; width=&quot;300&quot; height=&quot;300&quot;&gt;&lt;/canvas&gt;
    &lt;button id=&quot;pauseButton&quot; fdprocessedid=&quot;imgj4r&quot;&gt;Пауза&lt;/button&gt;
    &lt;button id=&quot;undoButton&quot; disabled=&quot;&quot;&gt;Скасувати&lt;/button&gt;
    &lt;div id=&quot;nextBlocks&quot;&gt;
        &lt;canvas id=&quot;block1&quot; class=&quot;blockCanvas&quot; width=&quot;80&quot; height=&quot;80&quot; draggable=&quot;true&quot;&gt;&lt;/canvas&gt;
        &lt;canvas id=&quot;block2&quot; class=&quot;blockCanvas&quot; width=&quot;80&quot; height=&quot;80&quot; draggable=&quot;true&quot;&gt;&lt;/canvas&gt;
        &lt;canvas id=&quot;block3&quot; class=&quot;blockCanvas&quot; width=&quot;80&quot; height=&quot;80&quot; draggable=&quot;true&quot;&gt;&lt;/canvas&gt;
    &lt;/div&gt;
    &lt;div id=&quot;score&quot;&gt;Очки: 0&lt;/div&gt;
    &lt;div id=&quot;highScore&quot;&gt;Рекорд: 0&lt;/div&gt;
    &lt;div id=&quot;bonusMessage&quot;&gt;&lt;/div&gt;
    &lt;div id=&quot;gameOver&quot;&gt;
        &lt;h2&gt;Гра закінчена!&lt;/h2&gt;
        &lt;p id=&quot;finalScore&quot;&gt;&lt;/p&gt;
        &lt;button onclick=&quot;restartGame()&quot;&gt;Грати знову&lt;/button&gt;
    &lt;/div&gt;
    &lt;div id=&quot;pauseOverlay&quot;&gt;
        &lt;h2&gt;Гра на паузі&lt;/h2&gt;
        &lt;button onclick=&quot;togglePause()&quot;&gt;Відновити&lt;/button&gt;
    &lt;/div&gt;

    &lt;div class=&quot;accordion&quot;&gt;
        &lt;div class=&quot;accordion-item&quot;&gt;
            &lt;div class=&quot;accordion-header&quot; onclick=&quot;toggleAccordion(this)&quot;&gt;Таблиця блоків&lt;/div&gt;
            &lt;div class=&quot;accordion-content&quot;&gt;
                &lt;table&gt;
                    &lt;thead&gt;
                        &lt;tr&gt;
                            &lt;th&gt;Назва&lt;/th&gt;
                            &lt;th&gt;Зображення&lt;/th&gt;
                            &lt;th&gt;Структура&lt;/th&gt;
                            &lt;th&gt;Використання&lt;/th&gt;
                        &lt;/tr&gt;
                    &lt;/thead&gt;
                    &lt;tbody&gt;
                        &lt;tr&gt;
                            &lt;td&gt;Одинарний&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeSingle&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для заповнення окремих клітинок&lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;tr&gt;
                            &lt;td&gt;L-форма&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeL&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1, 1],&lt;br&gt;[1, 0]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для кутів або вузьких просторів&lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;tr&gt;
                            &lt;td&gt;T-форма&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeT&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1, 1, 1],&lt;br&gt;[0, 1, 0]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для горизонтальних ліній з виступом&lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;tr&gt;
                            &lt;td&gt;I-форма (4)&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeI4&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1, 1, 1, 1]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для заповнення рядків/стовпців&lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;tr&gt;
                            &lt;td&gt;Квадрат&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeSquare&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1, 1],&lt;br&gt;[1, 1]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для компактних квадратних просторів&lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;tr&gt;
                            &lt;td&gt;Z-форма&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeZ&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1, 1, 0],&lt;br&gt;[0, 1, 1]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для зміщених &quot;змійок&quot;&lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;tr&gt;
                            &lt;td&gt;I-форма (5)&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeI5&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1, 1, 1, 1, 1]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для довгих рядків/стовпців&lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;tr&gt;
                            &lt;td&gt;I-форма (3)&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeI3&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1, 1, 1]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для середніх рядків/стовпців&lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;tr&gt;
                            &lt;td&gt;I-форма (2)&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeI2&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1, 1]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для коротких рядків/стовпців&lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;tr&gt;
                            &lt;td&gt;Діагональ 2x2&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeDiagonal2&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1, 0],&lt;br&gt;[0, 1]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для заповнення діагональних просторів&lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;tr&gt;
                            &lt;td&gt;Діагональ 3x3&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeDiagonal3&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1, 0, 0],&lt;br&gt;[0, 1, 0],&lt;br&gt;[0, 0, 1]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для довгих діагональних ліній&lt;/td&gt;
                        &lt;/tr&gt;
                    &lt;/tbody&gt;
                &lt;/table&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;accordion-item&quot;&gt;
            &lt;div class=&quot;accordion-header&quot; onclick=&quot;toggleAccordion(this)&quot;&gt;Інструкція&lt;/div&gt;
            &lt;div class=&quot;accordion-content&quot;&gt;
                &lt;h3&gt;Мета гри&lt;/h3&gt;
                &lt;p&gt;&quot;Мозаїка Майстрів&quot; — це головоломка, де гравець розміщує блоки на сітці 10x10, щоб очищати цілі рядки або стовпці. Мета — набрати якомога більше очок і встановити рекорд. Гра закінчується, коли жоден блок не можна розмістити.&lt;/p&gt;
                
                &lt;h3&gt;Правила гри&lt;/h3&gt;
                &lt;ul&gt;
                    &lt;li&gt;&lt;b&gt;Ігрове поле&lt;/b&gt;: Сітка 10x10, де клітинки можуть бути порожніми або заповненими.&lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Черга блоків&lt;/b&gt;: До трьох блоків відображаються знизу для розміщення.&lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Розміщення&lt;/b&gt;: Перетягуйте блоки на сітку. Розміщення можливе лише у вільних місцях.&lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Очищення ліній&lt;/b&gt;:
                        &lt;ul&gt;
                            &lt;li&gt;Повний рядок або стовпець очищається.&lt;/li&gt;
                            &lt;li&gt;1 лінія: 100 очок.&lt;/li&gt;
                            &lt;li&gt;2+ ліній: 100 + 50 за кожну додаткову (наприклад, 2 лінії = 150 очок).&lt;/li&gt;
                        &lt;/ul&gt;
                    &lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Бонус за очищення поля&lt;/b&gt;: 25% від суми очок, якщо поле порожнє.&lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Рекорд&lt;/b&gt;: Зберігається у браузері, відображається під час гри та після завершення.&lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Кінець гри&lt;/b&gt;: Гра закінчується, якщо блоки неможливо розмістити.&lt;/li&gt;
                &lt;/ul&gt;

                &lt;h3&gt;Дії гравця&lt;/h3&gt;
                &lt;ul&gt;
                    &lt;li&gt;&lt;b&gt;Перетягування&lt;/b&gt;:
                        &lt;ul&gt;
                            &lt;li&gt;ПК: Лівою кнопкою миші.&lt;/li&gt;
                            &lt;li&gt;Сенсорні пристрої: Торкніться та перетягніть.&lt;/li&gt;
                        &lt;/ul&gt;
                    &lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Поворот&lt;/b&gt;: Права кнопка миші (90°).&lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Перевертання&lt;/b&gt;:
                        &lt;ul&gt;
                            &lt;li&gt;ПК: Середня кнопка миші або подвійне клацання.&lt;/li&gt;
                            &lt;li&gt;Сенсорні пристрої: Подвійне торкання.&lt;/li&gt;
                        &lt;/ul&gt;
                    &lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Скасування ходу&lt;/b&gt;: Кнопка &quot;Скасувати&quot; для останнього ходу.&lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Пауза&lt;/b&gt;: Кнопка &quot;Пауза&quot;/&quot;Відновити&quot;.&lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Перезапуск&lt;/b&gt;: Кнопка &quot;Грати знову&quot; на екрані &quot;Гра закінчена&quot;.&lt;/li&gt;
                &lt;/ul&gt;

                &lt;h3&gt;Поради&lt;/h3&gt;
                &lt;ul&gt;
                    &lt;li&gt;Плануйте ходи, щоб створювати повні лінії.&lt;/li&gt;
                    &lt;li&gt;Використовуйте одинарний блок для прогалин.&lt;/li&gt;
                    &lt;li&gt;Скасовуйте невдалі ходи.&lt;/li&gt;
                    &lt;li&gt;Намагайтеся очищати кілька ліній для бонусів.&lt;/li&gt;
                    &lt;li&gt;Експериментуйте з діагональними блоками для унікальних комбінацій.&lt;/li&gt;
                &lt;/ul&gt;
            &lt;/div&gt;
        &lt;/div&gt;
    &lt;/div&gt;

    &lt;script&gt;
        // Акордеон-меню
        function toggleAccordion(header) {
            const content = header.nextElementSibling;
            const isActive = content.classList.contains(&#039;active&#039;);
            document.querySelectorAll(&#039;.accordion-content&#039;).forEach(item =&gt; {
                item.classList.remove(&#039;active&#039;);
                item.previousElementSibling.classList.remove(&#039;active&#039;);
            });
            if (!isActive) {
                content.classList.add(&#039;active&#039;);
                header.classList.add(&#039;active&#039;);
            }
        }

        // Ігрова логіка
        const gameCanvas = document.getElementById(&#039;gameCanvas&#039;);
        const ctx = gameCanvas.getContext(&#039;2d&#039;);
        const gridSize = 10;
        const cellSize = gameCanvas.width / gridSize; // 30px
        const scoreElement = document.getElementById(&#039;score&#039;);
        const highScoreElement = document.getElementById(&#039;highScore&#039;);
        const bonusMessageElement = document.getElementById(&#039;bonusMessage&#039;);
        const gameOverElement = document.getElementById(&#039;gameOver&#039;);
        const finalScoreElement = document.getElementById(&#039;finalScore&#039;);
        const pauseButton = document.getElementById(&#039;pauseButton&#039;);
        const undoButton = document.getElementById(&#039;undoButton&#039;);
        const pauseOverlay = document.getElementById(&#039;pauseOverlay&#039;);

        let grid = Array(gridSize).fill().map(() =&gt; Array(gridSize).fill(null));
        let score = 0;
        let highScore = parseInt(localStorage.getItem(&#039;blockLegendHighScore&#039;)) || 0;
        let currentBlocks = [];
        let selectedBlock = null;
        let gameActive = true;
        let gamePaused = false;
        let lastMove = null;

        highScoreElement.textContent = `Рекорд: ${highScore}`;
        console.log(&#039;Завантажено рекорд:&#039;, highScore);

        const blockShapes = [
            [[1]], // Одинарний (1x1)
            [[1]], // Одинарний (збільшена ймовірність)
            [[1, 1], [1, 0]], // L-форма
            [[1, 1, 1], [0, 1, 0]], // T-форма
            [[1, 1, 1, 1]], // I-форма (4)
            [[1, 1], [1, 1]], // Квадрат
            [[1, 1, 0], [0, 1, 1]], // Z-форма
            [[1, 1, 1, 1, 1]], // I-форма (5)
            [[1, 1, 1]], // I-форма (3)
            [[1, 1]], // I-форма (2)
            [[1, 0], [0, 1]], // Діагональ 2x2
            [[1, 0, 0], [0, 1, 0], [0, 0, 1]] // Діагональ 3x3
        ];

        const colors = [&#039;#FF0000&#039;, &#039;#00FF00&#039;, &#039;#0000FF&#039;, &#039;#FFFF00&#039;, &#039;#FF00FF&#039;, &#039;#FFA500&#039;, &#039;#800080&#039;, &#039;#00FFFF&#039;, &#039;#FF4500&#039;, &#039;#2E8B57&#039;, &#039;#DAA520&#039;, &#039;#8A2BE2&#039;];

        // Малювання блоків у таблиці
        function drawTableBlock(canvasId, shape, color) {
            const canvas = document.getElementById(canvasId);
            const ctx = canvas.getContext(&#039;2d&#039;);
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            const maxSize = Math.max(shape.length, shape[0].length);
            const blockCellSize = canvas.width / maxSize;
            shape.forEach((row, y) =&gt; {
                row.forEach((cell, x) =&gt; {
                    if (cell) {
                        ctx.fillStyle = color;
                        ctx.fillRect(x * blockCellSize + 2, y * blockCellSize + 2, blockCellSize - 4, blockCellSize - 4);
                        ctx.strokeStyle = &#039;#000&#039;;
                        ctx.strokeRect(x * blockCellSize + 2, y * blockCellSize + 2, blockCellSize - 4, blockCellSize - 4);
                    }
                });
            });
        }

        // Ініціалізація малюнків у таблиці
        drawTableBlock(&#039;shapeSingle&#039;, blockShapes[0], colors[0]);
        drawTableBlock(&#039;shapeL&#039;, blockShapes[2], colors[1]);
        drawTableBlock(&#039;shapeT&#039;, blockShapes[3], colors[2]);
        drawTableBlock(&#039;shapeI4&#039;, blockShapes[4], colors[3]);
        drawTableBlock(&#039;shapeSquare&#039;, blockShapes[5], colors[4]);
        drawTableBlock(&#039;shapeZ&#039;, blockShapes[6], colors[0]);
        drawTableBlock(&#039;shapeI5&#039;, blockShapes[7], colors[5]);
        drawTableBlock(&#039;shapeI3&#039;, blockShapes[8], colors[6]);
        drawTableBlock(&#039;shapeI2&#039;, blockShapes[9], colors[1]);
        drawTableBlock(&#039;shapeDiagonal2&#039;, blockShapes[10], colors[10]);
        drawTableBlock(&#039;shapeDiagonal3&#039;, blockShapes[11], colors[11]);

        function showBonusMessage(message) {
            bonusMessageElement.textContent = message;
            bonusMessageElement.style.display = &#039;block&#039;;
            setTimeout(() =&gt; {
                bonusMessageElement.style.display = &#039;none&#039;;
            }, 2000);
        }

        function rotateShape(shape) {
            const rows = shape.length;
            const cols = shape[0].length;
            const newShape = Array(cols).fill().map(() =&gt; Array(rows).fill(0));
            for (let y = 0; y &lt; rows; y++) {
                for (let x = 0; x &lt; cols; x++) {
                    newShape[x][rows - 1 - y] = shape[y][x];
                }
            }
            return newShape;
        }

        function flipShape(shape) {
            const newShape = shape.map(row =&gt; [...row].reverse());
            return newShape;
        }

        function undoMove() {
            if (!lastMove || !gameActive || gamePaused) return;
            const { grid: prevGrid, score: prevScore, block, blockIndex } = lastMove;
            grid = prevGrid.map(row =&gt; [...row]);
            score = prevScore;
            scoreElement.textContent = `Очки: ${score}`;
            currentBlocks.splice(blockIndex, 0, block);
            for (let i = 0; i &lt; 3; i++) {
                if (i &lt; currentBlocks.length) {
                    drawBlock(i, currentBlocks[i].shape, currentBlocks[i].color);
                } else {
                    document.getElementById(`block${i + 1}`).getContext(&#039;2d&#039;).clearRect(0, 0, 80, 80);
                }
            }
            lastMove = null;
            undoButton.disabled = true;
            drawGrid();
            console.log(&#039;Хід скасовано&#039;);
        }

        function generateBlocks() {
            console.log(&#039;Генеруються нові блоки, поточна кількість:&#039;, currentBlocks.length);
            currentBlocks = [];
            for (let i = 1; i &lt;= 3; i++) {
                document.getElementById(`block${i}`).getContext(&#039;2d&#039;).clearRect(0, 0, 80, 80);
            }
            for (let i = 0; i &lt; 3; i++) {
                const shapeIndex = Math.floor(Math.random() * blockShapes.length);
                const color = colors[Math.floor(Math.random() * colors.length)];
                currentBlocks.push({ shape: blockShapes[shapeIndex], color });
                drawBlock(i, blockShapes[shapeIndex], color);
                console.log(`Згенеровано блок ${i + 1}: форма ${JSON.stringify(blockShapes[shapeIndex])}, колір ${color}`);
            }
            console.log(&#039;Нові блоки створено:&#039;, JSON.stringify(currentBlocks.map(b =&gt; ({ shape: b.shape, color: b.color }))));
            drawGrid();
        }

        function drawBlock(index, shape, color) {
            const blockCanvas = document.getElementById(`block${index + 1}`);
            const blockCtx = blockCanvas.getContext(&#039;2d&#039;);
            blockCtx.clearRect(0, 0, blockCanvas.width, blockCanvas.height);
            const maxSize = Math.max(shape.length, shape[0].length);
            const blockCellSize = Math.min(blockCanvas.width / maxSize, blockCanvas.height / maxSize) * 0.9;
            const offsetX = (blockCanvas.width - maxSize * blockCellSize) / 2;
            const offsetY = (blockCanvas.height - maxSize * blockCellSize) / 2;
            shape.forEach((row, y) =&gt; {
                row.forEach((cell, x) =&gt; {
                    if (cell) {
                        blockCtx.fillStyle = color;
                        blockCtx.fillRect(offsetX + x * blockCellSize + 2, offsetY + y * blockCellSize + 2, blockCellSize - 4, blockCellSize - 4);
                        blockCtx.strokeStyle = &#039;#000&#039;;
                        blockCtx.strokeRect(offsetX + x * blockCellSize + 2, offsetY + y * blockCellSize + 2, blockCellSize - 4, blockCellSize - 4);
                    }
                });
            });
        }

        function drawGrid() {
            ctx.clearRect(0, 0, gameCanvas.width, gameCanvas.height);
            for (let y = 0; y &lt; gridSize; y++) {
                for (let x = 0; x &lt; gridSize; x++) {
                    ctx.strokeStyle = &#039;#000&#039;;
                    ctx.strokeRect(x * cellSize, y * cellSize, cellSize, cellSize);
                    if (grid[y][x]) {
                        ctx.fillStyle = grid[y][x];
                        ctx.fillRect(x * cellSize + 2, y * cellSize + 2, cellSize - 4, cellSize - 4);
                    }
                }
            }
        }

        function drawPreview(shape, x, y, valid) {
            drawGrid();
            if (shape &amp;&amp; x &gt;= 0 &amp;&amp; y &gt;= 0) {
                ctx.globalAlpha = 0.5;
                for (let sy = 0; sy &lt; shape.length; sy++) {
                    for (let sx = 0; sx &lt; shape[sy].length; sx++) {
                        if (shape[sy][sx]) {
                            ctx.fillStyle = valid ? selectedBlock.color : &#039;#FF0000&#039;;
                            ctx.fillRect((x + sx) * cellSize + 2, (y + sy) * cellSize + 2, cellSize - 4, cellSize - 4);
                            ctx.strokeStyle = &#039;#000&#039;;
                            ctx.strokeRect((x + sx) * cellSize + 2, (y + sy) * cellSize + 2, cellSize - 4, cellSize - 4);
                        }
                    }
                }
                ctx.globalAlpha = 1.0;
            }
        }

        function canPlaceBlock(shape, x, y) {
            for (let sy = 0; sy &lt; shape.length; sy++) {
                for (let sx = 0; sx &lt; shape[sy].length; sx++) {
                    if (shape[sy][sx]) {
                        const gridX = x + sx;
                        const gridY = y + sy;
                        if (gridX &lt; 0 || gridX &gt;= gridSize || gridY &lt; 0 || gridY &gt;= gridSize || grid[gridY][gridX]) {
                            return false;
                        }
                    }
                }
            }
            return true;
        }

        function placeBlock(shape, color, x, y, blockIndex) {
            console.log(`Розміщення блоку на позиції (${x}, ${y}), індекс: ${blockIndex}, форма:`, JSON.stringify(shape));
            lastMove = {
                grid: grid.map(row =&gt; [...row]),
                score,
                block: { shape, color },
                blockIndex
            };
            undoButton.disabled = false;
            for (let sy = 0; sy &lt; shape.length; sy++) {
                for (let sx = 0; sx &lt; shape[sy].length; sx++) {
                    if (shape[sy][sx]) {
                        grid[y + sy][x + sx] = color;
                    }
                }
            }
            console.log(&#039;Блок розміщено, викликаємо checkLines&#039;);
            checkLines();
            console.log(&#039;checkLines завершено, викликаємо checkGameOver&#039;);
            checkGameOver();
            drawGrid();
            console.log(&#039;Розміщення завершено, поточна черга:&#039;, JSON.stringify(currentBlocks.map(b =&gt; ({ shape: b.shape, color: b.color }))));
        }

        function checkLines() {
            let linesCleared = 0;
            for (let y = gridSize - 1; y &gt;= 0; y--) {
                if (grid[y].every(cell =&gt; cell)) {
                    grid.splice(y, 1);
                    grid.unshift(Array(gridSize).fill(null));
                    linesCleared++;
                    y++;
                }
            }
            for (let x = gridSize - 1; x &gt;= 0; x--) {
                let isFull = true;
                for (let y = 0; y &lt; gridSize; y++) {
                    if (!grid[y][x]) {
                        isFull = false;
                        break;
                    }
                }
                if (isFull) {
                    for (let y = 0; y &lt; gridSize; y++) {
                        grid[y].splice(x, 1);
                        grid[y].push(null);
                    }
                    linesCleared++;
                    x++;
                }
            }
            if (linesCleared &gt; 0) {
                let lineBonus = linesCleared === 1 ? 100 : 100 + (linesCleared - 1) * 50;
                score += lineBonus;
                if (linesCleared &gt; 1) {
                    showBonusMessage(`Бонус за ${linesCleared} лінії: +${lineBonus} очок`);
                    console.log(`Бонус за очищення ${linesCleared} ліній: +${lineBonus} очок`);
                }
                const isGridEmpty = grid.every(row =&gt; row.every(cell =&gt; !cell));
                if (isGridEmpty &amp;&amp; score &gt; 0) {
                    const clearBonus = Math.floor(score * 0.25);
                    score += clearBonus;
                    showBonusMessage(`Бонус за повне очищення поля: +${clearBonus} очок`);
                    console.log(`Бонус за повне очищення поля: +${clearBonus} очок`);
                }
                scoreElement.textContent = `Очки: ${score}`;
                if (score &gt; highScore) {
                    highScore = score;
                    localStorage.setItem(&#039;blockLegendHighScore&#039;, highScore);
                    highScoreElement.textContent = `Рекорд: ${highScore}`;
                    console.log(&#039;Новий рекорд:&#039;, highScore);
                }
            }
            console.log(&#039;Очищено ліній:&#039;, linesCleared, &#039;Очки:&#039;, score, &#039;Рекорд:&#039;, highScore);
        }

        function checkGameOver() {
            console.log(&#039;Перевірка стану гри. Кількість блоків:&#039;, currentBlocks.length, &#039;Блоки:&#039;, JSON.stringify(currentBlocks.map(b =&gt; ({ shape: b.shape, color: b.color }))));
            if (currentBlocks.length === 0) {
                console.log(&#039;Черга порожня, генеруємо нові блоки&#039;);
                setTimeout(() =&gt; {
                    generateBlocks();
                    console.log(&#039;Нові блоки згенеровано, нова черга:&#039;, JSON.stringify(currentBlocks.map(b =&gt; ({ shape: b.shape, color: b.color }))));
                }, 0);
                return;
            }
            let canPlaceAny = false;
            for (let block of currentBlocks) {
                for (let y = 0; y &lt; gridSize; y++) {
                    for (let x = 0; x &lt; gridSize; x++) {
                        if (canPlaceBlock(block.shape, x, y)) {
                            canPlaceAny = true;
                            break;
                        }
                    }
                    if (canPlaceAny) break;
                }
                if (canPlaceAny) break;
            }
            console.log(&#039;Чи можна розмістити блок:&#039;, canPlaceAny);
            if (!canPlaceAny) {
                gameActive = false;
                if (score &gt; highScore) {
                    highScore = score;
                    localStorage.setItem(&#039;blockLegendHighScore&#039;, highScore);
                    console.log(&#039;Новий рекорд на кінці гри:&#039;, highScore);
                }
                finalScoreElement.textContent = `Ваш рахунок: ${score}\nРекорд: ${highScore}`;
                gameOverElement.style.display = &#039;block&#039;;
                console.log(&#039;Гра закінчена. Рахунок:&#039;, score, &#039;Рекорд:&#039;, highScore);
            }
        }

        function restartGame() {
            grid = Array(gridSize).fill().map(() =&gt; Array(gridSize).fill(null));
            score = 0;
            scoreElement.textContent = `Очки: ${score}`;
            highScoreElement.textContent = `Рекорд: ${highScore}`;
            gameOverElement.style.display = &#039;none&#039;;
            gamePaused = false;
            pauseButton.textContent = &#039;Пауза&#039;;
            pauseOverlay.style.display = &#039;none&#039;;
            undoButton.disabled = true;
            lastMove = null;
            gameActive = true;
            currentBlocks = [];
            generateBlocks();
            drawGrid();
            console.log(&#039;Гра перезапущена. Рахунок:&#039;, score, &#039;Рекорд:&#039;, highScore);
        }

        function togglePause() {
            if (!gameActive) return;
            gamePaused = !gamePaused;
            pauseButton.textContent = gamePaused ? &#039;Відновити&#039; : &#039;Пауза&#039;;
            pauseOverlay.style.display = gamePaused ? &#039;block&#039; : &#039;none&#039;;
            console.log(&#039;Гра на паузі:&#039;, gamePaused);
        }

        pauseButton.addEventListener(&#039;click&#039;, togglePause);
        undoButton.addEventListener(&#039;click&#039;, undoMove);

        const blockCanvases = document.querySelectorAll(&#039;.blockCanvas&#039;);
        blockCanvases.forEach(canvas =&gt; {
            canvas.addEventListener(&#039;dragstart&#039;, (e) =&gt; {
                if (!gameActive || gamePaused) return;
                const index = parseInt(canvas.id.replace(&#039;block&#039;, &#039;&#039;)) - 1;
                selectedBlock = currentBlocks[index];
                canvas.classList.add(&#039;dragging&#039;);
                e.dataTransfer.setData(&#039;text/plain&#039;, index);
                console.log(&#039;Початок перетягування блоку:&#039;, index, &#039;Блок:&#039;, JSON.stringify(selectedBlock));
            });

            canvas.addEventListener(&#039;dragend&#039;, (e) =&gt; {
                canvas.classList.remove(&#039;dragging&#039;);
                drawGrid();
                console.log(&#039;Кінець перетягування&#039;);
            });

            canvas.addEventListener(&#039;contextmenu&#039;, (e) =&gt; {
                e.preventDefault();
                if (!gameActive || gamePaused) return;
                const index = parseInt(canvas.id.replace(&#039;block&#039;, &#039;&#039;)) - 1;
                currentBlocks[index].shape = rotateShape(currentBlocks[index].shape);
                drawBlock(index, currentBlocks[index].shape, currentBlocks[index].color);
                console.log(&#039;Блок повернуто:&#039;, index, &#039;Нова форма:&#039;, JSON.stringify(currentBlocks[index].shape));
            });

            canvas.addEventListener(&#039;mousedown&#039;, (e) =&gt; {
                if (e.button === 1) {
                    e.preventDefault();
                    if (!gameActive || gamePaused) return;
                    const index = parseInt(canvas.id.replace(&#039;block&#039;, &#039;&#039;)) - 1;
                    currentBlocks[index].shape = flipShape(currentBlocks[index].shape);
                    drawBlock(index, currentBlocks[index].shape, currentBlocks[index].color);
                    console.log(&#039;Блок перевернуто (середня кнопка):&#039;, index, &#039;Нова форма:&#039;, JSON.stringify(currentBlocks[index].shape));
                }
            });

            canvas.addEventListener(&#039;dblclick&#039;, (e) =&gt; {
                e.preventDefault();
                if (!gameActive || gamePaused) return;
                const index = parseInt(canvas.id.replace(&#039;block&#039;, &#039;&#039;)) - 1;
                if (index &gt;= 0 &amp;&amp; index &lt; currentBlocks.length) {
                    currentBlocks[index].shape = flipShape(currentBlocks[index].shape);
                    drawBlock(index, currentBlocks[index].shape, currentBlocks[index].color);
                    console.log(&#039;Блок перевернуто (подвійне клацання):&#039;, index, &#039;Нова форма:&#039;, JSON.stringify(currentBlocks[index].shape));
                }
            });

            canvas.addEventListener(&#039;touchstart&#039;, (e) =&gt; {
                if (!gameActive || gamePaused) return;
                const index = parseInt(canvas.id.replace(&#039;block&#039;, &#039;&#039;)) - 1;
                if (index &gt;= 0 &amp;&amp; index &lt; currentBlocks.length) {
                    selectedBlock = currentBlocks[index];
                    canvas.classList.add(&#039;dragging&#039;);
                    console.log(&#039;Початок сенсорного перетягування блоку:&#039;, index, &#039;Блок:&#039;, JSON.stringify(selectedBlock));
                } else {
                    console.error(&#039;Помилка: невалідний індекс блоку на touchstart&#039;, index);
                }
            });

            canvas.addEventListener(&#039;touchmove&#039;, (e) =&gt; {
                e.preventDefault();
                if (!gameActive || !selectedBlock || gamePaused) return;
                const touch = e.touches[0];
                const rect = gameCanvas.getBoundingClientRect();
                const x = Math.floor((touch.clientX - rect.left) / cellSize);
                const y = Math.floor((touch.clientY - rect.top) / cellSize);
                const valid = canPlaceBlock(selectedBlock.shape, x, y);
                drawPreview(selectedBlock.shape, x, y, valid);
            });

            canvas.addEventListener(&#039;touchend&#039;, (e) =&gt; {
                if (!gameActive || !selectedBlock || gamePaused) return;
                const touch = e.changedTouches[0];
                const rect = gameCanvas.getBoundingClientRect();
                const x = Math.floor((touch.clientX - rect.left) / cellSize);
                const y = Math.floor((touch.clientY - rect.top) / cellSize);
                const index = parseInt(canvas.id.replace(&#039;block&#039;, &#039;&#039;)) - 1;
                console.log(`Сенсорне розміщення: координати (${x}, ${y}), індекс: ${index}, блок:`, JSON.stringify(selectedBlock));
                if (index &gt;= 0 &amp;&amp; index &lt; currentBlocks.length) {
                    if (canPlaceBlock(selectedBlock.shape, x, y)) {
                        placeBlock(selectedBlock.shape, selectedBlock.color, x, y, index);
                        currentBlocks.splice(index, 1);
                        console.log(&#039;Блок видалено з черги. Залишилося:&#039;, currentBlocks.length, &#039;Блоки:&#039;, JSON.stringify(currentBlocks.map(b =&gt; ({ shape: b.shape, color: b.color }))));
                        for (let i = 0; i &lt; 3; i++) {
                            const blockCanvas = document.getElementById(`block${i + 1}`);
                            blockCanvas.getContext(&#039;2d&#039;).clearRect(0, 0, blockCanvas.width, blockCanvas.height);
                            if (i &lt; currentBlocks.length) {
                                drawBlock(i, currentBlocks[i].shape, currentBlocks[i].color);
                            }
                        }
                        checkGameOver();
                        selectedBlock = null;
                    } else {
                        console.log(&#039;Неможливо розмістити блок на позиції:&#039;, x, y);
                    }
                } else {
                    console.error(&#039;Помилка: невалідний індекс блоку на touchend&#039;, index);
                }
                canvas.classList.remove(&#039;dragging&#039;);
                drawGrid();
                console.log(&#039;Сенсорне розміщення завершено&#039;);
            });
        });

        gameCanvas.addEventListener(&#039;dragover&#039;, (e) =&gt; {
            e.preventDefault();
            if (!gameActive || !selectedBlock || gamePaused) return;
            const rect = gameCanvas.getBoundingClientRect();
            const x = Math.floor((e.clientX - rect.left) / cellSize);
            const y = Math.floor((e.clientY - rect.top) / cellSize);
            const valid = canPlaceBlock(selectedBlock.shape, x, y);
            drawPreview(selectedBlock.shape, x, y, valid);
        });

        gameCanvas.addEventListener(&#039;drop&#039;, (e) =&gt; {
            e.preventDefault();
            if (!gameActive || !selectedBlock || gamePaused) return;
            const rect = gameCanvas.getBoundingClientRect();
            const x = Math.floor((e.clientX - rect.left) / cellSize);
            const y = Math.floor((e.clientY - rect.top) / cellSize);
            const index = parseInt(e.dataTransfer.getData(&#039;text/plain&#039;));
            console.log(`Розміщення через drag: координати (${x}, ${y}), індекс: ${index}, блок:`, JSON.stringify(selectedBlock));
            if (index &gt;= 0 &amp;&amp; index &lt; currentBlocks.length) {
                if (canPlaceBlock(selectedBlock.shape, x, y)) {
                    placeBlock(selectedBlock.shape, selectedBlock.color, x, y, index);
                    currentBlocks.splice(index, 1);
                    console.log(&#039;Блок видалено з черги. Залишилося:&#039;, currentBlocks.length, &#039;Блоки:&#039;, JSON.stringify(currentBlocks.map(b =&gt; ({ shape: b.shape, color: b.color }))));
                    for (let i = 0; i &lt; 3; i++) {
                        const blockCanvas = document.getElementById(`block${i + 1}`);
                        blockCanvas.getContext(&#039;2d&#039;).clearRect(0, 0, blockCanvas.width, blockCanvas.height);
                        if (i &lt; currentBlocks.length) {
                            drawBlock(i, currentBlocks[i].shape, currentBlocks[i].color);
                        }
                    }
                    checkGameOver();
                    selectedBlock = null;
                } else {
                    console.log(&#039;Неможливо розмістити блок на позиції:&#039;, x, y);
                }
            } else {
                console.error(&#039;Помилка: невалідний індекс блоку на drop&#039;, index);
            }
        });

        generateBlocks();
        drawGrid();
        console.log(&#039;Гра ініціалізована — Мозаїка Майстрів Версія 1.9&#039;);
    &lt;/script&gt;</description>
            </item>
                    <item>
                <title>Гра Мозаїка майстрів</title>
                <link>http://margo.mozello.shop/gry/params/post/5139155/gra-mozaka-majstrv</link>
                <pubDate>Sun, 28 Sep 2025 11:32:00 +0000</pubDate>
                <description>&lt;span style=&quot;text-align: start; font-weight: 300; font-style: normal&quot;&gt;Права кнопка миші — поворот блоку, Середня кнопка/подвійне торкання — перевертання, Кнопка &quot;Скасувати&quot; — скасування ход&lt;br&gt;гру створив вебпрограміст Бурка Мирон&lt;br&gt;&lt;/span&gt;&lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
    &lt;title&gt;Мозаїка Майстрів — Версія 1.7&lt;/title&gt;
    &lt;style&gt;
        body {
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            min-height: 100vh;
            margin: 0;
            padding: 10px;
            background-color: #f0f0f0;
            font-family: Arial, sans-serif;
            overflow: auto;
        }
        #gameCanvas {
            border: 2px solid #333;
            background-color: #e3f1c6;
            max-width: 100%;
            height: auto;
            margin-top: 20px;
        }
        #nextBlocks {
            display: flex;
            justify-content: center;
            margin-top: 10px;
            flex-wrap: wrap;
            width: 100%;
            max-width: 260px;
            gap: 1px;
        }
        .blockCanvas {
            border: 1px solid #ccc;
            cursor: grab;
            width: 80px;
            height: 80px;
            margin: 2px;
        }
        .blockCanvas.dragging {
            opacity: 0.5;
            cursor: grabbing;
        }
        #score, #highScore {
            font-size: 20px;
            margin-top: 10px;
        }
        #bonusMessage {
            display: none;
            position: fixed;
            top: 20%;
            left: 50%;
            transform: translateX(-50%);
            background-color: rgba(0, 128, 0, 0.8);
            color: white;
            padding: 10px 20px;
            border-radius: 5px;
            z-index: 1000;
            font-size: 18px;
        }
        #gameOver, #pauseOverlay {
            display: none;
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            background-color: rgba(0, 0, 0, 0.8);
            color: white;
            padding: 15px;
            border-radius: 10px;
            text-align: center;
            z-index: 1000;
        }
        button {
            margin-top: 10px;
            padding: 8px 16px;
            font-size: 14px;
            cursor: pointer;
        }
        h2 {
            margin: 10px 0;
        }
        p {
            margin: 5px 0;
        }
        .accordion {
            width: 100%;
            max-width: 500px;
            margin-top: 20px;
        }
        .accordion-item {
            border: 1px solid #333;
            margin-bottom: 5px;
            border-radius: 5px;
        }
        .accordion-header {
            background-color: #ddd;
            padding: 10px;
            cursor: pointer;
            font-size: 18px;
            font-weight: bold;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }
        .accordion-header::after {
            content: &#039;▼&#039;;
            font-size: 14px;
        }
        .accordion-header.active::after {
            content: &#039;▲&#039;;
        }
        .accordion-content {
            display: none;
            padding: 10px;
            background-color: #fff;
        }
        .accordion-content.active {
            display: block;
        }
        .accordion-content table {
            width: 100%;
            border-collapse: collapse;
            margin-bottom: 15px;
        }
        .accordion-content th, .accordion-content td {
            border: 1px solid #333;
            padding: 8px;
            text-align: center;
        }
        .accordion-content th {
            background-color: #ddd;
        }
        .accordion-content pre {
            margin: 0;
            font-size: 12px;
        }
        .accordion-content canvas {
            border: 1px solid #ccc;
        }
    &lt;/style&gt;


    &lt;h2&gt;Мозаїка Майстрів — Версія 1.7&lt;/h2&gt;
    &lt;canvas id=&quot;gameCanvas&quot; width=&quot;300&quot; height=&quot;300&quot;&gt;&lt;/canvas&gt;
    &lt;button id=&quot;pauseButton&quot; fdprocessedid=&quot;94ja&quot;&gt;Пауза&lt;/button&gt;
    &lt;button id=&quot;undoButton&quot; disabled=&quot;&quot;&gt;Скасувати&lt;/button&gt;
    &lt;div id=&quot;nextBlocks&quot;&gt;
        &lt;canvas id=&quot;block1&quot; class=&quot;blockCanvas&quot; width=&quot;80&quot; height=&quot;80&quot; draggable=&quot;true&quot;&gt;&lt;/canvas&gt;
        &lt;canvas id=&quot;block2&quot; class=&quot;blockCanvas&quot; width=&quot;80&quot; height=&quot;80&quot; draggable=&quot;true&quot;&gt;&lt;/canvas&gt;
        &lt;canvas id=&quot;block3&quot; class=&quot;blockCanvas&quot; width=&quot;80&quot; height=&quot;80&quot; draggable=&quot;true&quot;&gt;&lt;/canvas&gt;
    &lt;/div&gt;
    &lt;div id=&quot;score&quot;&gt;Очки: 0&lt;/div&gt;
    &lt;div id=&quot;highScore&quot;&gt;Рекорд: 0&lt;/div&gt;
    &lt;div id=&quot;bonusMessage&quot;&gt;&lt;/div&gt;
    &lt;div id=&quot;gameOver&quot;&gt;
        &lt;h2&gt;Гра закінчена!&lt;/h2&gt;
        &lt;p id=&quot;finalScore&quot;&gt;&lt;/p&gt;
        &lt;button onclick=&quot;restartGame()&quot;&gt;Грати знову&lt;/button&gt;
    &lt;/div&gt;
    &lt;div id=&quot;pauseOverlay&quot;&gt;
        &lt;h2&gt;Гра на паузі&lt;/h2&gt;
        &lt;button onclick=&quot;togglePause()&quot;&gt;Відновити&lt;/button&gt;
    &lt;/div&gt;

    &lt;div class=&quot;accordion&quot;&gt;
        &lt;div class=&quot;accordion-item&quot;&gt;
            &lt;div class=&quot;accordion-header&quot; onclick=&quot;toggleAccordion(this)&quot;&gt;Таблиця блоків&lt;/div&gt;
            &lt;div class=&quot;accordion-content&quot;&gt;
                &lt;table&gt;
                    &lt;thead&gt;
                        &lt;tr&gt;
                            &lt;th&gt;Назва&lt;/th&gt;
                            &lt;th&gt;Зображення&lt;/th&gt;
                            &lt;th&gt;Структура&lt;/th&gt;
                            &lt;th&gt;Використання&lt;/th&gt;
                        &lt;/tr&gt;
                    &lt;/thead&gt;
                    &lt;tbody&gt;
                        &lt;tr&gt;
                            &lt;td&gt;Одинарний&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeSingle&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для заповнення окремих клітинок&lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;tr&gt;
                            &lt;td&gt;L-форма&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeL&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1, 1],&lt;br&gt;[1, 0]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для кутів або вузьких просторів&lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;tr&gt;
                            &lt;td&gt;T-форма&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeT&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1, 1, 1],&lt;br&gt;[0, 1, 0]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для горизонтальних ліній з виступом&lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;tr&gt;
                            &lt;td&gt;I-форма (4)&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeI4&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1, 1, 1, 1]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для заповнення рядків/стовпців&lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;tr&gt;
                            &lt;td&gt;Квадрат&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeSquare&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1, 1],&lt;br&gt;[1, 1]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для компактних квадратних просторів&lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;tr&gt;
                            &lt;td&gt;Z-форма&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeZ&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1, 1, 0],&lt;br&gt;[0, 1, 1]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для зміщених &quot;змійок&quot;&lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;tr&gt;
                            &lt;td&gt;I-форма (5)&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeI5&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1, 1, 1, 1, 1]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для довгих рядків/стовпців&lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;tr&gt;
                            &lt;td&gt;I-форма (3)&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeI3&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1, 1, 1]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для середніх рядків/стовпців&lt;/td&gt;
                        &lt;/tr&gt;
                        &lt;tr&gt;
                            &lt;td&gt;I-форма (2)&lt;/td&gt;
                            &lt;td&gt;&lt;canvas id=&quot;shapeI2&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;&lt;/td&gt;
                            &lt;td&gt;&lt;pre&gt;[[1, 1]]&lt;/pre&gt;&lt;/td&gt;
                            &lt;td&gt;Для коротких рядків/стовпців&lt;/td&gt;
                        &lt;/tr&gt;
                    &lt;/tbody&gt;
                &lt;/table&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        &lt;div class=&quot;accordion-item&quot;&gt;
            &lt;div class=&quot;accordion-header&quot; onclick=&quot;toggleAccordion(this)&quot;&gt;Інструкція&lt;/div&gt;
            &lt;div class=&quot;accordion-content&quot;&gt;
                &lt;h3&gt;Мета гри&lt;/h3&gt;
                &lt;p&gt;&quot;Мозаїка Майстрів&quot; — це головоломка, де гравець розміщує блоки на сітці 10x10, щоб очищати цілі рядки або стовпці. Мета — набрати якомога більше очок і встановити рекорд. Гра закінчується, коли жоден блок не можна розмістити.&lt;/p&gt;
                
                &lt;h3&gt;Правила гри&lt;/h3&gt;
                &lt;ul&gt;
                    &lt;li&gt;&lt;b&gt;Ігрове поле&lt;/b&gt;: Сітка 10x10, де клітинки можуть бути порожніми або заповненими.&lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Черга блоків&lt;/b&gt;: До трьох блоків відображаються знизу для розміщення.&lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Розміщення&lt;/b&gt;: Перетягуйте блоки на сітку. Розміщення можливе лише у вільних місцях.&lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Очищення ліній&lt;/b&gt;:
                        &lt;ul&gt;
                            &lt;li&gt;Повний рядок або стовпець очищається.&lt;/li&gt;
                            &lt;li&gt;1 лінія: 100 очок.&lt;/li&gt;
                            &lt;li&gt;2+ ліній: 100 + 50 за кожну додаткову (наприклад, 2 лінії = 150 очок).&lt;/li&gt;
                        &lt;/ul&gt;
                    &lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Бонус за очищення поля&lt;/b&gt;: 25% від суми очок, якщо поле порожнє.&lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Рекорд&lt;/b&gt;: Зберігається у браузері, відображається під час гри та після завершення.&lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Кінець гри&lt;/b&gt;: Гра закінчується, якщо блоки неможливо розмістити.&lt;/li&gt;
                &lt;/ul&gt;

                &lt;h3&gt;Дії гравця&lt;/h3&gt;
                &lt;ul&gt;
                    &lt;li&gt;&lt;b&gt;Перетягування&lt;/b&gt;:
                        &lt;ul&gt;
                            &lt;li&gt;ПК: Лівою кнопкою миші.&lt;/li&gt;
                            &lt;li&gt;Сенсорні пристрої: Торкніться та перетягніть.&lt;/li&gt;
                        &lt;/ul&gt;
                    &lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Поворот&lt;/b&gt;: Права кнопка миші (90°).&lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Перевертання&lt;/b&gt;:
                        &lt;ul&gt;
                            &lt;li&gt;ПК: Середня кнопка миші або подвійне клацання.&lt;/li&gt;
                            &lt;li&gt;Сенсорні пристрої: Подвійне торкання.&lt;/li&gt;
                        &lt;/ul&gt;
                    &lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Скасування ходу&lt;/b&gt;: Кнопка &quot;Скасувати&quot; для останнього ходу.&lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Пауза&lt;/b&gt;: Кнопка &quot;Пауза&quot;/&quot;Відновити&quot;.&lt;/li&gt;
                    &lt;li&gt;&lt;b&gt;Перезапуск&lt;/b&gt;: Кнопка &quot;Грати знову&quot; на екрані &quot;Гра закінчена&quot;.&lt;/li&gt;
                &lt;/ul&gt;

                &lt;h3&gt;Поради&lt;/h3&gt;
                &lt;ul&gt;
                    &lt;li&gt;Плануйте ходи, щоб створювати повні лінії.&lt;/li&gt;
                    &lt;li&gt;Використовуйте одинарний блок для прогалин.&lt;/li&gt;
                    &lt;li&gt;Скасовуйте невдалі ходи.&lt;/li&gt;
                    &lt;li&gt;Намагайтеся очищати кілька ліній для бонусів.&lt;/li&gt;
                &lt;/ul&gt;
            &lt;/div&gt;
        &lt;/div&gt;
    &lt;/div&gt;

    &lt;script&gt;
        // Акордеон-меню
        function toggleAccordion(header) {
            const content = header.nextElementSibling;
            const isActive = content.classList.contains(&#039;active&#039;);
            document.querySelectorAll(&#039;.accordion-content&#039;).forEach(item =&gt; {
                item.classList.remove(&#039;active&#039;);
                item.previousElementSibling.classList.remove(&#039;active&#039;);
            });
            if (!isActive) {
                content.classList.add(&#039;active&#039;);
                header.classList.add(&#039;active&#039;);
            }
        }

        // Ігрова логіка
        const gameCanvas = document.getElementById(&#039;gameCanvas&#039;);
        const ctx = gameCanvas.getContext(&#039;2d&#039;);
        const gridSize = 10;
        const cellSize = gameCanvas.width / gridSize; // 30px
        const scoreElement = document.getElementById(&#039;score&#039;);
        const highScoreElement = document.getElementById(&#039;highScore&#039;);
        const bonusMessageElement = document.getElementById(&#039;bonusMessage&#039;);
        const gameOverElement = document.getElementById(&#039;gameOver&#039;);
        const finalScoreElement = document.getElementById(&#039;finalScore&#039;);
        const pauseButton = document.getElementById(&#039;pauseButton&#039;);
        const undoButton = document.getElementById(&#039;undoButton&#039;);
        const pauseOverlay = document.getElementById(&#039;pauseOverlay&#039;);

        let grid = Array(gridSize).fill().map(() =&gt; Array(gridSize).fill(null));
        let score = 0;
        let highScore = parseInt(localStorage.getItem(&#039;blockLegendHighScore&#039;)) || 0;
        let currentBlocks = [];
        let selectedBlock = null;
        let gameActive = true;
        let gamePaused = false;
        let lastMove = null;

        highScoreElement.textContent = `Рекорд: ${highScore}`;
        console.log(&#039;Завантажено рекорд:&#039;, highScore);

        const blockShapes = [
            [[1]], // Одинарний (1x1)
            [[1]], // Одинарний (збільшена ймовірність)
            [[1, 1], [1, 0]], // L-форма
            [[1, 1, 1], [0, 1, 0]], // T-форма
            [[1, 1, 1, 1]], // I-форма (4)
            [[1, 1], [1, 1]], // Квадрат
            [[1, 1, 0], [0, 1, 1]], // Z-форма
            [[1, 1, 1, 1, 1]], // I-форма (5)
            [[1, 1, 1]], // I-форма (3)
            [[1, 1]], // I-форма (2)
        ];

        const colors = [&#039;#FF0000&#039;, &#039;#00FF00&#039;, &#039;#0000FF&#039;, &#039;#FFFF00&#039;, &#039;#FF00FF&#039;, &#039;#FFA500&#039;, &#039;#800080&#039;];

        // Малювання блоків у таблиці
        function drawTableBlock(canvasId, shape, color) {
            const canvas = document.getElementById(canvasId);
            const ctx = canvas.getContext(&#039;2d&#039;);
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            const maxSize = Math.max(shape.length, shape[0].length);
            const blockCellSize = canvas.width / maxSize;
            shape.forEach((row, y) =&gt; {
                row.forEach((cell, x) =&gt; {
                    if (cell) {
                        ctx.fillStyle = color;
                        ctx.fillRect(x * blockCellSize + 2, y * blockCellSize + 2, blockCellSize - 4, blockCellSize - 4);
                        ctx.strokeStyle = &#039;#000&#039;;
                        ctx.strokeRect(x * blockCellSize + 2, y * blockCellSize + 2, blockCellSize - 4, blockCellSize - 4);
                    }
                });
            });
        }

        // Ініціалізація малюнків у таблиці
        drawTableBlock(&#039;shapeSingle&#039;, blockShapes[0], colors[0]);
        drawTableBlock(&#039;shapeL&#039;, blockShapes[2], colors[1]);
        drawTableBlock(&#039;shapeT&#039;, blockShapes[3], colors[2]);
        drawTableBlock(&#039;shapeI4&#039;, blockShapes[4], colors[3]);
        drawTableBlock(&#039;shapeSquare&#039;, blockShapes[5], colors[4]);
        drawTableBlock(&#039;shapeZ&#039;, blockShapes[6], colors[0]);
        drawTableBlock(&#039;shapeI5&#039;, blockShapes[7], colors[5]);
        drawTableBlock(&#039;shapeI3&#039;, blockShapes[8], colors[6]);
        drawTableBlock(&#039;shapeI2&#039;, blockShapes[9], colors[1]);

        function showBonusMessage(message) {
            bonusMessageElement.textContent = message;
            bonusMessageElement.style.display = &#039;block&#039;;
            setTimeout(() =&gt; {
                bonusMessageElement.style.display = &#039;none&#039;;
            }, 2000);
        }

        function rotateShape(shape) {
            const rows = shape.length;
            const cols = shape[0].length;
            const newShape = Array(cols).fill().map(() =&gt; Array(rows).fill(0));
            for (let y = 0; y &lt; rows; y++) {
                for (let x = 0; x &lt; cols; x++) {
                    newShape[x][rows - 1 - y] = shape[y][x];
                }
            }
            return newShape;
        }

        function flipShape(shape) {
            const newShape = shape.map(row =&gt; [...row].reverse());
            return newShape;
        }

        function undoMove() {
            if (!lastMove || !gameActive || gamePaused) return;
            const { grid: prevGrid, score: prevScore, block, blockIndex } = lastMove;
            grid = prevGrid.map(row =&gt; [...row]);
            score = prevScore;
            scoreElement.textContent = `Очки: ${score}`;
            currentBlocks.splice(blockIndex, 0, block);
            for (let i = 0; i &lt; 3; i++) {
                if (i &lt; currentBlocks.length) {
                    drawBlock(i, currentBlocks[i].shape, currentBlocks[i].color);
                } else {
                    document.getElementById(`block${i + 1}`).getContext(&#039;2d&#039;).clearRect(0, 0, 80, 80);
                }
            }
            lastMove = null;
            undoButton.disabled = true;
            drawGrid();
            console.log(&#039;Хід скасовано&#039;);
        }

        function generateBlocks() {
            console.log(&#039;Генеруються нові блоки, поточна кількість:&#039;, currentBlocks.length);
            currentBlocks = [];
            for (let i = 1; i &lt;= 3; i++) {
                document.getElementById(`block${i}`).getContext(&#039;2d&#039;).clearRect(0, 0, 80, 80);
            }
            for (let i = 0; i &lt; 3; i++) {
                const shapeIndex = Math.floor(Math.random() * blockShapes.length);
                const color = colors[Math.floor(Math.random() * colors.length)];
                currentBlocks.push({ shape: blockShapes[shapeIndex], color });
                drawBlock(i, blockShapes[shapeIndex], color);
                console.log(`Згенеровано блок ${i + 1}: форма ${JSON.stringify(blockShapes[shapeIndex])}, колір ${color}`);
            }
            console.log(&#039;Нові блоки створено:&#039;, JSON.stringify(currentBlocks.map(b =&gt; ({ shape: b.shape, color: b.color }))));
            drawGrid();
        }

        function drawBlock(index, shape, color) {
            const blockCanvas = document.getElementById(`block${index + 1}`);
            const blockCtx = blockCanvas.getContext(&#039;2d&#039;);
            blockCtx.clearRect(0, 0, blockCanvas.width, blockCanvas.height);
            const maxSize = Math.max(shape.length, shape[0].length);
            const blockCellSize = Math.min(blockCanvas.width / maxSize, blockCanvas.height / maxSize) * 0.9;
            const offsetX = (blockCanvas.width - maxSize * blockCellSize) / 2;
            const offsetY = (blockCanvas.height - maxSize * blockCellSize) / 2;
            shape.forEach((row, y) =&gt; {
                row.forEach((cell, x) =&gt; {
                    if (cell) {
                        blockCtx.fillStyle = color;
                        blockCtx.fillRect(offsetX + x * blockCellSize + 2, offsetY + y * blockCellSize + 2, blockCellSize - 4, blockCellSize - 4);
                        blockCtx.strokeStyle = &#039;#000&#039;;
                        blockCtx.strokeRect(offsetX + x * blockCellSize + 2, offsetY + y * blockCellSize + 2, blockCellSize - 4, blockCellSize - 4);
                    }
                });
            });
        }

        function drawGrid() {
            ctx.clearRect(0, 0, gameCanvas.width, gameCanvas.height);
            for (let y = 0; y &lt; gridSize; y++) {
                for (let x = 0; x &lt; gridSize; x++) {
                    ctx.strokeStyle = &#039;#000&#039;;
                    ctx.strokeRect(x * cellSize, y * cellSize, cellSize, cellSize);
                    if (grid[y][x]) {
                        ctx.fillStyle = grid[y][x];
                        ctx.fillRect(x * cellSize + 2, y * cellSize + 2, cellSize - 4, cellSize - 4);
                    }
                }
            }
        }

        function drawPreview(shape, x, y, valid) {
            drawGrid();
            if (shape &amp;&amp; x &gt;= 0 &amp;&amp; y &gt;= 0) {
                ctx.globalAlpha = 0.5;
                for (let sy = 0; sy &lt; shape.length; sy++) {
                    for (let sx = 0; sx &lt; shape[sy].length; sx++) {
                        if (shape[sy][sx]) {
                            ctx.fillStyle = valid ? selectedBlock.color : &#039;#FF0000&#039;;
                            ctx.fillRect((x + sx) * cellSize + 2, (y + sy) * cellSize + 2, cellSize - 4, cellSize - 4);
                            ctx.strokeStyle = &#039;#000&#039;;
                            ctx.strokeRect((x + sx) * cellSize + 2, (y + sy) * cellSize + 2, cellSize - 4, cellSize - 4);
                        }
                    }
                }
                ctx.globalAlpha = 1.0;
            }
        }

        function canPlaceBlock(shape, x, y) {
            for (let sy = 0; sy &lt; shape.length; sy++) {
                for (let sx = 0; sx &lt; shape[sy].length; sx++) {
                    if (shape[sy][sx]) {
                        const gridX = x + sx;
                        const gridY = y + sy;
                        if (gridX &lt; 0 || gridX &gt;= gridSize || gridY &lt; 0 || gridY &gt;= gridSize || grid[gridY][gridX]) {
                            return false;
                        }
                    }
                }
            }
            return true;
        }

        function placeBlock(shape, color, x, y, blockIndex) {
            console.log(`Розміщення блоку на позиції (${x}, ${y}), індекс: ${blockIndex}, форма:`, JSON.stringify(shape));
            lastMove = {
                grid: grid.map(row =&gt; [...row]),
                score,
                block: { shape, color },
                blockIndex
            };
            undoButton.disabled = false;
            for (let sy = 0; sy &lt; shape.length; sy++) {
                for (let sx = 0; sx &lt; shape[sy].length; sx++) {
                    if (shape[sy][sx]) {
                        grid[y + sy][x + sx] = color;
                    }
                }
            }
            console.log(&#039;Блок розміщено, викликаємо checkLines&#039;);
            checkLines();
            console.log(&#039;checkLines завершено, викликаємо checkGameOver&#039;);
            checkGameOver();
            drawGrid();
            console.log(&#039;Розміщення завершено, поточна черга:&#039;, JSON.stringify(currentBlocks.map(b =&gt; ({ shape: b.shape, color: b.color }))));
        }

        function checkLines() {
            let linesCleared = 0;
            for (let y = gridSize - 1; y &gt;= 0; y--) {
                if (grid[y].every(cell =&gt; cell)) {
                    grid.splice(y, 1);
                    grid.unshift(Array(gridSize).fill(null));
                    linesCleared++;
                    y++;
                }
            }
            for (let x = gridSize - 1; x &gt;= 0; x--) {
                let isFull = true;
                for (let y = 0; y &lt; gridSize; y++) {
                    if (!grid[y][x]) {
                        isFull = false;
                        break;
                    }
                }
                if (isFull) {
                    for (let y = 0; y &lt; gridSize; y++) {
                        grid[y].splice(x, 1);
                        grid[y].push(null);
                    }
                    linesCleared++;
                    x++;
                }
            }
            if (linesCleared &gt; 0) {
                let lineBonus = linesCleared === 1 ? 100 : 100 + (linesCleared - 1) * 50;
                score += lineBonus;
                if (linesCleared &gt; 1) {
                    showBonusMessage(`Бонус за ${linesCleared} лінії: +${lineBonus} очок`);
                    console.log(`Бонус за очищення ${linesCleared} ліній: +${lineBonus} очок`);
                }
                const isGridEmpty = grid.every(row =&gt; row.every(cell =&gt; !cell));
                if (isGridEmpty &amp;&amp; score &gt; 0) {
                    const clearBonus = Math.floor(score * 0.25);
                    score += clearBonus;
                    showBonusMessage(`Бонус за повне очищення поля: +${clearBonus} очок`);
                    console.log(`Бонус за повне очищення поля: +${clearBonus} очок`);
                }
                scoreElement.textContent = `Очки: ${score}`;
                if (score &gt; highScore) {
                    highScore = score;
                    localStorage.setItem(&#039;blockLegendHighScore&#039;, highScore);
                    highScoreElement.textContent = `Рекорд: ${highScore}`;
                    console.log(&#039;Новий рекорд:&#039;, highScore);
                }
            }
            console.log(&#039;Очищено ліній:&#039;, linesCleared, &#039;Очки:&#039;, score, &#039;Рекорд:&#039;, highScore);
        }

        function checkGameOver() {
            console.log(&#039;Перевірка стану гри. Кількість блоків:&#039;, currentBlocks.length, &#039;Блоки:&#039;, JSON.stringify(currentBlocks.map(b =&gt; ({ shape: b.shape, color: b.color }))));
            if (currentBlocks.length === 0) {
                console.log(&#039;Черга порожня, генеруємо нові блоки&#039;);
                setTimeout(() =&gt; {
                    generateBlocks();
                    console.log(&#039;Нові блоки згенеровано, нова черга:&#039;, JSON.stringify(currentBlocks.map(b =&gt; ({ shape: b.shape, color: b.color }))));
                }, 0);
                return;
            }
            let canPlaceAny = false;
            for (let block of currentBlocks) {
                for (let y = 0; y &lt; gridSize; y++) {
                    for (let x = 0; x &lt; gridSize; x++) {
                        if (canPlaceBlock(block.shape, x, y)) {
                            canPlaceAny = true;
                            break;
                        }
                    }
                    if (canPlaceAny) break;
                }
                if (canPlaceAny) break;
            }
            console.log(&#039;Чи можна розмістити блок:&#039;, canPlaceAny);
            if (!canPlaceAny) {
                gameActive = false;
                if (score &gt; highScore) {
                    highScore = score;
                    localStorage.setItem(&#039;blockLegendHighScore&#039;, highScore);
                    console.log(&#039;Новий рекорд на кінці гри:&#039;, highScore);
                }
                finalScoreElement.textContent = `Ваш рахунок: ${score}\nРекорд: ${highScore}`;
                gameOverElement.style.display = &#039;block&#039;;
                console.log(&#039;Гра закінчена. Рахунок:&#039;, score, &#039;Рекорд:&#039;, highScore);
            }
        }

        function restartGame() {
            grid = Array(gridSize).fill().map(() =&gt; Array(gridSize).fill(null));
            score = 0;
            scoreElement.textContent = `Очки: ${score}`;
            highScoreElement.textContent = `Рекорд: ${highScore}`;
            gameOverElement.style.display = &#039;none&#039;;
            gamePaused = false;
            pauseButton.textContent = &#039;Пауза&#039;;
            pauseOverlay.style.display = &#039;none&#039;;
            undoButton.disabled = true;
            lastMove = null;
            gameActive = true;
            currentBlocks = [];
            generateBlocks();
            drawGrid();
            console.log(&#039;Гра перезапущена. Рахунок:&#039;, score, &#039;Рекорд:&#039;, highScore);
        }

        function togglePause() {
            if (!gameActive) return;
            gamePaused = !gamePaused;
            pauseButton.textContent = gamePaused ? &#039;Відновити&#039; : &#039;Пауза&#039;;
            pauseOverlay.style.display = gamePaused ? &#039;block&#039; : &#039;none&#039;;
            console.log(&#039;Гра на паузі:&#039;, gamePaused);
        }

        pauseButton.addEventListener(&#039;click&#039;, togglePause);
        undoButton.addEventListener(&#039;click&#039;, undoMove);

        const blockCanvases = document.querySelectorAll(&#039;.blockCanvas&#039;);
        blockCanvases.forEach(canvas =&gt; {
            canvas.addEventListener(&#039;dragstart&#039;, (e) =&gt; {
                if (!gameActive || gamePaused) return;
                const index = parseInt(canvas.id.replace(&#039;block&#039;, &#039;&#039;)) - 1;
                selectedBlock = currentBlocks[index];
                canvas.classList.add(&#039;dragging&#039;);
                e.dataTransfer.setData(&#039;text/plain&#039;, index);
                console.log(&#039;Початок перетягування блоку:&#039;, index, &#039;Блок:&#039;, JSON.stringify(selectedBlock));
            });

            canvas.addEventListener(&#039;dragend&#039;, (e) =&gt; {
                canvas.classList.remove(&#039;dragging&#039;);
                drawGrid();
                console.log(&#039;Кінець перетягування&#039;);
            });

            canvas.addEventListener(&#039;contextmenu&#039;, (e) =&gt; {
                e.preventDefault();
                if (!gameActive || gamePaused) return;
                const index = parseInt(canvas.id.replace(&#039;block&#039;, &#039;&#039;)) - 1;
                currentBlocks[index].shape = rotateShape(currentBlocks[index].shape);
                drawBlock(index, currentBlocks[index].shape, currentBlocks[index].color);
                console.log(&#039;Блок повернуто:&#039;, index, &#039;Нова форма:&#039;, JSON.stringify(currentBlocks[index].shape));
            });

            canvas.addEventListener(&#039;mousedown&#039;, (e) =&gt; {
                if (e.button === 1) {
                    e.preventDefault();
                    if (!gameActive || gamePaused) return;
                    const index = parseInt(canvas.id.replace(&#039;block&#039;, &#039;&#039;)) - 1;
                    currentBlocks[index].shape = flipShape(currentBlocks[index].shape);
                    drawBlock(index, currentBlocks[index].shape, currentBlocks[index].color);
                    console.log(&#039;Блок перевернуто (середня кнопка):&#039;, index, &#039;Нова форма:&#039;, JSON.stringify(currentBlocks[index].shape));
                }
            });

            canvas.addEventListener(&#039;dblclick&#039;, (e) =&gt; {
                e.preventDefault();
                if (!gameActive || gamePaused) return;
                const index = parseInt(canvas.id.replace(&#039;block&#039;, &#039;&#039;)) - 1;
                if (index &gt;= 0 &amp;&amp; index &lt; currentBlocks.length) {
                    currentBlocks[index].shape = flipShape(currentBlocks[index].shape);
                    drawBlock(index, currentBlocks[index].shape, currentBlocks[index].color);
                    console.log(&#039;Блок перевернуто (подвійне клацання):&#039;, index, &#039;Нова форма:&#039;, JSON.stringify(currentBlocks[index].shape));
                }
            });

            canvas.addEventListener(&#039;touchstart&#039;, (e) =&gt; {
                if (!gameActive || gamePaused) return;
                const index = parseInt(canvas.id.replace(&#039;block&#039;, &#039;&#039;)) - 1;
                if (index &gt;= 0 &amp;&amp; index &lt; currentBlocks.length) {
                    selectedBlock = currentBlocks[index];
                    canvas.classList.add(&#039;dragging&#039;);
                    console.log(&#039;Початок сенсорного перетягування блоку:&#039;, index, &#039;Блок:&#039;, JSON.stringify(selectedBlock));
                } else {
                    console.error(&#039;Помилка: невалідний індекс блоку на touchstart&#039;, index);
                }
            });

            canvas.addEventListener(&#039;touchmove&#039;, (e) =&gt; {
                e.preventDefault();
                if (!gameActive || !selectedBlock || gamePaused) return;
                const touch = e.touches[0];
                const rect = gameCanvas.getBoundingClientRect();
                const x = Math.floor((touch.clientX - rect.left) / cellSize);
                const y = Math.floor((touch.clientY - rect.top) / cellSize);
                const valid = canPlaceBlock(selectedBlock.shape, x, y);
                drawPreview(selectedBlock.shape, x, y, valid);
            });

            canvas.addEventListener(&#039;touchend&#039;, (e) =&gt; {
                if (!gameActive || !selectedBlock || gamePaused) return;
                const touch = e.changedTouches[0];
                const rect = gameCanvas.getBoundingClientRect();
                const x = Math.floor((touch.clientX - rect.left) / cellSize);
                const y = Math.floor((touch.clientY - rect.top) / cellSize);
                const index = parseInt(canvas.id.replace(&#039;block&#039;, &#039;&#039;)) - 1;
                console.log(`Сенсорне розміщення: координати (${x}, ${y}), індекс: ${index}, блок:`, JSON.stringify(selectedBlock));
                if (index &gt;= 0 &amp;&amp; index &lt; currentBlocks.length) {
                    if (canPlaceBlock(selectedBlock.shape, x, y)) {
                        placeBlock(selectedBlock.shape, selectedBlock.color, x, y, index);
                        currentBlocks.splice(index, 1);
                        console.log(&#039;Блок видалено з черги. Залишилося:&#039;, currentBlocks.length, &#039;Блоки:&#039;, JSON.stringify(currentBlocks.map(b =&gt; ({ shape: b.shape, color: b.color }))));
                        for (let i = 0; i &lt; 3; i++) {
                            const blockCanvas = document.getElementById(`block${i + 1}`);
                            blockCanvas.getContext(&#039;2d&#039;).clearRect(0, 0, blockCanvas.width, blockCanvas.height);
                            if (i &lt; currentBlocks.length) {
                                drawBlock(i, currentBlocks[i].shape, currentBlocks[i].color);
                            }
                        }
                        checkGameOver();
                        selectedBlock = null;
                    } else {
                        console.log(&#039;Неможливо розмістити блок на позиції:&#039;, x, y);
                    }
                } else {
                    console.error(&#039;Помилка: невалідний індекс блоку на touchend&#039;, index);
                }
                canvas.classList.remove(&#039;dragging&#039;);
                drawGrid();
                console.log(&#039;Сенсорне розміщення завершено&#039;);
            });
        });

        gameCanvas.addEventListener(&#039;dragover&#039;, (e) =&gt; {
            e.preventDefault();
            if (!gameActive || !selectedBlock || gamePaused) return;
            const rect = gameCanvas.getBoundingClientRect();
            const x = Math.floor((e.clientX - rect.left) / cellSize);
            const y = Math.floor((e.clientY - rect.top) / cellSize);
            const valid = canPlaceBlock(selectedBlock.shape, x, y);
            drawPreview(selectedBlock.shape, x, y, valid);
        });

        gameCanvas.addEventListener(&#039;drop&#039;, (e) =&gt; {
            e.preventDefault();
            if (!gameActive || !selectedBlock || gamePaused) return;
            const rect = gameCanvas.getBoundingClientRect();
            const x = Math.floor((e.clientX - rect.left) / cellSize);
            const y = Math.floor((e.clientY - rect.top) / cellSize);
            const index = parseInt(e.dataTransfer.getData(&#039;text/plain&#039;));
            console.log(`Розміщення через drag: координати (${x}, ${y}), індекс: ${index}, блок:`, JSON.stringify(selectedBlock));
            if (index &gt;= 0 &amp;&amp; index &lt; currentBlocks.length) {
                if (canPlaceBlock(selectedBlock.shape, x, y)) {
                    placeBlock(selectedBlock.shape, selectedBlock.color, x, y, index);
                    currentBlocks.splice(index, 1);
                    console.log(&#039;Блок видалено з черги. Залишилося:&#039;, currentBlocks.length, &#039;Блоки:&#039;, JSON.stringify(currentBlocks.map(b =&gt; ({ shape: b.shape, color: b.color }))));
                    for (let i = 0; i &lt; 3; i++) {
                        const blockCanvas = document.getElementById(`block${i + 1}`);
                        blockCanvas.getContext(&#039;2d&#039;).clearRect(0, 0, blockCanvas.width, blockCanvas.height);
                        if (i &lt; currentBlocks.length) {
                            drawBlock(i, currentBlocks[i].shape, currentBlocks[i].color);
                        }
                    }
                    checkGameOver();
                    selectedBlock = null;
                } else {
                    console.log(&#039;Неможливо розмістити блок на позиції:&#039;, x, y);
                }
            } else {
                console.error(&#039;Помилка: невалідний індекс блоку на drop&#039;, index);
            }
        });

        generateBlocks();
        drawGrid();
        console.log(&#039;Гра ініціалізована — Мозаїка Майстрів Версія 1.7&#039;);
    &lt;/script&gt;</description>
            </item>
                    <item>
                <title>гра схожа на тетріс</title>
                <link>http://margo.mozello.shop/gry/params/post/5139139/gra-shozha-na-tetrs</link>
                <pubDate>Sun, 28 Sep 2025 10:40:00 +0000</pubDate>
                <description>гггггггггггггггггггг
&lt;hr class=&quot;moze-more-divider&quot;&gt;
&lt;p&gt;2&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;Блоки Легенда — Версія 1.5&lt;/title&gt;
  &lt;style&gt;
    body {
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            min-height: 100vh;
            margin: 0;
            padding: 10px;
            background-color: #f0f0f0;
            font-family: Arial, sans-serif;
            overflow: auto;
        }
        #gameCanvas {
            border: 2px solid #333;
            background-color: #e3f1c6;
            max-width: 100%;
            height: auto;
            margin-top: 20px;
        }
        #nextBlocks {
            display: flex;
            justify-content: center;
            margin-top: 10px;
            flex-wrap: wrap;
            width: 100%;
            max-width: 260px;
            gap: 1px;
        }
        .blockCanvas {
            border: 1px solid #ccc;
            cursor: grab;
            width: 80px;
            height: 80px;
            margin: 2px;
        }
        .blockCanvas.dragging {
            opacity: 0.5;
            cursor: grabbing;
        }
        #score, #highScore {
            font-size: 20px;
            margin-top: 10px;
        }
        #bonusMessage {
            display: none;
            position: fixed;
            top: 20%;
            left: 50%;
            transform: translateX(-50%);
            background-color: rgba(0, 128, 0, 0.8);
            color: white;
            padding: 10px 20px;
            border-radius: 5px;
            z-index: 1000;
            font-size: 18px;
        }
        #gameOver, #pauseOverlay {
            display: none;
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            background-color: rgba(0, 0, 0, 0.8);
            color: white;
            padding: 15px;
            border-radius: 10px;
            text-align: center;
            z-index: 1000;
        }
        button {
            margin-top: 10px;
            padding: 8px 16px;
            font-size: 14px;
            cursor: pointer;
        }
        h2 {
            margin: 10px 0;
        }
        p {
            margin: 5px 0;
        }
        #blockTable {
            width: 100%;
            max-width: 500px;
            border-collapse: collapse;
            margin-bottom: 15px;
        }
        #blockTable th, #blockTable td {
            border: 1px solid #333;
            padding: 8px;
            text-align: center;
        }
        #blockTable th {
            background-color: #ddd;
        }
        #blockTable canvas {
            border: 1px solid #ccc;
        }
  &lt;/style&gt;



  &lt;table id=&quot;blockTable&quot;&gt;
    &lt;thead&gt;
      &lt;tr&gt;
        &lt;th&gt;Назва&lt;/th&gt;
        &lt;th&gt;Зображення&lt;/th&gt;
        &lt;th&gt;Структура&lt;/th&gt;
        &lt;th&gt;Використання&lt;/th&gt;
      &lt;/tr&gt;
    &lt;/thead&gt;
    &lt;tbody&gt;
      &lt;tr&gt;
        &lt;td&gt;Одинарний&lt;/td&gt;
        &lt;td&gt;
          &lt;canvas id=&quot;shapeSingle&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;
        &lt;/td&gt;
        &lt;td&gt;
          &lt;pre&gt;[[1]]&lt;/pre&gt;
        &lt;/td&gt;
        &lt;td&gt;Для заповнення окремих клітинок&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;L-форма&lt;/td&gt;
        &lt;td&gt;
          &lt;canvas id=&quot;shapeL&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;
        &lt;/td&gt;
        &lt;td&gt;
          &lt;pre&gt;[[1, 1],
            &lt;br&gt;[1, 0]]&lt;/pre&gt;
        &lt;/td&gt;
        &lt;td&gt;Для кутів або вузьких просторів&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;T-форма&lt;/td&gt;
        &lt;td&gt;
          &lt;canvas id=&quot;shapeT&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;
        &lt;/td&gt;
        &lt;td&gt;
          &lt;pre&gt;[[1, 1, 1],
            &lt;br&gt;[0, 1, 0]]&lt;/pre&gt;
        &lt;/td&gt;
        &lt;td&gt;Для горизонтальних ліній з виступом&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;I-форма (4)&lt;/td&gt;
        &lt;td&gt;
          &lt;canvas id=&quot;shapeI4&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;
        &lt;/td&gt;
        &lt;td&gt;
          &lt;pre&gt;[[1, 1, 1, 1]]&lt;/pre&gt;
        &lt;/td&gt;
        &lt;td&gt;Для заповнення рядків/стовпців&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;Квадрат&lt;/td&gt;
        &lt;td&gt;
          &lt;canvas id=&quot;shapeSquare&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;
        &lt;/td&gt;
        &lt;td&gt;
          &lt;pre&gt;[[1, 1],
            &lt;br&gt;[1, 1]]&lt;/pre&gt;
        &lt;/td&gt;
        &lt;td&gt;Для компактних квадратних просторів&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;Z-форма&lt;/td&gt;
        &lt;td&gt;
          &lt;canvas id=&quot;shapeZ&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;
        &lt;/td&gt;
        &lt;td&gt;
          &lt;pre&gt;[[1, 1, 0],
            &lt;br&gt;[0, 1, 1]]&lt;/pre&gt;
        &lt;/td&gt;
        &lt;td&gt;Для зміщених &quot;змійок&quot;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;I-форма (5)&lt;/td&gt;
        &lt;td&gt;
          &lt;canvas id=&quot;shapeI5&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;
        &lt;/td&gt;
        &lt;td&gt;
          &lt;pre&gt;[[1, 1, 1, 1, 1]]&lt;/pre&gt;
        &lt;/td&gt;
        &lt;td&gt;Для довгих рядків/стовпців&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;I-форма (3)&lt;/td&gt;
        &lt;td&gt;
          &lt;canvas id=&quot;shapeI3&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;
        &lt;/td&gt;
        &lt;td&gt;
          &lt;pre&gt;[[1, 1, 1]]&lt;/pre&gt;
        &lt;/td&gt;
        &lt;td&gt;Для середніх рядків/стовпців&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;I-форма (2)&lt;/td&gt;
        &lt;td&gt;
          &lt;canvas id=&quot;shapeI2&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;
        &lt;/td&gt;
        &lt;td&gt;
          &lt;pre&gt;[[1, 1]]&lt;/pre&gt;
        &lt;/td&gt;
        &lt;td&gt;Для коротких рядків/стовпців&lt;/td&gt;
      &lt;/tr&gt;
    &lt;/tbody&gt;
  &lt;/table&gt;
  &lt;h2&gt;Блоки Легенда — Версія 1.5&lt;/h2&gt;
  &lt;p&gt;Права кнопка миші — поворот блоку, Середня кнопка/подвійне торкання — перевертання,
    Кнопка &quot;Скасувати&quot; — скасування ходу&lt;/p&gt;
  &lt;canvas id=&quot;gameCanvas&quot; width=&quot;300&quot; height=&quot;300&quot;&gt;&lt;/canvas&gt;
  &lt;button id=&quot;pauseButton&quot; fdprocessedid=&quot;q11yh8&quot;&gt;Пауза&lt;/button&gt;
  &lt;button id=&quot;undoButton&quot; disabled=&quot;&quot;&gt;Скасувати&lt;/button&gt;
  &lt;div id=&quot;nextBlocks&quot;&gt;
    &lt;canvas id=&quot;block1&quot; class=&quot;blockCanvas&quot; width=&quot;80&quot; height=&quot;80&quot; draggable=&quot;true&quot;&gt;&lt;/canvas&gt;
    &lt;canvas id=&quot;block2&quot; class=&quot;blockCanvas&quot; width=&quot;80&quot; height=&quot;80&quot; draggable=&quot;true&quot;&gt;&lt;/canvas&gt;
    &lt;canvas id=&quot;block3&quot; class=&quot;blockCanvas&quot; width=&quot;80&quot; height=&quot;80&quot; draggable=&quot;true&quot;&gt;&lt;/canvas&gt;
  &lt;/div&gt;
  &lt;div id=&quot;score&quot;&gt;Очки: 0&lt;/div&gt;
  &lt;div id=&quot;highScore&quot;&gt;Рекорд: 0&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ллллллллллллллллллллллллллллл&lt;/div&gt;
  &lt;div id=&quot;bonusMessage&quot;&gt;&lt;/div&gt;
  &lt;div id=&quot;gameOver&quot;&gt;
    &lt;h2&gt;Гра закінчена!&lt;/h2&gt;
    &lt;p id=&quot;finalScore&quot;&gt;&lt;/p&gt;
    &lt;button onclick=&quot;restartGame()&quot;&gt;Грати знову&lt;/button&gt;
  &lt;/div&gt;
  &lt;div id=&quot;pauseOverlay&quot;&gt;
    &lt;h2&gt;Гра на паузі&lt;/h2&gt;
    &lt;button onclick=&quot;togglePause()&quot;&gt;Відновити&lt;/button&gt;
  &lt;/div&gt;

  &lt;script&gt;
    const gameCanvas = document.getElementById(&#039;gameCanvas&#039;);
        const ctx = gameCanvas.getContext(&#039;2d&#039;);
        const gridSize = 10;
        const cellSize = gameCanvas.width / gridSize; // 30px
        const scoreElement = document.getElementById(&#039;score&#039;);
        const highScoreElement = document.getElementById(&#039;highScore&#039;);
        const bonusMessageElement = document.getElementById(&#039;bonusMessage&#039;);
        const gameOverElement = document.getElementById(&#039;gameOver&#039;);
        const finalScoreElement = document.getElementById(&#039;finalScore&#039;);
        const pauseButton = document.getElementById(&#039;pauseButton&#039;);
        const undoButton = document.getElementById(&#039;undoButton&#039;);
        const pauseOverlay = document.getElementById(&#039;pauseOverlay&#039;);

        let grid = Array(gridSize).fill().map(() =&gt; Array(gridSize).fill(null));
        let score = 0;
        let highScore = parseInt(localStorage.getItem(&#039;blockLegendHighScore&#039;)) || 0;
        let currentBlocks = [];
        let selectedBlock = null;
        let gameActive = true;
        let gamePaused = false;
        let lastMove = null;

        highScoreElement.textContent = `Рекорд: ${highScore}`;
        console.log(&#039;Завантажено рекорд:&#039;, highScore);

        const blockShapes = [
            [[1]], // Одинарний (1x1)
            [[1]], // Одинарний (збільшена ймовірність)
            [[1, 1], [1, 0]], // L-форма
            [[1, 1, 1], [0, 1, 0]], // T-форма
            [[1, 1, 1, 1]], // I-форма (4)
            [[1, 1], [1, 1]], // Квадрат
            [[1, 1, 0], [0, 1, 1]], // Z-форма
            [[1, 1, 1, 1, 1]], // I-форма (5)
            [[1, 1, 1]], // I-форма (3)
            [[1, 1]], // I-форма (2)
        ];

        const colors = [&#039;#FF0000&#039;, &#039;#00FF00&#039;, &#039;#0000FF&#039;, &#039;#FFFF00&#039;, &#039;#FF00FF&#039;, &#039;#FFA500&#039;, &#039;#800080&#039;];

        function showBonusMessage(message) {
            bonusMessageElement.textContent = message;
            bonusMessageElement.style.display = &#039;block&#039;;
            setTimeout(() =&gt; {
                bonusMessageElement.style.display = &#039;none&#039;;
            }, 2000);
        }

        function rotateShape(shape) {
            const rows = shape.length;
            const cols = shape[0].length;
            const newShape = Array(cols).fill().map(() =&gt; Array(rows).fill(0));
            for (let y = 0; y &lt; rows; y++) {
                for (let x = 0; x &lt; cols; x++) {
                    newShape[x][rows - 1 - y] = shape[y][x];
                }
            }
            return newShape;
        }

        function flipShape(shape) {
            const newShape = shape.map(row =&gt; [...row].reverse());
            return newShape;
        }

        function undoMove() {
            if (!lastMove || !gameActive || gamePaused) return;
            const { grid: prevGrid, score: prevScore, block, blockIndex } = lastMove;
            grid = prevGrid.map(row =&gt; [...row]);
            score = prevScore;
            scoreElement.textContent = `Очки: ${score}`;
            currentBlocks.splice(blockIndex, 0, block);
            for (let i = 0; i &lt; 3; i++) {
                if (i &lt; currentBlocks.length) {
                    drawBlock(i, currentBlocks[i].shape, currentBlocks[i].color);
                } else {
                    document.getElementById(`block${i + 1}`).getContext(&#039;2d&#039;).clearRect(0, 0, 80, 80);
                }
            }
            lastMove = null;
            undoButton.disabled = true;
            drawGrid();
            console.log(&#039;Хід скасовано&#039;);
        }

        function drawTableBlock(canvasId, shape, color) {
            const canvas = document.getElementById(canvasId);
            const ctx = canvas.getContext(&#039;2d&#039;);
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            const maxSize = Math.max(shape.length, shape[0].length);
            const blockCellSize = canvas.width / maxSize;
            shape.forEach((row, y) =&gt; {
                row.forEach((cell, x) =&gt; {
                    if (cell) {
                        ctx.fillStyle = color;
                        ctx.fillRect(x * blockCellSize + 2, y * blockCellSize + 2, blockCellSize - 4, blockCellSize - 4);
                        ctx.strokeStyle = &#039;#000&#039;;
                        ctx.strokeRect(x * blockCellSize + 2, y * blockCellSize + 2, blockCellSize - 4, blockCellSize - 4);
                    }
                });
            });
        }

        drawTableBlock(&#039;shapeSingle&#039;, blockShapes[0], colors[0]);
        drawTableBlock(&#039;shapeL&#039;, blockShapes[2], colors[1]);
        drawTableBlock(&#039;shapeT&#039;, blockShapes[3], colors[2]);
        drawTableBlock(&#039;shapeI4&#039;, blockShapes[4], colors[3]);
        drawTableBlock(&#039;shapeSquare&#039;, blockShapes[5], colors[4]);
        drawTableBlock(&#039;shapeZ&#039;, blockShapes[6], colors[0]);
        drawTableBlock(&#039;shapeI5&#039;, blockShapes[7], colors[5]);
        drawTableBlock(&#039;shapeI3&#039;, blockShapes[8], colors[6]);
        drawTableBlock(&#039;shapeI2&#039;, blockShapes[9], colors[1]);

        function generateBlocks() {
            console.log(&#039;Генеруються нові блоки, поточна кількість:&#039;, currentBlocks.length);
            currentBlocks = [];
            for (let i = 1; i &lt;= 3; i++) {
                document.getElementById(`block${i}`).getContext(&#039;2d&#039;).clearRect(0, 0, 80, 80);
            }
            for (let i = 0; i &lt; 3; i++) {
                const shapeIndex = Math.floor(Math.random() * blockShapes.length);
                const color = colors[Math.floor(Math.random() * colors.length)];
                currentBlocks.push({ shape: blockShapes[shapeIndex], color });
                drawBlock(i, blockShapes[shapeIndex], color);
                console.log(`Згенеровано блок ${i + 1}: форма ${JSON.stringify(blockShapes[shapeIndex])}, колір ${color}`);
            }
            console.log(&#039;Нові блоки створено:&#039;, JSON.stringify(currentBlocks.map(b =&gt; ({ shape: b.shape, color: b.color }))));
            drawGrid();
        }

        function drawBlock(index, shape, color) {
            const blockCanvas = document.getElementById(`block${index + 1}`);
            const blockCtx = blockCanvas.getContext(&#039;2d&#039;);
            blockCtx.clearRect(0, 0, blockCanvas.width, blockCanvas.height);
            const maxSize = Math.max(shape.length, shape[0].length);
            const blockCellSize = Math.min(blockCanvas.width / maxSize, blockCanvas.height / maxSize) * 0.9;
            const offsetX = (blockCanvas.width - maxSize * blockCellSize) / 2;
            const offsetY = (blockCanvas.height - maxSize * blockCellSize) / 2;
            shape.forEach((row, y) =&gt; {
                row.forEach((cell, x) =&gt; {
                    if (cell) {
                        blockCtx.fillStyle = color;
                        blockCtx.fillRect(offsetX + x * blockCellSize + 2, offsetY + y * blockCellSize + 2, blockCellSize - 4, blockCellSize - 4);
                        blockCtx.strokeStyle = &#039;#000&#039;;
                        blockCtx.strokeRect(offsetX + x * blockCellSize + 2, offsetY + y * blockCellSize + 2, blockCellSize - 4, blockCellSize - 4);
                    }
                });
            });
        }

        function drawGrid() {
            ctx.clearRect(0, 0, gameCanvas.width, gameCanvas.height);
            for (let y = 0; y &lt; gridSize; y++) {
                for (let x = 0; x &lt; gridSize; x++) {
                    ctx.strokeStyle = &#039;#000&#039;;
                    ctx.strokeRect(x * cellSize, y * cellSize, cellSize, cellSize);
                    if (grid[y][x]) {
                        ctx.fillStyle = grid[y][x];
                        ctx.fillRect(x * cellSize + 2, y * cellSize + 2, cellSize - 4, cellSize - 4);
                    }
                }
            }
        }

        function drawPreview(shape, x, y, valid) {
            drawGrid();
            if (shape &amp;&amp; x &gt;= 0 &amp;&amp; y &gt;= 0) {
                ctx.globalAlpha = 0.5;
                for (let sy = 0; sy &lt; shape.length; sy++) {
                    for (let sx = 0; sx &lt; shape[sy].length; sx++) {
                        if (shape[sy][sx]) {
                            ctx.fillStyle = valid ? selectedBlock.color : &#039;#FF0000&#039;;
                            ctx.fillRect((x + sx) * cellSize + 2, (y + sy) * cellSize + 2, cellSize - 4, cellSize - 4);
                            ctx.strokeStyle = &#039;#000&#039;;
                            ctx.strokeRect((x + sx) * cellSize + 2, (y + sy) * cellSize + 2, cellSize - 4, cellSize - 4);
                        }
                    }
                }
                ctx.globalAlpha = 1.0;
            }
        }

        function canPlaceBlock(shape, x, y) {
            for (let sy = 0; sy &lt; shape.length; sy++) {
                for (let sx = 0; sx &lt; shape[sy].length; sx++) {
                    if (shape[sy][sx]) {
                        const gridX = x + sx;
                        const gridY = y + sy;
                        if (gridX &lt; 0 || gridX &gt;= gridSize || gridY &lt; 0 || gridY &gt;= gridSize || grid[gridY][gridX]) {
                            return false;
                        }
                    }
                }
            }
            return true;
        }

        function placeBlock(shape, color, x, y, blockIndex) {
            console.log(`Розміщення блоку на позиції (${x}, ${y}), індекс: ${blockIndex}, форма:`, JSON.stringify(shape));
            lastMove = {
                grid: grid.map(row =&gt; [...row]),
                score,
                block: { shape, color },
                blockIndex
            };
            undoButton.disabled = false;
            for (let sy = 0; sy &lt; shape.length; sy++) {
                for (let sx = 0; sx &lt; shape[sy].length; sx++) {
                    if (shape[sy][sx]) {
                        grid[y + sy][x + sx] = color;
                    }
                }
            }
            console.log(&#039;Блок розміщено, викликаємо checkLines&#039;);
            checkLines();
            console.log(&#039;checkLines завершено, викликаємо checkGameOver&#039;);
            checkGameOver();
            drawGrid();
            console.log(&#039;Розміщення завершено, поточна черга:&#039;, JSON.stringify(currentBlocks.map(b =&gt; ({ shape: b.shape, color: b.color }))));
        }

        function checkLines() {
            let linesCleared = 0;
            for (let y = gridSize - 1; y &gt;= 0; y--) {
                if (grid[y].every(cell =&gt; cell)) {
                    grid.splice(y, 1);
                    grid.unshift(Array(gridSize).fill(null));
                    linesCleared++;
                    y++;
                }
            }
            for (let x = gridSize - 1; x &gt;= 0; x--) {
                let isFull = true;
                for (let y = 0; y &lt; gridSize; y++) {
                    if (!grid[y][x]) {
                        isFull = false;
                        break;
                    }
                }
                if (isFull) {
                    for (let y = 0; y &lt; gridSize; y++) {
                        grid[y].splice(x, 1);
                        grid[y].push(null);
                    }
                    linesCleared++;
                    x++;
                }
            }
            if (linesCleared &gt; 0) {
                let lineBonus = linesCleared === 1 ? 100 : 100 + (linesCleared - 1) * 50;
                score += lineBonus;
                if (linesCleared &gt; 1) {
                    showBonusMessage(`Бонус за ${linesCleared} лінії: +${lineBonus} очок`);
                    console.log(`Бонус за очищення ${linesCleared} ліній: +${lineBonus} очок`);
                }
                const isGridEmpty = grid.every(row =&gt; row.every(cell =&gt; !cell));
                if (isGridEmpty &amp;&amp; score &gt; 0) {
                    const clearBonus = Math.floor(score * 0.25);
                    score += clearBonus;
                    showBonusMessage(`Бонус за повне очищення поля: +${clearBonus} очок`);
                    console.log(`Бонус за повне очищення поля: +${clearBonus} очок`);
                }
                scoreElement.textContent = `Очки: ${score}`;
                if (score &gt; highScore) {
                    highScore = score;
                    localStorage.setItem(&#039;blockLegendHighScore&#039;, highScore);
                    highScoreElement.textContent = `Рекорд: ${highScore}`;
                    console.log(&#039;Новий рекорд:&#039;, highScore);
                }
            }
            console.log(&#039;Очищено ліній:&#039;, linesCleared, &#039;Очки:&#039;, score, &#039;Рекорд:&#039;, highScore);
        }

        function checkGameOver() {
            console.log(&#039;Перевірка стану гри. Кількість блоків:&#039;, currentBlocks.length, &#039;Блоки:&#039;, JSON.stringify(currentBlocks.map(b =&gt; ({ shape: b.shape, color: b.color }))));
            if (currentBlocks.length === 0) {
                console.log(&#039;Черга порожня, генеруємо нові блоки&#039;);
                setTimeout(() =&gt; {
                    generateBlocks();
                    console.log(&#039;Нові блоки згенеровано, нова черга:&#039;, JSON.stringify(currentBlocks.map(b =&gt; ({ shape: b.shape, color: b.color }))));
                }, 0);
                return;
            }
            let canPlaceAny = false;
            for (let block of currentBlocks) {
                for (let y = 0; y &lt; gridSize; y++) {
                    for (let x = 0; x &lt; gridSize; x++) {
                        if (canPlaceBlock(block.shape, x, y)) {
                            canPlaceAny = true;
                            break;
                        }
                    }
                    if (canPlaceAny) break;
                }
                if (canPlaceAny) break;
            }
            console.log(&#039;Чи можна розмістити блок:&#039;, canPlaceAny);
            if (!canPlaceAny) {
                gameActive = false;
                if (score &gt; highScore) {
                    highScore = score;
                    localStorage.setItem(&#039;blockLegendHighScore&#039;, highScore);
                    console.log(&#039;Новий рекорд на кінці гри:&#039;, highScore);
                }
                finalScoreElement.textContent = `Ваш рахунок: ${score}\nРекорд: ${highScore}`;
                gameOverElement.style.display = &#039;block&#039;;
                console.log(&#039;Гра закінчена. Рахунок:&#039;, score, &#039;Рекорд:&#039;, highScore);
            }
        }

        function restartGame() {
            grid = Array(gridSize).fill().map(() =&gt; Array(gridSize).fill(null));
            score = 0;
            scoreElement.textContent = `Очки: ${score}`;
            highScoreElement.textContent = `Рекорд: ${highScore}`;
            gameOverElement.style.display = &#039;none&#039;;
            gamePaused = false;
            pauseButton.textContent = &#039;Пауза&#039;;
            pauseOverlay.style.display = &#039;none&#039;;
            undoButton.disabled = true;
            lastMove = null;
            gameActive = true;
            currentBlocks = [];
            generateBlocks();
            drawGrid();
            console.log(&#039;Гра перезапущена. Рахунок:&#039;, score, &#039;Рекорд:&#039;, highScore);
        }

        function togglePause() {
            if (!gameActive) return;
            gamePaused = !gamePaused;
            pauseButton.textContent = gamePaused ? &#039;Відновити&#039; : &#039;Пауза&#039;;
            pauseOverlay.style.display = gamePaused ? &#039;block&#039; : &#039;none&#039;;
            console.log(&#039;Гра на паузі:&#039;, gamePaused);
        }

        pauseButton.addEventListener(&#039;click&#039;, togglePause);
        undoButton.addEventListener(&#039;click&#039;, undoMove);

        const blockCanvases = document.querySelectorAll(&#039;.blockCanvas&#039;);
        blockCanvases.forEach(canvas =&gt; {
            canvas.addEventListener(&#039;dragstart&#039;, (e) =&gt; {
                if (!gameActive || gamePaused) return;
                const index = parseInt(canvas.id.replace(&#039;block&#039;, &#039;&#039;)) - 1;
                selectedBlock = currentBlocks[index];
                canvas.classList.add(&#039;dragging&#039;);
                e.dataTransfer.setData(&#039;text/plain&#039;, index);
                console.log(&#039;Початок перетягування блоку:&#039;, index, &#039;Блок:&#039;, JSON.stringify(selectedBlock));
            });

            canvas.addEventListener(&#039;dragend&#039;, (e) =&gt; {
                canvas.classList.remove(&#039;dragging&#039;);
                drawGrid();
                console.log(&#039;Кінець перетягування&#039;);
            });

            canvas.addEventListener(&#039;contextmenu&#039;, (e) =&gt; {
                e.preventDefault();
                if (!gameActive || gamePaused) return;
                const index = parseInt(canvas.id.replace(&#039;block&#039;, &#039;&#039;)) - 1;
                currentBlocks[index].shape = rotateShape(currentBlocks[index].shape);
                drawBlock(index, currentBlocks[index].shape, currentBlocks[index].color);
                console.log(&#039;Блок повернуто:&#039;, index, &#039;Нова форма:&#039;, JSON.stringify(currentBlocks[index].shape));
            });

            canvas.addEventListener(&#039;mousedown&#039;, (e) =&gt; {
                if (e.button === 1) {
                    e.preventDefault();
                    if (!gameActive || gamePaused) return;
                    const index = parseInt(canvas.id.replace(&#039;block&#039;, &#039;&#039;)) - 1;
                    currentBlocks[index].shape = flipShape(currentBlocks[index].shape);
                    drawBlock(index, currentBlocks[index].shape, currentBlocks[index].color);
                    console.log(&#039;Блок перевернуто:&#039;, index, &#039;Нова форма:&#039;, JSON.stringify(currentBlocks[index].shape));
                }
            });

            canvas.addEventListener(&#039;dblclick&#039;, (e) =&gt; {
                e.preventDefault();
                if (!gameActive || gamePaused) return;
                const index = parseInt(canvas.id.replace(&#039;block&#039;, &#039;&#039;)) - 1;
                currentBlocks[index].shape = flipShape(currentBlocks[index].shape);
                drawBlock(index, currentBlocks[index].shape, currentBlocks[index].color);
                console.log(&#039;Блок перевернуто (подвійне торкання):&#039;, index, &#039;Нова форма:&#039;, JSON.stringify(currentBlocks[index].shape));
            });

            canvas.addEventListener(&#039;touchstart&#039;, (e) =&gt; {
                if (!gameActive || gamePaused) return;
                const index = parseInt(canvas.id.replace(&#039;block&#039;, &#039;&#039;)) - 1;
                if (index &gt;= 0 &amp;&amp; index &lt; currentBlocks.length) {
                    selectedBlock = currentBlocks[index];
                    canvas.classList.add(&#039;dragging&#039;);
                    console.log(&#039;Початок сенсорного перетягування блоку:&#039;, index, &#039;Блок:&#039;, JSON.stringify(selectedBlock));
                } else {
                    console.error(&#039;Помилка: невалідний індекс блоку на touchstart&#039;, index);
                }
            });

            canvas.addEventListener(&#039;touchmove&#039;, (e) =&gt; {
                e.preventDefault();
                if (!gameActive || !selectedBlock || gamePaused) return;
                const touch = e.touches[0];
                const rect = gameCanvas.getBoundingClientRect();
                const x = Math.floor((touch.clientX - rect.left) / cellSize);
                const y = Math.floor((touch.clientY - rect.top) / cellSize);
                const valid = canPlaceBlock(selectedBlock.shape, x, y);
                drawPreview(selectedBlock.shape, x, y, valid);
            });

            canvas.addEventListener(&#039;touchend&#039;, (e) =&gt; {
                if (!gameActive || !selectedBlock || gamePaused) return;
                const touch = e.changedTouches[0];
                const rect = gameCanvas.getBoundingClientRect();
                const x = Math.floor((touch.clientX - rect.left) / cellSize);
                const y = Math.floor((touch.clientY - rect.top) / cellSize);
                const index = parseInt(canvas.id.replace(&#039;block&#039;, &#039;&#039;)) - 1;
                console.log(`Сенсорне розміщення: координати (${x}, ${y}), індекс: ${index}, блок:`, JSON.stringify(selectedBlock));
                if (index &gt;= 0 &amp;&amp; index &lt; currentBlocks.length) {
                    if (canPlaceBlock(selectedBlock.shape, x, y)) {
                        placeBlock(selectedBlock.shape, selectedBlock.color, x, y, index);
                        currentBlocks.splice(index, 1);
                        console.log(&#039;Блок видалено з черги. Залишилося:&#039;, currentBlocks.length, &#039;Блоки:&#039;, JSON.stringify(currentBlocks.map(b =&gt; ({ shape: b.shape, color: b.color }))));
                        for (let i = 0; i &lt; 3; i++) {
                            const blockCanvas = document.getElementById(`block${i + 1}`);
                            blockCanvas.getContext(&#039;2d&#039;).clearRect(0, 0, blockCanvas.width, blockCanvas.height);
                            if (i &lt; currentBlocks.length) {
                                drawBlock(i, currentBlocks[i].shape, currentBlocks[i].color);
                            }
                        }
                        checkGameOver();
                        selectedBlock = null;
                    } else {
                        console.log(&#039;Неможливо розмістити блок на позиції:&#039;, x, y);
                    }
                } else {
                    console.error(&#039;Помилка: невалідний індекс блоку на touchend&#039;, index);
                }
                canvas.classList.remove(&#039;dragging&#039;);
                drawGrid();
                console.log(&#039;Сенсорне розміщення завершено&#039;);
            });
        });

        gameCanvas.addEventListener(&#039;dragover&#039;, (e) =&gt; {
            e.preventDefault();
            if (!gameActive || !selectedBlock || gamePaused) return;
            const rect = gameCanvas.getBoundingClientRect();
            const x = Math.floor((e.clientX - rect.left) / cellSize);
            const y = Math.floor((e.clientY - rect.top) / cellSize);
            const valid = canPlaceBlock(selectedBlock.shape, x, y);
            drawPreview(selectedBlock.shape, x, y, valid);
        });

        gameCanvas.addEventListener(&#039;drop&#039;, (e) =&gt; {
            e.preventDefault();
            if (!gameActive || !selectedBlock || gamePaused) return;
            const rect = gameCanvas.getBoundingClientRect();
            const x = Math.floor((e.clientX - rect.left) / cellSize);
            const y = Math.floor((e.clientY - rect.top) / cellSize);
            const index = parseInt(e.dataTransfer.getData(&#039;text/plain&#039;));
            console.log(`Розміщення через drag: координати (${x}, ${y}), індекс: ${index}, блок:`, JSON.stringify(selectedBlock));
            if (index &gt;= 0 &amp;&amp; index &lt; currentBlocks.length) {
                if (canPlaceBlock(selectedBlock.shape, x, y)) {
                    placeBlock(selectedBlock.shape, selectedBlock.color, x, y, index);
                    currentBlocks.splice(index, 1);
                    console.log(&#039;Блок видалено з черги. Залишилося:&#039;, currentBlocks.length, &#039;Блоки:&#039;, JSON.stringify(currentBlocks.map(b =&gt; ({ shape: b.shape, color: b.color }))));
                    for (let i = 0; i &lt; 3; i++) {
                        const blockCanvas = document.getElementById(`block${i + 1}`);
                        blockCanvas.getContext(&#039;2d&#039;).clearRect(0, 0, blockCanvas.width, blockCanvas.height);
                        if (i &lt; currentBlocks.length) {
                            drawBlock(i, currentBlocks[i].shape, currentBlocks[i].color);
                        }
                    }
                    checkGameOver();
                    selectedBlock = null;
                } else {
                    console.log(&#039;Неможливо розмістити блок на позиції:&#039;, x, y);
                }
            } else {
                console.error(&#039;Помилка: невалідний індекс блоку на drop&#039;, index);
            }
        });

        generateBlocks();
        drawGrid();
        console.log(&#039;Гра ініціалізована — Версія 1.5&#039;);
  &lt;/script&gt;</description>
            </item>
                    <item>
                <title>Перша новина</title>
                <link>http://margo.mozello.shop/gry/params/post/5139131/persha-novina</link>
                <pubDate>Sun, 28 Sep 2025 10:21:00 +0000</pubDate>
                <description>&lt;p&gt;Це демо-текст, щоб продемонструвати як буде виглядати повідомлення в блозі. Видаліть
  цей пост і додайте свої власні повідомлення.&lt;/p&gt;
&lt;hr class=&quot;moze-more-divider&quot;&gt;
&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh
  euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim
  ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl
  ut aliquip ex ea commodo consequat.&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;Блоки Легенда — Версія 1.4&lt;/title&gt;
  &lt;style&gt;
    body {
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            min-height: 100vh;
            margin: 0;
            padding: 10px;
            background-color: #f0f0f0;
            font-family: Arial, sans-serif;
            overflow: auto;
        }
        #gameCanvas {
            border: 2px solid #333;
            background-color: #e3f1c6;
            max-width: 100%;
            height: auto;
            margin-top: 20px;
        }
        #nextBlocks {
            display: flex;
            justify-content: center;
            margin-top: 10px;
            flex-wrap: wrap;
            width: 100%;
            max-width: 260px;
            gap: 1px;
        }
        .blockCanvas {
            border: 1px solid #ccc;
            cursor: grab;
            width: 80px;
            height: 80px;
            margin: 2px;
        }
        .blockCanvas.dragging {
            opacity: 0.5;
            cursor: grabbing;
        }
        #score, #highScore {
            font-size: 20px;
            margin-top: 10px;
        }
        #gameOver, #pauseOverlay {
            display: none;
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            background-color: rgba(0, 0, 0, 0.8);
            color: white;
            padding: 15px;
            border-radius: 10px;
            text-align: center;
            z-index: 1000;
        }
        button {
            margin-top: 10px;
            padding: 8px 16px;
            font-size: 14px;
            cursor: pointer;
        }
        h2 {
            margin: 10px 0;
        }
        p {
            margin: 5px 0;
        }
        #blockTable {
            width: 100%;
            max-width: 500px;
            border-collapse: collapse;
            margin-bottom: 15px;
        }
        #blockTable th, #blockTable td {
            border: 1px solid #333;
            padding: 8px;
            text-align: center;
        }
        #blockTable th {
            background-color: #ddd;
        }
        #blockTable canvas {
            border: 1px solid #ccc;
        }
  &lt;/style&gt;



  &lt;table id=&quot;blockTable&quot;&gt;
    &lt;thead&gt;
      &lt;tr&gt;
        &lt;th&gt;Назва&lt;/th&gt;
        &lt;th&gt;Зображення&lt;/th&gt;
        &lt;th&gt;Структура&lt;/th&gt;
        &lt;th&gt;Використання&lt;/th&gt;
      &lt;/tr&gt;
    &lt;/thead&gt;
    &lt;tbody&gt;
      &lt;tr&gt;
        &lt;td&gt;Одинарний&lt;/td&gt;
        &lt;td&gt;
          &lt;canvas id=&quot;shapeSingle&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;
        &lt;/td&gt;
        &lt;td&gt;
          &lt;pre&gt;[[1]]&lt;/pre&gt;
        &lt;/td&gt;
        &lt;td&gt;Для заповнення окремих клітинок&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;L-форма&lt;/td&gt;
        &lt;td&gt;
          &lt;canvas id=&quot;shapeL&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;
        &lt;/td&gt;
        &lt;td&gt;
          &lt;pre&gt;[[1, 1],
            &lt;br&gt;[1, 0]]&lt;/pre&gt;
        &lt;/td&gt;
        &lt;td&gt;Для кутів або вузьких просторів&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;T-форма&lt;/td&gt;
        &lt;td&gt;
          &lt;canvas id=&quot;shapeT&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;
        &lt;/td&gt;
        &lt;td&gt;
          &lt;pre&gt;[[1, 1, 1],
            &lt;br&gt;[0, 1, 0]]&lt;/pre&gt;
        &lt;/td&gt;
        &lt;td&gt;Для горизонтальних ліній з виступом&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;I-форма (4)&lt;/td&gt;
        &lt;td&gt;
          &lt;canvas id=&quot;shapeI4&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;
        &lt;/td&gt;
        &lt;td&gt;
          &lt;pre&gt;[[1, 1, 1, 1]]&lt;/pre&gt;
        &lt;/td&gt;
        &lt;td&gt;Для заповнення рядків/стовпців&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;Квадрат&lt;/td&gt;
        &lt;td&gt;
          &lt;canvas id=&quot;shapeSquare&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;
        &lt;/td&gt;
        &lt;td&gt;
          &lt;pre&gt;[[1, 1],
            &lt;br&gt;[1, 1]]&lt;/pre&gt;
        &lt;/td&gt;
        &lt;td&gt;Для компактних квадратних просторів&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;Z-форма&lt;/td&gt;
        &lt;td&gt;
          &lt;canvas id=&quot;shapeZ&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;
        &lt;/td&gt;
        &lt;td&gt;
          &lt;pre&gt;[[1, 1, 0],
            &lt;br&gt;[0, 1, 1]]&lt;/pre&gt;
        &lt;/td&gt;
        &lt;td&gt;Для зміщених &quot;змійок&quot;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;I-форма (5)&lt;/td&gt;
        &lt;td&gt;
          &lt;canvas id=&quot;shapeI5&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;
        &lt;/td&gt;
        &lt;td&gt;
          &lt;pre&gt;[[1, 1, 1, 1, 1]]&lt;/pre&gt;
        &lt;/td&gt;
        &lt;td&gt;Для довгих рядків/стовпців&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;I-форма (3)&lt;/td&gt;
        &lt;td&gt;
          &lt;canvas id=&quot;shapeI3&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;
        &lt;/td&gt;
        &lt;td&gt;
          &lt;pre&gt;[[1, 1, 1]]&lt;/pre&gt;
        &lt;/td&gt;
        &lt;td&gt;Для середніх рядків/стовпців&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;I-форма (2)&lt;/td&gt;
        &lt;td&gt;
          &lt;canvas id=&quot;shapeI2&quot; width=&quot;60&quot; height=&quot;60&quot;&gt;&lt;/canvas&gt;
        &lt;/td&gt;
        &lt;td&gt;
          &lt;pre&gt;[[1, 1]]&lt;/pre&gt;
        &lt;/td&gt;
        &lt;td&gt;Для коротких рядків/стовпців&lt;/td&gt;
      &lt;/tr&gt;
    &lt;/tbody&gt;
  &lt;/table&gt;
  &lt;h2&gt;Блоки Легенда — Версія 1.4&lt;/h2&gt;
  &lt;p&gt;Права кнопка миші — поворот блоку, Середня кнопка/подвійне торкання — перевертання,
    Кнопка &quot;Скасувати&quot; — скасування ходу&lt;/p&gt;
  &lt;canvas id=&quot;gameCanvas&quot; width=&quot;300&quot; height=&quot;300&quot;&gt;&lt;/canvas&gt;
  &lt;button id=&quot;pauseButton&quot;&gt;Пауза&lt;/button&gt;
  &lt;button id=&quot;undoButton&quot; disabled=&quot;&quot;&gt;Скасувати&lt;/button&gt;
  &lt;div id=&quot;nextBlocks&quot;&gt;
    &lt;canvas id=&quot;block1&quot; class=&quot;blockCanvas&quot; width=&quot;80&quot; height=&quot;80&quot; draggable=&quot;true&quot;&gt;&lt;/canvas&gt;
    &lt;canvas id=&quot;block2&quot; class=&quot;blockCanvas&quot; width=&quot;80&quot; height=&quot;80&quot; draggable=&quot;true&quot;&gt;&lt;/canvas&gt;
    &lt;canvas id=&quot;block3&quot; class=&quot;blockCanvas&quot; width=&quot;80&quot; height=&quot;80&quot; draggable=&quot;true&quot;&gt;&lt;/canvas&gt;
  &lt;/div&gt;
  &lt;div id=&quot;score&quot;&gt;Очки: 0&lt;/div&gt;
  &lt;div id=&quot;highScore&quot;&gt;Рекорд: 0&lt;/div&gt;
  &lt;div id=&quot;gameOver&quot;&gt;
    &lt;h2&gt;Гра закінчена!&lt;/h2&gt;
    &lt;p id=&quot;finalScore&quot;&gt;&lt;/p&gt;
    &lt;button onclick=&quot;restartGame()&quot;&gt;Грати знову&lt;/button&gt;
  &lt;/div&gt;
  &lt;div id=&quot;pauseOverlay&quot;&gt;
    &lt;h2&gt;Гра на паузі&lt;/h2&gt;
    &lt;button onclick=&quot;togglePause()&quot;&gt;Відновити&lt;/button&gt;
  &lt;/div&gt;

  &lt;script&gt;
    const gameCanvas = document.getElementById(&#039;gameCanvas&#039;);
        const ctx = gameCanvas.getContext(&#039;2d&#039;);
        const gridSize = 10;
        const cellSize = gameCanvas.width / gridSize; // 30px
        const scoreElement = document.getElementById(&#039;score&#039;);
        const highScoreElement = document.getElementById(&#039;highScore&#039;);
        const gameOverElement = document.getElementById(&#039;gameOver&#039;);
        const finalScoreElement = document.getElementById(&#039;finalScore&#039;);
        const pauseButton = document.getElementById(&#039;pauseButton&#039;);
        const undoButton = document.getElementById(&#039;undoButton&#039;);
        const pauseOverlay = document.getElementById(&#039;pauseOverlay&#039;);

        let grid = Array(gridSize).fill().map(() =&gt; Array(gridSize).fill(null));
        let score = 0;
        let highScore = parseInt(localStorage.getItem(&#039;blockLegendHighScore&#039;)) || 0;
        let currentBlocks = [];
        let selectedBlock = null;
        let gameActive = true;
        let gamePaused = false;
        let lastMove = null;

        highScoreElement.textContent = `Рекорд: ${highScore}`;
        console.log(&#039;Завантажено рекорд:&#039;, highScore);

        const blockShapes = [
            [[1]], // Одинарний (1x1)
            [[1]], // Одинарний (збільшена ймовірність)
            [[1, 1], [1, 0]], // L-форма
            [[1, 1, 1], [0, 1, 0]], // T-форма
            [[1, 1, 1, 1]], // I-форма (4)
            [[1, 1], [1, 1]], // Квадрат
            [[1, 1, 0], [0, 1, 1]], // Z-форма
            [[1, 1, 1, 1, 1]], // I-форма (5)
            [[1, 1, 1]], // I-форма (3)
            [[1, 1]], // I-форма (2)
        ];

        const colors = [&#039;#FF0000&#039;, &#039;#00FF00&#039;, &#039;#0000FF&#039;, &#039;#FFFF00&#039;, &#039;#FF00FF&#039;, &#039;#FFA500&#039;, &#039;#800080&#039;];

        function rotateShape(shape) {
            const rows = shape.length;
            const cols = shape[0].length;
            const newShape = Array(cols).fill().map(() =&gt; Array(rows).fill(0));
            for (let y = 0; y &lt; rows; y++) {
                for (let x = 0; x &lt; cols; x++) {
                    newShape[x][rows - 1 - y] = shape[y][x];
                }
            }
            return newShape;
        }

        function flipShape(shape) {
            const newShape = shape.map(row =&gt; [...row].reverse());
            return newShape;
        }

        function undoMove() {
            if (!lastMove || !gameActive || gamePaused) return;
            const { grid: prevGrid, score: prevScore, block, blockIndex } = lastMove;
            grid = prevGrid.map(row =&gt; [...row]);
            score = prevScore;
            scoreElement.textContent = `Очки: ${score}`;
            currentBlocks.splice(blockIndex, 0, block);
            for (let i = 0; i &lt; 3; i++) {
                if (i &lt; currentBlocks.length) {
                    drawBlock(i, currentBlocks[i].shape, currentBlocks[i].color);
                } else {
                    document.getElementById(`block${i + 1}`).getContext(&#039;2d&#039;).clearRect(0, 0, 80, 80);
                }
            }
            lastMove = null;
            undoButton.disabled = true;
            drawGrid();
            console.log(&#039;Хід скасовано&#039;);
        }

        function drawTableBlock(canvasId, shape, color) {
            const canvas = document.getElementById(canvasId);
            const ctx = canvas.getContext(&#039;2d&#039;);
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            const maxSize = Math.max(shape.length, shape[0].length);
            const blockCellSize = canvas.width / maxSize;
            shape.forEach((row, y) =&gt; {
                row.forEach((cell, x) =&gt; {
                    if (cell) {
                        ctx.fillStyle = color;
                        ctx.fillRect(x * blockCellSize + 2, y * blockCellSize + 2, blockCellSize - 4, blockCellSize - 4);
                        ctx.strokeStyle = &#039;#000&#039;;
                        ctx.strokeRect(x * blockCellSize + 2, y * blockCellSize + 2, blockCellSize - 4, blockCellSize - 4);
                    }
                });
            });
        }

        drawTableBlock(&#039;shapeSingle&#039;, blockShapes[0], colors[0]);
        drawTableBlock(&#039;shapeL&#039;, blockShapes[2], colors[1]);
        drawTableBlock(&#039;shapeT&#039;, blockShapes[3], colors[2]);
        drawTableBlock(&#039;shapeI4&#039;, blockShapes[4], colors[3]);
        drawTableBlock(&#039;shapeSquare&#039;, blockShapes[5], colors[4]);
        drawTableBlock(&#039;shapeZ&#039;, blockShapes[6], colors[0]);
        drawTableBlock(&#039;shapeI5&#039;, blockShapes[7], colors[5]);
        drawTableBlock(&#039;shapeI3&#039;, blockShapes[8], colors[6]);
        drawTableBlock(&#039;shapeI2&#039;, blockShapes[9], colors[1]);

        function generateBlocks() {
            console.log(&#039;Генеруються нові блоки, поточна кількість:&#039;, currentBlocks.length);
            currentBlocks = [];
            for (let i = 1; i &lt;= 3; i++) {
                document.getElementById(`block${i}`).getContext(&#039;2d&#039;).clearRect(0, 0, 80, 80);
            }
            for (let i = 0; i &lt; 3; i++) {
                const shapeIndex = Math.floor(Math.random() * blockShapes.length);
                const color = colors[Math.floor(Math.random() * colors.length)];
                currentBlocks.push({ shape: blockShapes[shapeIndex], color });
                drawBlock(i, blockShapes[shapeIndex], color);
                console.log(`Згенеровано блок ${i + 1}: форма ${JSON.stringify(blockShapes[shapeIndex])}, колір ${color}`);
            }
            console.log(&#039;Нові блоки створено:&#039;, JSON.stringify(currentBlocks.map(b =&gt; ({ shape: b.shape, color: b.color }))));
            drawGrid();
        }

        function drawBlock(index, shape, color) {
            const blockCanvas = document.getElementById(`block${index + 1}`);
            const blockCtx = blockCanvas.getContext(&#039;2d&#039;);
            blockCtx.clearRect(0, 0, blockCanvas.width, blockCanvas.height);
            const maxSize = Math.max(shape.length, shape[0].length);
            const blockCellSize = Math.min(blockCanvas.width / maxSize, blockCanvas.height / maxSize) * 0.9;
            const offsetX = (blockCanvas.width - maxSize * blockCellSize) / 2;
            const offsetY = (blockCanvas.height - maxSize * blockCellSize) / 2;
            shape.forEach((row, y) =&gt; {
                row.forEach((cell, x) =&gt; {
                    if (cell) {
                        blockCtx.fillStyle = color;
                        blockCtx.fillRect(offsetX + x * blockCellSize + 2, offsetY + y * blockCellSize + 2, blockCellSize - 4, blockCellSize - 4);
                        blockCtx.strokeStyle = &#039;#000&#039;;
                        blockCtx.strokeRect(offsetX + x * blockCellSize + 2, offsetY + y * blockCellSize + 2, blockCellSize - 4, blockCellSize - 4);
                    }
                });
            });
        }

        function drawGrid() {
            ctx.clearRect(0, 0, gameCanvas.width, gameCanvas.height);
            for (let y = 0; y &lt; gridSize; y++) {
                for (let x = 0; x &lt; gridSize; x++) {
                    ctx.strokeStyle = &#039;#000&#039;;
                    ctx.strokeRect(x * cellSize, y * cellSize, cellSize, cellSize);
                    if (grid[y][x]) {
                        ctx.fillStyle = grid[y][x];
                        ctx.fillRect(x * cellSize + 2, y * cellSize + 2, cellSize - 4, cellSize - 4);
                    }
                }
            }
        }

        function drawPreview(shape, x, y, valid) {
            drawGrid();
            if (shape &amp;&amp; x &gt;= 0 &amp;&amp; y &gt;= 0) {
                ctx.globalAlpha = 0.5;
                for (let sy = 0; sy &lt; shape.length; sy++) {
                    for (let sx = 0; sx &lt; shape[sy].length; sx++) {
                        if (shape[sy][sx]) {
                            ctx.fillStyle = valid ? selectedBlock.color : &#039;#FF0000&#039;;
                            ctx.fillRect((x + sx) * cellSize + 2, (y + sy) * cellSize + 2, cellSize - 4, cellSize - 4);
                            ctx.strokeStyle = &#039;#000&#039;;
                            ctx.strokeRect((x + sx) * cellSize + 2, (y + sy) * cellSize + 2, cellSize - 4, cellSize - 4);
                        }
                    }
                }
                ctx.globalAlpha = 1.0;
            }
        }

        function canPlaceBlock(shape, x, y) {
            for (let sy = 0; sy &lt; shape.length; sy++) {
                for (let sx = 0; sx &lt; shape[sy].length; sx++) {
                    if (shape[sy][sx]) {
                        const gridX = x + sx;
                        const gridY = y + sy;
                        if (gridX &lt; 0 || gridX &gt;= gridSize || gridY &lt; 0 || gridY &gt;= gridSize || grid[gridY][gridX]) {
                            return false;
                        }
                    }
                }
            }
            return true;
        }

        function placeBlock(shape, color, x, y, blockIndex) {
            console.log(`Розміщення блоку на позиції (${x}, ${y}), індекс: ${blockIndex}, форма:`, JSON.stringify(shape));
            lastMove = {
                grid: grid.map(row =&gt; [...row]),
                score,
                block: { shape, color },
                blockIndex
            };
            undoButton.disabled = false;
            for (let sy = 0; sy &lt; shape.length; sy++) {
                for (let sx = 0; sx &lt; shape[sy].length; sx++) {
                    if (shape[sy][sx]) {
                        grid[y + sy][x + sx] = color;
                    }
                }
            }
            console.log(&#039;Блок розміщено, викликаємо checkLines&#039;);
            checkLines();
            console.log(&#039;checkLines завершено, викликаємо checkGameOver&#039;);
            checkGameOver();
            drawGrid();
            console.log(&#039;Розміщення завершено, поточна черга:&#039;, JSON.stringify(currentBlocks.map(b =&gt; ({ shape: b.shape, color: b.color }))));
        }

        function checkLines() {
            let linesCleared = 0;
            for (let y = gridSize - 1; y &gt;= 0; y--) {
                if (grid[y].every(cell =&gt; cell)) {
                    grid.splice(y, 1);
                    grid.unshift(Array(gridSize).fill(null));
                    linesCleared++;
                    y++;
                }
            }
            for (let x = gridSize - 1; x &gt;= 0; x--) {
                let isFull = true;
                for (let y = 0; y &lt; gridSize; y++) {
                    if (!grid[y][x]) {
                        isFull = false;
                        break;
                    }
                }
                if (isFull) {
                    for (let y = 0; y &lt; gridSize; y++) {
                        grid[y].splice(x, 1);
                        grid[y].push(null);
                    }
                    linesCleared++;
                    x++;
                }
            }
            if (linesCleared &gt; 0) {
                score += linesCleared * 100;
                scoreElement.textContent = `Очки: ${score}`;
                if (score &gt; highScore) {
                    highScore = score;
                    localStorage.setItem(&#039;blockLegendHighScore&#039;, highScore);
                    highScoreElement.textContent = `Рекорд: ${highScore}`;
                    console.log(&#039;Новий рекорд:&#039;, highScore);
                }
            }
            console.log(&#039;Очищено ліній:&#039;, linesCleared, &#039;Очки:&#039;, score, &#039;Рекорд:&#039;, highScore);
        }

        function checkGameOver() {
            console.log(&#039;Перевірка стану гри. Кількість блоків:&#039;, currentBlocks.length, &#039;Блоки:&#039;, JSON.stringify(currentBlocks.map(b =&gt; ({ shape: b.shape, color: b.color }))));
            if (currentBlocks.length === 0) {
                console.log(&#039;Черга порожня, генеруємо нові блоки&#039;);
                setTimeout(() =&gt; {
                    generateBlocks();
                    console.log(&#039;Нові блоки згенеровано, нова черга:&#039;, JSON.stringify(currentBlocks.map(b =&gt; ({ shape: b.shape, color: b.color }))));
                }, 0);
                return;
            }
            let canPlaceAny = false;
            for (let block of currentBlocks) {
                for (let y = 0; y &lt; gridSize; y++) {
                    for (let x = 0; x &lt; gridSize; x++) {
                        if (canPlaceBlock(block.shape, x, y)) {
                            canPlaceAny = true;
                            break;
                        }
                    }
                    if (canPlaceAny) break;
                }
                if (canPlaceAny) break;
            }
            console.log(&#039;Чи можна розмістити блок:&#039;, canPlaceAny);
            if (!canPlaceAny) {
                gameActive = false;
                if (score &gt; highScore) {
                    highScore = score;
                    localStorage.setItem(&#039;blockLegendHighScore&#039;, highScore);
                    console.log(&#039;Новий рекорд на кінці гри:&#039;, highScore);
                }
                finalScoreElement.textContent = `Ваш рахунок: ${score}\nРекорд: ${highScore}`;
                gameOverElement.style.display = &#039;block&#039;;
                console.log(&#039;Гра закінчена. Рахунок:&#039;, score, &#039;Рекорд:&#039;, highScore);
            }
        }

        function restartGame() {
            grid = Array(gridSize).fill().map(() =&gt; Array(gridSize).fill(null));
            score = 0;
            scoreElement.textContent = `Очки: ${score}`;
            highScoreElement.textContent = `Рекорд: ${highScore}`;
            gameOverElement.style.display = &#039;none&#039;;
            gamePaused = false;
            pauseButton.textContent = &#039;Пауза&#039;;
            pauseOverlay.style.display = &#039;none&#039;;
            undoButton.disabled = true;
            lastMove = null;
            gameActive = true;
            currentBlocks = [];
            generateBlocks();
            drawGrid();
            console.log(&#039;Гра перезапущена. Рахунок:&#039;, score, &#039;Рекорд:&#039;, highScore);
        }

        function togglePause() {
            if (!gameActive) return;
            gamePaused = !gamePaused;
            pauseButton.textContent = gamePaused ? &#039;Відновити&#039; : &#039;Пауза&#039;;
            pauseOverlay.style.display = gamePaused ? &#039;block&#039; : &#039;none&#039;;
            console.log(&#039;Гра на паузі:&#039;, gamePaused);
        }

        pauseButton.addEventListener(&#039;click&#039;, togglePause);
        undoButton.addEventListener(&#039;click&#039;, undoMove);

        const blockCanvases = document.querySelectorAll(&#039;.blockCanvas&#039;);
        blockCanvases.forEach(canvas =&gt; {
            canvas.addEventListener(&#039;dragstart&#039;, (e) =&gt; {
                if (!gameActive || gamePaused) return;
                const index = parseInt(canvas.id.replace(&#039;block&#039;, &#039;&#039;)) - 1;
                selectedBlock = currentBlocks[index];
                canvas.classList.add(&#039;dragging&#039;);
                e.dataTransfer.setData(&#039;text/plain&#039;, index);
                console.log(&#039;Початок перетягування блоку:&#039;, index, &#039;Блок:&#039;, JSON.stringify(selectedBlock));
            });

            canvas.addEventListener(&#039;dragend&#039;, (e) =&gt; {
                canvas.classList.remove(&#039;dragging&#039;);
                drawGrid();
                console.log(&#039;Кінець перетягування&#039;);
            });

            canvas.addEventListener(&#039;contextmenu&#039;, (e) =&gt; {
                e.preventDefault();
                if (!gameActive || gamePaused) return;
                const index = parseInt(canvas.id.replace(&#039;block&#039;, &#039;&#039;)) - 1;
                currentBlocks[index].shape = rotateShape(currentBlocks[index].shape);
                drawBlock(index, currentBlocks[index].shape, currentBlocks[index].color);
                console.log(&#039;Блок повернуто:&#039;, index, &#039;Нова форма:&#039;, JSON.stringify(currentBlocks[index].shape));
            });

            canvas.addEventListener(&#039;mousedown&#039;, (e) =&gt; {
                if (e.button === 1) {
                    e.preventDefault();
                    if (!gameActive || gamePaused) return;
                    const index = parseInt(canvas.id.replace(&#039;block&#039;, &#039;&#039;)) - 1;
                    currentBlocks[index].shape = flipShape(currentBlocks[index].shape);
                    drawBlock(index, currentBlocks[index].shape, currentBlocks[index].color);
                    console.log(&#039;Блок перевернуто:&#039;, index, &#039;Нова форма:&#039;, JSON.stringify(currentBlocks[index].shape));
                }
            });

            canvas.addEventListener(&#039;dblclick&#039;, (e) =&gt; {
                e.preventDefault();
                if (!gameActive || gamePaused) return;
                const index = parseInt(canvas.id.replace(&#039;block&#039;, &#039;&#039;)) - 1;
                currentBlocks[index].shape = flipShape(currentBlocks[index].shape);
                drawBlock(index, currentBlocks[index].shape, currentBlocks[index].color);
                console.log(&#039;Блок перевернуто (подвійне торкання):&#039;, index, &#039;Нова форма:&#039;, JSON.stringify(currentBlocks[index].shape));
            });

            canvas.addEventListener(&#039;touchstart&#039;, (e) =&gt; {
                if (!gameActive || gamePaused) return;
                const index = parseInt(canvas.id.replace(&#039;block&#039;, &#039;&#039;)) - 1;
                if (index &gt;= 0 &amp;&amp; index &lt; currentBlocks.length) {
                    selectedBlock = currentBlocks[index];
                    canvas.classList.add(&#039;dragging&#039;);
                    console.log(&#039;Початок сенсорного перетягування блоку:&#039;, index, &#039;Блок:&#039;, JSON.stringify(selectedBlock));
                } else {
                    console.error(&#039;Помилка: невалідний індекс блоку на touchstart&#039;, index);
                }
            });

            canvas.addEventListener(&#039;touchmove&#039;, (e) =&gt; {
                e.preventDefault();
                if (!gameActive || !selectedBlock || gamePaused) return;
                const touch = e.touches[0];
                const rect = gameCanvas.getBoundingClientRect();
                const x = Math.floor((touch.clientX - rect.left) / cellSize);
                const y = Math.floor((touch.clientY - rect.top) / cellSize);
                const valid = canPlaceBlock(selectedBlock.shape, x, y);
                drawPreview(selectedBlock.shape, x, y, valid);
            });

            canvas.addEventListener(&#039;touchend&#039;, (e) =&gt; {
                if (!gameActive || !selectedBlock || gamePaused) return;
                const touch = e.changedTouches[0];
                const rect = gameCanvas.getBoundingClientRect();
                const x = Math.floor((touch.clientX - rect.left) / cellSize);
                const y = Math.floor((touch.clientY - rect.top) / cellSize);
                const index = parseInt(canvas.id.replace(&#039;block&#039;, &#039;&#039;)) - 1;
                console.log(`Сенсорне розміщення: координати (${x}, ${y}), індекс: ${index}, блок:`, JSON.stringify(selectedBlock));
                if (index &gt;= 0 &amp;&amp; index &lt; currentBlocks.length) {
                    if (canPlaceBlock(selectedBlock.shape, x, y)) {
                        placeBlock(selectedBlock.shape, selectedBlock.color, x, y, index);
                        currentBlocks.splice(index, 1);
                        console.log(&#039;Блок видалено з черги. Залишилося:&#039;, currentBlocks.length, &#039;Блоки:&#039;, JSON.stringify(currentBlocks.map(b =&gt; ({ shape: b.shape, color: b.color }))));
                        for (let i = 0; i &lt; 3; i++) {
                            const blockCanvas = document.getElementById(`block${i + 1}`);
                            blockCanvas.getContext(&#039;2d&#039;).clearRect(0, 0, blockCanvas.width, blockCanvas.height);
                            if (i &lt; currentBlocks.length) {
                                drawBlock(i, currentBlocks[i].shape, currentBlocks[i].color);
                            }
                        }
                        checkGameOver();
                        selectedBlock = null;
                    } else {
                        console.log(&#039;Неможливо розмістити блок на позиції:&#039;, x, y);
                    }
                } else {
                    console.error(&#039;Помилка: невалідний індекс блоку на touchend&#039;, index);
                }
                canvas.classList.remove(&#039;dragging&#039;);
                drawGrid();
                console.log(&#039;Сенсорне розміщення завершено&#039;);
            });
        });

        gameCanvas.addEventListener(&#039;dragover&#039;, (e) =&gt; {
            e.preventDefault();
            if (!gameActive || !selectedBlock || gamePaused) return;
            const rect = gameCanvas.getBoundingClientRect();
            const x = Math.floor((e.clientX - rect.left) / cellSize);
            const y = Math.floor((e.clientY - rect.top) / cellSize);
            const valid = canPlaceBlock(selectedBlock.shape, x, y);
            drawPreview(selectedBlock.shape, x, y, valid);
        });

        gameCanvas.addEventListener(&#039;drop&#039;, (e) =&gt; {
            e.preventDefault();
            if (!gameActive || !selectedBlock || gamePaused) return;
            const rect = gameCanvas.getBoundingClientRect();
            const x = Math.floor((e.clientX - rect.left) / cellSize);
            const y = Math.floor((e.clientY - rect.top) / cellSize);
            const index = parseInt(e.dataTransfer.getData(&#039;text/plain&#039;));
            console.log(`Розміщення через drag: координати (${x}, ${y}), індекс: ${index}, блок:`, JSON.stringify(selectedBlock));
            if (index &gt;= 0 &amp;&amp; index &lt; currentBlocks.length) {
                if (canPlaceBlock(selectedBlock.shape, x, y)) {
                    placeBlock(selectedBlock.shape, selectedBlock.color, x, y, index);
                    currentBlocks.splice(index, 1);
                    console.log(&#039;Блок видалено з черги. Залишилося:&#039;, currentBlocks.length, &#039;Блоки:&#039;, JSON.stringify(currentBlocks.map(b =&gt; ({ shape: b.shape, color: b.color }))));
                    for (let i = 0; i &lt; 3; i++) {
                        const blockCanvas = document.getElementById(`block${i + 1}`);
                        blockCanvas.getContext(&#039;2d&#039;).clearRect(0, 0, blockCanvas.width, blockCanvas.height);
                        if (i &lt; currentBlocks.length) {
                            drawBlock(i, currentBlocks[i].shape, currentBlocks[i].color);
                        }
                    }
                    checkGameOver();
                    selectedBlock = null;
                } else {
                    console.log(&#039;Неможливо розмістити блок на позиції:&#039;, x, y);
                }
            } else {
                console.error(&#039;Помилка: невалідний індекс блоку на drop&#039;, index);
            }
        });

        generateBlocks();
        drawGrid();
        console.log(&#039;Гра ініціалізована — Версія 1.4&#039;);
  &lt;/script&gt;</description>
            </item>
            </channel>
</rss>