diff --git a/src/index.html b/src/index.html
index cf82080f7..add5fbc88 100644
--- a/src/index.html
+++ b/src/index.html
@@ -1,11 +1,13 @@
+
2048
+
@@ -60,4 +63,5 @@ 2048
+
diff --git a/src/scripts/main.js b/src/scripts/main.js
index c6e3f8784..ffd48816e 100644
--- a/src/scripts/main.js
+++ b/src/scripts/main.js
@@ -1,3 +1,200 @@
'use strict';
-// write your code here
+const rows = [...document.querySelectorAll('.field-row')];
+const columns = [[], [], [], []];
+const cells = document.querySelectorAll('.field-cell');
+const cellsInRow = rows.map((row) => [...row.querySelectorAll('.field-cell')]);
+const startCellVelues = [2, 2, 2, 2, 2, 2, 2, 2, 2, 4];
+
+const startButton = document.querySelector('.start');
+const messageStart = document.querySelector('.message-start');
+const messageLose = document.querySelector('.message-lose');
+const messageWin = document.querySelector('.message-win');
+const score = document.querySelector('.game-score');
+
+for (let i = 0; i < 4; i++) {
+ for (let j = 0; j < 4; j++) {
+ columns[j].push(rows[i].children[j]);
+ }
+}
+
+let clearCells = [...cells];
+let started = false;
+let rotated = false;
+
+function randomCellFill() {
+ if (!clearCells.length) {
+ return;
+ }
+
+ const randomIndex = (someArr) => Math.floor(Math.random() * someArr.length);
+ const randomCell = clearCells[randomIndex(clearCells)];
+ const randomValue = startCellVelues[randomIndex(startCellVelues)];
+
+ randomCell.classList = (`field-cell field-cell--${randomValue}`);
+ randomCell.innerText = randomValue;
+
+ clearCells.splice(clearCells.indexOf(randomCell), 1);
+}
+
+const start = () => {
+ messageStart.style = 'display: none;';
+ startButton.classList = 'button restart';
+ startButton.innerText = 'Restart';
+
+ randomCellFill();
+ randomCellFill();
+ started = true;
+};
+
+const restart = () => {
+ messageLose.classList.add('hidden');
+ messageWin.classList.add('hidden');
+ clearCells = [...cells];
+ score.innerText = 0;
+
+ cells.forEach(cell => {
+ cell.innerText = '';
+ cell.className = 'field-cell';
+ });
+
+ randomCellFill();
+ randomCellFill();
+};
+
+function isMergePossible() {
+ const wholeField = [...cellsInRow, ...columns];
+
+ for (const line of wholeField) {
+ for (let i = 0; i < 3; i++) {
+ if (line[i].innerText === line[i + 1].innerText) {
+ return true;
+ }
+ }
+ }
+}
+
+function deleteCell(element) {
+ element.innerText = '';
+ element.className = 'field-cell';
+ clearCells.push(element);
+}
+
+function cellMerge(curr, prev) {
+ const value = curr.innerText * 2;
+
+ curr.innerText = value;
+ curr.className = `field-cell field-cell--${value}`;
+ score.innerText = +score.innerText + value;
+ deleteCell(prev);
+
+ curr.dataset.blocked = true;
+ prev.dataset.blocked = true;
+
+ if (value === 2048) {
+ messageWin.classList.remove('hidden');
+ }
+}
+
+function rotateCell(curr, prev) {
+ curr.innerText = prev.innerText;
+ curr.className = prev.className;
+ clearCells.splice(clearCells.indexOf(curr), 1);
+ deleteCell(prev);
+}
+
+function arrowUp() {
+ for (const column of columns) {
+ rotateCells([...column].reverse());
+ }
+}
+
+function arrowDown() {
+ for (const column of columns) {
+ rotateCells(column);
+ }
+}
+
+function arrowRight() {
+ for (const row of cellsInRow) {
+ rotateCells(row);
+ }
+}
+
+function arrowLeft() {
+ for (const row of cellsInRow) {
+ rotateCells([...row].reverse());
+ }
+}
+
+function arrowMove(direction) {
+ if (!clearCells.length && !isMergePossible()) {
+ messageLose.classList.remove('hidden');
+ }
+
+ switch (direction) {
+ case 'ArrowUp':
+ arrowUp();
+ break;
+ case 'ArrowDown':
+ arrowDown();
+ break;
+ case 'ArrowRight':
+ arrowRight();
+ break;
+ case 'ArrowLeft':
+ arrowLeft();
+ break;
+ }
+
+ cells.forEach(cell => {
+ cell.removeAttribute('data-blocked');
+ });
+}
+
+function rotateCells(line) {
+ for (let i = 3; i > 0; i--) {
+ const moveAllowed = clearCells.includes(line[i])
+ && !clearCells.includes(line[i - 1]);
+
+ const mergeAllowed = line[i].innerText === line[i - 1].innerText
+ && line[i].innerText.length
+ && !line[i - 1].dataset.blocked;
+
+ if ((mergeAllowed || moveAllowed) && !rotated) {
+ rotated = true;
+ }
+
+ if (mergeAllowed) {
+ cellMerge(line[i], line[i - 1]);
+ rotateCells(line);
+ }
+
+ if (moveAllowed) {
+ rotateCell(line[i], line[i - 1]);
+ rotateCells(line);
+ }
+ }
+}
+
+document.addEventListener('keydown', (evt) => {
+ const arrowDirections = ['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'];
+
+ if (arrowDirections.includes(evt.key)) {
+ evt.preventDefault();
+ arrowMove(evt.key);
+
+ if (rotated) {
+ randomCellFill();
+ rotated = false;
+ }
+ }
+});
+
+startButton.addEventListener('click', () => {
+ if (!started) {
+ start();
+ } else {
+ restart();
+ }
+});
diff --git a/src/styles/main.scss b/src/styles/main.scss
index c43f37dcf..02c412e08 100644
--- a/src/styles/main.scss
+++ b/src/styles/main.scss
@@ -10,6 +10,8 @@ body {
font-weight: 900;
}
+$values: 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048;
+
.field-cell {
background: #d6cdc4;
width: 75px;