2048 / script.js
JingyeChen22's picture
Create script.js
1e917c6 verified
class Game {
constructor() {
this.grid = Array(4).fill().map(() => Array(4).fill(0));
this.score = 0;
this.init();
}
init() {
this.addNewTile();
this.addNewTile();
this.updateDisplay();
}
addNewTile() {
const emptyCells = [];
for (let i = 0; i < 4; i++) {
for (let j = 0; j < 4; j++) {
if (this.grid[i][j] === 0) {
emptyCells.push({x: i, y: j});
}
}
}
if (emptyCells.length > 0) {
const randomCell = emptyCells[Math.floor(Math.random() * emptyCells.length)];
this.grid[randomCell.x][randomCell.y] = Math.random() < 0.9 ? 2 : 4;
}
}
updateDisplay() {
for (let i = 0; i < 4; i++) {
for (let j = 0; j < 4; j++) {
const cell = document.getElementById(`cell-${i}-${j}`);
const value = this.grid[i][j];
cell.className = 'grid-cell' + (value ? ` tile tile-${value}` : '');
cell.textContent = value || '';
}
}
document.getElementById('score').textContent = this.score;
}
move(direction) {
let moved = false;
const oldGrid = JSON.stringify(this.grid);
switch(direction) {
case 'left':
moved = this.moveLeft();
break;
case 'right':
moved = this.moveRight();
break;
case 'up':
moved = this.moveUp();
break;
case 'down':
moved = this.moveDown();
break;
}
if (moved) {
this.addNewTile();
this.updateDisplay();
if (this.isGameOver()) {
alert('Game Over!');
}
}
}
moveLeft() {
let moved = false;
for (let i = 0; i < 4; i++) {
let row = this.grid[i].filter(cell => cell !== 0);
for (let j = 0; j < row.length - 1; j++) {
if (row[j] === row[j + 1]) {
row[j] *= 2;
this.score += row[j];
row.splice(j + 1, 1);
moved = true;
}
}
while (row.length < 4) {
row.push(0);
}
if (row.join(',') !== this.grid[i].join(',')) {
moved = true;
}
this.grid[i] = row;
}
return moved;
}
moveRight() {
let moved = false;
for (let i = 0; i < 4; i++) {
let row = this.grid[i].filter(cell => cell !== 0);
for (let j = row.length - 1; j > 0; j--) {
if (row[j] === row[j - 1]) {
row[j] *= 2;
this.score += row[j];
row.splice(j - 1, 1);
row.unshift(0);
moved = true;
}
}
while (row.length < 4) {
row.unshift(0);
}
if (row.join(',') !== this.grid[i].join(',')) {
moved = true;
}
this.grid[i] = row;
}
return moved;
}
moveUp() {
let moved = false;
for (let j = 0; j < 4; j++) {
let column = [];
for (let i = 0; i < 4; i++) {
column.push(this.grid[i][j]);
}
column = column.filter(cell => cell !== 0);
for (let i = 0; i < column.length - 1; i++) {
if (column[i] === column[i + 1]) {
column[i] *= 2;
this.score += column[i];
column.splice(i + 1, 1);
moved = true;
}
}
while (column.length < 4) {
column.push(0);
}
for (let i = 0; i < 4; i++) {
if (this.grid[i][j] !== column[i]) {
moved = true;
}
this.grid[i][j] = column[i];
}
}
return moved;
}
moveDown() {
let moved = false;
for (let j = 0; j < 4; j++) {
let column = [];
for (let i = 0; i < 4; i++) {
column.push(this.grid[i][j]);
}
column = column.filter(cell => cell !== 0);
for (let i = column.length - 1; i > 0; i--) {
if (column[i] === column[i - 1]) {
column[i] *= 2;
this.score += column[i];
column.splice(i - 1, 1);
column.unshift(0);
moved = true;
}
}
while (column.length < 4) {
column.unshift(0);
}
for (let i = 0; i < 4; i++) {
if (this.grid[i][j] !== column[i]) {
moved = true;
}
this.grid[i][j] = column[i];
}
}
return moved;
}
isGameOver() {
// Check for empty cells
for (let i = 0; i < 4; i++) {
for (let j = 0; j < 4; j++) {
if (this.grid[i][j] === 0) {
return false;
}
}
}
// Check for possible merges
for (let i = 0; i < 4; i++) {
for (let j = 0; j < 4; j++) {
if (j < 3 && this.grid[i][j] === this.grid[i][j + 1]) return false;
if (i < 3 && this.grid[i][j] === this.grid[i + 1][j]) return false;
}
}
return true;
}
}
// Initialize game
let game = new Game();
// Event listeners
document.addEventListener('keydown', (event) => {
switch(event.key) {
case 'ArrowLeft':
game.move('left');
break;
case 'ArrowRight':
game.move('right');
break;
case 'ArrowUp':
game.move('up');
break;
case 'ArrowDown':
game.move('down');
break;
}
});
document.getElementById('new-game').addEventListener('click', () => {
game = new Game();
});