<commit_before>
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import _ from 'lodash'

import DragPiece from '../containers/drag-piece'
import DropSquare from '../containers/drop-square'

export default class Board extends Component {
  constructor (props) {
    super(props)
    this.hoverDropSquare = this.hoverDropSquare.bind(this)
    this.pieceDrop = this.pieceDrop.bind(this)
    this.canDragDrop = this.canDragDrop.bind(this)
    this.isMovePossible = this.isMovePossible.bind(this)
    this.state = {
      markedSquaresForCapture: [],
      hintSquares: []
    }
  }

  resetState () {
    const newState = {
      markedSquaresForCapture: [],
      hintSquares: []
    }

    if (!_.isEqual(this.state, newState)) {
      this.setState(newState)
    }
  }

  selectMoves (from, to) {
    const { moves } = this.props
    const hint = this.state.hintSquares

    let possibleMoves = moves.filter(x => x.begin() === from && x.end() === to)
    if (possibleMoves.length === 0) {
      return null
    }

    if (possibleMoves.length === 1) {
      return possibleMoves[0] // only one move is possible to selected square
    }

    // there are more then one way to go to to squares :)
    // use hint to compute which move is the best match
    let rankedMoves = possibleMoves.map(move => {
      let rank = 0
      let j = 0 // index in hint
      for (const i of move.squares) {
        if (i === hint[j]) {
          rank++
          j++
        }
      }
      return { move, rank }
    })

    rankedMoves.sort((a, b) => b.rank - a.rank) // sort in reverse order
    if (rankedMoves[0].rank > rankedMoves[1].rank) {
      return rankedMoves[0].move
    } else {
      // so rank is equal we need to prioritize simple moves and then shorter moves
      const simple = rankedMoves.find(x => !x.move.isCapture())
      if (simple) {
        return simple.move
      }

      const shortest = _
        .takeWhile(rankedMoves, x => x.rank === rankedMoves[0].rank)
        .map(x => x.move)
        .sort((a, b) => a.squares.length - b.squares.length)

      if (shortest[0].squares.length < shortest[1].squares.length) {
        return shortest[0]
      }
    }

    return null // still ambiguous
  }

  pieceDrop (from, to) {
    this.resetState()

    if (from == null || to == null) {
      return // empty drop
    }

    const move = this.selectMoves(from, to)
    if (!move) {
      throw new Error('Ambiguous move selected.')
    }

    return this.props.onPieceMove(move)
  }

  hoverDropSquare (from, to) {
    if (from === to) {
      this.resetState()
    }<commit_msg>Another hard to find bug<commit_after>
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import _ from 'lodash'

import DragPiece from '../containers/drag-piece'
import DropSquare from '../containers/drop-square'

export default class Board extends Component {
  constructor (props) {
    super(props)
    this.hoverDropSquare = this.hoverDropSquare.bind(this)
    this.pieceDrop = this.pieceDrop.bind(this)
    this.canDragDrop = this.canDragDrop.bind(this)
    this.isMovePossible = this.isMovePossible.bind(this)
    this.state = {
      markedSquaresForCapture: [],
      hintSquares: []
    }
  }

  resetState () {
    const newState = {
      markedSquaresForCapture: [],
      hintSquares: []
    }

    if (!_.isEqual(this.state, newState)) {
      this.setState(newState)
    }
  }

  selectMoves (from, to) {
    const { moves } = this.props
    const hint = this.state.hintSquares

    let possibleMoves = moves.filter(x => x.begin() === from && x.end() === to)
    if (possibleMoves.length === 0) {
      return null
    }

    if (possibleMoves.length === 1) {
      return possibleMoves[0] // only one move is possible to selected square
    }

    // there are more then one way to go to to squares :)
    // use hint to compute which move is the best match
    let rankedMoves = possibleMoves.map(move => {
      let rank = 0
      let j = 0 // index in hint
      for (const i of move.squares) {
        if (i === hint[j]) {
          rank++
          j++
        }
      }
      return { move, rank }
    })

    rankedMoves.sort((a, b) => b.rank - a.rank) // sort in reverse order
    if (rankedMoves[0].rank > rankedMoves[1].rank) {
      return rankedMoves[0].move
    } else {
      // so rank is equal we need to prioritize simple moves and then shorter moves
      const simple = rankedMoves.find(x => !x.move.isCapture())
      if (simple) {
        return simple.move
      }

      const shortest = _
        .takeWhile(rankedMoves, x => x.rank === rankedMoves[0].rank)
        .map(x => x.move)
        .sort((a, b) => a.squares.length - b.squares.length)

      if (shortest[0].squares.length < shortest[1].squares.length) {
        return shortest[0]
      }
    }

    return null // still ambiguous
  }

  pieceDrop (from, to) {
    try {
      if (from == null || to == null) {
        return // empty drop
      }

      const move = this.selectMoves(from, to)
      if (!move) {
        throw new Error('Ambiguous move selected.')
      }

      return this.props.onPieceMove(move)
    } finally {
      this.resetState()
    }
  }

  hoverDropSquare (from, to) {
    if (from === to) {
      this.resetState()
    }
{'fraction_non_alphanumeric': 0.12802114803625378, 'fraction_numerical': 0.004531722054380665, 'mean_word_length': 2.2496932515337424, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 19, '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': '775911', 'n_tokens_mistral': 1757, 'n_tokens_neox': 1685, 'n_words': 444}