示例#1
0
        public MazeVisualizerDTO Visualize(MazeFE maze, string algorithm)
        {
            try
            {
                if ("BFS".Equals(algorithm))
                {
                    return(_bfsService.Visualize(maze));
                }

                if ("A-STAR".Equals(algorithm))
                {
                    return(_aStarService.Visualize(maze));
                }

                if ("BIDIRECTIONAL-BFS".Equals(algorithm))
                {
                    return(_bfsTwoWayService.Visualize(maze));
                }

                throw new ApiException(400, "No such algorithm available");
            }
            catch (ApiException e)
            {
                throw e;
            }
        }
示例#2
0
        public ActionResult <MazeDTO> CreateMaze(Guid userId, [FromBody] MazeFE maze)
        {
            _logger.LogInformation("POST request for saving maze from user with id {0}\n\n", userId.ToString());

            try
            {
                var accessToken = Request.Headers["Bearer"];
                var payload     = Authorize(accessToken);
            }
            catch (ApiException e)
            {
                return(Unauthorized(new UnauthorizedError(e.Message)));
            }

            try
            {
                MazeDTO retMazeDTO = _mazeService.CreateMazeByUserId(userId, maze);
                return(Created("Maze created", retMazeDTO));
            }
            catch (ApiException e)
            {
                if (e.StatusCode == 400)
                {
                    return(BadRequest(new BadRequestError(e.Message)));
                }

                return(NotFound(new NotFoundError(e.Message)));
            }
        }
示例#3
0
        public ActionResult <Score> SubmitSolution(Guid id, [FromBody] MazeFE userSolution)
        {
            _logger.LogInformation("POST request to submit a solution for maze with Id {0}\n\n", id);

            IDictionary <string, object> payload;

            try
            {
                var accessToken = Request.Headers["Bearer"];
                payload = Authorize(accessToken);
            }
            catch (ApiException e)
            {
                return(Unauthorized(new UnauthorizedError(e.Message)));
            }

            try
            {
                Score score = _mazeService.Submit(id, (string)payload["userId"], userSolution);
                return(Ok(score));
            }
            catch (ApiException e)
            {
                if (e.StatusCode == 403)
                {
                    return(StatusCode(403, new ForbiddenError(e.Message)));
                }

                return(BadRequest(new BadRequestError(e.Message)));
            }
        }
示例#4
0
        public MazeVisualizerDTO Visualize(MazeFE mazeFE)
        {
            if (mazeFE.PointList.Count() != mazeFE.Width * mazeFE.Height)
            {
                throw new ApiException(400, "Invalid maze. Width and height don't match the number of points given");
            }

            if (mazeFE.PointList.Count(p => p.Value == 1) != 1)
            {
                throw new ApiException(400, "Invalid maze. No start point given");
            }

            if (mazeFE.PointList.Count(p => p.Value == 2) != 1)
            {
                throw new ApiException(400, "Invalid maze. No end point given");
            }

            Point startPoint = new Point();
            Point endPoint   = new Point();

            // generate matrix from mazeFE
            int[,] matrix = new int[mazeFE.Height, mazeFE.Width];
            foreach (Point p in mazeFE.PointList)
            {
                matrix[p.I, p.J] = 0;

                if (p.Value == 1)
                {
                    startPoint.I     = p.I;
                    startPoint.J     = p.J;
                    startPoint.Value = 1;
                    matrix[p.I, p.J] = 1;
                }
                else if (p.Value == 2)
                {
                    endPoint.I = p.I;
                    endPoint.J = p.J;
                }
                else if (p.Value == 3)
                {
                    matrix[p.I, p.J] = -1;
                }
            }

            if ((startPoint.I == endPoint.I && System.Math.Abs(startPoint.J - endPoint.J) == 1) ||
                (startPoint.J == endPoint.J && System.Math.Abs(startPoint.I - endPoint.I) == 1))
            {
                throw new ApiException(400, "Invalid maze. Start point right next to end point");
            }

            MazeVisualizerDTO solution = Solve(matrix, startPoint, endPoint, mazeFE.Width, mazeFE.Height);

            if (!solution.Solution.Any())
            {
                throw new ApiException(400, "Invalid maze. No solution found");
            }

            return(solution);
        }
