Esempio n. 1
0
        /// <summary>
        /// Set the values for the map in memory
        /// </summary>
        /// <remarks>This mapper will also identify the blue and red points, needed by the pathfinder</remarks>
        /// <param name="image">A valid image</param>
        private void LoadBitmapAsMap(Bitmap image)
        {
            for (int y = 0; y < image.Height; y++)
            {
                for (int x = 0; x < image.Width; x++)
                {
                    var currentPixel = image.GetPixel(x, y);

                    if (currentPixel.ToArgb() == Color.Black.ToArgb())
                    {
                        map[x, y] = false;
                    }
                    else
                    {
                        map[x, y] = true;
                    }

                    //hmmm this is so fragile, given all the potential red/blue values... :/
                    if (currentPixel.ToArgb() == Color.Red.ToArgb())
                    {
                        Start = new MPoint(x, y);

                        //Console.WriteLine(string.Format("red point at {0}-{1}", x, y));
                    }

                    if (currentPixel.ToArgb() == Color.Blue.ToArgb())
                    {
                        End = new MPoint(x, y);
                        //Console.WriteLine(string.Format("blue point at {0}-{1}", x, y));
                    }
                }
            }

            for (int x = 0; x < image.Width; x++)
            {
                for (int y = 0; y < image.Height; y++)
                {
                    var firstPixel = image.GetPixel(x, y);

                    if (firstPixel.ToArgb() == Color.Black.ToArgb())
                    {
                        map[x, y] = false;
                    }
                    else
                    {
                        map[x, y] = true;
                    }
                }
            }
        }
Esempio n. 2
0
        /// <summary>
        /// This is a Depth-First search implementation where the frontier acts like a last-in first-out stack.
        /// The elements are added to the stack one at a time.
        /// The one selected and taken off the frontier at any time is the last element that was added.
        /// </summary>
        public static List <MPoint> DepthFirstSearch(MPoint start, MPoint end, Map map)
        {
            int width  = map.Width;
            int height = map.Height;

            Map visitedPoints = new Map(width, height);

            List <MPoint> points = new List <MPoint>();

            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    if (x == 0 || y == 0 || x == width || y == height)
                    {
                        visitedPoints[x, y] = true;
                    }
                }
            }

            Stack <MPoint> stack = new Stack <MPoint>();

            stack.Push(start);
            visitedPoints[start.X, start.Y] = true;

            while (stack.Count != 0)
            {
                MPoint cur = stack.Peek();
                int    x   = cur.X;
                int    y   = cur.Y;

                if (end.X == x && end.Y == y)
                {
                    break;
                }

                MPoint target = new MPoint(-1, -1);
                if (IsValid(x + 1, y, map, visitedPoints, width, height))
                {
                    target = new MPoint(x + 1, y);
                }
                else if (IsValid(x, y + 1, map, visitedPoints, width, height))
                {
                    target = new MPoint(x, y + 1);
                }
                else if (IsValid(x - 1, y, map, visitedPoints, width, height))
                {
                    target = new MPoint(x - 1, y);
                }
                else if (IsValid(x, y - 1, map, visitedPoints, width, height))
                {
                    target = new MPoint(x, y - 1);
                }
                if (target.X != -1)
                {
                    stack.Push(target);
                    visitedPoints[target.X, target.Y] = true;
                }
                else
                {
                    stack.Pop();
                }
            }

            points.AddRange(stack);
            points.Reverse();
            return(points);
        }
