Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URLs added here will be added as <link>s in order, and before the CSS in the editor. You can use the CSS from another Pen by using its URL and the proper URL extension.

+ add another resource

JavaScript

Babel includes JSX processing.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Packages

Add Packages

Search for and use JavaScript packages from npm here. By selecting a package, an import statement will be added to the top of the JavaScript editor for this package.

Behavior

Auto Save

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

Format on Save

If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.

Editor Settings

Code Indentation

Want to change your Syntax Highlighting theme, Fonts and more?

Visit your global Editor Settings.

HTML

              
                <!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>2048</title>
    <link rel="stylesheet" href="style.css" />
    <script src="app.js" charset="utf-8"></script>
  </head>
  <body>
    <h1>2048 Tile Game</h1>
    <div class="score-container">
        <div class="score-title">score</div>
      <span id="score">0</span>
    </div>
    
    <div id="results"></div>
    
    <div class="grid"></div>
    
  </body>
</html>
              
            
!

CSS

              
                h1 {
 text-align: center;
  margiin-top: 2rem;
  margin-bottom: 3rem;
}

.grid {
  display: flex;
  flex-wrap: wrap;
  align-content: space-evenly;
  width: 530px;
  height: 600px;
  background: maroon;
}

/*div inside "grid" div*/
.grid div {
  width: 100px;
  height: 100px;
  background: orange;
  font-size: 60px;
  text-align: center;
  font-weight:bold;
  margin: 1rem;
  
}

.score-container {
  width: 100px;
  height: 100px;
  background: tan;
  border: 10px solid black;
  text-align: center;
  margin-bottom: 2rem;
}

.score-title, #score{
  font-weight: bold;
  font-size: 30px;
  margin: 0.5rem;
}


#results{
 font-size: 30px;
  font-weight: bold;
  margin-bottom: 1rem;
}
              
            
!

JS

              
                //add document event listener
