From 7010081ebdfd670e125781204ecf19dba9f8aafb Mon Sep 17 00:00:00 2001 From: Teelirium <74907594+Teelirium@users.noreply.github.com> Date: Tue, 28 Sep 2021 23:43:03 +0500 Subject: [PATCH 1/3] complete task 1 to 10 --- index.js | 164 +++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 148 insertions(+), 16 deletions(-) diff --git a/index.js b/index.js index 7553909..898f56f 100644 --- a/index.js +++ b/index.js @@ -2,19 +2,39 @@ const CROSS = 'X'; const ZERO = 'O'; const EMPTY = ' '; +let field; +let maxTurns; +let turn; +let winCombination; +let isGameOver; +let winner; + +const winTypes = { + horizontal: 'horiz', + vertical: 'vert', + diagonalLeft: 'diagL', + diagonalRight: 'diagR' +} + const container = document.getElementById('fieldWrapper'); startGame(); addResetListener(); -function startGame () { - renderGrid(3); +function startGame() { + field = []; + turn = 0; + winCombination = []; + isGameOver = false; + winner = ""; + renderGrid(prompt("Задайте размер поля:", 3)); } -function renderGrid (dimension) { +function renderGrid(dimension) { container.innerHTML = ''; - + maxTurns = dimension ** 2; for (let i = 0; i < dimension; i++) { + field[i] = []; const row = document.createElement('tr'); for (let j = 0; j < dimension; j++) { const cell = document.createElement('td'); @@ -26,41 +46,153 @@ function renderGrid (dimension) { } } -function cellClickHandler (row, col) { - // Пиши код тут +function cellClickHandler(row, col) { + if (isGameOver) return; console.log(`Clicked on cell: ${row}, ${col}`); + if (field[row][col] !== undefined) + return; + field[row][col] = CROSS; + processClick(field[row][col], row, col); + if (!isGameOver) botClick(); +} + +function botClick() { + if (isGameOver) return; + let freeCellCount = field.length ** 2 - turn; + let randomFreeCell = Math.floor(Math.random() * freeCellCount); + let counter = 0; + let row, col; + + cellSearch: for (let y = 0; y < field.length; y++) + for (let x = 0; x < field.length; x++) { + if (field[y][x] === undefined) { + if (counter === randomFreeCell) { + [row, col] = [y, x]; + break cellSearch; + } + counter++; + } + } + + console.log(`Bot clicked on cell: ${row}, ${col}`); + field[row][col] = ZERO; + processClick(field[row][col], row, col); +} + +function processClick(symbol, row, col) { + renderSymbolInCell(symbol, row, col); + checkWin(symbol, row, col); + turn++; + if (turn === maxTurns && !winner) isGameOver = true; + else if (!winner) return; + //console.log(isGameOver); + colorWinningLine(); + announceWinner(); +} + +function checkWin(symbol, row, col) { + if ((col === 0 || field[row][col - 1] === symbol) && + (col === field.length - 1 || field[row][col + 1] === symbol)) + winCombination = getWinningCombo(winTypes.horizontal, symbol, row, col); + + if ((row === 0 || field[row - 1][col] === symbol) && + (row === field.length - 1 || field[row + 1][col] === symbol)) + winCombination = getWinningCombo(winTypes.vertical, symbol, row, col); + if (row === col && + (row === 0 || field[row - 1][col - 1] === symbol) && + (row === field.length - 1 || field[row + 1][col + 1] === symbol)) + winCombination = getWinningCombo(winTypes.diagonalLeft, symbol, row, col); - /* Пользоваться методом для размещения символа в клетке так: - renderSymbolInCell(ZERO, row, col); - */ + if (field.length - 1 - row === col && + (row === 0 || field[row - 1][col + 1] === symbol) && + (col === 0 || field[row + 1][col - 1] === symbol)) + winCombination = getWinningCombo(winTypes.diagonalRight, symbol, row, col); + + if (winCombination.length === field.length) { + isGameOver = true; + winner = symbol; + } + //console.log(winCombination); +} + +function getWinningCombo(winType, symbol, row, col) { + let combination = [] + for (let i = 0; i < field.length; i++) { + switch (winType) { + case winTypes.vertical: + if (field[i][col] === symbol) + combination.push([i, col]); + break; + case winTypes.horizontal: + if (field[row][i] === symbol) + combination.push([row, i]); + break; + case winTypes.diagonalLeft: + if (field[i][i] === symbol) + combination.push([i, i]); + break; + case winTypes.diagonalRight: + if (field[field.length - 1 - i][i] === symbol) + combination.push([field.length - 1 - i, i]) + break; + } + } + if (combination.length === field.length) + return combination; + return []; +} + +function announceWinner() { + if (!isGameOver) return; + switch (winner) { + case CROSS: + alert('Победили крестики!'); + break; + case ZERO: + alert('Победили нолики!'); + break; + default: + alert('Победила дружба!'); + break; + } +} + +function colorWinningLine() { + for (let i = 0; i < winCombination.length; i++) { + let row = winCombination[i][0]; + let col = winCombination[i][1]; + const targetCell = findCell(row, col); + targetCell.style.backgroundColor = "red"; + } } -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; } -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 +203,7 @@ function testWin () { } /* Ничья */ -function testDraw () { +function testDraw() { clickOnCell(2, 0); clickOnCell(1, 0); clickOnCell(1, 1); @@ -84,6 +216,6 @@ function testDraw () { clickOnCell(2, 2); } -function clickOnCell (row, col) { +function clickOnCell(row, col) { findCell(row, col).click(); } From 26df608430a7e9dcb01a641691e040205a3ff153 Mon Sep 17 00:00:00 2001 From: Teelirium <74907594+Teelirium@users.noreply.github.com> Date: Wed, 29 Sep 2021 14:50:46 +0500 Subject: [PATCH 2/3] complete task 11 --- index.js | 79 +++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 50 insertions(+), 29 deletions(-) diff --git a/index.js b/index.js index 898f56f..3cc6da1 100644 --- a/index.js +++ b/index.js @@ -60,28 +60,40 @@ function botClick() { if (isGameOver) return; let freeCellCount = field.length ** 2 - turn; let randomFreeCell = Math.floor(Math.random() * freeCellCount); - let counter = 0; let row, col; + let symbol = ZERO; + [row, col] = getCellCoords(randomFreeCell, symbol); + console.log(`Bot clicked on cell: ${row}, ${col}`); + field[row][col] = symbol; + processClick(field[row][col], row, col); +} +function getCellCoords(randomFreeCell, symbol) { + let counter = 0; + let winRow, winCol, randRow, randCol; cellSearch: for (let y = 0; y < field.length; y++) for (let x = 0; x < field.length; x++) { if (field[y][x] === undefined) { - if (counter === randomFreeCell) { - [row, col] = [y, x]; + if (counter === randomFreeCell) + [randRow, randCol] = [y, x]; + field[y][x] = symbol; + winner = checkWinner(symbol, y, x); + if (winner !== symbol) field[y][x] = undefined; + else { + [winRow, winCol] = [y, x]; break cellSearch; } counter++; } } - - console.log(`Bot clicked on cell: ${row}, ${col}`); - field[row][col] = ZERO; - processClick(field[row][col], row, col); + if (winner !== symbol) + return [randRow, randCol]; + return [winRow, winCol]; } function processClick(symbol, row, col) { renderSymbolInCell(symbol, row, col); - checkWin(symbol, row, col); + winner = checkWinner(symbol, row, col); turn++; if (turn === maxTurns && !winner) isGameOver = true; else if (!winner) return; @@ -90,51 +102,60 @@ function processClick(symbol, row, col) { announceWinner(); } -function checkWin(symbol, row, col) { +function checkWinner(symbol, row, col) { + winCombination = checkForWinCombination(symbol, row, col); + //console.log(winCombination); + if (winCombination.length === field.length) { + isGameOver = true; + return symbol; + } + return ""; +} + +function checkForWinCombination(symbol, row, col) { if ((col === 0 || field[row][col - 1] === symbol) && (col === field.length - 1 || field[row][col + 1] === symbol)) - winCombination = getWinningCombo(winTypes.horizontal, symbol, row, col); + return getWinCombination(winTypes.horizontal, symbol, row, col); if ((row === 0 || field[row - 1][col] === symbol) && (row === field.length - 1 || field[row + 1][col] === symbol)) - winCombination = getWinningCombo(winTypes.vertical, symbol, row, col); + return getWinCombination(winTypes.vertical, symbol, row, col); if (row === col && (row === 0 || field[row - 1][col - 1] === symbol) && (row === field.length - 1 || field[row + 1][col + 1] === symbol)) - winCombination = getWinningCombo(winTypes.diagonalLeft, symbol, row, col); + return getWinCombination(winTypes.diagonalLeft, symbol, row, col); if (field.length - 1 - row === col && (row === 0 || field[row - 1][col + 1] === symbol) && (col === 0 || field[row + 1][col - 1] === symbol)) - winCombination = getWinningCombo(winTypes.diagonalRight, symbol, row, col); - - if (winCombination.length === field.length) { - isGameOver = true; - winner = symbol; - } - //console.log(winCombination); + return getWinCombination(winTypes.diagonalRight, symbol, row, col); + return []; } -function getWinningCombo(winType, symbol, row, col) { +function getWinCombination(winType, symbol, row, col) { let combination = [] - for (let i = 0; i < field.length; i++) { + combAssembly: for (let i = 0; i < field.length; i++) { switch (winType) { case winTypes.vertical: - if (field[i][col] === symbol) - combination.push([i, col]); + if (field[i][col] !== symbol) + break combAssembly; + combination.push([i, col]); break; case winTypes.horizontal: - if (field[row][i] === symbol) - combination.push([row, i]); + if (field[row][i] !== symbol) + break combAssembly; + combination.push([row, i]); break; case winTypes.diagonalLeft: - if (field[i][i] === symbol) - combination.push([i, i]); + if (field[i][i] !== symbol) + break combAssembly; + combination.push([i, i]); break; case winTypes.diagonalRight: - if (field[field.length - 1 - i][i] === symbol) - combination.push([field.length - 1 - i, i]) + if (field[field.length - 1 - i][i] !== symbol) + break combAssembly; + combination.push([field.length - 1 - i, i]) break; } } From 9358554803b535fca6e8b3452da1623944bae880 Mon Sep 17 00:00:00 2001 From: Teelirium <74907594+Teelirium@users.noreply.github.com> Date: Fri, 1 Oct 2021 09:16:41 +0500 Subject: [PATCH 3/3] complete task 12 --- index.js | 38 +++++++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/index.js b/index.js index 3cc6da1..fbf3d52 100644 --- a/index.js +++ b/index.js @@ -8,6 +8,7 @@ let turn; let winCombination; let isGameOver; let winner; +let expansionEnabled; const winTypes = { horizontal: 'horiz', @@ -27,18 +28,21 @@ function startGame() { winCombination = []; isGameOver = false; winner = ""; - renderGrid(prompt("Задайте размер поля:", 3)); + let dimension = prompt("Задайте размер поля:", 3); + for (let y = 0; y < dimension; y++) + field[y] = []; + expansionEnabled = confirm("Включить автоматическое расширение поля?"); + renderGrid(dimension); } function renderGrid(dimension) { container.innerHTML = ''; maxTurns = dimension ** 2; for (let i = 0; i < dimension; i++) { - field[i] = []; const row = document.createElement('tr'); for (let j = 0; j < dimension; j++) { const cell = document.createElement('td'); - cell.textContent = EMPTY; + cell.textContent = field[i][j] === undefined ? EMPTY : field[i][j]; cell.addEventListener('click', () => cellClickHandler(i, j)); row.appendChild(cell); } @@ -74,7 +78,7 @@ function getCellCoords(randomFreeCell, symbol) { cellSearch: for (let y = 0; y < field.length; y++) for (let x = 0; x < field.length; x++) { if (field[y][x] === undefined) { - if (counter === randomFreeCell) + if (counter === randomFreeCell) [randRow, randCol] = [y, x]; field[y][x] = symbol; winner = checkWinner(symbol, y, x); @@ -93,8 +97,13 @@ function getCellCoords(randomFreeCell, symbol) { function processClick(symbol, row, col) { renderSymbolInCell(symbol, row, col); - winner = checkWinner(symbol, row, col); - turn++; + winner = checkWinner(symbol, row, col); + turn++; + if (expansionEnabled && turn * 2 >= field.length ** 2) { + field = expandField(); + renderGrid(field.length); + } + if (turn === maxTurns && !winner) isGameOver = true; else if (!winner) return; //console.log(isGameOver); @@ -164,6 +173,21 @@ function getWinCombination(winType, symbol, row, col) { return []; } +function expandField() { + let newSize = field.length + 2; + maxTurns = newSize ** 2; + let newField = []; + for (let y = 0; y < newSize; y++) + newField[y] = []; + + for (let y = 0; y < field.length; y++) + for (let x = 0; x < field.length; x++) + newField[y + 1][x + 1] = field[y][x]; + + console.log("Field expanded!"); + return newField; +} + function announceWinner() { if (!isGameOver) return; switch (winner) { @@ -206,8 +230,8 @@ function addResetListener() { } function resetClickHandler() { - startGame(); console.log('reset!'); + startGame(); }