Завайбкодил Мермина-Переса на JS (играть онлайн)
От: Shmj Ниоткуда  
Дата: 29.03.25 10:03
Оценка: 14 (2) +1
ИИ заговнокодил игру Мермина-Переса тут: https://jsfiddle.net/4bsfj5wd/

Как играть:

1. Кликаете выбор ведущего (строка и рядок). Подсвечивается.
2. Кликаете выбор Алисы. Алиса знает только строку. Третья ячейка вычисляется по правилам.
3. Аналогично — выбор Боба.

Победа — если игроки угадали и на пересечении значение совпало. Знать точно нельзя, т.к. Алиса получает лишь номер строки от ведущего а Боб лишь номер рядка.

Причина зачем делалось — игру не могли понять по описаниям. Тот же жрец D. Mon пытался объяснить
Автор: D. Mon
Дата: 19.03.25
нам, простым смертным, как можно читерить с помощью квантовой запутанности — но не все поняли даже саму суть игры.

А тут все наглядно — можно сыграть и прочувствовать на практике.

  Дамп
// ------------------------- ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ -------------------------
const board = document.getElementById('gameBoard');

// Выбранная строка (Алиса) и столбец (Боб)
let currentRow = null;
let currentCol = null;

// Двумерный массив: cellData[row][col] = { 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) -------------------------
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 !== '');
}

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

/**
 * inferThird(values, expectedProduct)
 * Если заполнено 2 ячейки из 3, возвращает знак для третьей, чтобы
 * произведение (v1 * v2 * v3) = expectedProduct (1 или -1).
 * Если заполнено <2, возвращает null.
 */
function inferThird(values, expectedProduct) {
  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;
  }
  // Нужно, чтобы итог = expectedProduct
  return (product === expectedProduct) ? '+' : '-';
}

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

/**
 * checkIntersection()
 * Проверяем «пересекающуюся ячейку» (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';
  }
}

// ------------------------- УПРАВЛЕНИЕ СТРОКАМИ (АЛИСА) -------------------------
function setAliceChoice(index, value) {
  if (currentRow === null) {
    alert("Сначала выберите строку (Алиса)");
    return;
  }
  // Записать новое значение
  cellData[currentRow][index].alice = value;
  updateCellText(currentRow, index);

  // Проверяем, сколько ячеек заполнено, пробуем автодополнение
  let rowValues = cellData[currentRow].map(c => c.alice);
  const thirdSign = inferThird(rowValues, +1); // хотим +1 для Алисы

  if (thirdSign && rowValues.filter(v => v !== '').length === 2) {
    const missingIndex = rowValues.findIndex(v => v === '');
    rowValues[missingIndex] = thirdSign;
  }
  // Если все 3 заполнены, «чиним» при необходимости
  rowValues = fixIfAllThreeFilled(rowValues, +1);

  // Записать обратно и отрисовать
  rowValues.forEach((val, i) => {
    cellData[currentRow][i].alice = val;
    updateCellText(currentRow, i);
  });

  checkIntersection();
}

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

  // Автодополнение (ожидаем -1 по столбцу)
  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);
  });

  checkIntersection();
}


<!DOCTYPE html>
<html lang="ru">
<head>
  <meta charset="UTF-8">
  <title>Игра Мермина-Переса</title>
  <!-- Подключаем внешний CSS -->
  <link rel="stylesheet" href="style.css">
</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>

  <!-- Подключаем внешний скрипт (JS) -->
  <script src="script.js"></script>
</body>
</html>


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-я строка таблицы) */
#resultMessageCell {
  border: none;
  font-size: 2em;  
  text-align: center;
  height: auto;
}


Не написал ни одной строчки кода. Ушло примерно час времени, чтобы по шагам объяснить ему одно за другим. Пришлось переходить на модель o1, т.к. обычная уперлась в потолок и начала ломать код.

По сути получается что написать вручную (если работаешь с технологией) — быстрее, чем ему объяснить по шагам. Но! Если ты языка не знаешь или редко на нем пишешь — то быстрее объяснить.
=сначала спроси у GPT=
Отредактировано 29.03.2025 10:08 Shmj . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.