<commit_before>var React = require('react'),
  Heading = require('./heading'),
  AboveGame = require('./above-game'),
  GameContainer = require('./game-container'),
  StorageManager = require('./local_storage_manager'),
  KeyboardInputManager = require('./keyboard_input_manager'),
  Grid = require('./grid'),
  Tile = require('./tile').Tile;

var storageManager = new StorageManager();

var Container = React.createClass({
  componentWillMount: function() {
    this.setup();
  },

  componentDidMount: function() {
    this.inputManager = new KeyboardInputManager();
    this.inputManager.on("move", this.move);
    this.inputManager.on("restart", this.restart);
    this.inputManager.on("keepPlaying", this.keepPlaying);
  },

  render: function() {
    return (
      <div className="container">
        <Heading score={this.state.score} best={this.state.best}/>
        <AboveGame/>
        <GameContainer size={this.props.size} tiles={this.state.tiles} won={this.state.won} over={this.state.over}/>
        <p className="game-explanation">
          <strong className="important">How to play:</strong> Use your <strong>arrow keys</strong> to move the tiles. When two tiles with the same number touch, they <strong>merge into one!</strong>
        </p>
        <hr/>
        <p>
          Created by <a href="http://www.emeraldion.it" target="_blank"><NAME></a>. A clone of <a href="https://gabrielecirulli.github.io/2048/" target="_blank">2048</a> by <a href="http://gabrielecirulli.com" target="_blank"><NAME></a> written using <a href="https://facebook.github.io/react" target="_blank">React</a>.
        </p>
      </div>
    );
  },

  getRandomTiles: function() {
    var ret = [];
    for (var i = 0; i < this.props.startTiles; i++) {
      ret.push(this.getRandomTile())
    }
    return ret;
  },

  getRandomTile: function() {
    var value = Math.random() < 0.9 ? 2 : 4;
    var pos = this.grid.randomAvailableCell();
    var tile = new Tile(pos, value);
    this.grid.insertTile(tile);
    return {
      value: value,
      x: pos.x,
      y: pos.y,
      prog: tile.prog
    };
  },

  continueGame: function() {
    this.won = false;
    this.over = false;
    // this.setState({won: this.won, over: this.over});
  },

  restart: function () {
    storageManager.clearGameState();
    this.continueGame(); // Clear the game won/lost message
    this.setup();
  },

  // Keep playing after winning (allows going over 2048)
  keepPlaying: function () {
    this.keepPlaying = true;
    this.continueGame(); // Clear the game won/lost message
  },

  // Return true if the game is lost, or has won and the user hasn't kept playing
  isGameTerminated: function () {
    return this.over || (this.won && !this.keepPlaying);
  },

  // Set up the game
  setup: function () {
    var previousState = storageManager.getGameState();

    // Reload the game from a previous game if present
    if (previousState) {
      this.grid        = new Grid(previousState.grid.size,
                                  previousState.grid.cells); // Reload grid
      this.score       = previousState.score;
      this.over        = previousState.over;
      this.won         = previousState.won;
      this.keepPlaying = previousState.keepPlaying;
    } else {
      this.grid        = new Grid(this.props.size);
      this.score       = 0;
      this.over        = false;
      this.won         = false;
      this.keepPlaying = false;
    }
    this.setState({score: this.score, best: storageManager.getBestScore(), tiles: this.getRandomTiles()});
  },

  // Set up the initial tiles to start the game with
  addStartTiles: function () {
    for (var i = 0; i < this.startTiles; i++) {
      this.addRandomTile();
    }
  },

  // Adds a tile in a random position
  addRandomTile: function () {
    if (this.grid.cellsAvailable()) {
      var value = Math.random() < 0.9 ? 2 : 4;
      var tile = new Tile(this.grid.randomAvailableCell(), value);

      this.grid.insertTile(tile);
    }
  },

  // Sends the updated grid to the actuator
  actuate: function () {
    // Clear the state when the game is over (game over only, not win)
    if (this.over) {
      storageManager.clearGameState();
    } else {
      storageManager.setGameState(this.serialize());
    }

    // this.actuator.actuate(this.grid, {<commit_msg>Solves issue #2<commit_after>var React = require('react'),
  Heading = require('./heading'),
  AboveGame = require('./above-game'),
  GameContainer = require('./game-container'),
  StorageManager = require('./local_storage_manager'),
  KeyboardInputManager = require('./keyboard_input_manager'),
  Grid = require('./grid'),
  Tile = require('./tile').Tile;

var storageManager = new StorageManager();

var Container = React.createClass({
  componentWillMount: function() {
    this.setup();
  },

  componentDidMount: function() {
    this.inputManager = new KeyboardInputManager();
    this.inputManager.on("move", this.move);
    this.inputManager.on("restart", this.restart);
    this.inputManager.on("keepPlaying", this.keepPlaying);
  },

  render: function() {
    return (
      <div className="container">
        <Heading score={this.state.score} best={this.state.best}/>
        <AboveGame/>
        <GameContainer size={this.props.size} tiles={this.state.tiles} won={this.state.won} over={this.state.over}/>
        <p className="game-explanation">
          <strong className="important">How to play:</strong> Use your <strong>arrow keys</strong> to move the tiles. When two tiles with the same number touch, they <strong>merge into one!</strong>
        </p>
        <hr/>
        <p>
          Created by <a href="http://www.emeraldion.it" target="_blank"><NAME></a>. A clone of <a href="https://gabrielecirulli.github.io/2048/" target="_blank">2048</a> by <a href="http://gabrielecirulli.com" target="_blank"><NAME></a> written using <a href="https://facebook.github.io/react" target="_blank">React</a>.
        </p>
      </div>
    );
  },

  getRandomTiles: function() {
    var ret = [];
    for (var i = 0; i < this.props.startTiles; i++) {
      ret.push(this.getRandomTile())
    }
    return ret;
  },

  getRandomTile: function() {
    var value = Math.random() < 0.9 ? 2 : 4;
    var pos = this.grid.randomAvailableCell();
    var tile = new Tile(pos, value);
    this.grid.insertTile(tile);
    return {
      value: value,
      x: pos.x,
      y: pos.y,
      prog: tile.prog
    };
  },

  continueGame: function() {
    this.won = false;
    this.over = false;
    // this.setState({won: this.won, over: this.over});
  },

  restart: function () {
    storageManager.clearGameState();
    this.continueGame(); // Clear the game won/lost message
    this.setup();
  },

  // Keep playing after winning (allows going over 2048)
  keepPlaying: function () {
    this.keepPlaying = true;
    this.continueGame(); // Clear the game won/lost message
  },

  // Return true if the game is lost, or has won and the user hasn't kept playing
  isGameTerminated: function () {
    return this.over || (this.won && !this.keepPlaying);
  },

  // Set up the game
  setup: function () {
    var previousState = storageManager.getGameState();

    // Reload the game from a previous game if present
    if (previousState) {
      this.grid        = new Grid(previousState.grid.size,
                                  previousState.grid.cells); // Reload grid
      this.score       = previousState.score;
      this.over        = previousState.over;
      this.won         = previousState.won;
      this.keepPlaying = previousState.keepPlaying;
    } else {
      this.grid        = new Grid(this.props.size);
      this.score       = 0;
      this.over        = false;
      this.won         = false;
      this.keepPlaying = false;
    }
    this.setState({score: this.score, best: storageManager.getBestScore(), tiles: this.getRandomTiles(), over: this.over, won: this.won});
  },

  // Set up the initial tiles to start the game with
  addStartTiles: function () {
    for (var i = 0; i < this.startTiles; i++) {
      this.addRandomTile();
    }
  },

  // Adds a tile in a random position
  addRandomTile: function () {
    if (this.grid.cellsAvailable()) {
      var value = Math.random() < 0.9 ? 2 : 4;
      var tile = new Tile(this.grid.randomAvailableCell(), value);

      this.grid.insertTile(tile);
    }
  },

  // Sends the updated grid to the actuator
  actuate: function () {
    // Clear the state when the game is over (game over only, not win)
    if (this.over) {
      storageManager.clearGameState();
    } else {
      storageManager.setGameState(this.serialize());
    }

    // this.actuator.actuate(this.grid, {
{'fraction_non_alphanumeric': 0.14741816505301983, 'fraction_numerical': 0.005417242969110189, 'mean_word_length': 2.678253497244595, 'pattern_counts': {'":': 0, '<': 63, '<?xml version=': 0, '>': 55, 'https://': 4, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '615751', 'n_tokens_mistral': 2726, 'n_tokens_neox': 2623, 'n_words': 658}