<commit_before>/* eslint { indent: 0 } */
import BaseModel from "Models/BaseModel";
import Matrix from "./Matrix";

import cloneDeep from "lodash.clonedeep";
import { slFetch } from "saylua-fetch";

const LB_FPS = 60;
const LB_MIN_TIMEOUT = 10;
const LB_PIECES = [[0, 1, 0, 0, // i
                    0, 1, 0, 0,
                    0, 1, 0, 0,
                    0, 1, 0, 0],

                   [0, 0, 2, 0, // j
                    0, 0, 2, 0,
                    0, 2, 2, 0,
                    0, 0, 0, 0],

                   [0, 3, 0, 0, // l
                    0, 3, 0, 0,
                    0, 3, 3, 0,
                    0, 0, 0, 0],

                   [0, 0, 0, 0, // o
                    0, 4, 4, 0,
                    0, 4, 4, 0,
                    0, 0, 0, 0],

                   [0, 0, 0, 0, // t
                    5, 5, 5, 0,
                    0, 5, 0, 0,
                    0, 0, 0, 0],

                   [0, 0, 0, 0, // s
                    0, 6, 6, 0,
                    6, 6, 0, 0,
                    0, 0, 0, 0],

                   [0, 0, 0, 0, // z
                    7, 7, 0, 0,
                    0, 7, 7, 0,
                    0, 0, 0, 0]];

// GameState
// --------------------------------------
// Keeps track of the player's current tetris state.

export default class GameState extends BaseModel {
  constructor() {
    super();
    this.gameId = document.querySelector('meta[name="arcade-game-id"]').content;
  }

  clearGameState() {
    this.frames = 0;
    this.lastDrop = 0;
    this.timeout = 800;
    this.gameOver = false;
    this.paused = false;
    this.canDrop = true;
    this.keyState = {};
    this.fast = false;
    this.score = 0;
    this.gameMatrix = new Matrix(18, 10);
    this.placedPieces = new Matrix(18, 10);
    this.nextPiece = null;
    this.piece = {"matrix": new Matrix(4, 4), "r": -3, "c": 2};

    this.gameLog = [];
    this.scoreSent = false;

    clearInterval(this.timer);
  }

  start() {
    this.clearGameState();
    this.getNextPiece();

    this.startTime = new Date().getTime();
    this.timer = setInterval(this.timeStep.bind(this), 1000 / LB_FPS);
  }

  isRunning() {
    return this.timer && !(this.gameOver || this.paused);
  }

  checkGameOver() {
    // If the first row has any pieces, there is a game over.
    let matrix = this.placedPieces;
    for (let i = 0; i < matrix.width; i++) {
      if (matrix.get(0, i)) return true;
    }
    return false;
  }

  endGame() {
    this.piece = null;
    this.gameOver = true;

    let game = this;

    slFetch('/api/arcade/score/' + this.gameId + '/', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      credentials: 'include',
      body: JSON.stringify({
        score: this.score,
        startTime: this.startTime,
        gameLog: this.gameLog,
        frames: this.frames
      })
    }).then((response) => {
      if (response.ok) {
        return response.json();
      }
      console.error('Sending score failed!'); // eslint-disable-line no-console
    }).then((json) => {
      // TODO: Actually use the response. Retry this on failure.
      game.scoreSent = true;
      game.triggerUpdate();
    });

