Untitled

mail@pastecode.io avatarunknown
plain_text
2 months ago
23 kB
1
Indexable
Never
document.addEventListener('DOMContentLoaded', () => {
  var container = document.getElementById("container");
  for (var i = 1; i <= 210; i++) {
    var div = document.createElement("div");
    div.textContent = "";
    container.appendChild(div);
    if (i >= 201) {
      div.classList.add('taken');
    }
  }
  var nextContainer = document.getElementById("nextContainer");
  for (var i = 1; i <= 16; i++) {
    var divNext = document.createElement("div");
    divNext.textContent = "";
    nextContainer.appendChild(divNext);
  }

  const colors = [
    'orange',
    'red',
    'purple',
    'green',
    'blue',
    'cyan',
    'yellow'
  ]

  const grid = document.querySelector('.grid')
  const scoreDisplay = document.querySelector('#score');
  const startBtn = document.querySelector('#start-button');
  const restartBtnGameOver = document.querySelector('#over-restart-button');
  const restartBtn = document.querySelector('#paused-restart-button');
  const submitNameButton = document.getElementById("submit-name-button");
  const nameInput = document.getElementById("name-input");
  const timercontainer = document.getElementById('timer');
  const minutes = document.getElementById('minutes');
  const seconds = document.getElementById('seconds');
  const finalScoreElement = document.getElementById('final-score');
  const continueBtn = document.getElementById('paused-continue-button');
  const scoresPerPage = 10;
  const previousPageBtn = document.getElementById("previous-page-btn");
  const nextPageBtn = document.getElementById("next-page-btn");
  const width = 10

  let squares = Array.from(document.querySelectorAll('.grid div'))
  let submittedName = "";
  let nextRandom = 0
  let score = "0"
  let isGamePaused = true;
  let newNext = false;
  let animationFrameId;
  let timerInterval = 0
  let scoreJSON = [];
  let totalPages = 0;
  let currentPage = 1;

  var sec = 0
  var scoreJSONlength = 0;

  const lTetromino = [
    [1, width + 1, width * 2 + 1, 2],
    [width, width + 1, width + 2, width * 2 + 2],
    [1, width + 1, width * 2 + 1, width * 2],
    [width, width * 2, width * 2 + 1, width * 2 + 2]
  ]

  const reverseLTetromino = [
    [0, 1, width + 1, width * 2 + 1],
    [width, width + 1, width + 2, 2],
    [1, width + 1, width * 2 + 1, width * 2 + 2],
    [width, width + 1, width + 2, width * 2]
  ];

  const zTetromino = [
    [0, width, width + 1, width * 2 + 1],
    [width + 1, width + 2, width * 2, width * 2 + 1],
    [0, width, width + 1, width * 2 + 1],
    [width + 1, width + 2, width * 2, width * 2 + 1]
  ]

  const tTetromino = [
    [1, width, width + 1, width + 2],
    [1, width + 1, width + 2, width * 2 + 1],
    [width, width + 1, width + 2, width * 2 + 1],
    [1, width, width + 1, width * 2 + 1]
  ]

  const oTetromino = [
    [0, 1, width, width + 1],
    [0, 1, width, width + 1],
    [0, 1, width, width + 1],
    [0, 1, width, width + 1]
  ]

  const iTetromino = [
    [1, width + 1, width * 2 + 1, width * 3 + 1],
    [width, width + 1, width + 2, width + 3],
    [1, width + 1, width * 2 + 1, width * 3 + 1],
    [width, width + 1, width + 2, width + 3]
  ]

  const sTetromino = [
    [0, 1, width + 1, width + 2],
    [1, width + 1, width, width * 2],
    [0, 1, width + 1, width + 2],
    [1, width + 1, width, width * 2]
  ];


  const tetrominoes = [lTetromino, reverseLTetromino, zTetromino, tTetromino, oTetromino, iTetromino, sTetromino]

  let currentPosition = 4
  let currentRotation = 0

  function generateRandom(min = 0, max = 7) {

    // find diff
    let difference = max - min;

    // generate random number 
    let rand = Math.random();

    // multiply with difference 
    rand = Math.floor(rand * difference);

    // add with min value 
    rand = rand + min;

    return rand;
  }

  let x = generateRandom()

  let current = tetrominoes[x][currentRotation]

  var jsonData = {};

  async function getJSON() {
    const response = await fetch("http://localhost:8000/displayscore")
    scoreJSON = await response.json();
    scoreJSONlength = scoreJSON.length
    totalPages = Math.ceil(scoreJSONlength / scoresPerPage);
    formatJSON(scoreJSON)

  }

  function displayScores(page) {
    const startIndex = (page - 1) * scoresPerPage; // Calculate the start index for the current page
    const endIndex = startIndex + scoresPerPage; // Calculate the end index for the current page
    const currentPageScores = scoreJSON.slice(startIndex, endIndex); // Get the scores for the current page

    getJSON(currentPageScores); // Display the scores on the page
  }

  previousPageBtn.addEventListener('click', () => {
    if (currentPage > 1) {
      currentPage--; // Update current page
      displayScores(currentPage); // Display scores for the updated page
      updatePaginationButtons(); // Update pagination buttons
    }
  });

  // Event listener for next page button
  nextPageBtn.addEventListener('click', () => {
    if (currentPage < totalPages) {
      currentPage++; // Update current page
      displayScores(currentPage); // Display scores for the updated page
      updatePaginationButtons(); // Update pagination buttons
    }
  });

  // Display scores for the initial page
  displayScores(currentPage);
  updatePaginationButtons();

  function updatePaginationButtons() {
    // Enable/disable previous page button based on the current page
    if (currentPage === 1) {
      previousPageBtn.disabled = true;
    } else {
      previousPageBtn.disabled = false;
    }

    // Enable/disable next page button based on the current page
    if (currentPage === totalPages) {
      nextPageBtn.disabled = true;
    } else {
      nextPageBtn.disabled = false;
    }
  }



  function formatJSON(scoreJSON) {

    // Calculate the start and end indices of the scores to display based on the current page
    const startIndex = (currentPage - 1) * scoresPerPage;
    const endIndex = startIndex + scoresPerPage;

    var tableBody = document.getElementById("table_body");
    tableBody.innerHTML = ""; // Clear the previous content of the table body

    // Sort the scores based on score and time
    scoreJSON.sort((a, b) => {
      if (a.Score === b.Score) {
        // If scores are equal, compare the times
        return a.Time.localeCompare(b.Time);
      }
      // Sort by score in descending order
      return b.Score - a.Score;
    });

    // Iterate over the scores within the current page range and create table rows
    for (var j = startIndex; j < Math.min(endIndex, scoreJSON.length); j++) {
      var score = scoreJSON[j];

      // Create a row for each score
      var row = document.createElement("tr");

      // Create cells for each property of the score
      var rankCell = document.createElement("td");
      rankCell.textContent = score.Rank;

      var nameCell = document.createElement("td");
      nameCell.textContent = score.Name;

      var scoreCell = document.createElement("td");
      scoreCell.textContent = score.Score;

      var timeCell = document.createElement("td");
      timeCell.textContent = score.Time;

      // Append cells to the row
      row.appendChild(rankCell);
      row.appendChild(nameCell);
      row.appendChild(scoreCell);
      row.appendChild(timeCell);

      // Append the row to the table body
      tableBody.appendChild(row);

      var rows = tableBody.getElementsByTagName("tr");
      for (var i = 0; i < rows.length; i++) {
        rows[i].getElementsByTagName("td")[0].textContent = startIndex + i + 1;
      }
    }
  }


  submitNameButton.addEventListener("click", async (event) => {
    event.preventDefault();
    const name = nameInput.value.trim();
    if (name !== "") {
      const jsonData = {}; // Declare jsonData locally
  
      submittedName = name;
      nameInput.disabled = true;
      submitNameButton.disabled = true;
      jsonData.ID = (scoreJSONlength + 2).toString();
      jsonData.Rank = scoreJSONlength + 2;
      jsonData.Name = submittedName;
      jsonData.Score = score;
      jsonData.Time = minutes.innerHTML + seconds.innerHTML;
      console.log(jsonData);
  
      // Call the function to submit the JSON data
      await submitJSON(jsonData); // Pass the jsonData to the submitJSON function
    }
  });

  async function submitJSON(data) {
    const url = "http://localhost:8000/submitscore";
    const fetchOptions = {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify(data),

    };
    console.log(fetchOptions.body);
    console.log(jsonData);
    try {
      const response = await fetch(url, fetchOptions);
      const result = await response.json();

      console.log(result);

    } catch (error) {
      console.error("Error submitting JSON:", error);
    }
    getJSON();
  }

  function draw() {
    undraw();

    current.forEach(index => {
      squares[currentPosition + index].classList.add('tetromino')
      squares[currentPosition + index].style.backgroundColor = colors[x]
    })
  }

  //undraw the Tetromino
  function undraw() {
    current.forEach(index => {
      squares[currentPosition + index].classList.remove('tetromino')
      squares[currentPosition + index].style.backgroundColor = ''

    })
  }

  /* setInterval(moveDown, 500) */

  function moveDown() {
    if (isGamePaused) return;
    if (!current.some(index => squares[currentPosition + index + width].classList.contains('taken'))) {
      undraw();
      currentPosition += width;
      draw();
    } else {
       // Check the top rows before freezing the tetromino
      freeze();
      checkTopRows();
    }
  }




  function freeze() {
    if (current.some(index => {
      const nextPosition = currentPosition + index + width;
      return squares[nextPosition].classList.contains('taken');
    })) {
      current.forEach(index => squares[currentPosition + index].classList.add('taken'));
      x = nextRandom
      nextRandom = generateRandom()
      currentRotation = 0;
      current = tetrominoes[x][currentRotation];
      currentPosition = 4;

      addScore()

      draw();
      newNext = false;



      if (current.some(index => squares[currentPosition + index].classList.contains('taken'))) {
        gameOver();
      } else {
        displayNext();
      }

      
    }
  }


  function moveLeft() {
    if (isGamePaused) return;
    undraw();
    if (!current.some(index => (currentPosition + index) % width === 0) && !current.some(index => squares[currentPosition + index - 1].classList.contains('taken'))) {
      currentPosition -= 1;
    }
    draw();
  }

  function moveRight() {
    if (isGamePaused) return;
    undraw();
    if (!current.some(index => (currentPosition + index) % width === width - 1) && !current.some(index => squares[currentPosition + index + 1].classList.contains('taken'))) {
      currentPosition += 1;
    }
    draw();
  }


  function rotate() {
    if (isGamePaused) return;
  
    undraw();
  
    const nextRotation = (currentRotation + 1) % current.length; // Calculate the next rotation index
  
    // Create a temporary copy of the tetromino with the next rotation
    const tempTetromino = tetrominoes[x][nextRotation];
    let tempPosition = currentPosition;
    checkRotatedPosition(tempPosition, nextRotation);
  
    // Check if the temporary tetromino position is valid
    if (!tempTetromino.some(index => {
      const nextPosition = currentPosition + index;
      return (
        nextPosition < 0 || // Check if it's out of bounds on the left side
        nextPosition >= squares.length || // Check if it's out of bounds on the right side
        squares[nextPosition].classList.contains('taken') // Check if it collides with a taken cell
      );
    })) {
      currentRotation = nextRotation;
      current = tempTetromino;
    }
  
    draw();
    freeze();
  }
  

  const displaySquares = document.querySelectorAll('.nextUp div')
  const displayWidth = 4
  let displayIndex = 0


  // Järjekord loeb
  const upNextTetrominoes = [
    [1, displayWidth + 1, displayWidth * 2 + 1, 2],
    [0, 1, displayWidth + 1, displayWidth * 2 + 1],
    [0, displayWidth, displayWidth + 1, displayWidth * 2 + 1],
    [1, displayWidth, displayWidth + 1, displayWidth + 2],
    [0, 1, displayWidth, displayWidth + 1],
    [1, displayWidth + 1, displayWidth * 2 + 1, displayWidth * 3 + 1],
    [0, 1, displayWidth + 1, displayWidth + 2]
  ]

  function displayNext() {
    if (!newNext) {
      displaySquares.forEach(square => {
        square.classList.remove('tetromino')
        square.style.backgroundColor = ''
      })
      upNextTetrominoes[nextRandom].forEach(index => {
        displaySquares[displayIndex + index].classList.add('tetromino')
        displaySquares[displayIndex + index].style.backgroundColor = colors[nextRandom]
      })
      newNext = true;
    }
  }

  let animationTimeout;
  let gameStart = true;

  function debounce(delay, func) {
    let timeoutId;
    return function (...args) {
      clearTimeout(timeoutId);
      timeoutId = setTimeout(() => func.apply(this, args), delay);
    };
  }

  function clearAnimationTimeout() {
    clearTimeout(animationTimeout);
    animationTimeout = null;
  }

  function startBtnClick() {
    // Pausing the game
    if (animationFrameId) {
      cancelAnimationFrame(animationFrameId);
      animationFrameId = null;
      clearAnimationTimeout();
      isGamePaused = true;
      document.getElementById('paused').style.display = 'block';
      document.getElementById('start-button').style.display = 'none';
    } else {
      if (gameStart) {
        // Starts the countdown for the game when it is first run
        gameStart = false;
        document.getElementById('paused').style.display = 'block';
        countDownUnpause();
      }
      else {
        // Start the countdown on when unpausing
        countDownUnpause();
        
      }
    }
  }

  function countDownUnpause() {
    let count = 3;
    const countdownTimer = document.getElementById('countdownTimer');
    const countdownContainer = document.getElementById('countdownContainer');
    const pauseContainer = document.getElementById('pauseContainer');

    countdownContainer.style.display = 'flex';
    pauseContainer.style.display = 'none';

    const countdownInterval = setInterval(() => {
      count--;
      countdownTimer.innerHTML = count;
      if (count === 0) {
        clearInterval(countdownInterval);
        countdownContainer.style.display = 'none';
        pauseContainer.style.display = 'block';
        startGameLoop();
        firstClick = false;
        document.getElementById('start-button').style.display = 'block'; // Reset the firstClick flag after the countdown finishes
      }
    }, 1000);
  }

  function startGameLoop() {
    isGamePaused = false;
    document.getElementById("countdownTimer").innerHTML = "3";
    // Other game setup code
    timer();
    //draw();
    document.getElementById('paused').style.display = 'none';
    document.getElementById('timer').style.display = 'block'; // Show the timer
    nextRandom = generateRandom();
    displayNext(); // Show the next tetromino immediately

    let previousTimestamp = 0;
    animationFrameId = requestAnimationFrame((timestamp) =>
      moveDownLoop(timestamp, previousTimestamp)
    );
  }



  // Add a debounced version of the startBtnClick function
  const debouncedStartBtnClick = debounce(400, startBtnClick);

  startBtn.addEventListener('click', debouncedStartBtnClick);
  continueBtn.addEventListener('click', debouncedStartBtnClick);


  function moveDownLoop(timestamp, previousTimestamp) {
    if (!isGamePaused) {
      if (timestamp - previousTimestamp >= 500) { // Adjust the delay duration here (in milliseconds)
        moveDown();
        draw();
        previousTimestamp = timestamp;
      }
      animationFrameId = requestAnimationFrame(newTimestamp => moveDownLoop(newTimestamp, previousTimestamp));
    }
  }

  timercontainer.style.display = 'block'; // Show the timer
  seconds.innerHTML = '00';
  minutes.innerHTML = '00:';
  scoreDisplay.innerHTML = '0';

  function timer() {
    clearInterval(timerInterval);

    function pad(val) {
      return val > 9 ? val : "0" + val;
    }

    document.getElementById("seconds").innerHTML = pad(sec % 60);
    document.getElementById("minutes").innerHTML = pad(parseInt(sec / 60, 10)) + ":";

    timerInterval = setInterval(function () {
      if (!isGamePaused) {
        document.getElementById("seconds").innerHTML = pad(++sec % 60);
        document.getElementById("minutes").innerHTML = pad(parseInt(sec / 60, 10)) + ":";
      }
    }, 1000);
  }

  function gameOver() {
    if (current.some(index => squares[currentPosition + index].classList.contains('taken'))) {
      scoreDisplay.innerHTML = 'Game Over'
      getJSON();
      finalScoreElement.innerHTML += score
      cancelAnimationFrame(animationFrameId)
      document.getElementById('game-over').style.display = 'block';
      document.getElementById('start-button').style.display = 'none';
      isGamePaused = true;
      for (let i = 0; i < squares.length - width; i++) {
        squares[i].classList.remove('tetromino');
        squares[i].classList.remove('taken');
        squares[i].style.backgroundColor = ''
      }
      displaySquares.forEach(square => {
        square.classList.remove('tetromino')
        square.style.backgroundColor = ''
      })
    
  }
}
  restartBtnGameOver.addEventListener('click', restartGame);
  restartBtn.addEventListener('click', restartGame);

  function restartGame() {
    Restarter();
    newNext = false;
    document.getElementById('start-button').style.display = 'block';
  }


  function Restarter() {
    currentPage = 1;
    updatePaginationButtons();
    nameInput.disabled = false;
    submitNameButton.disabled = false;
    score = 0;
    sec = 0;
    minutes.innerHTML = "00:";
    seconds.innerHTML = "00";
    finalScoreElement.innerHTML = "Final Score: ";
    for (let i = 0; i < squares.length - width; i++) {
      squares[i].classList.remove('tetromino');
      squares[i].classList.remove('taken');
      squares[i].style.backgroundColor = ''
      document.getElementById('paused').style.display = 'none';
      document.getElementById('game-over').style.display = 'none';
      startBtn.addEventListener('click', debouncedStartBtnClick);
      gameStart = true;
    }
    score = 0;
    scoreDisplay.textContent = score;
    currentPosition = 4;
    currentRotation = 0;
    x = generateRandom();
    current = tetrominoes[x][currentRotation];
    isGamePaused = true;
    cancelAnimationFrame(animationFrameId);
    animationFrameId = null;
  }

  function isAtRight() {
    return current.some(index => (currentPosition + index + 1) % width === 0)
  }

  function isAtLeft() {
    return current.some(index => (currentPosition + index) % width === 0)
  }

  function checkRotatedPosition(P, rotation) {
    P = currentPosition; // Assign the current position to P
    const currentWidth = current.some(index => (P + index) % width === 0);
  
    // Calculate the width of the rotated tetromino
    const rotatedWidth = tetrominoes[x][rotation].some(index => (P + index) % width === 0);
  
    // Check if the tetromino is too close to the left or right edge after rotation
    if (current.some(index => (P + index + 1) % width === 0)) {
      if (isAtRight() && rotatedWidth) {
        currentPosition -= 1;
      }
    } else if (current.some(index => (P + index) % width === width - 1)) {
      if (isAtLeft() && rotatedWidth) {
        currentPosition += 1;
      }
    } else if (current.some(index => (P + index) % width === 0)) {
      if (isAtRight() && rotatedWidth) {
        currentPosition -= 1;
      } else if (isAtLeft() && rotatedWidth) {
        currentPosition += 1;
      }
    }
  
    // Check if the rotated tetromino overlaps with a taken cell
    const tempTetromino = tetrominoes[x][rotation];
    const tempPosition = currentPosition;
    let overlapsTakenCell = false;
  
    tempTetromino.forEach(index => {
      const nextPosition = tempPosition + index;
      if (
        nextPosition < 0 ||
        nextPosition >= squares.length ||
        squares[nextPosition].classList.contains('taken')
      ) {
        overlapsTakenCell = true;
      }
    });
  
    // If there's an overlap, shift the tetromino back toward the wall
    if (overlapsTakenCell) {
      if (rotatedWidth) {
        currentPosition -= 1;
      } else {
        currentPosition += 1;
      }
    }
  }
  

  function checkTopRows() {
    for (let row = 0; row <= 2; row++) {
      for (let col = 3; col <= 5; col++) {
        const index = row * 10 + col;
        if (squares[index].classList.contains('taken')) {
          // The specified rows and cells have taken cells, game over or other action can be taken
          // ...
          return true; // Exit the function if any taken cell is found
        }

      }
    }
    return false;

    // The top rows are clear, another tetromino can be placed there
    // ...
  }

  setInterval(checkTopRows, 1000);

  function addScore() {
    let counter = 0;
    let currentScore = 0;

    for (let i = 0; i < 199; i += width) {
      const row = [i, i + 1, i + 2, i + 3, i + 4, i + 5, i + 6, i + 7, i + 8, i + 9];

      if (row.every(index => squares[index].classList.contains('taken'))) {
        counter++;
        row.forEach(index => {
          squares[index].classList.remove('taken');
          squares[index].classList.remove('tetromino');
          squares[index].style.backgroundColor = '';
        });
        currentScore += 10;

        const squaresRemoved = squares.splice(i, width);
        squares = squaresRemoved.concat(squares);
        squares.forEach(cell => {
          grid.appendChild(cell);
        });
      }
    }

    if (counter === 4) {
      currentScore *= 2;
    }
    if (currentScore !== 0) {
      score = parseInt(score) + currentScore;
    }

    scoreDisplay.innerHTML = parseInt(score); // Convert score to number before displaying
  }



  function control(e) {
    if (e.keyCode === 37) {
      moveLeft()
    } else if (e.keyCode === 39) {
      moveRight()
    } else if (e.keyCode === 40) {
      moveDown()
    } else if (e.keyCode === 38) {
      rotate()
    }
  }
  document.addEventListener('keydown', control)



})