//this puts all the JS code inside the event listener
document.addEventListener("DOMContentLoaded", () => {
  //select our grid so JS can interact with chosen div called "grid"
  const gridDisplay = document.querySelector(".grid");
  //select div with div id = "score"
  const scoreDisplay = document.getElementById("score");
  //select div with div id = "result"
  const resultDisplay = document.getElementById("results");
  //init width of grid with 4
  const width = 4;
  //init squares array
  squares = [];
  //init score
  let score = 0;

  //create a playing board w/ for loop because incrementing each square inside board until filled
  function createBoard() {
    //as long as i < 16, keep looping + 1
    for (let i = 0; i < width * width; i++) {
      //creates a dive called "square" in grid
      square = document.createElement("div");
      //inside square
      square.innerHTML = 0;
      //add square var into grid with appendChild
      gridDisplay.appendChild(square);
      //create square array called "squares" by pushing suqare into array
      squares.push(square);
    }
    //call generate() here
    generate();
    //invoke again to create 2 twice, and won't over lap because it checks to see if there is a 0 first
    generate();
  }
  //create board by running function
  createBoard();

  //generate random number
  function generate() {
    //create a random number using JS method 'Math.random()', and Math.floor to get whole number
    let randomNumber = Math.floor(Math.random() * squares.length);
    //check to see if we can put the #2 in here, by checking if random position has innerHTML=0
    if (squares[randomNumber].innerHTML == 0) {
      //if true, value for random position innerHTML  = 2
      squares[randomNumber].innerHTML = 2;
      //check for loss
      checkForGameOver();
    }
    //if false, run loop again
    else {
      generate();
    }
  }

  //we want all numbers to swipe right
  function moveRight() {
    //need for loop again to loop over grid
    for (let i = 0; i < width * width; i++) {
      //we want numbers to shuffle to right, and need to define row first with modulus
      if (i % 4 === 0) {
        //execute
        let totalOne = squares[i].innerHTML;
        let totalTwo = squares[i + 1].innerHTML;
        let totalThree = squares[i + 2].innerHTML;
        let totalFour = squares[i + 3].innerHTML;
        //create new array called row, and convert from strings to int
        let row = [
          parseInt(totalOne),
          parseInt(totalTwo),
          parseInt(totalThree),
          parseInt(totalFour)
        ];

        //check row value
        //console.log(row);

        //move numbers to right with filter method, pass numbers we want and store as new array to create new row
        let filteredRow = row.filter((num) => num);
        //check to see if filterRow works
        //console.log(filteredRow);

        //fill all elements with 0 that don't have a number by creating new var called "missing" minus length of fitleredRow array
        let missing = 4 - filteredRow.length;
        //create var for 0 to create array for missing var and fill with value=0
        let zeros = Array(missing).fill(0);
        //check zeros
        //console.log(zeros);

        //attach zeros array to filtered array in right order with new var and concat
        //we want zeros first then numbers
        let newRow = zeros.concat(filteredRow);
        //check newRow
        //console.log(newRow)

        //assign new numbers to rows, starting at first index
        squares[i].innerHTML = newRow[0];
        squares[i + 1].innerHTML = newRow[1];
        squares[i + 2].innerHTML = newRow[2];
        squares[i + 3].innerHTML = newRow[3];
      }
    }
  }

  //check function moveRight works, expecting 4 rows of arrays
  //moveRight();

  //we want all numbers to swipe left
  function moveLeft() {
    //need for loop again to loop over grid
    for (let i = 0; i < width * width; i++) {
      //we want numbers to shuffle to right, and need to define row first with modulus
      if (i % 4 === 0) {
        //execute
        let totalOne = squares[i].innerHTML;
        let totalTwo = squares[i + 1].innerHTML;
        let totalThree = squares[i + 2].innerHTML;
        let totalFour = squares[i + 3].innerHTML;
        //create new array called row, and convert from strings to int
        let row = [
          parseInt(totalOne),
          parseInt(totalTwo),
          parseInt(totalThree),
          parseInt(totalFour)
        ];

        //check row value
        //console.log(row);

        //move numbers to right with filter method, pass numbers we want and store as new array to create new row
        let filteredRow = row.filter((num) => num);
        //check to see if filterRow works
        //console.log(filteredRow);

        //fill all elements with 0 that don't have a number by creating new var called "missing" minus length of fitleredRow array
        let missing = 4 - filteredRow.length;
        //create var for 0 to create array for missing var and fill with value=0
        let zeros = Array(missing).fill(0);
        //check zeros
        //console.log(zeros);

        //attach zeros array to filtered array in right order with new var and concat
        //we want zeros first then numbers
        let newRow = filteredRow.concat(zeros);
        //check newRow
        //console.log(newRow)

        //assign new numbers to rows, starting at first index
        squares[i].innerHTML = newRow[0];
        squares[i + 1].innerHTML = newRow[1];
        squares[i + 2].innerHTML = newRow[2];
        squares[i + 3].innerHTML = newRow[3];
      }
    }
  }

  //swipe down
  function moveDown() {
    //for loop over array for column and look for first 4 elements in squares array
    for (let i = 0; i < 4; i++) {
      //each loop, check squares below it for whole column
      let totalOne = squares[i].innerHTML;
      let totalTwo = squares[i + width].innerHTML;
      let totalThree = squares[i + width * 2].innerHTML;
      let totalFour = squares[i + width * 3].innerHTML;
      //create a column made of a new array with the 4 values and convert str to int
      let column = [
        parseInt(totalOne),
        parseInt(totalTwo),
        parseInt(totalThree),
        parseInt(totalFour)
      ];

      //filter column for numbers
      let filteredColumn = column.filter((num) => num);
      //find remaining missing positions by minus 4 from filteredColumn length
      let missing = 4 - filteredColumn.length;
      //create new array for zeros and pass missing position and fill with value 0
      let zeros = Array(missing).fill(0);
      //combine zeros array with filteredCol array, we want numbers to the right
      let newColumn = zeros.concat(filteredColumn);

      //add values of columns to squares of innerHTML
      squares[i].innerHTML = newColumn[0];
      squares[i + width].innerHTML = newColumn[1];
      squares[i + width * 2].innerHTML = newColumn[2];
      squares[i + width * 3].innerHTML = newColumn[3];
    }
  }

  //swipe up
  function moveUp() {
    //for loop over array for column and look for first 4 elements in squares array
    for (let i = 0; i < 4; i++) {
      //each loop, check squares below it for whole column
      let totalOne = squares[i].innerHTML;
      let totalTwo = squares[i + width].innerHTML;
      let totalThree = squares[i + width * 2].innerHTML;
      let totalFour = squares[i + width * 3].innerHTML;
      //create a column made of a new array with the 4 values and convert str to int
      let column = [
        parseInt(totalOne),
        parseInt(totalTwo),
        parseInt(totalThree),
        parseInt(totalFour)
      ];

      //filter column for numbers
      let filteredColumn = column.filter((num) => num);
      //find remaining missing positions by minus 4 from filteredColumn length
      let missing = 4 - filteredColumn.length;
      //create new array for zeros and pass missing position and fill with value 0
      let zeros = Array(missing).fill(0);
      //combine zeros array with filteredCol array, we want numbers to the right
      let newColumn = filteredColumn.concat(zeros);

      //add values of columns to squares of innerHTML
      squares[i].innerHTML = newColumn[0];
      squares[i + width].innerHTML = newColumn[1];
      squares[i + width * 2].innerHTML = newColumn[2];
      squares[i + width * 3].innerHTML = newColumn[3];
    }
  }

  //Now we create the combineRow function
  function combineRow() {
    //loop through another array 15 times bc we don't want to count the last one, does not exist
    for (let i = 0; i < 15; i++) {
      //if square is equal to sq down of next to it
      if (squares[i].innerHTML === squares[i + 1].innerHTML) {
        //if true, they are same and combine and convert from str to int
        let combinedTotal =
          parseInt(squares[i].innerHTML) + parseInt(squares[i + 1].innerHTML);

        //in squares array, pass number we are looping over[i] get into innerHTML and assign a new total
        squares[i].innerHTML = combinedTotal;
        //give next sq down total = 0
        squares[i + 1].innerHTML = 0;
        //add score
        score += combinedTotal;
        //display score
        scoreDisplay.innerHTML = score;
      }
    }
    //check for win
    checkForWin();
  }

  //Now we create the combineColumn function
  function combineColumn() {
    //loop through another array 12 times bc are checking squares below
    for (let i = 0; i < 12; i++) {
      //if square is equal to sq down of next to it
      if (squares[i].innerHTML === squares[i + width].innerHTML) {
        //if true, they are same and combine and convert from str to int
        let combinedTotal =
          parseInt(squares[i].innerHTML) +
          parseInt(squares[i + width].innerHTML);

        //in squares array, pass number we are looping over[i] get into innerHTML and assign a new total
        squares[i].innerHTML = combinedTotal;
        //give next sq down total = 0
        squares[i + width].innerHTML = 0;
        //add score
        score += combinedTotal;
        //display score
        scoreDisplay.innerHTML = score;
      }
    }
    //check for win
    checkForWin();
  }

  //to see if combining, need to assign keycodes, if we press up, down, etc, it should invoke functions
  function control(e) {
    //if keycode is eq to 39, key# for keyboard
    if (e.keyCode === 39) {
      //number will slide right
      keyRight();
    }
    //if keycode is 37
    else if (e.keyCode === 37) {
      //number slides left
      keyLeft();
    }
    //if keycode is 38
    else if (e.keyCode === 38) {
      //number slides up
      keyUp();
    }
    //else keycode is 40
    else if (e.keyCode === 40) {
      //number moves down
      keyDown();
    }
  }
  //need to add event listener for when key pressed
  document.addEventListener("keyup", control);

  //function keyright then add into control function
  function keyRight() {
    //combine moveRight
    moveRight();
    combineRow();
    moveRight();
    generate();
  }

  //function keyLeft then add into control function after keyRight
  function keyLeft() {
    //combine moveLeft
    moveLeft();
    combineRow();
    moveLeft();
    generate();
  }

  //function keyDown
  function keyDown() {
    moveDown();
    combineColumn();
    moveDown();
    generate();
  }

  //function keyUp
  function keyUp() {
    moveUp();
    combineColumn();
    moveUp();
    generate();
  }

  //check function moveRight works, expecting 4 rows of arrays
  //moveLeft();

  //check if win with number 2048, and add function to end of 'combineRow()'and 'combineColumn()'
  function checkForWin() {
    //for loop over squares.length
    for (let i = 0; i < squares.length; i++) {
      //if square innerHTML = 2048
      if (squares[i].innerHTML == 2048) {
        //display win
        resultDisplay.innerHTML = "You Win!";
        //then remove controls by removing event listener for keys
        document.removeEventListener("keyup", control);
      }
    }
  }

  //gameover function, check if there are no 0s on board, add in generate()
  function checkForGameOver() {
    //init zeros value
    let zeros = 0;
    //for loop through board
    for (let i = 0; i < squares.length; i++) {
      //count how many 0s are in grid
      if (squares[i].innerHTML == 0) {
        //count zeros
        zeros++;
      }
    }
    //after loop runs, check if zeros deeply eq 0
    if (zeros === 0) {
      //display you lose
      resultDisplay.innerHTML = "Oh no, you lose!";
      //remove event listener
      document.removeEventListener("keyup", control);
    }
  }
});

              
            
!
999px

Console