From 1acfe1272591719f8167b35a95053bed436fdff8 Mon Sep 17 00:00:00 2001 From: Artem Date: Wed, 5 Feb 2025 17:44:50 +0100 Subject: [PATCH 1/5] test --- README.md | 2 +- src/index.html | 37 ++++--- src/modules/Game.class.js | 211 ++++++++++++++++++++++++++++++++++++-- src/scripts/main.js | 29 +++++- src/styles/main.scss | 5 +- 5 files changed, 257 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index 5aab92544..de196bb11 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ You can change the HTML/CSS layout if you need it. ## Deploy and Pull Request 1. Replace `` with your Github username in the link - - [DEMO LINK](https://.github.io/js_2048_game/) + - [DEMO LINK](https://Artemida1609.github.io/js_2048_game/) 2. Follow [this instructions](https://mate-academy.github.io/layout_task-guideline/) - Run `npm run test` command to test your code; - Run `npm run test:only -- -n` to run fast test ignoring linter; diff --git a/src/index.html b/src/index.html index aff3d1a98..71f379669 100644 --- a/src/index.html +++ b/src/index.html @@ -28,31 +28,31 @@

2048

- - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + +
@@ -65,6 +65,9 @@

2048

- + diff --git a/src/modules/Game.class.js b/src/modules/Game.class.js index 65cd219c9..f2eee34d8 100644 --- a/src/modules/Game.class.js +++ b/src/modules/Game.class.js @@ -25,10 +25,116 @@ class Game { console.log(initialState); } - moveLeft() {} - moveRight() {} - moveUp() {} - moveDown() {} + moveRight() { + const trElements = document.querySelectorAll('tbody > tr'); + const trArray = Array.from(trElements); + + for (const tr of trArray) { + for (let i = tr.children.length - 1; i >= 0; i--) { + if (tr.children[i].classList.length > 1) { + if (tr.children[3].classList.length === 1) { + moveOnEmpty(tr, i, 3); + } else if ( + tr.children[3].innerHTML === tr.children[i].innerHTML && + i !== 3 + ) { + mergeCellsInRow(tr, i, 3); + } else if (tr.children[2].classList.length === 1) { + moveOnEmpty(tr, i, 2); + } else if ( + tr.children[2].innerHTML === tr.children[i].innerHTML && + i !== 2 + ) { + mergeCellsInRow(tr, i, 2); + } + } + } + } + } + + moveLeft() { + const trElements = document.querySelectorAll('tbody > tr'); + const trArray = Array.from(trElements); + + for (const tr of trArray) { + for (let i = 0; i < tr.children.length; i++) { + if (tr.children[i].classList.length > 1) { + if (tr.children[0].classList.length === 1) { + moveOnEmpty(tr, i, 0); + } else if ( + tr.children[0].innerHTML === tr.children[i].innerHTML && + i !== 0 + ) { + mergeCellsInRow(tr, i, 0); + } else if (tr.children[1].classList.length === 1) { + moveOnEmpty(tr, i, 1); + } else if ( + tr.children[1].innerHTML === tr.children[i].innerHTML && + i !== 1 + ) { + mergeCellsInRow(tr, i, 1); + } + } + } + } + } + moveUp() { + const tbody = document.querySelector('tbody'); + const rows = tbody.rows; + + for (let i = 0; i < rows[0].cells.length; i++) { + for (let j = 0; j < rows.length; j++) { + const cell = rows[j].cells[i]; + + if (cell.classList.length > 1) { + if (rows[0].cells[i].classList.length === 1) { + moveOnEmptyCell(tbody, j, i, 0); + } else if ( + rows[0].cells[i].innerHTML === rows[j].cells[i].innerHTML && + j !== 0 + ) { + mergeCellsInCell(tbody, j, i, 0); + } else if (rows[1].cells[i].classList.length === 1) { + moveOnEmptyCell(tbody, j, i, 1); + } else if ( + rows[1].cells[i].innerHTML === rows[j].cells[i].innerHTML && + j !== 1 + ) { + mergeCellsInCell(tbody, j, i, 1); + } + } + } + } + } + + moveDown() { + const tbody = document.querySelector('tbody'); + const rows = tbody.rows; + + for (let i = 0; i < rows[0].cells.length; i++) { + for (let j = rows.length - 2; j >= 0; j--) { + const cell = rows[j].cells[i]; + + if (cell.classList.length > 1) { + if (rows[3].cells[i].classList.length === 1) { + moveOnEmptyCell(tbody, j, i, 3); + } else if ( + rows[3].cells[i].innerHTML === rows[j].cells[i].innerHTML && + j !== 3 + ) { + mergeCellsInCell(tbody, j, i, 3); + } else if (rows[2].cells[i].classList.length === 1) { + moveOnEmptyCell(tbody, j, i, 2); + } else if ( + rows[2].cells[i].innerHTML === rows[j].cells[i].innerHTML && + j !== 2 + ) { + mergeCellsInCell(tbody, j, i, 2); + } + } + } + } + } /** * @returns {number} @@ -55,14 +161,107 @@ class Game { /** * Starts the game. */ - start() {} + start() { + const startButton = document.querySelector('.button.start'); + + startButton.classList.add('restart'); + startButton.classList.remove('start'); + startButton.textContent = 'Restart'; + + const tdElements = document.querySelectorAll('.field-cell'); + const tdArray = Array.from(tdElements); + let firstElement, secondElement; + let uniqueElements = new Set(); + + while (uniqueElements.size !== 2) { + firstElement = tdArray[getRandomInt(tdArray.length - 1)]; + secondElement = tdArray[getRandomInt(tdArray.length - 1)]; + uniqueElements = new Set([firstElement, secondElement]); + } + + if (uniqueElements.size === 2) { + firstElement.classList.add('field-cell--2'); + firstElement.innerHTML = '2'; + secondElement.classList.add('field-cell--2'); + secondElement.innerHTML = '2'; + } + } /** * Resets the game. */ - restart() {} + restart() { + const restartButton = document.querySelector('.button.restart'); + + restartButton.classList.remove('restart'); + restartButton.classList.add('start'); + + restartButton.textContent = 'Start'; + + const tdElements = document.querySelectorAll('.field-cell'); + const tdArray = Array.from(tdElements); + + tdArray.forEach((element) => { + element.className = 'field-cell'; + element.innerHTML = ''; + }); + } // Add your own methods here } module.exports = Game; + +function getRandomInt(num) { + return Math.floor(Math.random() * num); +} + +function moveOnEmpty(tr, i, index) { + tr.children[index].innerHTML = tr.children[i].innerHTML; + tr.children[i].innerHTML = ''; + + tr.children[index].classList = tr.children[i].classList; + tr.children[i].className = 'field-cell'; +} + +function moveOnEmptyCell(tbody, j, i, index) { + tbody.rows[index].cells[i].innerHTML = tbody.rows[j].cells[i].innerHTML; + tbody.rows[j].cells[i].innerHTML = ''; + + tbody.rows[index].cells[i].classList = tbody.rows[j].cells[i].classList; + tbody.rows[j].cells[i].className = 'field-cell'; +} + +function mergeCellsInRow(tr, i, index) { + const number = parseInt(tr.children[i].innerHTML); + const doubleNumber = number * 2; + + tr.children[index].innerHTML = doubleNumber; + tr.children[i].innerHTML = ''; + + const classList = tr.children[i].classList; + const className = classList[1]; + + if (className) { + tr.children[i].classList.remove(className); + } + + tr.children[index].classList.add(`field-cell--${doubleNumber}`); +} + +function mergeCellsInCell(tbody, j, i, index) { + const number = parseInt(tbody.rows[j].cells[i].innerHTML); + const doubleNumber = number * 2; + + tbody.rows[index].cells[i].innerHTML = doubleNumber; + tbody.rows[j].cells[i].innerHTML = ''; + + const classList = tbody.rows[j].cells[i].classList; + const className = classList[1]; + + if (className) { + tbody.rows[j].cells[i].classList.remove(className); + } + + tbody.rows[index].cells[i].classList.add(`field-cell--${doubleNumber}`); +} diff --git a/src/scripts/main.js b/src/scripts/main.js index dc7f045a3..cee6a9d4a 100644 --- a/src/scripts/main.js +++ b/src/scripts/main.js @@ -1,7 +1,32 @@ 'use strict'; // Uncomment the next lines to use your game instance in the browser -// const Game = require('../modules/Game.class'); -// const game = new Game(); +const Game = require('../modules/Game.class'); +const game = new Game(); // Write your code here + +const button = document.querySelector('.button'); + +if (button) { + button.addEventListener('click', () => { + if (button.classList.contains('start')) { + game.start(); + } else if (button.classList.contains('restart')) { + game.restart(); + } + }); +} + +// в дужках повинно бути 'event' | тут але виводило помилку в npm run lint +document.addEventListener('keydown', () => { + if (event.key === 'ArrowLeft') { + game.moveLeft(); + } else if (event.key === 'ArrowRight') { + game.moveRight(); + } else if (event.key === 'ArrowUp') { + game.moveUp(); + } else if (event.key === 'ArrowDown') { + game.moveDown(); + } +}); diff --git a/src/styles/main.scss b/src/styles/main.scss index c43f37dcf..1c041c668 100644 --- a/src/styles/main.scss +++ b/src/styles/main.scss @@ -18,11 +18,12 @@ body { color: #776e65; box-sizing: border-box; text-align: center; - vertical-align: center; + vertical-align: middle; user-select: none; &--2 { background: #eee4da; + color: #776e65; } &--4 { @@ -148,6 +149,8 @@ h1 { .restart { background: #f1b2b2; + width: 85px; + font-size: 20px; &:hover { background: #f87474; From 3ef06efe0a445d1d16348d5dbe8f9ce154db1863 Mon Sep 17 00:00:00 2001 From: Artem Date: Sun, 9 Feb 2025 13:10:53 +0100 Subject: [PATCH 2/5] solution --- src/index.html | 32 +-- src/modules/Game.class.js | 429 +++++++++++++++++++++++++------------- src/scripts/main.js | 37 +++- src/styles/main.scss | 20 ++ 4 files changed, 353 insertions(+), 165 deletions(-) diff --git a/src/index.html b/src/index.html index 71f379669..afb1016e1 100644 --- a/src/index.html +++ b/src/index.html @@ -28,31 +28,31 @@

