public async Task <Vector2D> MovePlayer(string nickname, Vector2D direction)
        {
            var player   = _clusterClient.GetGrain <IPlayerActor>(nickname);
            var position = await player.Move(direction);

            string zoneId = _routingService.GetZoneId(position);
            var    zone   = _clusterClient.GetGrain <IZoneActor>(zoneId);
            await zone.RoutePlayerMovement(player);

            var playerPosition = new PlayerPositionChanged(nickname, position);
            await _hubContext.Clients.All.SendAsync(UpdatePositionMethod, nickname, playerPosition);

            return(position);
        }
        /// <summary>
        /// Backtracking and Recursion method, places player position on a X,Y and calls itself again until solution is found
        /// </summary>
        /// <param name="x">Player X position</param>
        /// <param name="y">Player Y position</param>
        /// <param name="prevMovement"></param>
        /// <param name="currentWord">Current Word (part of a solution) that will be "collected" after visiting places</param>
        /// <param name="pathWord">Current Path that will be "collected" after visiting places</param>
        /// <returns></returns>
        bool MoveNextStep(int x, int y, char prevMovement, string currentWord, string pathWord)
        {
            PlayerPositionChanged?.Invoke(boardDefinition, currentWord, pathWord);


            string fltWord = new string(currentWord.Where(c => ALPHABET.Contains(c)).ToArray());


            if (fltWord == BoardWord)
            {
                if (x == PlayerEndPos.X && y == PlayerEndPos.Y)
                {
                    Solution[x, y] = true;
                    pathWord      += GameBoard[x, y];


                    solutionWord     = currentWord;
                    solutionPathWord = pathWord;

                    return(true);
                }
            }

            char c = ' ';

            if (AreValidBounds(x, y))
            {
                c = GameBoard[x, y];
                if (ALPHABET.Contains(c))
                {
                    c = '+';
                }

                if (Solution[x, y] && Tunnels[x, y])
                {
                    c = prevMovement;
                }
            }


            if (IsValidPosition(x, y, fltWord))
            {
                if (Solution[x, y])
                {
                    c = prevMovement;
                }


                pathWord += GameBoard[x, y];


                if (ALPHABET.Contains(GameBoard[x, y]) && !Solution[x, y])
                {
                    currentWord += GameBoard[x, y];
                }

                Solution[x, y] = true;


                switch (c)
                {
                case (char)BoardLetterDefinition.MoveHorizontal:
                    // Move horizontally


                    if (MoveNextStep(x - 1, y, c, currentWord, pathWord))
                    {
                        return(true);
                    }
                    if (MoveNextStep(x + 1, y, c, currentWord, pathWord))
                    {
                        return(true);
                    }
                    break;

                case (char)BoardLetterDefinition.MoveVertical:
                    // Move vertically


                    if (MoveNextStep(x, y - 1, c, currentWord, pathWord))
                    {
                        return(true);
                    }
                    if (MoveNextStep(x, y + 1, c, currentWord, pathWord))
                    {
                        return(true);
                    }
                    break;

                case (char)BoardLetterDefinition.MoveAnywhere:
                case (char)BoardLetterDefinition.PlayerStartPosition:
                    // Move in each direction


                    if (MoveNextStep(x + 1, y, c, currentWord, pathWord))
                    {
                        return(true);
                    }
                    if (MoveNextStep(x, y + 1, c, currentWord, pathWord))
                    {
                        return(true);
                    }
                    if (MoveNextStep(x - 1, y, c, currentWord, pathWord))
                    {
                        return(true);
                    }
                    if (MoveNextStep(x, y - 1, c, currentWord, pathWord))
                    {
                        return(true);
                    }
                    break;
                }

                if (!Tunnels[x, y])
                {
                    Solution[x, y] = false;
                }

                // Simplified, the same as currentWord.Substring(0, currentWord.Length -1)
                currentWord = currentWord[0..^ 1];