Esempio n. 3
0
        /// <summary>
        /// Generates the map for the maze by validating each of the target points.
        /// </summary>
        /// <param name="map"></param>
        /// <param name="maze"></param>
        /// <param name="r"></param>
        private void GenerateMap(Maze maze, Random r)
        {
            long steps       = ((maze.Width - 1) / 2) * ((maze.Height - 1) / 2);
            long currentStep = 1;

            int x = 1;
            int y = 1;

            var stack = new Stack <MPoint>();

            stack.Push(new MPoint(x, y));

            maze.map[x, y] = true;

            MPoint[] targets = new MPoint[4];

            while (stack.Count != 0)
            {
                MPoint currentPoint  = stack.Peek();
                int    targetCounter = 0;

                x = currentPoint.X;
                y = currentPoint.Y;

                if (IsValid(x - 2, y, maze.map, maze))
                {
                    targets[targetCounter].X = x - 2;
                    targets[targetCounter].Y = y;
                    targetCounter++;
                }
                if (IsValid(x + 2, y, maze.map, maze))
                {
                    targets[targetCounter].X = x + 2;
                    targets[targetCounter].Y = y;
                    targetCounter++;
                }
                if (IsValid(x, y - 2, maze.map, maze))
                {
                    targets[targetCounter].X = x;
                    targets[targetCounter].Y = y - 2;
                    targetCounter++;
                }
                if (IsValid(x, y + 2, maze.map, maze))
                {
                    targets[targetCounter].X = x;
                    targets[targetCounter].Y = y + 2;
                    targetCounter++;
                }

                if (targetCounter > 0)
                {
                    var target = targets[r.Next(targetCounter)];
                    stack.Push(target);
                    maze.map[target.X, target.Y] = true;

                    currentStep++;

                    if (target.X < x)
                    {
                        maze.map[x - 1, y] = true;
                    }
                    else if (target.X > x)
                    {
                        maze.map[x + 1, y] = true;
                    }
                    else if (target.Y < y)
                    {
                        maze.map[x, y - 1] = true;
                    }
                    else if (target.Y > y)
                    {
                        maze.map[x, y + 1] = true;
                    }
                }
                else
                {
                    stack.Pop();
                }
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Allow us to save as an image file based on calculated Path
        /// </summary>
        /// <param name="fileName">Name for the output file</param>
        /// <param name="imageFormat">Supported formats include Bmp, Gif, png and all the other formats define in the ImageFormat enumeration </param>
        /// <param name="path"> List of map points equivalent to the map array</param>
        public void Save(String fileName, ImageFormat imageFormat, List <MPoint> path)
        {
            using (Bitmap bitmap = new Bitmap(map.Width - 1, map.Height - 1, PixelFormat.Format4bppIndexed))
            {
                Rectangle  frame   = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
                BitmapData bmpData = bitmap.LockBits(frame, ImageLockMode.ReadWrite, bitmap.PixelFormat);
                IntPtr     pointer = bmpData.Scan0;

                int    bytes     = Math.Abs(bmpData.Stride) * bitmap.Height;
                byte[] rgbValues = new byte[bytes];

                Marshal.Copy(pointer, rgbValues, 0, bytes);

                for (int y = 0; y < map.Height - 1; y++)
                {
                    int counter = bmpData.Stride * y;
                    int x       = 0;
                    for (int i = 0; i < bmpData.Stride; i++)
                    {
                        if (x >= bitmap.Width)
                        {
                            break;
                        }

                        BitArray bitArray = new BitArray(8);

                        for (int j = 4; j >= 0; j = j - 4)
                        {
                            if (map[x, y])
                            {
                                bitArray[j + 3] = true;
                                bitArray[j + 2] = true;
                                bitArray[j + 1] = true;
                                bitArray[j + 0] = true;
                            }
                            else
                            {
                                bitArray[j + 3] = false;
                                bitArray[j + 2] = false;
                                bitArray[j + 1] = false;
                                bitArray[j + 0] = false;
                            }
                            x++;
                        }
                        rgbValues[counter] = (byte)GetIntFromBitArray(bitArray);
                        counter++;
                    }
                }

                for (int i = 0; i < path.Count; i++)
                {
                    MPoint point = path[i];
                    int    xrest = point.X % 2;

                    int pos = bmpData.Stride * point.Y + point.X / 2;

                    BitArray bitar = GetBitArrayFromByte(rgbValues[pos]);

                    int xtra = 4;

                    if (xrest >= 1)
                    {
                        xtra = 0;
                    }

                    //per requirement the start point is represented as red
                    if (i == 0)
                    {
                        bitar[xtra + 3] = true;
                        bitar[xtra + 2] = false;
                        bitar[xtra + 1] = false;
                        bitar[xtra + 0] = true;
                    }
                    else if (i == path.Count - 1) //per requirement the end point is represented as blue
                    {
                        bitar[xtra + 3] = false;
                        bitar[xtra + 2] = true;
                        bitar[xtra + 1] = false;
                        bitar[xtra + 0] = false;
                    }
                    else //per requirement solution will be highlited in green
                    {
                        bitar[xtra + 3] = true;
                        bitar[xtra + 2] = false;
                        bitar[xtra + 1] = true;
                        bitar[xtra + 0] = false;
                    }
                    rgbValues[pos] = (byte)GetIntFromBitArray(bitar);
                }

                Marshal.Copy(rgbValues, 0, pointer, bytes);
                bitmap.UnlockBits(bmpData);
                bitmap.Save(fileName, imageFormat);
            }
        }