| | // ------------------------- ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ -------------------------
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;
}
|