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; } }
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))); } }
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))); } }
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); }
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); }
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()); }
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)); }
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()); }
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))); } }
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); }