Re[2]: Завайбкодил Мермина-Переса на JS (играть онлайн)
От: Shmj Ниоткуда  
Дата: 29.03.25 12:00
Оценка:
Здравствуйте, The Minister, Вы писали:

TM>Только почему-то из РФ не открывается. Попробовал через иностранный VPN — открылось.


Ну вот, даже тут вам просто так истину не донесешь — запрещают открывать глаза.

А как же вам можно запустить JS код?

Вот одним HTML-файлом:

  Скрытый текст
<!DOCTYPE html>
<html lang="ru">
<head>
  <meta charset="UTF-8">
  <title>Игра Мермина-Переса</title>
  <style>
    body {
      font-family: sans-serif;
      display: flex;
      justify-content: space-around;
      margin: 20px;
    }
    .panel {
      display: flex;
      flex-direction: column;
      gap: 10px;
    }
    .row {
      display: flex;
      align-items: center;
      gap: 5px;
    }
    button {
      padding: 5px 10px;
      cursor: pointer;
    }
    table {
      border-collapse: collapse;
      margin-top: 20px;
    }
    td {
      width: 100px;
      height: 100px;
      border: 1px solid #000;
      text-align: center;
      vertical-align: middle;
      font-size: 24px;
    }
    .row-highlight {
      background-color: lightgreen;
    }
    .col-highlight {
      background-color: lightcoral;
    }
    .alice-choice {
      color: darkgreen;
      font-weight: bold;
    }
    .bob-choice {
      color: darkred;
      font-weight: bold;
    }

    /* Ячейка результата (4-я строка таблицы) */
    td#resultMessageCell {
      border: none;
      font-size: 2em;  
      text-align: center;
      height: auto;
    }
  </style>
