Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Develop #1092

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open

Develop #1092

Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
third commit
nex1994 committed Dec 21, 2024
commit 927c6428972ab292733091630a9af50a4dc01007
5 changes: 2 additions & 3 deletions src/index.html
Original file line number Diff line number Diff line change
@@ -21,7 +21,7 @@ <h1>2048</h1>
Score:
<span class="game-score">0</span>
</p>
<button class="button start">Start</button>
<button class="button start button-start">Start</button>
</div>
</div>

@@ -65,7 +65,6 @@ <h1>2048</h1>
</p>
</div>
</div>
<script type="module" defer
src="scripts/main.js"></script>
<script type="module" src="/src/scripts/main.js"></script>
</body>
</html>
111 changes: 62 additions & 49 deletions src/modules/Game.class.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,6 @@
'use strict';

/**
* This class represents the game.
* Now it has a basic structure, that is needed for testing.
* Feel free to add more props and methods if needed.
*/
class Game {
/**
* Creates a new game instance.
*
* @param {number[][]} initialState
* The initial state of the board.
* @default
* [[0, 0, 0, 0],
* [0, 0, 0, 0],
* [0, 0, 0, 0],
* [0, 0, 0, 0]]
*
* If passed, the board will be initialized with the provided
* initial state.
*/
constructor(
cells = [
[0, 0, 0, 0],
@@ -93,60 +74,92 @@ class Game {
if (moved) {
this.addRandomTitle();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There seems to be a typo in the method name addRandomTitle. It should likely be addRandomTile to reflect the action of adding a random tile to the board.

}
this.checkGameOver();
}

moveLeft() {
this.move('left');
}
moveRight() {
this.move('right');
}
moveUp() {
this.move('up');
}
moveDown() {
this.move('down');
}

this.chechGameOver();
checkGameOver() {
if (this.board.some((row) => row.includes(2048))) {
this.status = 'win';
} else if (!this.canMove()) {
this.status = 'lose';
}
}

moveLeft() {}
moveRight() {}
moveUp() {}
moveDown() {}
canMove() {
for (let i = 0; i < 4; i++) {
for (let j = 0; j < 4; j++) {
if (this.board[i][j] === 0) {
return true;
}

if (j < 3 && this.board[i][j] === this.board[i][j + 1]) {
return true;
}

if (i < 3 && this.board[i][j] === this.board[i + 1][j]) {
return true;
}
}
}

return false;
}

addRandomTitle() {
const emptyCells = [];

this.board.forEach((row, rowIndex) => {
row.forEach((value, colIndex) => {
if (value === 0) {
emptyCells.push({ rowIndex, colIndex });
}
});
});

if (emptyCells.length > 0) {
const randomIndex = Math.floor(Math.random() * emptyCells.length);
const { rowIndex, colIndex } = emptyCells[randomIndex];

this.board[rowIndex][colIndex] = Math.random() < 0.9 ? 2 : 4;
}
}

/**
* @returns {number}
*/
getScore() {
return this.getScore;
return this.score;
}

/**
* @returns {number[][]}
*/
getState() {
return this.board.map((row) => [...row]);
}

/**
* Returns the current game status.
*
* @returns {string} One of: 'idle', 'playing', 'win', 'lose'
*
* `idle` - the game has not started yet (the initial state);
* `playing` - the game is in progress;
* `win` - the game is won;
* `lose` - the game is lost
*/
getStatus() {
return this.status;
}

/**
* Starts the game.
*/
start() {
this.status = 'playing';
this.addRandomTitle();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same typo as above: addRandomTitle should be addRandomTile.

this.addRandomTitle();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same typo as above: addRandomTitle should be addRandomTile.

}

/**
* Resets the game.
*/
restart() {
this.board = this.cells.map((row) => [...row]);
this.score = 0;
this.status = 'idle';
}

// Add your own methods here
}

module.exports = Game;
89 changes: 87 additions & 2 deletions src/scripts/main.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,106 @@
'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 startButton = document.querySelector('.start');
const startButton = document.querySelector('.button-start');
const scoreElement = document.querySelector('.game-score');
const messageStart = document.querySelector('.message-start');
const messageWin = document.querySelector('.message-win');
const messageLose = document.querySelector('.message-lose');

function updateBoard() {
const state = game.getState();

state.forEach((row, rowIndex) => {
row.forEach((value, colIndex) => {
const cell = document.querySelector(
`[data-position="${rowIndex}-${colIndex}"]`,
);

if (!cell) {
return;
}

cell.textContent = value !== 0 ? value : '';
updateCellClass(cell, value);
});
});
}

function updateCellClass(cell, value) {
cell.className = 'field-cell';

if (value !== 0) {
cell.classList.add(`field-cell--${value}`);
}
}

function updateScore() {
scoreElement.textContent = game.getScore();
}

function updateMessages() {
const statusGame = game.getStatus();

messageStart.classList.add('hidden');
messageLose.classList.add('hidden');
messageWin.classList.add('hidden');

switch (statusGame) {
case 'win':
messageWin.classList.remove('hidden');
break;
case 'lose':
messageLose.classList.remove('hidden');
break;
case 'idle':
messageStart.classList.remove('hidden');
break;
default:
break;
}
}

startButton.addEventListener('click', () => {
if (startButton.classList.contains('start')) {
game.start();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensure that the start method in the Game class correctly initializes the game state. There was a typo in the Game class regarding the method name addRandomTitle, which should be addRandomTile. Make sure this is corrected in the Game class to avoid runtime errors.

updateBoard();
updateMessages();
startButton.classList.remove('start');
startButton.classList.add('restart');
startButton.textContent = 'Restart';
} else {
game.restart();
updateBoard();
updateMessages();
updateScore();
startButton.classList.remove('restart');
startButton.classList.add('start');
startButton.textContent = 'Start';
}
});

window.addEventListener('keydown', (ev) => {
switch (ev.key) {
case 'ArrowLeft':
game.moveLeft();
break;
case 'ArrowRight':
game.moveRight();
break;
case 'ArrowUp':
game.moveUp();
break;
case 'ArrowDown':
game.moveDown();
break;
default:
return;
}

updateBoard();
updateScore();
updateMessages();
});