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

2048 #544

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

2048 #544

Show file tree
Hide file tree
Changes from 3 commits
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
16 changes: 7 additions & 9 deletions src/index.html
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta charset="UTF-8"></meta>
<meta name="viewport" content="width=device-width, initial-scale=1.0"></meta>
<title>2048</title>
<link rel="stylesheet" href="./styles/main.scss">
<link rel="stylesheet" href="./styles/main.scss"></link>
</head>
<body>
<div class="container">
<div class="game-header">
<h1>2048</h1>
<div class="controls">
<p class="info">
Score: <span class="game-score">0</span>
</p>
<p class="info">Score: <span class="game-score">0</span></p>
<button class="button start">Start</button>
</div>
</div>
Expand All @@ -34,15 +32,13 @@ <h1>2048</h1>
<td class="field-cell"></td>
</tr>


<tr class="field-row">
<td class="field-cell"></td>
<td class="field-cell"></td>
<td class="field-cell"></td>
<td class="field-cell"></td>
</tr>


<tr class="field-row">
<td class="field-cell"></td>
<td class="field-cell"></td>
Expand All @@ -55,7 +51,9 @@ <h1>2048</h1>
<div class="message-container">
<p class="message message-lose hidden">You lose! Restart the game?</p>
<p class="message message-win hidden">Winner! Congrats! You did it!</p>
<p class="message message-start">Press "Start" to begin game. Good luck!</p>
<p class="message message-start">
Press "Start" to begin game. Good luck!
</p>
</div>
</div>
<script type="text/javascript" src="scripts/main.js"></script>
Expand Down
319 changes: 318 additions & 1 deletion src/scripts/main.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,320 @@
'use strict';

// write your code here
const messageStart = document.querySelector('.message-start');
const messageLose = document.querySelector('.message-lose');
const messageWin = document.querySelector('.message-win');
const button = document.querySelector('.button');
const score = document.querySelector('.game-score');

const board = [
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0],
];
const rows = 4;
const columns = 4;
let scoreCount = 0;
let won = false;
const initialBoard = board.map(row => [...row]);
let isInitialSetup = true;

button.addEventListener('click', () => {
if (isInitialSetup) {
messageStart.classList.add('hidden');
button.innerText = 'Restart';
button.classList.replace('start', 'restart');

setGame();
isInitialSetup = false;
} else {
messageWin.classList.add('hidden');
won = false;
resetFields();
setGame();
}
});

const table = document.querySelector('.game-field');

const setGame = () => {
for (let r = 0; r < rows; r++) {
const row = table.querySelectorAll('.field-row')[r];
const cells = row.querySelectorAll('.field-cell');

for (let c = 0; c < columns; c++) {
const cell = cells[c];

cell.setAttribute('id', `row_${r}-column_${c}`);

const number = board[r][c];

updateCell(cell, number);
}
}
setCell();
setCell();
};

const hasEmptyCell = () => {
for (let r = 0; r < rows; r++) {
for (let c = 0; c < columns; c++) {
if (board[r][c] === 0) {
return true;
}
}
}

Choose a reason for hiding this comment

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

You can use a "some" method here to reduce the amount of code a bit


return false;
};

const loseGame = () => {
if (hasEmptyCell()) {
return false;
}

for (let r = 0; r < rows; r++) {
for (let c = 0; c < rows; c++) {
if (board[r][c] === board[r][c + 1]) {
return false;
}
}
}

for (let r = 0; r < rows - 1; r++) {
for (let c = 0; c < rows; c++) {
if (board[r][c] === board[r + 1][c]) {
return false;
}
}
}

return true;
};

const resetFields = () => {
for (let r = 0; r < rows; r++) {
for (let c = 0; c < columns; c++) {
board[r][c] = 0;
}
}
};

const clearBoard = () => {
for (let r = 0; r < rows; r++) {
for (let c = 0; c < columns; c++) {
const cell = document.getElementById(`row_${r}-column_${c}`);

cell.innerText = '';
cell.classList.value = '';
cell.classList.add('field-cell');
}
}
scoreCount = 0;
score.innerHTML = scoreCount;
};

