<commit_before>const Phaser = require('./Phaser')
const Brain = require('./Brain')

class Animal {
  constructor (x, y, parent) {
    this.health = game.math.between(100, 150)
    this.age = 0
    this.score = 0
    this.generation = parent ? parent.generation + 1 : 1

    this.sprite = game.add.sprite(game.TILE_SIZE * (x + 0.5), game.TILE_SIZE * (y + 0.5), game.cache.getBitmapData('animal' + this.health))
    game.physics.enable(this.sprite, Phaser.Physics.ARCADE)
    this.sprite.body.setCircle(game.TILE_SIZE / 2)
    this.sprite.body.collideWorldBounds = true
    this.sprite.anchor.setTo(0.5, 0.5)
    this.updateColor()

    // Back-reference for collision handling based on sprites.
    this.sprite.animal = this

    this.sprite.angle = game.math.between(-180, 180)
    game.physics.arcade.velocityFromAngle(this.sprite.angle, game.math.between(10, 200), this.sprite.body.velocity)

    this.brain = parent ? new Brain(parent.brain) : new Brain(7, 10, 10, 3)
  }

  tick (tile) {
    this.health -= 2 + Math.sqrt(this.age * 0.01)
    this.age += 0.01

    let amountEating = 0

    if (tile.food >= 5) amountEating = 4
    else amountEating = tile.food

    if ((255 - this.health) < amountEating) amountEating = 255 - this.health

    if (amountEating) {
      this.health += amountEating
      this.score += amountEating
      tile.food -= amountEating
      tile.updateColor()
    }

    if (this.health < 0) this.health = 0

    const [speed, turn, wantToBreed] = this.brain.ask([
      tile.food,
      this.age,
      this.health,
      this.getFoodAhead(-30, 1),
      this.getFoodAhead(0, 2),
      this.getFoodAhead(30, 1),
      this.overlapWithAnother
    ])

    if (this.health > 250 && wantToBreed > 0.5) {
      this.health -= 70
      const {x, y} = this.getPosition()
      game.animals.add(new Animal(x, y, this))
    }

    this.sprite.angle += (turn - 0.5) * 100
    game.physics.arcade.velocityFromAngle(this.sprite.angle, speed * 200, this.sprite.body.velocity)
  }

  updateColor () {
    this.sprite.loadTexture(game.cache.getBitmapData('animal' + Math.floor(this.health)))
  }

  destroy () {
    this.sprite.destroy()
  }

  getPosition (point) {
    point = point || {x: this.sprite.centerX, y: this.sprite.centerY}
    return {
      x: Math.floor(point.x / game.TILE_SIZE),
      y: Math.floor(point.y / game.TILE_SIZE)
    }
  }

  getFoodAhead (angle, tiles) {
    const line = new Phaser.Line().fromAngle(this.sprite.centerX, this.sprite.centerY,
      game.math.degToRad(this.sprite.angle + angle), game.TILE_SIZE * tiles)

    const positionAhead = this.getPosition(line.end)
    const tileAhead = (game.tiles[positionAhead.x] || [])[positionAhead.y] || {}<commit_msg>refactor(index): tweak animal speed and aging for balance<commit_after>const Phaser = require('./Phaser')
const Brain = require('./Brain')

class Animal {
  constructor (x, y, parent) {
    this.health = game.math.between(100, 150)
    this.age = 0
    this.score = 0
    this.generation = parent ? parent.generation + 1 : 1

    this.sprite = game.add.sprite(game.TILE_SIZE * (x + 0.5), game.TILE_SIZE * (y + 0.5), game.cache.getBitmapData('animal' + this.health))
    game.physics.enable(this.sprite, Phaser.Physics.ARCADE)
    this.sprite.body.setCircle(game.TILE_SIZE / 2)
    this.sprite.body.collideWorldBounds = true
    this.sprite.anchor.setTo(0.5, 0.5)
    this.updateColor()

    // Back-reference for collision handling based on sprites.
    this.sprite.animal = this

    this.sprite.angle = game.math.between(-180, 180)
    game.physics.arcade.velocityFromAngle(this.sprite.angle, game.math.between(10, 200), this.sprite.body.velocity)

    this.brain = parent ? new Brain(parent.brain) : new Brain(7, 10, 10, 3)
  }

  tick (tile) {
    this.health -= 1 + Math.sqrt(this.age * 0.01)
    this.age += 0.01

    let amountEating = 0

    if (tile.food >= 5) amountEating = 4
    else amountEating = tile.food

    if ((255 - this.health) < amountEating) amountEating = 255 - this.health

    if (amountEating) {
      this.health += amountEating
      this.score += amountEating
      tile.food -= amountEating
      tile.updateColor()
    }

    if (this.health < 0) this.health = 0

    const [speed, turn, wantToBreed] = this.brain.ask([
      tile.food,
      this.age,
      this.health,
      this.getFoodAhead(-30, 1),
      this.getFoodAhead(0, 2),
      this.getFoodAhead(30, 1),
      this.overlapWithAnother
    ])

    if (this.health > 250 && wantToBreed > 0.5) {
      this.health -= 30
      const {x, y} = this.getPosition()
      game.animals.add(new Animal(x, y, this))
    }

    this.sprite.angle += (turn - 0.5) * 100
    game.physics.arcade.velocityFromAngle(this.sprite.angle, speed * 500, this.sprite.body.velocity)
  }

  updateColor () {
    this.sprite.loadTexture(game.cache.getBitmapData('animal' + Math.floor(this.health)))
  }

  destroy () {
    this.sprite.destroy()
  }

  getPosition (point) {
    point = point || {x: this.sprite.centerX, y: this.sprite.centerY}
    return {
      x: Math.floor(point.x / game.TILE_SIZE),
      y: Math.floor(point.y / game.TILE_SIZE)
    }
  }

  getFoodAhead (angle, tiles) {
    const line = new Phaser.Line().fromAngle(this.sprite.centerX, this.sprite.centerY,
      game.math.degToRad(this.sprite.angle + angle), game.TILE_SIZE * tiles)

    const positionAhead = this.getPosition(line.end)
    const tileAhead = (game.tiles[positionAhead.x] || [])[positionAhead.y] || {}
{'fraction_non_alphanumeric': 0.14565058479532164, 'fraction_numerical': 0.028143274853801168, 'mean_word_length': 2.8326330532212887, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 9, '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': '3044160', 'n_tokens_mistral': 2129, 'n_tokens_neox': 1925, 'n_words': 375}