From 54798139787fd06f964dabcdf9ba9620e742d66f Mon Sep 17 00:00:00 2001 From: Tolchenov Andrey Date: Mon, 27 Feb 2023 19:01:25 +0500 Subject: [PATCH] feat: exercise1 --- README.md | 18 +++---- index.js | 150 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 150 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index f946dc4..4e2cffe 100644 --- a/README.md +++ b/README.md @@ -3,15 +3,15 @@ Сейчас в коде описаны функции для рисования поля любого размера и рисования любого символа в клетке этого поля. Твоя задача дописать код, чтобы это стало полноценной игрой в Крестики-нолики. -1. Реши, как будешь хранить поле. Тебе нужна будет такая структура, в которой удобно понимать есть ли победитель: три клетки по горизонтали, вертикали или диагонали, заполненные одинаковыми символами. -2. Допиши функцию cellClickHandler, чтобы после клика ставился крестик или нолик в соответствующее поле. -3. Если поле, по которому кликнули, не пустое, символ ставиться не должен. -4. Если кончились ходы, выведи alert с текстом "Победила дружба". -5. Напиши функцию, которая считает: есть ли уже победитель. Если есть победитель, выведи alert с названием победителя -6. Если есть победитель, покрась победные значения в клетках в красный. -7. После победы, клик по полю больше не должен ставить крестик или нолик. -8. Обрабатывай клик по кнопке "Сначала": допиши метод resetClickHandler, чтобы поле очищалось. +*1. Реши, как будешь хранить поле. Тебе нужна будет такая структура, в которой удобно понимать есть ли победитель: три клетки по горизонтали, вертикали или диагонали, заполненные одинаковыми символами. +*2. Допиши функцию cellClickHandler, чтобы после клика ставился крестик или нолик в соответствующее поле. +*3. Если поле, по которому кликнули, не пустое, символ ставиться не должен. +*4. Если кончились ходы, выведи alert с текстом "Победила дружба". +*5. Напиши функцию, которая считает: есть ли уже победитель. Если есть победитель, выведи alert с названием победителя +*6. Если есть победитель, покрась победные значения в клетках в красный. +*7. После победы, клик по полю больше не должен ставить крестик или нолик. +*8. Обрабатывай клик по кнопке "Сначала": допиши метод resetClickHandler, чтобы поле очищалось. 9. \* Сделай так, чтобы можно было в начале игры задавать поле произвольного размера. -10. \* Напиши "искусственный интеллект" — функцию, которая будет ставить нолики с случайное пустое поле. +*10. \* Напиши "искусственный интеллект" — функцию, которая будет ставить нолики с случайное пустое поле. 11. \* Напиши чуть более умный искусственный интеллект — функция, ставящая нолики в случайном месте обязана поставить нолик в такое поле, нолик в котором приведет к выигрышу "ИИ". 12. \* Сделай так, чтобы при заполнении больше половины клеток на поле, оно бы расширялось: добавлялось бы по одному ряду с каждой стороны. diff --git a/index.js b/index.js index 7553909..8f86a2d 100644 --- a/index.js +++ b/index.js @@ -1,17 +1,49 @@ const CROSS = 'X'; const ZERO = 'O'; const EMPTY = ' '; +let NUMBER = 0; +let FIELD = []; +let SIZE = 3; const container = document.getElementById('fieldWrapper'); startGame(); addResetListener(); +function getRandomInt(max) { + return Math.floor(Math.random() * max); +} + +function makeSimpleAiTurn() { + while (true) { + row = getRandomInt(SIZE); + col = getRandomInt(SIZE); + if (FIELD[row][col] == EMPTY){ + FIELD[row][col] = ZERO; + renderSymbolInCell(ZERO, row, col); + break; + } + } + console.log('make') +} + +function fillField(){ + for (let i = 0; i < SIZE; i++){ + FIELD[i] = []; + for (let j = 0; j < SIZE; j++){ + FIELD[i][j] = EMPTY; + } + } +} + function startGame () { - renderGrid(3); + SIZE = parseInt(prompt('Size?')); + let AI = prompt('Play with AI? (yes/no)') === 'yes' ? true : false; + renderGrid(SIZE, AI); + fillField(SIZE); } -function renderGrid (dimension) { +function renderGrid (dimension, AI) { container.innerHTML = ''; for (let i = 0; i < dimension; i++) { @@ -19,21 +51,117 @@ function renderGrid (dimension) { for (let j = 0; j < dimension; j++) { const cell = document.createElement('td'); cell.textContent = EMPTY; - cell.addEventListener('click', () => cellClickHandler(i, j)); + cell.addEventListener('click', () => cellClickHandler(i, j, AI)); row.appendChild(cell); } container.appendChild(row); } } -function cellClickHandler (row, col) { - // Пиши код тут - console.log(`Clicked on cell: ${row}, ${col}`); +function checkIfSymbolWins(symbol){ + let won = true; + for (let i = 0; i < SIZE; i++) { + won = true; + for (let j = 0; j < SIZE; j++) { + if (FIELD[i][j] !== symbol) { + won = false; + } + } + if (won) { + for (let j = 0; j < SIZE; j++) { + renderSymbolInCell(symbol, i, j, 'red'); + } + return true; + } + } + + for (let i = 0; i < SIZE; i++) { + won = true; + for (let j = 0; j < SIZE; j++) { + if (FIELD[j][i] !== symbol) { + won = false; + } + } + if (won) { + for (let j = 0; j < SIZE; j++) { + renderSymbolInCell(symbol, j, i, 'red'); + } + return true; + } + } + + won = true; + for (let i = 0; i < SIZE; i++) { + if (FIELD[i][i] !== symbol) + won = false; + } + if (won){ + for (let i = 0; i < SIZE; i++) { + renderSymbolInCell(symbol, i, i, 'red'); + } + return true; + } + - /* Пользоваться методом для размещения символа в клетке так: - renderSymbolInCell(ZERO, row, col); - */ + won = true; + for (let i = 0; i < SIZE; i++) { + + if (FIELD[i][SIZE - i - 1] !== symbol) + won = false; + } + if (won){ + for (let i = 0; i < SIZE; i++) { + renderSymbolInCell(symbol, i, SIZE - i - 1, 'red'); + } + return true; + } + return false; +} + +function checkIfFriendsWins(){ + return NUMBER === SIZE * SIZE; +} + +function cellClickHandler (row, col, AI=false) { + let currentSymbol = EMPTY; + if (NUMBER % 2 === 0){ + currentSymbol = CROSS; + } + else{ + currentSymbol = ZERO; + } + if (FIELD[row][col] === EMPTY){ + renderSymbolInCell(currentSymbol, row, col); + FIELD[row][col] = currentSymbol; + + if (checkIfSymbolWins(CROSS)){ + alert('Cross Wins'); + return; + } + if (checkIfSymbolWins(ZERO)){ + alert('Zero Wins'); + return; + } + + NUMBER ++; + if (checkIfFriendsWins()){ + alert('Победила дружба'); + return; + } + } + if (AI === true){ + makeSimpleAiTurn(); + if (checkIfSymbolWins(ZERO)){ + alert('Zero Wins'); + return; + } + NUMBER++; + if (checkIfFriendsWins()){ + alert('Победила дружба'); + return; + } + } } function renderSymbolInCell (symbol, row, col, color = '#333') { @@ -54,6 +182,9 @@ function addResetListener () { } function resetClickHandler () { + startGame(); + NUMBER = 0; + fillField(); console.log('reset!'); } @@ -87,3 +218,4 @@ function testDraw () { function clickOnCell (row, col) { findCell(row, col).click(); } +