示例#5
0
        private Maze BuildMazeFromMazeFE(MazeFE mazeFE, string solution)
        {
            string state = "";

            foreach (Point point in mazeFE.PointList)
            {
                state += point.Value;
            }

            Maze maze = Maze.Create(mazeFE.Name, mazeFE.Width, mazeFE.Height, state.CompressString(), solution.CompressString());

            return(maze);
        }
示例#6
0
        public MazeDTO CreateMazeByUserId(Guid userId, MazeFE maze)
        {
            User user = _userRepository.FindById(userId);

            if (user == null)
            {
                _logger.LogError("User with id " + userId.ToString() + " not in database\n\n");
                throw new ApiException(404, "User with id " + userId.ToString() + " not in database");
            }

            string solution;

            try
            {
                solution = _bfsService.ValidateMaze(maze);
            }
            catch (ApiException e)
            {
                _logger.LogError(e.Message);
                throw e;
            }

            Maze mazeBE     = BuildMazeFromMazeFE(maze, solution);
            Maze storedMaze = CreateMaze(mazeBE);

            UserMaze userMaze    = UserMaze.Create(user, storedMaze);
            UserMaze retUserMaze = _userMazeRepository.Create(userMaze);

            return(MazeDTO.Builder()
                   .Id(storedMaze.MazeId)
                   .Name(storedMaze.Name)
                   .OwnerId(user.UserId)
                   .Owner(user.Username)
                   .PlayersCount(0)
                   .Width(storedMaze.Width)
                   .Height(storedMaze.Height)
                   .State(storedMaze.State.DecompressString())
                   .CreationTime(storedMaze.CreationTime)
                   .Build());
        }
示例#7
0
        public Score Submit(Guid mazeId, string userId, MazeFE userSolution)
        {
            Guid userGuid = new Guid(userId);
            User user     = _userRepository.FindById(userGuid);

            if (_userMazeRepository.FindById(mazeId, userGuid) != null)
            {
                throw new ApiException(403, "Already submitted solution for this maze");
            }

            if (!ValidateUserSolution(userSolution))
            {
                throw new ApiException(400, "Invalid solution");
            }

            Maze maze = _mazeRepository.FindById(mazeId);

            int userSolutionSize = userSolution.PointList.Count(p => p.Value == 4);

            int solutionSize = maze.Solution.DecompressString().Count(c => c == '1');
            int deviation    = Convert.ToInt32((userSolutionSize - solutionSize) * 100 / solutionSize);
            int accuracy     = Math.Max(0, 100 - deviation);

            string userSolutionString = "";

            foreach (Point point in userSolution.PointList)
            {
                userSolutionString += point.Value;
            }

            UserMaze um = UserMaze.Create(user, maze, "LOCKED", true, accuracy, userSolutionString.CompressString());

            _userMazeRepository.Create(um);

            return(new Score(accuracy));
        }
示例#8
0
        public string ValidateMaze(MazeFE mazeFE)
        {
            if (mazeFE.PointList.Count() != mazeFE.Width * mazeFE.Height)
            {
                throw new ApiException(400, "Invalid maze. Width and height don't match the number of points given");
            }

            if (mazeFE.PointList.Count(p => p.Value == 1) != 1)
            {
                throw new ApiException(400, "Invalid maze. No start point given");
            }

            if (mazeFE.PointList.Count(p => p.Value == 2) != 1)
            {
                throw new ApiException(400, "Invalid maze. No end point given");
            }

            Point startPoint = new Point();
            Point endPoint   = new Point();


            int[,] matrix = new int[mazeFE.Height, mazeFE.Width];
            foreach (Point p in mazeFE.PointList)
            {
                matrix[p.I, p.J] = 0;

                if (p.Value == 1)
                {
                    startPoint.I     = p.I;
                    startPoint.J     = p.J;
                    startPoint.Value = 1;
                    matrix[p.I, p.J] = 1;
                }
                else if (p.Value == 2)
                {
                    endPoint.I = p.I;
                    endPoint.J = p.J;
                }
                else if (p.Value == 3)
                {
                    matrix[p.I, p.J] = -1;
                }
            }

            if ((startPoint.I == endPoint.I && System.Math.Abs(startPoint.J - endPoint.J) == 1) ||
                (startPoint.J == endPoint.J && System.Math.Abs(startPoint.I - endPoint.I) == 1))
            {
                throw new ApiException(400, "Invalid maze. Start point right next to end point");
            }

            MazeVisualizerDTO solution = Solve(matrix, startPoint, endPoint, mazeFE.Width, mazeFE.Height);

            if (!solution.Solution.Any())
            {
                throw new ApiException(400, "Invalid maze. No solution found");
            }

            StringBuilder retSolution = new StringBuilder(new string('0', mazeFE.Width * mazeFE.Height));

            foreach (Point p in solution.Solution)
            {
                retSolution.Remove(p.I * mazeFE.Width + p.J, 1);
                retSolution.Insert(p.I * mazeFE.Width + p.J, '1');
            }

            return(retSolution.ToString());
        }
