Untitled

mail@pastecode.io avatar
unknown
plain_text
2 years ago
9.3 kB
0
Indexable
Never
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Brush = System.Drawing.Brush;
using Brushes = System.Drawing.Brushes;
using Point = System.Drawing.Point;

namespace MazeRevision
{
    public partial class MainWindow : Window
    {
        //Set the size of the maze e.g. 30 stands for: 30 * 30
        readonly int dimensions = 30;

        //Set the background color of the maze
        readonly Brush backgroundBrush = Brushes.MediumPurple;

        //Set the foreground color of the maze
        readonly Brush foregroundBrush = Brushes.White;


        int recursionCount = 0;
        int wdt;
        int hgt;
        int mazeWidth;
        int mazeHeight;
        Cell[,] cells;
        Direction randomDirection;

        public MainWindow()
        {
            InitializeComponent();
            SetValues();
            CreatePassage(new Point(0, 0));
            RemoveBorderWalls();
            DrawMaze();
        }

        private void SetValues()
        {
            mazeWidth = dimensions;
            mazeHeight = dimensions;
            cells = new Cell[mazeWidth, mazeHeight];
            for (int column = 0; column < mazeWidth; column++)
            {
                for (int row = 0; row < mazeHeight; row++)
                {
                    cells[column, row] = new Cell
                    {
                        coordinates = new Point(column, row)
                    };
                }
            }
        }

        private void RemoveBorderWalls()
        {
            for (int column = 0; column < mazeWidth; column++)
            {
                for (int row = 0; row < mazeHeight; row++)
                {
                    if(row == 0)
                    {
                        cells[column, row].northWall = false;
                    }
                    else if(row == mazeHeight)
                    {
                        cells[column, row].southWall = false;
                    }
                    if (column == 0)
                    {
                        cells[column, row].westWall = false;
                    }
                    else if(column == mazeWidth)
                    {
                        cells[column, row].eastWall = false;
                    }
                }
            }
        }

        private void CreatePassage(Point p)
        {
            List<Direction> validDirections;
            cells[p.X, p.Y].visited = true;

            validDirections = CheckForValideDirections(p);
            var hasReachedEnd = p.X == dimensions && p.Y == dimensions;
            while (validDirections.Count > 0 && recursionCount < 5000000 && hasReachedEnd == false)
            {
                var nextPoint = SetNextPoint(p, validDirections);
                RemoveWalls(p);
                recursionCount++;
                if (recursionCount < 1000)
                {
                    CreatePassage(nextPoint);
                    validDirections = CheckForValideDirections(p);
                }
            }
        }

        private void RemoveWalls(Point p)
        {
            switch (randomDirection)
            {
                case Direction.North:
                    cells[p.X, p.Y].northWall = false;
                    cells[p.X, p.Y - 1].southWall = false;
                    break;
                case Direction.East:
                    cells[p.X, p.Y].eastWall = false;
                    cells[p.X + 1, p.Y].westWall = false;
                    break;
                case Direction.South:
                    cells[p.X, p.Y].southWall = false;
                    cells[p.X, p.Y + 1].northWall = false;
                    break;
                case Direction.West:
                    cells[p.X, p.Y].westWall = false;
                    cells[p.X - 1, p.Y].eastWall = false;
                    break;
            }
        }

        private List<Direction> CheckForValideDirections(Point p)
        {
            List<Direction> validDirections = new List<Direction>() { Direction.North, Direction.South, Direction.West, Direction.East };
            List<Direction> invalidDirections = new List<Direction>();
            for (int i = 0; i < validDirections.Count; i++)
            {
                switch (validDirections[i])
                {
                    case Direction.North:
                        if (p.Y == 0 || cells[p.X, p.Y - 1].visited)
                            invalidDirections.Add(Direction.North);
                        break;
                    case Direction.East:
                        if (p.X == mazeWidth - 1 || cells[p.X + 1, p.Y].visited)
                            invalidDirections.Add(Direction.East);
                        break;
                    case Direction.South:
                        if (p.Y == mazeHeight - 1 || cells[p.X, p.Y + 1].visited)
                            invalidDirections.Add(Direction.South);
                        break;
                    case Direction.West:
                        if (p.X == 0 || cells[p.X - 1, p.Y].visited)
                            invalidDirections.Add(Direction.West);
                        break;
                }
            }

            foreach (var item in invalidDirections)
            {
                validDirections.Remove(item);
            }
            return validDirections;
        }

        private Point SetNextPoint(Point p, List<Direction> validDirections)
        {
            if (validDirections.Count < 2)
            {
                if (validDirections.Count == 0)
                {
                    randomDirection = Direction.Invalid;
                }
                else
                {
                    randomDirection = validDirections[0];
                }
            }
            else
            {
                Random random = new Random();
                randomDirection = validDirections[random.Next(validDirections.Count)];
            }
            if (randomDirection == Direction.North)
            {
                return new Point(p.X, p.Y - 1);
            }
            if (randomDirection == Direction.South)
            {
                return new Point(p.X, p.Y + 1);
            }
            if (randomDirection == Direction.West)
            {
                return new Point(p.X - 1, p.Y);
            }
            if (randomDirection == Direction.East)
            {
                return new Point(p.X + 1, p.Y);
            }
            return new Point(p.X, p.Y);

        }

        private void DrawMaze()
        {
            wdt = Convert.ToInt32(MazeImage.Width) / mazeWidth;
            hgt = Convert.ToInt32(MazeImage.Height) / mazeHeight;
            Bitmap bitmap = new Bitmap(Convert.ToInt32(MazeImage.Height), Convert.ToInt32(MazeImage.Width));
            Graphics graphics = Graphics.FromImage(bitmap);
            graphics.FillRectangle(backgroundBrush, new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height));
            for (int w = 0; w < mazeWidth; w++)
            {
                for (int h = 0; h < mazeHeight; h++)
                {
                    int x = w * wdt;
                    int y = h * hgt;
                    if (cells[w, h].northWall == true)
                    {
                        graphics.DrawLine(new System.Drawing.Pen(foregroundBrush), new Point(x, y), new Point(x + wdt, y));
                    }
                    if (cells[w, h].eastWall == true)
                    {
                        graphics.DrawLine(new System.Drawing.Pen(foregroundBrush), new Point(x + wdt, y), new Point(x + wdt, y + hgt));
                    }
                    if (cells[w, h].southWall == true)
                    {
                        graphics.DrawLine(new System.Drawing.Pen(foregroundBrush), new Point(x, y + hgt), new Point(x + wdt, y + hgt));
                    }
                    if (cells[w, h].westWall == true)
                    {
                        graphics.DrawLine(new System.Drawing.Pen(foregroundBrush), new Point(x, y), new Point(x, y + hgt));
                    }
                }
            }
            bitmap.Save(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\\test.bmp");
            MazeImage.Source = Imaging.CreateBitmapSourceFromHBitmap(bitmap.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromWidthAndHeight(Convert.ToInt32(MazeImage.Height), Convert.ToInt32(MazeImage.Width)));
        }

        private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            if (double.IsNaN(Grid.ActualHeight) || double.IsNaN(Grid.ActualWidth))
            {
                
            }
            else
            {
                MazeImage.Height = Grid.ActualHeight;
                MazeImage.Width = Grid.ActualWidth;
                DrawMaze();
            }
        }
    }
}