const setCell = () => {
if (!hasEmptyCell()) {
return;
}

let found = false;
const number = Math.random() < 0.8 ? 2 : 4;

while (!found) {
const row = Math.floor(Math.random() * rows);
const column = Math.floor(Math.random() * columns);

if (board[row][column] === 0) {
board[row][column] = 2;

const cell = document.getElementById(`row_${row}-column_${column}`);

cell.innerText = `${number}`;
cell.classList.add(`field-cell--${number}`);
found = true;
}
}

if (loseGame()) {
messageLose.classList.remove('hidden');

button.addEventListener('click', () => {
messageLose.classList.add('hidden');

clearBoard();
setGame();
});
}
};

const updateCell = (cell, number) => {
cell.innerText = '';
cell.classList.value = '';
cell.classList.add('field-cell');

if (number > 0) {
cell.innerText = number;

if (number < 4096) {
cell.classList.add(`field-cell--${number}`);
} else {
cell.classList.add(`field-cell--8192`);
}
}

if (number === 2048) {

Choose a reason for hiding this comment

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

Suggested change
if (number === 2048) {
if (number === 2048) {

Move magic numbers like 2048 to constant

messageWin.classList.remove('hidden');
won = true;
}
};

document.addEventListener('keyup', arrow => {
arrow.preventDefault();

if (won) {
return;
}

switch (arrow.key) {
case 'ArrowLeft':

Choose a reason for hiding this comment

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

Move all these magic words to variables and use it everywhere

slideLeft();
break;
case 'ArrowRight':
slideRight();
break;
case 'ArrowUp':
slideUp();
break;
case 'ArrowDown':
slideDown();
break;
default:
return;
}

document.querySelector('.game-score').innerText = scoreCount;
});

const filterZero = row => row.filter(num => num !== 0);

const slide = (row) => {
let initialRow = [...row];

initialRow = filterZero(initialRow);

for (let i = 0; i < initialRow.length - 1; i++) {
if (initialRow[i] === initialRow[i + 1]) {
initialRow[i] *= 2;
initialRow[i + 1] = 0;
scoreCount += initialRow[i];
}
}

initialRow = filterZero(initialRow);

while (initialRow.length < columns) {
initialRow.push(0);
}

return initialRow;
};

const slideLeft = () => {
for (let r = 0; r < rows; r++) {
let row = board[r];

row = slide(row);
board[r] = row;

for (let c = 0; c < columns; c++) {
const cell = document.getElementById(`row_${r}-column_${c}`);
const number = board[r][c];

updateCell(cell, number);
}
}

if (hasChanges(initialBoard, board)) {
setCell();
}
};

const slideRight = () => {
for (let r = 0; r < rows; r++) {
let row = board[r];

row.reverse();
row = slide(row);
row.reverse();
board[r] = row;

for (let c = 0; c < columns; c++) {
const cell = document.getElementById(`row_${r}-column_${c}`);
const number = board[r][c];

updateCell(cell, number);
}
}

if (hasChanges(initialBoard, board)) {
setCell();
}
};

Choose a reason for hiding this comment

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

This functions looks similar, i think we can try to combine them


const slideUp = () => {
for (let c = 0; c < columns; c++) {
let row = [board[0][c], board[1][c], board[2][c], board[3][c]];

row = slide(row);

for (let r = 0; r < rows; r++) {
board[r][c] = row[r];

const cell = document.getElementById(`row_${r}-column_${c}`);
const number = board[r][c];

updateCell(cell, number);
}
}

if (hasChanges(initialBoard, board)) {
setCell();
}
};

const slideDown = () => {
for (let c = 0; c < columns; c++) {
let row = [board[0][c], board[1][c], board[2][c], board[3][c]];

row.reverse();
row = slide(row);
row.reverse();

for (let r = 0; r < rows; r++) {
board[r][c] = row[r];

const cell = document.getElementById(`row_${r}-column_${c}`);
const number = board[r][c];

updateCell(cell, number);
}
}

if (hasChanges(initialBoard, board)) {
setCell();
}
};

const hasChanges = (arrayA, arrayB) => {
for (let i = 0; i < arrayA.length; i++) {
for (let j = 0; j < arrayA[i].length; j++) {
if (arrayA[i][j] !== arrayB[i][j]) {
return true;
}
}
}

return false;
};
Loading
Loading