Skip to content

Latest commit

 

History

History
131 lines (109 loc) · 4.27 KB

2048-gen.md

File metadata and controls

131 lines (109 loc) · 4.27 KB

CSS

All the CSS.

* { margin:0; padding:0; box-sizing:border-box }
body { display:flex; flex-direction:column; justify-content:center; align-items:center; background:#bbada0; font-family:Arial, sans-serif }
h1 { color:#776e65; text-align:center; margin:20px 0; font-size:60px }
#game { display:grid; grid-template-columns:repeat(4, 1fr); grid-template-rows:repeat(4, 1fr); gap:10px; width:500px; height:500px; background:#bbada0; padding:10px; box-shadow:0 0 40px rgba(0, 0, 0, 0.5); margin:0 auto }
.tile { display:flex; justify-content:center; align-items:center; background:#cdc1b4; font-weight:bold; font-size:55px; color:#f9f6f2 }
.tile.tile-empty { background:#cdc1b4; color:transparent }
.tile.tile-1 { background:#eee4da; color:#81a8b5 }
.tile.tile-2 { background:#ede0c8; color:#81a8b5 }
.tile.tile-3 { background:#f2b179 }
.tile.tile-4 { background:#f59563 }
.tile.tile-5 { background:#f67c5f }
.tile.tile-6 { background:#f65e3b }
.tile.tile-7 { background:#edcf72 }
.tile.tile-8 { background:#edcc61 }
.tile.tile-9 { background:#edc850 }
.tile.tile-10 { background:#edc53f; font-size:45px }
.tile.tile-11 { background:#edc22e; font-size:45px }
.tile.tile-12 { background:#3c3a32; font-size:45px }
.tile.tile-13 { background:#3c3a32; font-size:45px }
.tile.tile-14 { background:#3c3a32; font-size:36px }
.tile.tile-15 { background:#3c3a32; font-size:36px }
.tile.tile-16 { background:#3c3a32; font-size:36px }
.tile.tile-17 { background:#3c3a32; font-size:30px }

JS

All the game implementation. Note that the formatting is not consistent, as each function is generated separately by the LLM. If you care about this, you can use a code formatter, but you might be too busy implementing new features.

function setup_game() {
  let game = new Array(16).fill(0);
  let randomIndices = [];
  while(randomIndices.length < 2) {
    let r = Math.floor(Math.random() * 16);
    if(randomIndices.indexOf(r) === -1) randomIndices.push(r);
  }
  randomIndices.forEach(index => {
    game[index] = Math.random() < 0.9 ? 1 : 2;
  });
  return game;
}

function board(arr) {
  return arr.map(val => `<div class="tile ${val ? `tile-${val}` : 'tile-empty'}">${val ? 2 ** val : ''}</div>`).join('');
}

function handle_move_4cell(cells) {
    // Slide non-zero cells to the front
    let result = cells.filter(val => val > 0);
    result = [...result, ...Array(4 - result.length).fill(0)];

    // Merge adjacent cells if they are equal
    for (let i = 0; i < 3; i++) {
        if (result[i] !== 0 && result[i] === result[i + 1]) {
            result[i]++;
            result[i + 1] = 0;
        }
    }

    // Slide again after merge
    result = result.filter(val => val > 0);
    result = [...result, ...Array(4 - result.length).fill(0)];

    return result;
}

function game_update(board, direction) {
    let newBoard = Array(16).fill(0);
    let indices = {
        u: [[0, 4, 8, 12], [1, 5, 9, 13], [2, 6, 10, 14], [3, 7, 11, 15]],
        d: [[12, 8, 4, 0], [13, 9, 5, 1], [14, 10, 6, 2], [15, 11, 7, 3]],
        l: [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11], [12, 13, 14, 15]],
        r: [[3, 2, 1, 0], [7, 6, 5, 4], [11, 10, 9, 8], [15, 14, 13, 12]]
    };

    indices[direction].forEach((group, index) => {
        const values = group.map(i => board[i]);
        const moved = handle_move_4cell(values);
        moved.forEach((value, i) => {
            newBoard[group[i]] = value;
        });
    });

    return add_new_tile(board, newBoard);
}

function add_new_tile(boardBefore, boardAfter) {
  if (boardBefore.join() === boardAfter.join()) return boardAfter;

  let emptyIndices = [];
  boardAfter.forEach((val, idx) => {
    if (val === 0) emptyIndices.push(idx);
  });

  let newIndex = emptyIndices[Math.floor(Math.random() * emptyIndices.length)];
  boardAfter[newIndex] = Math.random() < 0.9 ? 1 : 2;

  return boardAfter;
}

let gameState = setup_game();

function updateDisplay() {
  document.getElementById('game').innerHTML = board(gameState);
}

updateDisplay();

document.addEventListener('keydown', function(event) {
  let move = '';
  switch (event.key) {
    case 'ArrowUp': move = 'u'; break;
    case 'ArrowDown': move = 'd'; break;
    case 'ArrowLeft': move = 'l'; break;
    case 'ArrowRight': move = 'r'; break;
  }
  if (move) {
    gameState = game_update(gameState, move);
    updateDisplay();
  }
});