示例#9
0
        public ActionResult <MazeVisualizerDTO> VisualizeMazeSolution(Guid userId, string algorithm, [FromBody] MazeFE maze)
        {
            _logger.LogInformation("GET request for {0} maze visualizer from user with id {1}\n\n", algorithm, userId.ToString());

            try
            {
                var accessToken = Request.Headers["Bearer"];
                var payload     = Authorize(accessToken);
            }
            catch (ApiException e)
            {
                return(Unauthorized(new UnauthorizedError(e.Message)));
            }

            try
            {
                MazeVisualizerDTO mazeVisualizerData = _mazeService.Visualize(maze, algorithm.ToUpper());
                return(Ok(mazeVisualizerData));
            }
            catch (ApiException e)
            {
                if (e.StatusCode == 400)
                {
                    return(BadRequest(new BadRequestError(e.Message)));
                }

                return(NotFound(new NotFoundError(e.Message)));
            }
        }
示例#10
0
        private bool ValidateUserSolution(MazeFE maze)
        {
            int[,] matrix = new int[maze.Height, maze.Width];
            Point startPoint = Point.Default;
            Point endPoint   = Point.Default;

            foreach (Point p in maze.PointList)
            {
                matrix[p.I, p.J] = 0;

                if (p.Value == 1)
                {
                    startPoint.I     = p.I;
                    startPoint.J     = p.J;
                    startPoint.Value = 1;
                    matrix[p.I, p.J] = 1;
                }
                else if (p.Value == 2)
                {
                    endPoint.I       = p.I;
                    endPoint.J       = p.J;
                    matrix[p.I, p.J] = 2;
                }
                else if (p.Value == 3)
                {
                    matrix[p.I, p.J] = -1;
                }
                else if (p.Value == 4)
                {
                    matrix[p.I, p.J] = 4;
                }
            }

            int[] di = { -1, 0, 1, 0 };
            int[] dj = { 0, 1, 0, -1 };

            for (int i = 0; i < maze.Height; i++)
            {
                for (int j = 0; j < maze.Width; j++)
                {
                    if (matrix[i, j] == 4)
                    {
                        int solNeighbourCount   = 0;
                        int startNeighbourCount = 0;
                        int endNeighbourCount   = 0;

                        for (int k = 0; k <= 3; k++)
                        {
                            int next_i = i + di[k];
                            int next_j = j + dj[k];

                            if (next_i >= 0 && next_i < maze.Height && next_j >= 0 && next_j < maze.Width)
                            {
                                int nextPointValue = matrix[next_i, next_j];

                                if (nextPointValue == 4)
                                {
                                    solNeighbourCount++;
                                }
                                else if (nextPointValue == 1)
                                {
                                    startNeighbourCount++;
                                }
                                else if (nextPointValue == 2)
                                {
                                    endNeighbourCount++;
                                }
                            }
                        }

                        if (solNeighbourCount == 2 && startNeighbourCount == 0 && endNeighbourCount == 0)
                        {
                            continue;
                        }
                        if (solNeighbourCount == 1 && ((startNeighbourCount ^ endNeighbourCount) == 1))
                        {
                            continue;
                        }
                        if (solNeighbourCount == 0 && ((startNeighbourCount + endNeighbourCount) == 2))
                        {
                            continue;
                        }

                        return(false);
                    }
                }
            }

            return(true);
        }