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

game completed #541

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
1. Replace `<your_account>` with your Github username in the link
- [DEMO LINK](https://<your_account>.github.io/js_2048_game/)
- [DEMO LINK](https://TommasoGiacopini.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;
Expand All @@ -8,13 +8,13 @@
### Task: 2048 game

Hey! Are you ready for a real hard check of your JavaScript skills, ninja?
If you are still here, let's do it.
If you are still here, let's do it.

In this task, you need to implement the 2048 game like in [this reference](https://play2048.co/)
Don't play for too long! We need you to write the code!

Okay, what do we have?
1) HTML and CSS are already written. You can use it, or implement your own design if you want.
Okay, what do we have?
1) HTML and CSS are already written. You can use it, or implement your own design if you want.
2) Reference.

That's it!
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"@linthtml/linthtml": "^0.3.2",
"@mate-academy/eslint-config": "*",
"@mate-academy/linthtml-config": "0.0.1",
"@mate-academy/scripts": "^0.7.12",
"@mate-academy/scripts": "^1.2.8",
"@mate-academy/stylelint-config": "0.0.9",
"colors": "^1.3.3",
"cypress": "^5.6.0",
Expand Down
Binary file added src/images/2048_logo.svg.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>2048</title>
<link
rel="icon"
href="images/2048_logo.svg.png"
type="image/favicon"
>
<link rel="stylesheet" href="./styles/main.scss">
</head>
<body>
Expand Down
195 changes: 194 additions & 1 deletion src/scripts/main.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,196 @@
'use strict';

// write your code here
const button = document.querySelector('button');
const gameScore = document.querySelector('.game-score');
const fieldRows = document.querySelectorAll('.field-row');
const msgStart = document.querySelector('.message-start');
const msgLose = document.querySelector('.message-lose');
const msgWin = document.querySelector('.message-win');

let newTable;
let table = [
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0],
];

const tableLength = table.length;
let SCORE = 0;
const WIN_SCORE = 2048;
let isWin = false;

button.addEventListener('click', e => {
document.addEventListener('keydown', move);

if (button.classList.contains('start')) {
button.classList.replace('start', 'restart');
button.innerText = 'Restart';
msgStart.classList.add('hidden');
} else {
isWin = false;
reset();
}

addNumber();
addNumber();

render();
});

function addNumber() {
const emptyCells = [];

table.forEach((y, yIndex) =>
y.forEach((cell, xIndex) =>
cell === 0 && emptyCells.push([yIndex, xIndex])
)
);

const [randomY, randomX]
= emptyCells[Math.floor(Math.random() * emptyCells.length)];

table[randomY][randomX] = Math.random() < 0.9 ? 2 : 4;
}

function render() {
for (let y = 0; y < tableLength; y++) {
for (let x = 0; x < tableLength; x++) {
const el = fieldRows[y].children[x];
const cell = table[y][x];

el.textContent = cell || '';

el.className
= `field-cell ${cell ? `field-cell--${cell}` : ''}`;
}
}

gameScore.textContent = SCORE;
}

function move(e) {
newTable = table;

switch (e.key) {
case 'ArrowLeft':
moveLeft();
break;

case 'ArrowRight':
moveRight();
break;

case 'ArrowDown':
moveDown();
break;

case 'ArrowUp':
moveUp();
break;

default:
return;
}

if (JSON.stringify(newTable) !== JSON.stringify(table)) {
table = newTable;
addNumber();
render();
}

if (isWin) {
msgWin.classList.remove('hidden');
}

if (!checkMove()) {
msgLose.classList.remove('hidden');
msgWin.classList.add('hidden');
document.removeEventListener('keydown', move);
}
}

function reset() {
table = table.map((y) => y.map(() => 0));
SCORE = 0;

[msgWin, msgLose].forEach(msg => msg.classList.add('hidden'));
}

function reverseRows() {
newTable.forEach(y => y.reverse());
}

function moveLeft() {
if (!checkRows()) {
return;
}

newTable = newTable.map(y => {
const newY
= y.filter(cell => cell !== 0)
.reduce((acc, cell) => {
const preCell = acc[acc.length - 1];

if (preCell === cell) {
acc[acc.length - 1] *= 2;
SCORE += acc[acc.length - 1];

if (acc[acc.length - 1] === WIN_SCORE) {
isWin = true;
}
} else {
acc.push(cell);
}

return acc;
}, []);

return newY.concat(Array(tableLength - newY.length).fill(0));
});
}

function moveRight() {
if (!checkRows()) {
return;
}

reverseRows();
moveLeft();
reverseRows();
}

function moveDown() {
movingField();
moveRight();
movingField();
}

function moveUp() {
movingField();
moveLeft();
movingField();
}

function checkColumns() {
return newTable.some(y =>
y.some((cell, x) => cell === y[x + 1])
);
}

function checkRows() {
return newTable.some(y =>
y.some((cell, x) => cell === y[x + 1]) || y.includes(0)
);
}

function movingField() {
newTable
= newTable[0].map((_, xIndex) =>
newTable.map(y => y[xIndex])
);
}

function checkMove() {
return checkRows() || (movingField(), checkColumns());
}
16 changes: 16 additions & 0 deletions src/styles/main.scss
Original file line number Diff line number Diff line change
Expand Up @@ -185,3 +185,19 @@ h1 {
width: 100%;
height: 150px;
}

// 'use strict';

// const button = document.querySelector('button');
// const messageWin = document.querySelector('.message-win');

// let newGame;

// let game = [
// [0, 0, 0, 0],
// [0, 0, 0, 0],
// [0, 0, 0, 0],
// [0, 0, 0, 0],
// ];

// let gameLength = game.length;
Loading