</head>
<body>
  <div class="panel">
    <h2>Выбор ведущего</h2>
    <h3>Выбор строки (Алиса)</h3>
    <button onclick="chooseRow(0)">Строка 1</button>
    <button onclick="chooseRow(1)">Строка 2</button>
    <button onclick="chooseRow(2)">Строка 3</button>

    <h3>Выбор столбца (Боб)</h3>
    <button onclick="chooseCol(0)">Столбец 1</button>
    <button onclick="chooseCol(1)">Столбец 2</button>
    <button onclick="chooseCol(2)">Столбец 3</button>
  </div>

  <!-- Таблица 3x3 + четвертая строка для надписи ПОБЕДА/ПОРАЖЕНИЕ -->
  <table id="gameBoard"></table>

  <div class="panel">
    <h3>Выбор Алисы</h3>
    <div class="row">
      <span>Ячейка 1:</span>
      <button onclick="setAliceChoice(0, '+')">+</button>
      <button onclick="setAliceChoice(0, '-')">-</button>
    </div>
    <div class="row">
      <span>Ячейка 2:</span>
      <button onclick="setAliceChoice(1, '+')">+</button>
      <button onclick="setAliceChoice(1, '-')">-</button>
    </div>

    <h3>Выбор Боба</h3>
    <div class="row">
      <span>Ячейка 1:</span>
      <button onclick="setBobChoice(0, '+')">+</button>
      <button onclick="setBobChoice(0, '-')">-</button>
    </div>
    <div class="row">
      <span>Ячейка 2:</span>
      <button onclick="setBobChoice(1, '+')">+</button>
      <button onclick="setBobChoice(1, '-')">-</button>
    </div>
  </div>

  <script>
    // ========================= ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ =========================
    const board = document.getElementById('gameBoard');
    let currentRow = null;
    let currentCol = null;

    // Двумерный массив с объектами: { alice: '+/-/пусто', bob: '+/-/пусто' }
    let cellData = Array.from({ length: 3 }, () =>
      Array.from({ length: 3 }, () => ({ alice: '', bob: '' }))
    );

    // Ссылка на ячейку (4-я строка), в которую пишем "ПОБЕДА" / "ПОРАЖЕНИЕ"
    let resultCell = null;

    // ========================= СОЗДАНИЕ ТАБЛИЦЫ =========================
    function createBoard() {
      // Создаём 3 строки по 3 ячейки
      for (let i = 0; i < 3; i++) {
        const row = board.insertRow();
        for (let j = 0; j < 3; j++) {
          row.insertCell();
        }
      }
      // Добавляем 4-ю строку: одна ячейка (colSpan=3)
      const resultRow = board.insertRow();
      const cell = resultRow.insertCell();
      cell.colSpan = 3;
      cell.id = 'resultMessageCell';
      resultCell = cell;
    }

    // ========================= ПОДСВЕТКИ =========================
    function clearRowHighlights() {
      for (let i = 0; i < 3; i++) {
        board.rows[i].classList.remove('row-highlight');
      }
    }
    function clearColHighlights() {
      for (let i = 0; i < 3; i++) {
        for (let j = 0; j < 3; j++) {
          board.rows[i].cells[j].classList.remove('col-highlight');
        }
      }
    }

    // ========================= ВЫБОР СТРОКИ/СТОЛБЦА =========================
    function chooseRow(rowIndex) {
      clearRowHighlights();
      clearBoardValues();
      currentRow = rowIndex;
      board.rows[rowIndex].classList.add('row-highlight');
      checkIntersection();
    }

    function chooseCol(colIndex) {
      clearColHighlights();
      clearBoardValues();
      currentCol = colIndex;
      for (let i = 0; i < 3; i++) {
        board.rows[i].cells[colIndex].classList.add('col-highlight');
      }
      checkIntersection();
    }

    // ========================= ОЧИСТКА ПОЛЯ (3x3) =========================
    // Не трогаем 4-ю строку, а лишь стираем сообщение
    function clearBoardValues() {
      for (let i = 0; i < 3; i++) {
        for (let j = 0; j < 3; j++) {
          const cell = board.rows[i].cells[j];
          cell.textContent = '';
          cell.classList.remove('alice-choice', 'bob-choice');
          cellData[i][j] = { alice: '', bob: '' };
        }
      }
      resultCell.textContent = '';
      resultCell.style.color = '';
    }

    // ========================= ОТРИСОВКА ЗНАКОВ =========================
    function updateCellText(row, col) {
      const data = cellData[row][col];
      const cell = board.rows[row].cells[col];
      const text = `${data.alice || ''}${data.alice && data.bob ? ' / ' : ''}${data.bob || ''}`;
      cell.textContent = text;
      cell.classList.toggle('alice-choice', data.alice !== '');
      cell.classList.toggle('bob-choice', data.bob !== '');
    }

    // ========================= ВСПОМОГАТЕЛЬНЫЕ ФУНКЦИИ =========================

    // Возвращает '+' или '-' для «третьей» ячейки, если уже 2 ячейки заполнены,
    // чтобы итоговое произведение (v1*v2*v3) = expectedProduct.
    // Если заполнено меньше 2, вернёт null (автодополнение пока невозможно).
    function inferThird(values, expectedProduct) {
      // Переводим в массив чисел: + => 1, - => -1, '' => null
      const signs = values.map(v => (v === '+') ? 1 : (v === '-') ? -1 : null);
      const filledCount = signs.filter(s => s !== null).length;
      if (filledCount < 2) return null;

      // Произведение уже заполненных
      let product = 1;
      for (let s of signs) {
        if (s !== null) product *= s;
      }
      // Если currentProduct = product, чтобы достигнуть expectedProduct
      // нам нужен знак: + (1), если product == expectedProduct, иначе - ( -1 ).
      return (product === expectedProduct) ? '+' : '-';
    }

    // Если все 3 ячейки уже заполнены, но их произведение не совпадает с expectedProduct,
    // «переворачиваем» именно третью ячейку (индекс 2).
    // Возвращаем обновлённый массив строк вида ['+','+','-'].
    function fixIfAllThreeFilled(values, expectedProduct) {
      // Проверим, действительно ли 3 заполнены
      if (values.every(v => v === '+' || v === '-')) {
        // Считаем текущее произведение
        let product = 1;
        for (let sign of values) {
          product *= (sign === '+') ? 1 : -1;
        }
        // Если не совпадает, «переворачиваем» последнюю ячейку
        if (product !== expectedProduct) {
          const last = values[2]; // (индекс 2 - третья)
          values[2] = (last === '+') ? '-' : '+';
        }
      }
      return values;
    }

    // Проверяет «пересекающуюся ячейку» (currentRow, currentCol).
    // Если там (alice,bob) оба уже стоят, выводит ПОБЕДА/ПОРАЖЕНИЕ.
    function checkIntersection() {
      if (currentRow === null || currentCol === null) {
        resultCell.textContent = '';
        resultCell.style.color = '';
        return;
      }
      const { alice, bob } = cellData[currentRow][currentCol];
      if (!alice || !bob) {
        resultCell.textContent = '';
        resultCell.style.color = '';
        return;
      }
      // Оба знака есть, проверяем совпадение
      if (alice === bob) {
        resultCell.textContent = 'ПОБЕДА';
        resultCell.style.color = 'green';
      } else {
        resultCell.textContent = 'ПОРАЖЕНИЕ';
        resultCell.style.color = 'red';
      }
    }

    // ========================= ФУНКЦИИ ВЫБОРА АЛИСЫ =========================
    // Строка Алисы должна иметь произведение +1
    function setAliceChoice(index, value) {
      if (currentRow === null) {
        alert("Сначала выберите строку (Алиса)");
        return;
      }
      // 1) Записываем новое значение
      cellData[currentRow][index].alice = value;
      updateCellText(currentRow, index);

      // 2) Смотрим, сколько ячеек заполнено
      let rowValues = cellData[currentRow].map(c => c.alice); // 3 значения ( + / - / '' )

      // Если ровно 2 заполнены, автодополняем третью
      const thirdSign = inferThird(rowValues, +1);
      if (thirdSign && rowValues.filter(v => v !== '').length === 2) {
        const missingIndex = rowValues.findIndex(v => v === '');
        rowValues[missingIndex] = thirdSign;
      }

      // Если все 3 заполнены, «чинim» при необходимости
      rowValues = fixIfAllThreeFilled(rowValues, +1);

      // 3) Записываем обратно в cellData и обновляем ячейки
      rowValues.forEach((val, i) => {
        cellData[currentRow][i].alice = val;
        updateCellText(currentRow, i);
      });

      // 4) Проверяем пересечение
      checkIntersection();
    }

    // ========================= ФУНКЦИИ ВЫБОРА БОБА =========================
    // Столбец Боба должен иметь произведение -1
    function setBobChoice(index, value) {
      if (currentCol === null) {
        alert("Сначала выберите столбец (Боб)");
        return;
      }
      // 1) Записать новое значение
      cellData[index][currentCol].bob = value;
      updateCellText(index, currentCol);

      // 2) Аналогичные шаги — но для столбца
      let colValues = [0,1,2].map(r => cellData[r][currentCol].bob);
      const thirdSign = inferThird(colValues, -1);

      if (thirdSign && colValues.filter(v => v !== '').length === 2) {
        const missingIndex = colValues.findIndex(v => v === '');
        colValues[missingIndex] = thirdSign;
      }

      // Если все 3 ячейки заполнены, «чиним»
      colValues = fixIfAllThreeFilled(colValues, -1);

      // Записываем обратно
      colValues.forEach((val, i) => {
        cellData[i][currentCol].bob = val;
        updateCellText(i, currentCol);
      });

      // 3) Проверка пересечения
      checkIntersection();
    }

    // ========================= ИНИЦИАЛИЗАЦИЯ =========================
    createBoard();
  </script>
</body>
</html>
=сначала спроси у GPT=
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.