    this.triggerUpdate();
  }

  timeStep() {
    if (!this.isRunning()) return;

    this.frames++;

    let timeout = this.timeout;
    // TODO: handle keys here
    if (this.keyState[13] || this.keyState[80]) {
      this.pause();
    }
    if (this.keyState[32]) {
      this.drop();
    }
    if (this.keyState[38] || this.keyState[87]) {
      this.rotate();
    }
    if (this.fast && this.canDrop) {<commit_msg>Finished basic bloxie controls, currently way too fast.<commit_after>/* eslint { indent: 0 } */
import BaseModel from "Models/BaseModel";
import Matrix from "./Matrix";

import cloneDeep from "lodash.clonedeep";
import { slFetch } from "saylua-fetch";

const LB_FPS = 60;
const LB_MIN_TIMEOUT = 10;
const LB_PIECES = [[0, 1, 0, 0, // i
                    0, 1, 0, 0,
                    0, 1, 0, 0,
                    0, 1, 0, 0],

                   [0, 0, 2, 0, // j
                    0, 0, 2, 0,
                    0, 2, 2, 0,
                    0, 0, 0, 0],

                   [0, 3, 0, 0, // l
                    0, 3, 0, 0,
                    0, 3, 3, 0,
                    0, 0, 0, 0],

                   [0, 0, 0, 0, // o
                    0, 4, 4, 0,
                    0, 4, 4, 0,
                    0, 0, 0, 0],

                   [0, 0, 0, 0, // t
                    5, 5, 5, 0,
                    0, 5, 0, 0,
                    0, 0, 0, 0],

                   [0, 0, 0, 0, // s
                    0, 6, 6, 0,
                    6, 6, 0, 0,
                    0, 0, 0, 0],

                   [0, 0, 0, 0, // z
                    7, 7, 0, 0,
                    0, 7, 7, 0,
                    0, 0, 0, 0]];

// GameState
// --------------------------------------
// Keeps track of the player's current tetris state.

export default class GameState extends BaseModel {
  constructor() {
    super();
    this.gameId = document.querySelector('meta[name="arcade-game-id"]').content;
  }

  clearGameState() {
    this.frames = 0;
    this.lastDrop = 0;
    this.timeout = 800;
    this.gameOver = false;
    this.paused = false;
    this.canDrop = true;
    this.keyState = {};
    this.fast = false;
    this.score = 0;
    this.gameMatrix = new Matrix(18, 10);
    this.placedPieces = new Matrix(18, 10);
    this.nextPiece = null;
    this.piece = {"matrix": new Matrix(4, 4), "r": -3, "c": 2};

    this.gameLog = [];
    this.scoreSent = false;

    clearInterval(this.timer);
  }

  start() {
    this.clearGameState();
    this.getNextPiece();

    this.startTime = new Date().getTime();
    this.timer = setInterval(this.timeStep.bind(this), 1000 / LB_FPS);
  }

  isRunning() {
    return this.timer && !(this.gameOver || this.paused);
  }

  checkGameOver() {
    // If the first row has any pieces, there is a game over.
    let matrix = this.placedPieces;
    for (let i = 0; i < matrix.width; i++) {
      if (matrix.get(0, i)) return true;
    }
    return false;
  }

  endGame() {
    this.piece = null;
    this.gameOver = true;

    let game = this;

    slFetch('/api/arcade/score/' + this.gameId + '/', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      credentials: 'include',
      body: JSON.stringify({
        score: this.score,
        startTime: this.startTime,
        gameLog: this.gameLog,
        frames: this.frames
      })
    }).then((response) => {
      if (response.ok) {
        return response.json();
      }
      console.error('Sending score failed!'); // eslint-disable-line no-console
    }).then((json) => {
      // TODO: Actually use the response. Retry this on failure.
      game.scoreSent = true;
      game.triggerUpdate();
    });

    this.triggerUpdate();
  }

  timeStep() {
    if (!this.isRunning()) return;

    this.frames++;

    let timeout = this.timeout;
    // TODO: handle keys here
    if (this.keyState[13] || this.keyState[80]) { // Enter, p
      this.pause();
    }
    if (this.keyState[32]) { // Space
      this.drop();
    }
    if (this.keyState[38] || this.keyState[87]) { // Up, w
      this.rotate();
    }
    if (this.keyState[40] || this.keyState[83]) { // Down, s
      this.speedUp();
    }
    if (this.keyState[37] || this.keyState[65]) { // Left, a
      this.moveLeft();
    }
    if (this.keyState[39] || this.keyState[68]) { // Right, d
      this.moveRight();
    }
    if (this.fast && this.canDrop) {
{'fraction_non_alphanumeric': 0.16471670829499147, 'fraction_numerical': 0.0412777704745629, 'mean_word_length': 1.4621359223300971, 'pattern_counts': {'":': 6, '<': 5, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6613818', 'n_tokens_mistral': 2828, 'n_tokens_neox': 2485, 'n_words': 688}