From b151d2fcae44f3a82a6af4ec5ca981a7913005f2 Mon Sep 17 00:00:00 2001 From: philya71828 Date: Sat, 7 Aug 2021 22:29:25 +0500 Subject: [PATCH 1/4] Task done 1 --- index.js | 138 +++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 118 insertions(+), 20 deletions(-) diff --git a/index.js b/index.js index 7553909..1f9593c 100644 --- a/index.js +++ b/index.js @@ -4,19 +4,37 @@ const EMPTY = ' '; const container = document.getElementById('fieldWrapper'); +let sym; // Символ текущего хода +let count = 0; // Количество совершенных ходов +let dim = 3; // Размерность поля +let arr = new Array(); // Массив, хранящий информацию о состоянии игрового поля + startGame(); addResetListener(); -function startGame () { - renderGrid(3); +function startGame () +{ + dim = Number(prompt('Размер поля:', dim)) || dim; // Запрос размера поля + sym = CROSS; + count = 0; + // Игровое поле пустое, соответственно заполняем массив + for (let row = 0; row < dim; row++) + { + arr[row] = new Array(dim); + for (let col = 0; col < dim; col++) + arr[row][col] = EMPTY; + } + renderGrid(dim); } -function renderGrid (dimension) { +function renderGrid (dimension) +{ container.innerHTML = ''; - - for (let i = 0; i < dimension; i++) { + for (let i = 0; i < dimension; i++) + { const row = document.createElement('tr'); - for (let j = 0; j < dimension; j++) { + for (let j = 0; j < dimension; j++) + { const cell = document.createElement('td'); cell.textContent = EMPTY; cell.addEventListener('click', () => cellClickHandler(i, j)); @@ -26,41 +44,119 @@ function renderGrid (dimension) { } } -function cellClickHandler (row, col) { - // Пиши код тут +function cellClickHandler (row, col) +{ + // Если ячейка не пустая, то прерываем выполнение функции + if ((findCell(row, col).textContent !== EMPTY) || (count == -1)) return; + count++; + renderSymbolInCell(sym, row, col); // Ставим символ + if (findWin(sym, row, col)) + { + if (sym === CROSS) + setTimeout(() => alert('Победили крестики!'), 500); + else setTimeout(() => alert('Победили нолики!'), 500); + count = -1; + return; + } + if (count === dim * dim) + { + setTimeout(() => alert('Победила дружба!'), 500); + return; + } + // Меняем символ для следующего хода + sym = (sym === ZERO) ? CROSS : ZERO; console.log(`Clicked on cell: ${row}, ${col}`); +} - - /* Пользоваться методом для размещения символа в клетке так: - renderSymbolInCell(ZERO, row, col); - */ +// Определяем, есть ли победа после текущего хода +function findWin (symbol, row, col) +{ + // Проверяем сроку + for (let i = 0; i < dim; i++) + { + if (arr[row][i] !== symbol) + break; + // В случае победы, перекрашиваем символы + if (i == dim - 1) + { + for (i = 0; i < dim; i++) + renderSymbolInCell(symbol, row, i, '#FF0000'); + return true; + } + } + // Проверяем столбец + for (let i = 0; i < dim; i++) + { + if (arr[i][col] !== symbol) + break; + if (i == dim - 1) + { + for (i = 0; i < dim; i++) + renderSymbolInCell(symbol, i, col, '#FF0000'); + return true; + } + } + // Проверяем главную диагональ + if (row == col) + for (let i = 0; i < dim; i++) + { + if(arr[i][i] !== symbol) + break; + if (i == dim - 1) + { + for (i = 0; i < dim; i++) + renderSymbolInCell(symbol, i, i, '#FF0000'); + return true; + } + } + // Проверяем побочную диагональ + if (row == dim - col - 1) + for (let i = 0; i < dim; i++) + { + if(arr[i][dim - i - 1] !== symbol) + break; + if (i == dim - 1) + { + for (i = 0; i < dim; i++) + renderSymbolInCell(symbol, i, dim - i - 1, '#FF0000'); + return true; + } + } } -function renderSymbolInCell (symbol, row, col, color = '#333') { +function renderSymbolInCell (symbol, row, col, color = '#333') +{ const targetCell = findCell(row, col); targetCell.textContent = symbol; targetCell.style.color = color; + arr[row][col] = sym; } -function findCell (row, col) { +function findCell (row, col) +{ const targetRow = container.querySelectorAll('tr')[row]; return targetRow.querySelectorAll('td')[col]; } -function addResetListener () { +function addResetListener () +{ const resetButton = document.getElementById('reset'); resetButton.addEventListener('click', resetClickHandler); } -function resetClickHandler () { +//Нажатие кнопки "Сначала" +function resetClickHandler () +{ + startGame(); console.log('reset!'); } /* Test Function */ /* Победа первого игрока */ -function testWin () { +function testWin () +{ clickOnCell(0, 2); clickOnCell(0, 0); clickOnCell(2, 0); @@ -71,7 +167,8 @@ function testWin () { } /* Ничья */ -function testDraw () { +function testDraw () +{ clickOnCell(2, 0); clickOnCell(1, 0); clickOnCell(1, 1); @@ -84,6 +181,7 @@ function testDraw () { clickOnCell(2, 2); } -function clickOnCell (row, col) { +function clickOnCell (row, col) +{ findCell(row, col).click(); -} +} \ No newline at end of file From b1f06069d0ec6b8f23f1ac04fb43fc094ad96726 Mon Sep 17 00:00:00 2001 From: philya71828 Date: Sun, 8 Aug 2021 13:34:45 +0500 Subject: [PATCH 2/4] =?UTF-8?q?=D0=A1=D0=BB=D1=83=D1=87=D0=B0=D0=B9=D0=BD?= =?UTF-8?q?=D1=8B=D0=B9=20=D0=98=D0=98,=20=D0=BF.=2010?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.js | 49 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 13 deletions(-) diff --git a/index.js b/index.js index 1f9593c..e329312 100644 --- a/index.js +++ b/index.js @@ -4,7 +4,6 @@ const EMPTY = ' '; const container = document.getElementById('fieldWrapper'); -let sym; // Символ текущего хода let count = 0; // Количество совершенных ходов let dim = 3; // Размерность поля let arr = new Array(); // Массив, хранящий информацию о состоянии игрового поля @@ -15,7 +14,6 @@ addResetListener(); function startGame () { dim = Number(prompt('Размер поля:', dim)) || dim; // Запрос размера поля - sym = CROSS; count = 0; // Игровое поле пустое, соответственно заполняем массив for (let row = 0; row < dim; row++) @@ -44,17 +42,44 @@ function renderGrid (dimension) } } +// Ход крестика function cellClickHandler (row, col) { - // Если ячейка не пустая, то прерываем выполнение функции + // Если ячейка не пустая или есть победитель, то прерываем выполнение функции if ((findCell(row, col).textContent !== EMPTY) || (count == -1)) return; count++; - renderSymbolInCell(sym, row, col); // Ставим символ - if (findWin(sym, row, col)) + renderSymbolInCell(CROSS, row, col); // Ставим символ + if (findWin(CROSS, row, col)) // Если побеждают крестики { - if (sym === CROSS) - setTimeout(() => alert('Победили крестики!'), 500); - else setTimeout(() => alert('Победили нолики!'), 500); + setTimeout(() => alert('Победили крестики!', 500)); + count = -1; + return; + } + if (count === dim * dim) + { + setTimeout(() => alert('Победила дружба!'), 500); + return; + } + setTimeout(() => setZero(), 200); + console.log(`Clicked on cell: ${row}, ${col}`); +} + +// Ход нолика +function setZero () +{ + count++; + //Случайным образом генерируем строку и столбец + let row = Math.floor(Math.random() * dim); + let col = Math.floor(Math.random() * dim); + while (findCell(row, col).textContent != EMPTY) + { + row = Math.floor(Math.random() * dim); + col = Math.floor(Math.random() * dim); + } + renderSymbolInCell(ZERO, row, col); + if (findWin(ZERO, row, col)) + { + setTimeout(() => alert('Победили нолики!', 500)); count = -1; return; } @@ -63,15 +88,13 @@ function cellClickHandler (row, col) setTimeout(() => alert('Победила дружба!'), 500); return; } - // Меняем символ для следующего хода - sym = (sym === ZERO) ? CROSS : ZERO; console.log(`Clicked on cell: ${row}, ${col}`); } // Определяем, есть ли победа после текущего хода function findWin (symbol, row, col) { - // Проверяем сроку + // Проверяем строку for (let i = 0; i < dim; i++) { if (arr[row][i] !== symbol) @@ -130,7 +153,7 @@ function renderSymbolInCell (symbol, row, col, color = '#333') targetCell.textContent = symbol; targetCell.style.color = color; - arr[row][col] = sym; + arr[row][col] = symbol; } function findCell (row, col) @@ -145,7 +168,7 @@ function addResetListener () resetButton.addEventListener('click', resetClickHandler); } -//Нажатие кнопки "Сначала" +// Нажатие кнопки "Сначала" function resetClickHandler () { startGame(); From b4eac68e4f14a594f5e4f318c5485eda27e2d216 Mon Sep 17 00:00:00 2001 From: philya71828 Date: Tue, 10 Aug 2021 14:22:53 +0500 Subject: [PATCH 3/4] =?UTF-8?q?=D0=A3=D0=BC=D0=BD=D1=8B=D0=B9=20=D0=98?= =?UTF-8?q?=D0=98,=20=D0=BF.=2011?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/launch.json | 15 +++++ index.js | 138 ++++++++++++++++++++++++++++++++++++-------- 2 files changed, 130 insertions(+), 23 deletions(-) create mode 100644 .vscode/launch.json diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..bbeab1b --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,15 @@ +{ + // Используйте IntelliSense, чтобы узнать о возможных атрибутах. + // Наведите указатель мыши, чтобы просмотреть описания существующих атрибутов. + // Для получения дополнительной информации посетите: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "pwa-chrome", + "request": "launch", + "name": "Launch Chrome against localhost", + "url": "http://localhost:8080", + "webRoot": "${workspaceFolder}" + } + ] +} \ No newline at end of file diff --git a/index.js b/index.js index e329312..e5d2070 100644 --- a/index.js +++ b/index.js @@ -4,7 +4,7 @@ const EMPTY = ' '; const container = document.getElementById('fieldWrapper'); -let count = 0; // Количество совершенных ходов +let count = 0; // Количество совершенных ходов, при наличие победителя равен -1 let dim = 3; // Размерность поля let arr = new Array(); // Массив, хранящий информацию о состоянии игрового поля @@ -15,12 +15,14 @@ function startGame () { dim = Number(prompt('Размер поля:', dim)) || dim; // Запрос размера поля count = 0; - // Игровое поле пустое, соответственно заполняем массив + // Игровое поле пустое, соответственно заполняем массив for (let row = 0; row < dim; row++) { - arr[row] = new Array(dim); + arr[row] = new Array(); for (let col = 0; col < dim; col++) + { arr[row][col] = EMPTY; + } } renderGrid(dim); } @@ -45,10 +47,10 @@ function renderGrid (dimension) // Ход крестика function cellClickHandler (row, col) { - // Если ячейка не пустая или есть победитель, то прерываем выполнение функции - if ((findCell(row, col).textContent !== EMPTY) || (count == -1)) return; - count++; - renderSymbolInCell(CROSS, row, col); // Ставим символ + // Если ячейка не пустая или уже есть победитель, то прерываем выполнение функции + if ((findCell(row, col).textContent !== EMPTY) || (count === -1)) return; + count++; // Увеличиваем кол-во шагов на 1 + renderSymbolInCell(CROSS, row, col); // Ставим крестик if (findWin(CROSS, row, col)) // Если побеждают крестики { setTimeout(() => alert('Победили крестики!', 500)); @@ -60,35 +62,124 @@ function cellClickHandler (row, col) setTimeout(() => alert('Победила дружба!'), 500); return; } - setTimeout(() => setZero(), 200); - console.log(`Clicked on cell: ${row}, ${col}`); + // Ход нолика + let EmpCl = new Array(); + count++; + // Проверяем, могут ли этим ходом выиграть нолики. Если могут - ставим выигрышный нолик + // Проверяем диагонали + EmpCl = CheckLine(CROSS, 0, 'dg'); + if (EmpCl[0] > -1) // Красим победную в красный и ставим признак победы + { + for (let j = 0; j < dim; j++) + renderSymbolInCell(ZERO, j, j, '#FF0000'); + setTimeout(() => alert('Победили нолики!', 500)); + count = -1; + return; + } + EmpCl = CheckLine(CROSS, 0, 'dgp'); + if (EmpCl[0] > -1) // Красим победную в красный и ставим признак победы + { + for (let j = 0; j < dim; j++) + renderSymbolInCell(ZERO, j, dim - j - 1, '#FF0000'); + setTimeout(() => alert('Победили нолики!', 500)); + count = -1; + return; + } + + for (let i = 0; i < dim; i++) + { // Проверяем строку + EmpCl = CheckLine(CROSS, i, 'row'); + if (EmpCl[0] > -1) + { + for (let j = 0; j < dim; j++) + renderSymbolInCell(ZERO, i, j, '#FF0000'); + setTimeout(() => alert('Победили нолики!', 500)); + count = -1; + return; + } + // Проверяем столбец + EmpCl = CheckLine(CROSS, i, 'col'); + if (EmpCl[0] > -1) + { + for (let j = 0; j < dim; j++) + renderSymbolInCell(ZERO, j, i, '#FF0000'); + setTimeout(() => alert('Победили нолики!', 500)); + count = -1; + return; + } + + } + + // Проверяем, могут ли этим ходом выиграть крестики. Если могут - ставим "противный" нолик + EmpCl = CheckLine(ZERO, 0, 'dg'); // проверяем главную диагональ + if (EmpCl[0] > -1) + { + renderSymbolInCell(ZERO, EmpCl[0], EmpCl[1]); + return; + } + EmpCl = CheckLine(ZERO, 0, 'dgp'); // проверяем побочную диагональ + if (EmpCl[0] > -1) + { + renderSymbolInCell(ZERO, EmpCl[0], EmpCl[1]); + return; + } + for (let i = 0; i < dim; i++) + { // Проверяем строку + EmpCl = CheckLine(ZERO, i, 'row'); + if (EmpCl[0] > -1) + + { renderSymbolInCell(ZERO, EmpCl[0], EmpCl[1]); + return; + } + // Проверяем столбец + EmpCl = CheckLine(ZERO, i, 'col'); + if (EmpCl[0] > -1) + { + renderSymbolInCell(ZERO, EmpCl[0], EmpCl[1]); + return; + } + } + // Если победных линий нет, ставим нолик случайным образом + setTimeout(() => setZero(), 200); + +} +// Определяем выигрышность линии - только одная ячейка пустая, а остальное заполнено, +// symbol - знак, который не должен встретиться на линии +function CheckLine(symbol, i, line) +{ let m = 0; + let row; let col; + let EmptyCell = new Array(); // координаты пустой клетки + for (let j = 0; j < dim; j++) + { if (line === 'row') {row = i; col = j;} // строка + if (line === 'col') {row = j; col = i;} // столбец + if (line === 'dg') {row = j; col = j;} // диагональ главная + if (line === 'dgp') {row = j; col = dim - j -1;} // диагональ побочная + if (arr[row][col] === EMPTY) + { + m++; + EmptyCell[0] = row; EmptyCell[1] = col; + } + if ((arr[row][col] === symbol) || (m > 1)) return EmptyCell[0] = -2; + } + return EmptyCell; } -// Ход нолика +// Случайный нолик function setZero () -{ - count++; - //Случайным образом генерируем строку и столбец - let row = Math.floor(Math.random() * dim); - let col = Math.floor(Math.random() * dim); - while (findCell(row, col).textContent != EMPTY) +{ // Случайным образом генерируем строку и столбец + let row; let col; + do { row = Math.floor(Math.random() * dim); col = Math.floor(Math.random() * dim); } + while ((findCell(row, col).textContent !== EMPTY)); renderSymbolInCell(ZERO, row, col); - if (findWin(ZERO, row, col)) - { - setTimeout(() => alert('Победили нолики!', 500)); - count = -1; - return; - } if (count === dim * dim) { setTimeout(() => alert('Победила дружба!'), 500); return; } - console.log(`Clicked on cell: ${row}, ${col}`); } // Определяем, есть ли победа после текущего хода @@ -154,6 +245,7 @@ function renderSymbolInCell (symbol, row, col, color = '#333') targetCell.textContent = symbol; targetCell.style.color = color; arr[row][col] = symbol; + console.log(`${symbol} on cell: ${row}, ${col}. Цвет: ${color}`); } function findCell (row, col) From 767a8ea5a5366677beb0620f81eed078ec2c7c8d Mon Sep 17 00:00:00 2001 From: philya71828 Date: Tue, 10 Aug 2021 19:20:56 +0500 Subject: [PATCH 4/4] Task done --- index.js | 60 ++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 48 insertions(+), 12 deletions(-) diff --git a/index.js b/index.js index e5d2070..5857e5e 100644 --- a/index.js +++ b/index.js @@ -1,19 +1,23 @@ const CROSS = 'X'; const ZERO = 'O'; -const EMPTY = ' '; +const EMPTY = ''; const container = document.getElementById('fieldWrapper'); let count = 0; // Количество совершенных ходов, при наличие победителя равен -1 let dim = 3; // Размерность поля let arr = new Array(); // Массив, хранящий информацию о состоянии игрового поля +let grow = false; // индикатор режима расширяющегося поля, true - режим включен startGame(); addResetListener(); function startGame () { - dim = Number(prompt('Размер поля:', dim)) || dim; // Запрос размера поля + dim = Number(prompt('Размер поля (не меньше 3 и не больше 10):', dim)) || dim; // Запрос размера поля + if (dim < 3) dim = 3; + if (dim > 10) dim = 10; + grow = confirm ('Включить режим расширяюшегося поля?'); count = 0; // Игровое поле пустое, соответственно заполняем массив for (let row = 0; row < dim; row++) @@ -46,9 +50,9 @@ function renderGrid (dimension) // Ход крестика function cellClickHandler (row, col) -{ +{ console.log(`Клик on cell: ${row}, ${col}.`); // Если ячейка не пустая или уже есть победитель, то прерываем выполнение функции - if ((findCell(row, col).textContent !== EMPTY) || (count === -1)) return; + if ((arr[row][col] !== EMPTY) || (count === -1)) return; count++; // Увеличиваем кол-во шагов на 1 renderSymbolInCell(CROSS, row, col); // Ставим крестик if (findWin(CROSS, row, col)) // Если побеждают крестики @@ -62,6 +66,9 @@ function cellClickHandler (row, col) setTimeout(() => alert('Победила дружба!'), 500); return; } + // Расширяем поле + if ((dim < 10) && (count > dim*dim/2) && grow) {growCell(); dim++;} + // Ход нолика let EmpCl = new Array(); count++; @@ -109,18 +116,20 @@ function cellClickHandler (row, col) } } - + // Расширяем поле + if ((dim < 10) && (count > dim*dim/2) && grow) {growCell(); dim++;} + // Проверяем, могут ли этим ходом выиграть крестики. Если могут - ставим "противный" нолик EmpCl = CheckLine(ZERO, 0, 'dg'); // проверяем главную диагональ if (EmpCl[0] > -1) { - renderSymbolInCell(ZERO, EmpCl[0], EmpCl[1]); + setTimeout(() => renderSymbolInCell(ZERO, EmpCl[0], EmpCl[1]), 200); return; } EmpCl = CheckLine(ZERO, 0, 'dgp'); // проверяем побочную диагональ if (EmpCl[0] > -1) { - renderSymbolInCell(ZERO, EmpCl[0], EmpCl[1]); + setTimeout(() => renderSymbolInCell(ZERO, EmpCl[0], EmpCl[1]), 200); return; } for (let i = 0; i < dim; i++) @@ -128,21 +137,21 @@ function cellClickHandler (row, col) EmpCl = CheckLine(ZERO, i, 'row'); if (EmpCl[0] > -1) - { renderSymbolInCell(ZERO, EmpCl[0], EmpCl[1]); + { setTimeout(() => renderSymbolInCell(ZERO, EmpCl[0], EmpCl[1]), 200); return; } // Проверяем столбец EmpCl = CheckLine(ZERO, i, 'col'); if (EmpCl[0] > -1) { - renderSymbolInCell(ZERO, EmpCl[0], EmpCl[1]); + setTimeout(() => renderSymbolInCell(ZERO, EmpCl[0], EmpCl[1]), 200); return; } } // Если победных линий нет, ставим нолик случайным образом - setTimeout(() => setZero(), 200); - + setTimeout(() => setZero(), 200); } + // Определяем выигрышность линии - только одная ячейка пустая, а остальное заполнено, // symbol - знак, который не должен встретиться на линии function CheckLine(symbol, i, line) @@ -164,6 +173,33 @@ function CheckLine(symbol, i, line) return EmptyCell; } +// Расширение поля до 10 +function growCell () +{ // Добавляем строку на страницу и в массив arr + row = document.createElement('tr'); + let d = dim; + arr[d] = new Array(); + for (let j = 0; j < dim; j++) + { + const cell = document.createElement('td'); + cell.textContent = EMPTY; + cell.addEventListener('click', () => cellClickHandler(d, j)); + row.appendChild(cell); + arr[d][j] = EMPTY; + } + container.appendChild(row); + // Добавляем столбец на страницу и в массив arr + for (let i = 0; i < dim + 1; i++) + { + const row = container.querySelectorAll('tr')[i]; + const cell = document.createElement('td'); + cell.textContent = EMPTY; + cell.addEventListener('click', () => cellClickHandler(i, d)); + row.appendChild(cell); + arr[i][d] = EMPTY; + } +} + // Случайный нолик function setZero () { // Случайным образом генерируем строку и столбец @@ -173,7 +209,7 @@ function setZero () row = Math.floor(Math.random() * dim); col = Math.floor(Math.random() * dim); } - while ((findCell(row, col).textContent !== EMPTY)); + while ((arr[row][col] !== EMPTY)); renderSymbolInCell(ZERO, row, col); if (count === dim * dim) {