private void Grab(GameObject fingerTipObj)
    {
        if (ChessBoardConstants.Instance.Engine.WhoseMove != ChessBoardConstants.Instance.Engine.HumanPlayer)
        {
            Debug.Log("Is not currently your turn!");
            return;
        }

        Grabbable b = NearestObjUtils.GetNearestGameObject(
            fingerTipObj,
            InteractionWorld.Instance.Grabbables);

        // TODO add limit

        currentlyGrabbing = b;
        b.GrabbingStart(fingerTipObj);
        Debug.Log("Started grabbing : " + b.name);

        UpdateValidTiles(b.Tile);

        List <Tile> validMoves = InteractionWorld.Instance.GetValidTiles();

        if (validMoves.Count == 0)
        {
            MoveCurrentlyGrabbedPiece(currentlyGrabbing.Tile);
            Debug.Log("Moved piece to original position.");
            return;
        }
    }
    public void Update()
    {
        // Only update tracking if hand tracking is of high confidence
        if (p.RightHandPinchDetector.OVRHand.IsDataHighConfidence)
        {
            Grabbable b = NearestObjUtils.GetNearestGameObject(
                p.RightHandPinchDetector.FingerTipObj,
                InteractionWorld.Instance.Grabbables);

            if (currentlyHovering != b)
            {
                if (currentlyHovering == null)
                {
                    currentlyHovering = b;
                }

                currentlyHovering.SetIsHovered(false);
                b.SetIsHovered(true);

                currentlyHovering = b;
            }
        }
    }
    private IEnumerator Ungrab()
    {
        if (currentlyGrabbing == null)
        {
            yield break;
        }

        Debug.Log("It is currently turn of " + ChessBoardConstants.Instance.Engine.WhoseMove);
        Debug.Log("Human is of color " + ChessBoardConstants.Instance.Engine.HumanPlayer);

        List <Tile> validMoves = InteractionWorld.Instance.GetValidTiles();

        Debug.Log("There is " + validMoves.Count + " valid moves from " + currentlyGrabbing.Tile.Position + "...");

        foreach (Tile tile in validMoves)
        {
            Debug.Log("Valid move : " + tile.Position);
        }

        Tile nearestValidTile = NearestObjUtils.GetNearestGameObject(
            p.RightHandPinchDetector.FingerTipObj,
            validMoves);


        Debug.Log("The nearest valid tile is " + nearestValidTile + ".");

        byte fromX = currentlyGrabbing.Tile.Position.x;
        byte fromY = currentlyGrabbing.Tile.Position.y;
        byte toX   = nearestValidTile.Position.x;
        byte toY   = nearestValidTile.Position.y;

        Debug.Log(fromX + " " + fromY + ", " + toX + "," + toY);


        if (fromX == toX && fromY == toY)
        {
            MoveCurrentlyGrabbedPiece(currentlyGrabbing.Tile);
            yield break;
        }

        bool isValidMove =
            ChessBoardConstants.Instance.Engine.IsValidMove(fromX, fromY, toX, toY);

        for (byte x = 0; x < 9; x++)
        {
            for (byte y = 0; y < 9; y++)
            {
                bool isValid = ChessBoardConstants.Instance.Engine.IsValidMove(fromX, fromY, x, y);
                Debug.Log("Is valid move : " + isValid + ", " + x + "," + y);
            }
        }

        if (!isValidMove)
        {
            Debug.Log("Is not a valid move!");
        }

        ChessBoardConstants.Instance.Engine.MovePiece(fromX, fromY, toX, toY);

        MoveCurrentlyGrabbedPiece(nearestValidTile);

        StartCoroutine(WaitForEngineThinking());
    }