namespace PP.MazeSolver {
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
static class Program {
// Solving maze (Sequential)
static List<Cell> ComputeSolution(Maze maze, Cell cell, int size, bool canUp, bool canDown, bool canRight, bool canLeft)
{
if ((cell.X == size - 1) && (cell.Y == size - 1)) // If arrived at Exit
{
List<Cell> solution = new List<Cell>();
solution.Add(cell);
return solution;
}
else
{
if (canUp == maze.HasConnectionUp(cell))
{
List<Cell> partialResult = ComputeSolution(maze, cell.Up, size, true, false, true, true);
if (partialResult != null)
{
partialResult.Insert(0, cell);
return partialResult;
}
}
if (canDown == maze.HasConnectionDown(cell))
{
List<Cell> partialResult = ComputeSolution(maze, cell.Down, size, false, true, true, true);
if (partialResult != null)
{
partialResult.Insert(0, cell);
return partialResult;
}
}
if (canRight == maze.HasConnectionRight(cell))
{
List<Cell> partialResult = ComputeSolution(maze, cell.Right, size, true, true, true, false);
if (partialResult != null)
{
partialResult.Insert(0, cell);
return partialResult;
}
}
if (canLeft == maze.HasConnectionLeft(cell))
{
List<Cell> partialResult = ComputeSolution(maze, cell.Left, size, true, true, false, true);
if (partialResult != null)
{
partialResult.Insert(0, cell);
return partialResult;
}
}
}
return null;
}
// Solving maze (parallel)
static List<Cell> ComputeSolutionParallel(Maze maze, Cell cell, int size, bool canUp, bool canDown, bool canRight, bool canLeft)
{
Thread t1 = new Thread(()=> CanUp(maze, cell.Up, size, true, false, true, true));
Thread t2 = new Thread(() => CanDown(maze, cell.Down, size, false, true, true, true));
Thread t3 = new Thread(() => CanRight(maze, cell.Right, size, true, true, true, false));
Thread t4 = new Thread(() => CanLeft(maze, cell.Left, size, true, true, false, true));
if ((cell.X == size - 1) && (cell.Y == size - 1)) // If arrived at Exit
{
List<Cell> solution = new List<Cell>();
solution.Add(cell);
return solution;
}
else
{
t1.Start();
t2.Start();
t3.Start();
t4.Start();
t1.Join();
t2.Join();
t3.Join();
t4.Join();
}
return null;
}
static List<Cell> CanUp(Maze m, Cell c, int size, bool canUp, bool canDown, bool canRight, bool canLeft)
{
if (canUp == m.HasConnectionUp(c))
{
List<Cell> partialResult = ComputeSolutionParallel(m, c.Up, size, true, false, true, true);
if (partialResult != null)
{
partialResult.Insert(0, c);
return partialResult;
}
}
return null;
}
static List<Cell> CanDown(Maze m, Cell c, int size, bool canUp, bool canDown, bool canRight, bool canLeft)
{
if (canDown == m.HasConnectionDown(c))
{
List<Cell> partialResult = ComputeSolutionParallel(m, c.Down, size, false, true, true, true);
if (partialResult != null)
{
partialResult.Insert(0, c);
return partialResult;
}
}
return null;
}
static List<Cell> CanRight(Maze m, Cell c, int size, bool canUp, bool canDown, bool canRight, bool canLeft)
{
if (canRight == m.HasConnectionRight(c))
{
List<Cell> partialResult = ComputeSolutionParallel(m, c.Right, size, true, true, true, false);
if (partialResult != null)
{
partialResult.Insert(0, c);
return partialResult;
}
}
return null;
}
static List<Cell> CanLeft(Maze m, Cell c, int size, bool canUp, bool canDown, bool canRight, bool canLeft)
{
if (canLeft == m.HasConnectionLeft(c))
{
List<Cell> partialResult = ComputeSolutionParallel(m, c.Left, size, true, true, false, true);
if (partialResult != null)
{
partialResult.Insert(0, c);
return partialResult;
}
}
return null;
}
static void Main(String[] args) {
// read size of maze from user input
Console.Write("Size of maze: ");
int size = Int32.Parse(Console.ReadLine());
// create a maze
Console.Write("Creating maze... ");
Stopwatch watch = Stopwatch.StartNew();
Maze maze = new Maze(size, size);
Console.WriteLine(watch.Elapsed);
// solve the created maze
Console.Write("Solving maze... ");
watch.Restart();
// MODIFY THIS SECTION BELOW TO SOLVE THE MAZE
// List<Cell> solution = ComputeSolution(maze, new Cell(0, 0), size, true, true, true, true);
List<Cell> solutionParallel = ComputeSolutionParallel(maze, new Cell(0, 0), size, true, true, true, true);
// END OF SECTION YOU SHOULD MODIFY
/* Console.WriteLine(watch.Elapsed);
ConsoleColor color = Console.ForegroundColor;
if (maze.IsSolutionCorrect(solution)) {
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("Correct!");
} else {
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Incorrect!");
}
Console.ForegroundColor = color;
Console.Write("Drawing maze... ");
// this will draw the maze together with the solution
maze.Save("maze with path.png", solution);
Console.WriteLine("done.");
Console.ReadLine();
*/
//------------------------------------------------------
Console.WriteLine(watch.Elapsed);
ConsoleColor colorP = Console.ForegroundColor;
if (maze.IsSolutionCorrect(solutionParallel))
{
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("Correct!");
}
else
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Incorrect!");
}
Console.ForegroundColor = colorP;
Console.Write("Drawing maze... ");
// this will draw the maze together with the solution
maze.Save("maze with path.png", solutionParallel);
Console.WriteLine("done.");
Console.ReadLine();
}
}
}