public static int MinimumMoves(int[][] grid) { // 0 is unvisited, 1 is visited horizontally, 2 vertically, 3 both. int[,] visited = new int[grid.Length, grid[0].Length]; int[,] shortestPathHorizontal = new int[grid.Length, grid[0].Length]; int[,] shortestPathVertical = new int[grid.Length, grid[0].Length]; for (int i = 0; i < shortestPathHorizontal.GetLength(0); i++) { for (int j = 0; j < shortestPathHorizontal.GetLength(1); j++) { shortestPathHorizontal[i, j] = int.MaxValue; shortestPathVertical[i, j] = int.MaxValue; } } SnakeCoordinate start = new SnakeCoordinate(0, 1, true); Queue <SnakeCoordinate> queue = new Queue <SnakeCoordinate>(); queue.Enqueue(start); visited[0, 1] = 1; shortestPathHorizontal[0, 1] = 0; while (queue.Count != 0) { var coord = queue.Dequeue(); if (coord.IsHorizontal) { MoveHorizontal(grid, queue, coord, shortestPathHorizontal, shortestPathVertical, visited); } else { MoveVertical(grid, queue, coord, shortestPathHorizontal, shortestPathVertical, visited); } } if (shortestPathHorizontal[grid.Length - 1, grid.Length - 1] == int.MaxValue) { return(-1); } return(shortestPathHorizontal[grid.Length - 1, grid.Length - 1]); }
private static void MoveHorizontal(int[][] grid, Queue <SnakeCoordinate> queue, SnakeCoordinate coord, int[,] shortestPathHorizontal, int[,] shortestPathVertical, int[,] visited) { // Move right int nxHead = coord.I; int nyHead = coord.J + 1; int nxBody = coord.I; int nyBody = coord.J; if (nyHead >= 0 && nyHead < grid.Length && (visited[nxHead, nyHead] == 0 || visited[nxHead, nyHead] == 2) && grid[nxHead][nyHead] == 0) { SnakeCoordinate coordinate = new SnakeCoordinate(nxHead, nyHead, true); queue.Enqueue(coordinate); if (shortestPathHorizontal[coord.I, coord.J] + 1 < shortestPathHorizontal[nxHead, nyHead]) { shortestPathHorizontal[nxHead, nyHead] = shortestPathHorizontal[coord.I, coord.J] + 1; } if (visited[nxHead, nyHead] == 0) { visited[nxHead, nyHead] = 1; } else { visited[nxHead, nyHead] = 3; } } // Move down nxHead = coord.I + 1; nyHead = coord.J; nxBody = coord.I + 1; nyBody = coord.J - 1; if (nxHead >= 0 && nxHead < grid.Length && (visited[nxHead, nyHead] == 0 || visited[nxHead, nyHead] == 2) && grid[nxHead][nyHead] == 0 && grid[nxBody][nyBody] == 0) { SnakeCoordinate coordinate = new SnakeCoordinate(nxHead, nyHead, true); queue.Enqueue(coordinate); if (shortestPathHorizontal[coord.I, coord.J] + 1 < shortestPathHorizontal[nxHead, nyHead]) { shortestPathHorizontal[nxHead, nyHead] = shortestPathHorizontal[coord.I, coord.J] + 1; } if (visited[nxHead, nyHead] == 0) { visited[nxHead, nyHead] = 1; } else { visited[nxHead, nyHead] = 3; } } // Rotate clockwise nxHead = coord.I + 1; nyHead = coord.J - 1; nxBody = coord.I; nyBody = coord.J - 1; if (nxHead >= 0 && nxHead < grid.Length && nyHead + 1 >= 0 && nyHead + 1 < grid.Length && (visited[nxHead, nyHead] == 0 || visited[nxHead, nyHead] == 1) && grid[nxHead][nyHead] == 0 && grid[nxHead][nyHead + 1] == 0) { SnakeCoordinate coordinate = new SnakeCoordinate(nxHead, nyHead, false); queue.Enqueue(coordinate); if (shortestPathHorizontal[coord.I, coord.J] + 1 < shortestPathVertical[nxHead, nyHead]) { shortestPathVertical[nxHead, nyHead] = shortestPathHorizontal[coord.I, coord.J] + 1; } if (visited[nxHead, nyHead] == 0) { visited[nxHead, nyHead] = 2; } else { visited[nxHead, nyHead] = 3; } } }