2048

- - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + +
diff --git a/src/modules/Game.class.js b/src/modules/Game.class.js index f2eee34d8..0b0ce6f54 100644 --- a/src/modules/Game.class.js +++ b/src/modules/Game.class.js @@ -26,125 +26,51 @@ class Game { } moveRight() { - const trElements = document.querySelectorAll('tbody > tr'); - const trArray = Array.from(trElements); - - for (const tr of trArray) { - for (let i = tr.children.length - 1; i >= 0; i--) { - if (tr.children[i].classList.length > 1) { - if (tr.children[3].classList.length === 1) { - moveOnEmpty(tr, i, 3); - } else if ( - tr.children[3].innerHTML === tr.children[i].innerHTML && - i !== 3 - ) { - mergeCellsInRow(tr, i, 3); - } else if (tr.children[2].classList.length === 1) { - moveOnEmpty(tr, i, 2); - } else if ( - tr.children[2].innerHTML === tr.children[i].innerHTML && - i !== 2 - ) { - mergeCellsInRow(tr, i, 2); - } - } - } - } + this.moveHorizontally('right'); } moveLeft() { - const trElements = document.querySelectorAll('tbody > tr'); - const trArray = Array.from(trElements); - - for (const tr of trArray) { - for (let i = 0; i < tr.children.length; i++) { - if (tr.children[i].classList.length > 1) { - if (tr.children[0].classList.length === 1) { - moveOnEmpty(tr, i, 0); - } else if ( - tr.children[0].innerHTML === tr.children[i].innerHTML && - i !== 0 - ) { - mergeCellsInRow(tr, i, 0); - } else if (tr.children[1].classList.length === 1) { - moveOnEmpty(tr, i, 1); - } else if ( - tr.children[1].innerHTML === tr.children[i].innerHTML && - i !== 1 - ) { - mergeCellsInRow(tr, i, 1); - } - } - } - } + this.moveHorizontally('left'); } - moveUp() { - const tbody = document.querySelector('tbody'); - const rows = tbody.rows; - for (let i = 0; i < rows[0].cells.length; i++) { - for (let j = 0; j < rows.length; j++) { - const cell = rows[j].cells[i]; - - if (cell.classList.length > 1) { - if (rows[0].cells[i].classList.length === 1) { - moveOnEmptyCell(tbody, j, i, 0); - } else if ( - rows[0].cells[i].innerHTML === rows[j].cells[i].innerHTML && - j !== 0 - ) { - mergeCellsInCell(tbody, j, i, 0); - } else if (rows[1].cells[i].classList.length === 1) { - moveOnEmptyCell(tbody, j, i, 1); - } else if ( - rows[1].cells[i].innerHTML === rows[j].cells[i].innerHTML && - j !== 1 - ) { - mergeCellsInCell(tbody, j, i, 1); - } - } - } - } + moveUp() { + this.moveVertically('up'); } moveDown() { - const tbody = document.querySelector('tbody'); - const rows = tbody.rows; - - for (let i = 0; i < rows[0].cells.length; i++) { - for (let j = rows.length - 2; j >= 0; j--) { - const cell = rows[j].cells[i]; - - if (cell.classList.length > 1) { - if (rows[3].cells[i].classList.length === 1) { - moveOnEmptyCell(tbody, j, i, 3); - } else if ( - rows[3].cells[i].innerHTML === rows[j].cells[i].innerHTML && - j !== 3 - ) { - mergeCellsInCell(tbody, j, i, 3); - } else if (rows[2].cells[i].classList.length === 1) { - moveOnEmptyCell(tbody, j, i, 2); - } else if ( - rows[2].cells[i].innerHTML === rows[j].cells[i].innerHTML && - j !== 2 - ) { - mergeCellsInCell(tbody, j, i, 2); - } - } - } - } + this.moveVertically('down'); } /** * @returns {number} */ - getScore() {} + getScore(num) { + const score = document.querySelector('.game-score'); + const currentScore = parseInt(score.innerHTML) || 0; + + score.innerHTML = currentScore + num; + } /** * @returns {number[][]} */ - getState() {} + getState() { + const tbody = document.querySelector('tbody'); + const rows = tbody.rows; + const table = []; + + for (let i = 0; i < rows.length; i++) { + table[i] = []; + + for (let j = 0; j < rows[i].cells.length; j++) { + const cell = rows[i].cells[j]; + + table[i].push(parseInt(cell.innerHTML) || 0); + } + } + + return table; + } /** * Returns the current game status. @@ -156,8 +82,110 @@ class Game { * `win` - the game is won; * `lose` - the game is lost */ - getStatus() {} + getStatus() { + if (this.hasWon()) { + return 'win'; + } + + if (this.hasLose()) { + return 'lose'; + } + + if (this.isPlaying()) { + return 'playing'; + } + + if (this.isIdle()) { + return 'idle'; + } + } + + setStatus(newStatus) { + return newStatus; + } + + hasWon() { + const tbody = document.querySelector('tbody'); + const rows = tbody.rows; + + for (let i = 0; i < rows.length; i++) { + const cells = rows[i].cells; + + for (let j = 0; j < cells.length; j++) { + if (parseInt(cells[j].innerHTML) === 2048) { + return true; + } + } + } + + return false; + } + + hasLose() { + const tbody = document.querySelector('tbody'); + const rows = tbody.rows; + const table = []; + + for (let i = 0; i < rows.length; i++) { + table[i] = []; + + const cells = rows[i].cells; + + for (let j = 0; j < cells.length; j++) { + table[i][j] = parseInt(cells[j].innerHTML) || 0; + } + } + + for (let i = 0; i < table.length; i++) { + for (let j = 0; j < table[i].length; j++) { + if (table[i][j] === 0) { + return false; + } + } + } + + for (let i = 0; i < table.length; i++) { + for (let j = 0; j < table[i].length - 1; j++) { + if (table[i][j] === table[i][j + 1]) { + return false; + } + } + } + + for (let i = 0; i < table.length - 1; i++) { + for (let j = 0; j < table.length - 1; j++) { + if (table[i][j] === table[i + 1][j]) { + return false; + } + } + } + + return true; + } + isIdle() { + const tdElements = document.querySelectorAll('tbody td'); + + for (let i = 0; i < tdElements.length; i++) { + if (parseInt(tdElements[i].innerHTML) > 0) { + return false; + } + } + + return true; + } + + isPlaying() { + const idle = this.isIdle(); + const lose = this.hasLose(); + const win = this.hasWon(); + + if (!idle && !lose && !win) { + return true; + } + + return false; + } /** * Starts the game. */ @@ -174,8 +202,8 @@ class Game { let uniqueElements = new Set(); while (uniqueElements.size !== 2) { - firstElement = tdArray[getRandomInt(tdArray.length - 1)]; - secondElement = tdArray[getRandomInt(tdArray.length - 1)]; + firstElement = tdArray[getRandomInt(tdArray.length)]; + secondElement = tdArray[getRandomInt(tdArray.length)]; uniqueElements = new Set([firstElement, secondElement]); } @@ -205,63 +233,178 @@ class Game { element.className = 'field-cell'; element.innerHTML = ''; }); + + const loseWindow = document.querySelector('.lose-window'); + + if (loseWindow) { + loseWindow.remove(); + } + + const winWindow = document.querySelector('.win-window'); + + if (winWindow) { + winWindow.remove(); + } + + const score = document.querySelector('.game-score'); + + if (score) { + score.innerHTML = '0'; + } + + this.setStatus('playing'); } // Add your own methods here -} + addNewCell() { + const tdElements = document.querySelectorAll('tbody td'); + const emptyCells = Array.from(tdElements).filter( + (cell) => cell.textContent.trim() === '', + ); + + if (emptyCells.length > 0) { + const newElement = emptyCells[getRandomInt(emptyCells.length)]; + const randomNumber = getRandomInt(2); + + if (randomNumber === 0) { + newElement.innerHTML = '2'; + newElement.classList.add('field-cell--2'); + } else if (randomNumber === 1) { + newElement.innerHTML = '4'; + newElement.classList.add('field-cell--4'); + } + } + } -module.exports = Game; + moveHorizontally(direction) { + const table = this.getState(); + const newTable = []; -function getRandomInt(num) { - return Math.floor(Math.random() * num); -} + const tbody = document.querySelector('tbody'); + const rows = tbody.rows; + let totalScore = 0; -function moveOnEmpty(tr, i, index) { - tr.children[index].innerHTML = tr.children[i].innerHTML; - tr.children[i].innerHTML = ''; + for (let i = 0; i < table.length; i++) { + let row = table[i].filter((val) => val > 0); - tr.children[index].classList = tr.children[i].classList; - tr.children[i].className = 'field-cell'; -} + for (let k = 0; k < row.length - 1; k++) { + if (row[k] === row[k + 1]) { + row[k] *= 2; + totalScore += row[k]; + row[k + 1] = 0; + } + } -function moveOnEmptyCell(tbody, j, i, index) { - tbody.rows[index].cells[i].innerHTML = tbody.rows[j].cells[i].innerHTML; - tbody.rows[j].cells[i].innerHTML = ''; + row = row.filter((val) => val > 0); - tbody.rows[index].cells[i].classList = tbody.rows[j].cells[i].classList; - tbody.rows[j].cells[i].className = 'field-cell'; -} + while (row.length !== 4) { + if (direction === 'right') { + row.unshift(0); + } else if (direction === 'left') { + row.push(0); + } + } + newTable.push(row); + } + + for (let i = 0; i < newTable.length; i++) { + for (let j = 0; j < newTable[i].length; j++) { + rows[i].cells[j].innerHTML = + newTable[i][j] > 0 ? `${newTable[i][j]}` : ''; + rows[i].cells[j].className = 'field-cell'; + + if (newTable[i][j] > 0) { + rows[i].cells[j].classList.add(`field-cell--${newTable[i][j]}`); + } + } + } + this.getScore(totalScore); + this.addNewCell(); + } + + moveVertically(direction) { + const table = this.getState(); + const newTable = []; + + const tbody = document.querySelector('tbody'); + const rows = tbody.rows; + let totalScore = 0; + + for (let i = 0; i < table[0].length; i++) { + let cell = []; + + for (let j = 0; j < table.length; j++) { + cell.push(table[j][i]); + } + + cell = cell.filter((val) => val > 0); + + for (let k = 0; k < cell.length - 1; k++) { + if (cell[k] === cell[k + 1]) { + cell[k] *= 2; + totalScore += cell[k]; + cell[k + 1] = 0; + } + } -function mergeCellsInRow(tr, i, index) { - const number = parseInt(tr.children[i].innerHTML); - const doubleNumber = number * 2; + cell = cell.filter((val) => val > 0); - tr.children[index].innerHTML = doubleNumber; - tr.children[i].innerHTML = ''; + while (cell.length !== 4) { + if (direction === 'down') { + cell.unshift(0); + } else if (direction === 'up') { + cell.push(0); + } + } + + for (let j = 0; j < table.length; j++) { + newTable[j] = newTable[j] || []; + newTable[j][i] = cell[j]; + } + } - const classList = tr.children[i].classList; - const className = classList[1]; + for (let i = 0; i < newTable.length; i++) { + for (let j = 0; j < newTable[i].length; j++) { + rows[i].cells[j].innerHTML = + newTable[i][j] > 0 ? `${newTable[i][j]}` : ''; + rows[i].cells[j].className = 'field-cell'; - if (className) { - tr.children[i].classList.remove(className); + if (newTable[i][j] > 0) { + rows[i].cells[j].classList.add(`field-cell--${newTable[i][j]}`); + } + } + } + this.getScore(totalScore); + this.addNewCell(); } - tr.children[index].classList.add(`field-cell--${doubleNumber}`); -} + loseWindow() { + const loseWindow = document.createElement('div'); -function mergeCellsInCell(tbody, j, i, index) { - const number = parseInt(tbody.rows[j].cells[i].innerHTML); - const doubleNumber = number * 2; + loseWindow.className = 'lose-window'; - tbody.rows[index].cells[i].innerHTML = doubleNumber; - tbody.rows[j].cells[i].innerHTML = ''; + const title = document.createElement('h2'); - const classList = tbody.rows[j].cells[i].classList; - const className = classList[1]; + title.textContent = 'You lose! Try again.'; + loseWindow.appendChild(title); + document.body.appendChild(loseWindow); + } + + winWindow() { + const winWindow = document.createElement('div'); + + winWindow.className = 'win-window'; - if (className) { - tbody.rows[j].cells[i].classList.remove(className); + const title = document.createElement('h2'); + + title.textContent = 'You won! Congratulation!.'; + winWindow.appendChild(title); + document.body.appendChild(winWindow); } +} - tbody.rows[index].cells[i].classList.add(`field-cell--${doubleNumber}`); +module.exports = Game; + +function getRandomInt(num) { + return Math.floor(Math.random() * num); } diff --git a/src/scripts/main.js b/src/scripts/main.js index cee6a9d4a..80389c1b7 100644 --- a/src/scripts/main.js +++ b/src/scripts/main.js @@ -12,21 +12,46 @@ if (button) { button.addEventListener('click', () => { if (button.classList.contains('start')) { game.start(); + game.setStatus('playing'); + startGameLoop(); } else if (button.classList.contains('restart')) { game.restart(); + game.setStatus('idle'); + startGameLoop(); } }); } -// в дужках повинно бути 'event' | тут але виводило помилку в npm run lint -document.addEventListener('keydown', () => { - if (event.key === 'ArrowLeft') { +let gameLoop; + +function startGameLoop() { + clearInterval(gameLoop); + + gameLoop = setInterval(() => { + const newStatus = game.getStatus(); + + if (newStatus === 'win') { + game.winWindow(); + clearInterval(gameLoop); + } else if (newStatus === 'lose') { + game.loseWindow(); + clearInterval(gameLoop); + } + }, 100); +} + +document.addEventListener('keydown', (eve) => { + if (!game.isPlaying()) { + return; + } + + if (eve.key === 'ArrowLeft') { game.moveLeft(); - } else if (event.key === 'ArrowRight') { + } else if (eve.key === 'ArrowRight') { game.moveRight(); - } else if (event.key === 'ArrowUp') { + } else if (eve.key === 'ArrowUp') { game.moveUp(); - } else if (event.key === 'ArrowDown') { + } else if (eve.key === 'ArrowDown') { game.moveDown(); } }); diff --git a/src/styles/main.scss b/src/styles/main.scss index 1c041c668..584395bee 100644 --- a/src/styles/main.scss +++ b/src/styles/main.scss @@ -188,3 +188,23 @@ h1 { width: 100%; height: 150px; } + +.lose-window { + position: absolute; + width: 50%; + height: 100px; + background: #d6cdc4; + color: #776e65; + text-align: center; + align-items: center; +} + +.win-window { + position: absolute; + width: 50%; + height: 100px; + background: yellow; + color: #fff; + text-align: center; + align-items: center; +} From da35b84b493ba518fb166c72a51c41f65fbffc4f Mon Sep 17 00:00:00 2001 From: Artem Date: Sun, 9 Feb 2025 13:27:16 +0100 Subject: [PATCH 3/5] hidding message --- src/modules/Game.class.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/modules/Game.class.js b/src/modules/Game.class.js index 0b0ce6f54..2161254e3 100644 --- a/src/modules/Game.class.js +++ b/src/modules/Game.class.js @@ -213,6 +213,11 @@ class Game { secondElement.classList.add('field-cell--2'); secondElement.innerHTML = '2'; } + + const startMessage = document.querySelector('.message-start'); + if (startMessage) { + startMessage.remove(); + } } /** @@ -253,6 +258,12 @@ class Game { } this.setStatus('playing'); + + const startMessage = document.createElement('p'); + startMessage.className = 'message message-start'; + startMessage.innerHTML = 'Press "Start" to begin game. Good luck!'; + const messageContainer = document.querySelector('.message-container'); + messageContainer.appendChild(startMessage); } // Add your own methods here From e4d51ecf59094f5f03490d1c4ac4b670cbdfe192 Mon Sep 17 00:00:00 2001 From: Artem Date: Sun, 9 Feb 2025 13:43:20 +0100 Subject: [PATCH 4/5] new cells --- src/modules/Game.class.js | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/modules/Game.class.js b/src/modules/Game.class.js index 2161254e3..1ef1d1fdb 100644 --- a/src/modules/Game.class.js +++ b/src/modules/Game.class.js @@ -215,6 +215,7 @@ class Game { } const startMessage = document.querySelector('.message-start'); + if (startMessage) { startMessage.remove(); } @@ -260,9 +261,12 @@ class Game { this.setStatus('playing'); const startMessage = document.createElement('p'); + startMessage.className = 'message message-start'; startMessage.innerHTML = 'Press "Start" to begin game. Good luck!'; + const messageContainer = document.querySelector('.message-container'); + messageContainer.appendChild(startMessage); } @@ -294,6 +298,7 @@ class Game { const tbody = document.querySelector('tbody'); const rows = tbody.rows; let totalScore = 0; + let tableChanged = false; for (let i = 0; i < table.length; i++) { let row = table[i].filter((val) => val > 0); @@ -302,6 +307,7 @@ class Game { if (row[k] === row[k + 1]) { row[k] *= 2; totalScore += row[k]; + tableChanged = true; row[k + 1] = 0; } } @@ -314,6 +320,7 @@ class Game { } else if (direction === 'left') { row.push(0); } + tableChanged = true; } newTable.push(row); } @@ -330,7 +337,9 @@ class Game { } } this.getScore(totalScore); - this.addNewCell(); + if (tableChanged) { + this.addNewCell(); + } } moveVertically(direction) { @@ -340,6 +349,7 @@ class Game { const tbody = document.querySelector('tbody'); const rows = tbody.rows; let totalScore = 0; + let tableChanged = false; for (let i = 0; i < table[0].length; i++) { let cell = []; @@ -354,6 +364,7 @@ class Game { if (cell[k] === cell[k + 1]) { cell[k] *= 2; totalScore += cell[k]; + tableChanged = true; cell[k + 1] = 0; } } @@ -366,6 +377,7 @@ class Game { } else if (direction === 'up') { cell.push(0); } + tableChanged = true; } for (let j = 0; j < table.length; j++) { @@ -386,7 +398,9 @@ class Game { } } this.getScore(totalScore); - this.addNewCell(); + if (tableChanged) { + this.addNewCell(); + } } loseWindow() { From 232555650d620c77d102f72ef9e26614496536e1 Mon Sep 17 00:00:00 2001 From: Artem Date: Sun, 9 Feb 2025 19:07:33 +0100 Subject: [PATCH 5/5] adding new cells --- src/modules/Game.class.js | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/src/modules/Game.class.js b/src/modules/Game.class.js index 1ef1d1fdb..1743740e9 100644 --- a/src/modules/Game.class.js +++ b/src/modules/Game.class.js @@ -301,8 +301,10 @@ class Game { let tableChanged = false; for (let i = 0; i < table.length; i++) { - let row = table[i].filter((val) => val > 0); - + let row = table[i].slice(); + let originalRow = [...row]; + row = row.filter((val) => val > 0); + for (let k = 0; k < row.length - 1; k++) { if (row[k] === row[k + 1]) { row[k] *= 2; @@ -311,8 +313,8 @@ class Game { row[k + 1] = 0; } } - row = row.filter((val) => val > 0); + while (row.length !== 4) { if (direction === 'right') { @@ -320,9 +322,12 @@ class Game { } else if (direction === 'left') { row.push(0); } - tableChanged = true; } newTable.push(row); + + if (!arraysEqual(originalRow, row)) { + tableChanged = true; + } } for (let i = 0; i < newTable.length; i++) { @@ -337,6 +342,7 @@ class Game { } } this.getScore(totalScore); + if (tableChanged) { this.addNewCell(); } @@ -358,7 +364,9 @@ class Game { cell.push(table[j][i]); } - cell = cell.filter((val) => val > 0); + cell = cell.slice(); + let originalCell = [...cell]; + cell = cell.filter((val) => val > 0) for (let k = 0; k < cell.length - 1; k++) { if (cell[k] === cell[k + 1]) { @@ -370,6 +378,7 @@ class Game { } cell = cell.filter((val) => val > 0); + while (cell.length !== 4) { if (direction === 'down') { @@ -377,13 +386,16 @@ class Game { } else if (direction === 'up') { cell.push(0); } - tableChanged = true; } for (let j = 0; j < table.length; j++) { newTable[j] = newTable[j] || []; newTable[j][i] = cell[j]; } + + if (!arraysEqual(originalCell, cell)) { + tableChanged = true; + } } for (let i = 0; i < newTable.length; i++) { @@ -398,6 +410,7 @@ class Game { } } this.getScore(totalScore); + if (tableChanged) { this.addNewCell(); } @@ -433,3 +446,7 @@ module.exports = Game; function getRandomInt(num) { return Math.floor(Math.random() * num); } + +function arraysEqual(arr1, arr2) { + return arr1.length === arr2.length && arr1.every((val, index) => val === arr2[index]); +} \ No newline at end of file