function findPossibleMoves({x, y}) {
  /*
    CONTINUE: not done searching yet, move one more square
    REGULAR: this move DOESN'T capture any enemy pieces
    CAPTURING: this move DOES capture enemy pieces
    FAILED: this move isn't valid
  */
  const moveTypes = {
    CONTINUE: 0,
    REGULAR: 1,
    CAPTURING: 2,
    FAILED: 3,
  };
  
  // Checks if a piece can be moved to these coordinates
  function findPossibleMove(x, y, firstRun) {
    const currentTile = getTile
      .apply(null, translateBoardToXY(argsToObj(x, y)))
      // filter out non-piece sprites, such as the selection sprite
      .filter((piece) => PLAYER_PIECES.includes(piece.type));

    // If no pieces found on given tile...
    if (currentTile.length === 0) {
      // ...and this isn't the first run of the for-loop...
      if (!firstRun) {
        // ...this is an attacking move
        return moveTypes.CAPTURING;
      } else {
        // ...otherwise, it is a regular move
        return moveTypes.REGULAR;
      }
    // If a piece was found on given tile...
    } else {
      // ...and it is a friendly piece, this is an invalid move.
      if (nowPlaying.includes(currentTile[0].type)) return moveTypes.FAILED;
    }

    // If none of the above conditions were met, continue searching
    return moveTypes.CONTINUE;
  }

  // If this returns true, then the for-loop within which this function runs must immediately break
  function loopHandler(x, y, firstRun, move) {
    switch (findPossibleMove(x, y, firstRun)) {
      case moveTypes.CAPTURING:
        move.isCapturing = true;
      case moveTypes.REGULAR:
        move.squaresMoved++;
        move.x = x;
        move.y = y;
        break;
      case moveTypes.FAILED:
        move.squaresMoved = 0;
        break;
      case moveTypes.CONTINUE:
        return false;
    }

    return true;
  }

  // Check if a point is within the board. The coordinates are in the Board format
  function isInBounds(x, y) {
    return x >= 0 && x < width() && y >= 0 && y < height() / 2;
  }

  // Find all possible moves
  const moves = [];
  // If the piece in the current tile is a king, sets variable to both movement modifiers, otherwise sets only one modifier, depending on piece color
  // 
  // Conditional variable assignment by Valentin on StackOverflow: https://stackoverflow.com/a/60437140/
  const movementModifiers =
    (getTile.apply(null, translateBoardToXY(argsToObj(x, y))).some((piece) => piece.type === nowPlaying[1])) && [ -1, 1 ] ||
    nowPlaying === PLAYERS.BLACK && [ 1 ] ||
    [ -1 ];

  // For each movement modifier, find possible moves
  for (const movementModifier of movementModifiers) {
    const startY = y + (x % 2);
    const startX = x + movementModifier;
  
    const firstMove = {
      x: startX,
      y: startY,
      squaresMoved: 0,
      isCapturing: false
    };
    forloop: for (let x = startX, y = startY, firstRun = true; isInBounds(x, y); x += movementModifier, y += (x + 1) % 2, firstRun = false) {
      if (loopHandler(x, y, firstRun, firstMove)) break;
    }
  
    const secondMove = {
      x: startX,
      y: startY,
      squaresMoved: 0,
      isCapturing: false
    };
    forloop: for (let x = startX, y = startY - 1, firstRun = true; isInBounds(x, y); x += movementModifier, y -= x % 2, firstRun = false) {
      if (loopHandler(x, y, firstRun, secondMove)) break;
    }
  
    moves.push(...[firstMove, secondMove].filter((move) => move.squaresMoved !== 0));
  }
  
  return moves;
}
Return a number of possible moves for a piece in those coordinates.
Note: that the coordinates are in the Board format