static void FloodFill(Point pos, Color col) { //Base Cases: //Is my position off-canvas to right or bottom if (pos.X >= Draw.ScaledWidth || pos.Y >= Draw.ScaledHeight) { return; } //Is this position off-canvas to top or left if (pos.X < 0 || pos.Y < 0) { return; } //What is the color of my current pixel Color Pixel = Draw.GetBBPixel(pos.X * Draw.Scale, pos.Y * Draw.Scale); bool IsBlack = (Pixel.R == 0 && Pixel.G == 0 && Pixel.B == 0); //If it's already colored, we're done (for now) if (!IsBlack) { return; } //Color the pixel Draw.SetBBScaledPixel(pos.X, pos.Y, col); Thread.Sleep(100); //Launch Floodfill for my 4 neighbors FloodFill(new Point(pos.X + 1, pos.Y), col); FloodFill(new Point(pos.X - 1, pos.Y), col); FloodFill(new Point(pos.X, pos.Y + 1), col); FloodFill(new Point(pos.X, pos.Y - 1), col); }
///////////////////////////////////////////////Method\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ /************************************************************************************************ * Method: Wanderer() * Effect: Receives an object of strucure when thread is started. A random color will be chosen, * and will draw pixels based on a random direction/velocity. * **********************************************************************************************/ public static void Wanderer(object holder) { DrawingData info = (DrawingData)(holder); //Unboxes structure Color drawingColor = RandColor.GetColor(); //Holds random color for drawing Point newPoint = info.m_pCoor; drawSpace.SetBBScaledPixel(info.m_pCoor.X, info.m_pCoor.Y, drawingColor); drawSpace.Render(); //Draw pixels for (int i = 0; i < info.m_iPixels; i++) { newPoint.X += rnd.Next(-1, 2); newPoint.Y += rnd.Next(-1, 2); newPoint.X = (newPoint.X < 0) ? 0 : newPoint.X; newPoint.Y = (newPoint.Y < 0) ? 0 : newPoint.Y; newPoint.X = (newPoint.X > 799) ? 799 : newPoint.X; newPoint.Y = (newPoint.Y > 599) ? 599 : newPoint.Y; drawSpace.SetBBScaledPixel(newPoint.X, newPoint.Y, drawingColor); Thread.Sleep(1); drawSpace.Render(); } //lock gdi drawer during loop }
public static void DrawWorldMap(Location CurrentLocation) { CDrawer Canvas = new CDrawer(1000, 1000); Canvas.Clear(); Canvas.Scale = 50; int[] cordarray = new int[2] { 0, 0 }; for (int row = 0; row < MapArray.GetLength(0); row++) { for (int columb = 0; columb < MapArray.GetLength(1); columb++) { foreach (Location locals in Locations) { if (locals.Coordinates.SequenceEqual(cordarray)) { Canvas.SetBBScaledPixel(row, columb, Color.Red); Canvas.AddText(locals.Name, 10, row, columb, 1, 1, Color.White); } if (CurrentLocation.Coordinates.SequenceEqual(cordarray)) { Canvas.SetBBScaledPixel(row, columb, Color.Green); } } cordarray[1]++; } cordarray[1] = 0; cordarray[0]++; } }
private void grow() { canvas.SetBBScaledPixel(start.X, start.Y, color); pointDict.Add(this.start, 64); Point cur_point = start; while (growing) { List<Point> adjacent = this.getAdjacent(cur_point); adjacent.ShuffleList(); var paired_list = adjacent.ToDictionary(x => x, x => pointDict.ContainsKey(x) ? pointDict[x] : 0).ToList(); paired_list.Sort((x, y) => x.Value.CompareTo(y.Value)); cur_point = paired_list[0].Key; if (pointDict.ContainsKey(cur_point)) { pointDict[cur_point] += (pointDict[cur_point] <= 191) ? 64 : 255 - pointDict[cur_point]; color_strength = pointDict[cur_point]; } else { pointDict.Add(cur_point, 64); color_strength = 64; } updateColor(); canvas.SetBBScaledPixel(cur_point.X, cur_point.Y, color); canvas.Render(); Thread.Sleep(1); } }
// Thread to traverse 2D grid in random fashion private void TraverseGridRandomly() { int steps = 0; CDrawer canvas = new CDrawer(WIDTH, HEIGHT); int[,] grid = new int[X_MAX, Y_MAX]; // 2D backing array for the grid Point current = new Point(0, 0); Point previous = new Point(0, 0); List <Point> nextPossiblePoint = new List <Point>(); // List of valid moves canvas.Scale = BLOCKSIZE; // Initialize each grid location with nominal value; for (int x = 0; x < X_MAX; ++x) { for (int y = 0; y < Y_MAX; ++y) { grid[x, y] = BASE_RGB_VALUE; } } while (!HasTravelledAll(grid)) { ++steps; // Increment intensity of current color to max of 255 grid[current.X, current.Y] = grid[current.X, current.Y] + 3 > 255 ? 255 : grid[current.X, current.Y] + 3; // Draw previous point in yellow - ignore initial start if (steps != 1) { canvas.SetBBScaledPixel(previous.X, previous.Y, Color.FromArgb(grid[previous.X, previous.Y], grid[previous.X, previous.Y], 0)); } // Draw current point location in red canvas.SetBBScaledPixel(current.X, current.Y, Color.Red); previous = current; // Clear previous list of valid movement and update list and move to new Point nextPossiblePoint.Clear(); nextPossiblePoint = validLocation(current); current = nextPossiblePoint[_rnd.Next(0, nextPossiblePoint.Count)]; } // Display number of steps on screen canvas.AddText(steps.ToString() + " Steps Taken", 25, Color.Blue); try { Invoke(new delVoidInt(UpdateUI), steps); } catch { System.Diagnostics.Trace.WriteLine("Target thread is dead"); } }
//whenever user presses the generate button, fill the GDI window //at randomly selected locations with the user choice from trackbar private void generateBtn_Click(object sender, EventArgs e) { int nIterate1 = 0; //iterate var 1 for 2D array int nIterate2 = 0; //iterate var 2 for 2D array int xPos = 0; //xPos of GDI window int yPos = 0; //yPos of GDI window int fillCount = 0; //determine how many pixels to fill in Random rnd = new Random(); //random number generator //2 for loops to iterate through 2D array for (nIterate1 = 0; nIterate1 < 80; nIterate1++) { for (nIterate2 = 0; nIterate2 < 60; nIterate2++) { //set color to black _fillColor[nIterate1, nIterate2] = Color.Black; } } //2 for loops to iterate through 2D array for (nIterate1 = 0; nIterate1 < 80; nIterate1++) { //create red border for left and right of GDIwindow _fillColor[nIterate1, 0] = Color.Red; _fillColor[nIterate1, 59] = Color.Red; for (nIterate2 = 0; nIterate2 < 60; nIterate2++) { //create red border for top and bottom of GDI window _fillColor[0, nIterate2] = Color.Red; _fillColor[79, nIterate2] = Color.Red; } } //set number of pixels to fill from trackbar fillCount = blockTrackbar.Value; //for loop to iterate through 2D array for (nIterate1 = 0; nIterate1 < fillCount; nIterate1++) { //choose random x and y values to fill xPos = rnd.Next(1, 79); yPos = rnd.Next(1, 59); //fill 2D array with randomly chosen x and y values _fillColor[xPos, yPos] = Color.Red; } //2 for loops to iterate through 2D array for (nIterate1 = 0; nIterate1 < 80; nIterate1++) { for (nIterate2 = 0; nIterate2 < 60; nIterate2++) { //set pixels in GDI window from randomly selected locations to red color _Canvas.SetBBScaledPixel(nIterate1, nIterate2, _fillColor[nIterate1, nIterate2]); } } }
//*********************************************************************************************************************************************** //Purpose: recursive method as an attempt to solve a loaded maze, checking surrounding positions to find the valid path. //Parameter:MazeInfo maze - used to determine the current state of maze (solved or not) and the steps taken to solve the maze // Point curPos - the moved position to check if the current position is a valid path to take //Returns: The maze's updated detail will be returned to check if the maze was solved or not //*********************************************************************************************************************************************** private MazeInfo MazeSolver(MazeInfo maze, Point curPos) { if (!_mazeDets.result && !_cancel) { Thread.Sleep(_throttle); //exit conditions if (curPos.X == maze.endPos.X && curPos.Y == maze.endPos.Y) { _stop.Stop(); _mazeDets.result = true; //changes the state and label of buttons this.Invoke(new MethodInvoker(delegate() { btnSolve.Enabled = false; })); this.Invoke(new MethodInvoker(delegate() { btnSolve.Text = "Solve"; })); this.Invoke(new MethodInvoker(delegate() { btnLoad.Enabled = true; })); //adds the collected final information to the listbox this.Invoke(new MethodInvoker(delegate() { listMazeLog.Items.Insert(0, $"The maze is solved in {maze.steps} steps / {_stop.ElapsedMilliseconds}ms"); })); return(maze); } //out of bounds -> return to previous position //wall/visited -> return to previous position if (curPos.X < 0 || curPos.X >= maze.mazeWidth || curPos.Y < 0 || curPos.Y >= maze.mazeHeight || _state[curPos.Y, curPos.X] == Wall.wall || _state[curPos.Y, curPos.X] == Wall.visited) { return(maze); } //will not colour the starting green pixel to another colour if (curPos.X != maze.startPos.X || curPos.Y != maze.startPos.Y) { _canvas.SetBBScaledPixel(curPos.X, curPos.Y, maze.livePath); _canvas.Render(); } maze.steps += 1; _state[curPos.Y, curPos.X] = Wall.visited; //attempt to move position MazeSolver(maze, new Point(curPos.X + 1, curPos.Y)); MazeSolver(maze, new Point(curPos.X - 1, curPos.Y)); MazeSolver(maze, new Point(curPos.X, curPos.Y - 1)); MazeSolver(maze, new Point(curPos.X, curPos.Y + 1)); //reached a dead end, colour the return path to grey if (_mazeDets.result == false) { _canvas.SetBBScaledPixel(curPos.X, curPos.Y, maze.deadPath); _canvas.Render(); } } return(_mazeDets); }
static void RandomBlocks() { Random rnd = new Random(); CDrawer can = new CDrawer(); System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch(); watch.Reset(); watch.Start(); can.AddText("Random Known Colors SetBBPixel : 2s", 28, 0, 0, can.ScaledWidth, can.ScaledHeight, Color.White); can.AddText("Random Known Colors SetBBPixel : 2s", 28, 2, 2, can.ScaledWidth + 2, can.ScaledHeight + 2, Color.Black); while (watch.ElapsedMilliseconds < 2000) { can.SetBBPixel(rnd.Next(can.ScaledWidth), rnd.Next(can.ScaledHeight), RandColor.GetKnownColor()); } can.Close(); can = new CDrawer(800, 800); can.Scale = 10; Console.WriteLine("Random Known Colors SetBBScaledPixel : 2s"); watch.Reset(); watch.Start(); can.AddText("Random Known Colors SetBBScaledPixel : 2s", 24); while (watch.ElapsedMilliseconds < 2000) { can.SetBBScaledPixel(rnd.Next(can.ScaledWidth), rnd.Next(can.ScaledHeight), RandColor.GetKnownColor()); } can.Close(); }
/// <summary> /// the classes main worker function more or less it loads up the form /// </summary> void Load() { try { // load in a bit map Bitmap TempBitMap = (Bitmap)Bitmap.FromFile(Path); //--------------------------------------------------------------------------- // the manditory check remove for any size if (TempBitMap.Width > 190 || TempBitMap.Height > 100) { throw new Exception("We are sorry but the image is too big. Please keep the images size to 190px by 100px as a larger object could result in a stack overflow. "); } //---------------------------------------------------------------------------------- // if the file loads close the old one if it is not Null and create a display box insished to what we need based on the bit map Display?.Close(); Display = new CDrawer(TempBitMap.Width * 10, TempBitMap.Height * 10, false); Display.Scale = 10; // create a spaces state identifyer as a 2D rep of it SpaceStates[,] Spaces = new SpaceStates[TempBitMap.Width, TempBitMap.Height]; // Set up a End and Start Point End = new Point(); Point Start = new Point(); // now we can begin a case by case pixle checking/ set them in the box for (int x = 0; x < TempBitMap.Width; x++) { for (int y = 0; y < TempBitMap.Height; y++) { Display.SetBBScaledPixel(x, y, TempBitMap.GetPixel(x, y)); // if it is black it is a wall if (TempBitMap.GetPixel(x, y) == Color.FromArgb(0, 0, 0)) { Spaces[x, y] = SpaceStates.closed; } // else its open but that is the default state so checking and writing will just slow us down // so now we check for start(green) and end(red) that fall into the open side and store them acordingly else if (TempBitMap.GetPixel(x, y) == Color.FromArgb(255, 0, 0))// red end { End = new Point(x, y); } else if (TempBitMap.GetPixel(x, y) == Color.FromArgb(0, 255, 0))// green start { Start = new Point(x, y); } } } if (End.X == 0 && End.Y == 0 && Start.X == 0 && Start.Y == 0) { throw new Exception("odd the maze seems to be missing start or end or we some how put them on top of one another"); } // only at the end render them Display.Render(); Maze.DoneLoadCallBack.Invoke(Display, Start, End, Spaces); } //throw out some message boxes for failed attempts catch (Exception e) { MessageBox.Show(e.Message); } }
/*********************************** * Author: Angelo M Sanches * Does the actual drawing *************************************/ private void DrawChecker_Tick(object sender, EventArgs e) { // get a point of last mouse click scaled Point Point; if (Box.GetLastMouseLeftClickScaled(out Point)) { // we draw off cursor if using extended draw if (Ch_DrawShape.Checked) { for (int i = 0; i < DrawLife.GetLength(0); i++) { for (int j = 0; j < DrawLife.GetLength(1); j++) { // for each point draw off of the click Eco[LimWraper(Point.X + i, 0, Eco.GetLength(0)), LimWraper(Point.Y + j, 0, Eco.GetLength(1))].bIsAlive = DrawLife[i, j].bIsAlive; Eco[LimWraper(Point.X + i, 0, Eco.GetLength(0)), LimWraper(Point.Y + j, 0, Eco.GetLength(1))].Colour = DrawLife[i, j].Colour; } } // re-render all Draw(); } // else we just set a single point and render that difference else { if (!Eco[Point.X, Point.Y].bIsAlive) { Eco[Point.X, Point.Y].bIsAlive = true; Eco[Point.X, Point.Y].Colour = Colour; Box.SetBBScaledPixel(Point.X, Point.Y, Colour); } else { Eco[Point.X, Point.Y].bIsAlive = false; Box.SetBBScaledPixel(Point.X, Point.Y, Color.Black); } Box.Render(); } } }
/*********************************** * Author: Angelo M Sanches * draws every time we click or eraces if need be *************************************/ private void DrawCheck_Tick(object sender, EventArgs e) { Point Get; if (Drawer.GetLastMouseLeftClickScaled(out Get)) { if (!DrawLife[Get.X, Get.Y].bIsAlive) { DrawLife[Get.X, Get.Y].bIsAlive = true; DrawLife[Get.X, Get.Y].Colour = DrawColour; Drawer.SetBBScaledPixel(Get.X, Get.Y, DrawColour); } else { DrawLife[Get.X, Get.Y].bIsAlive = false; Drawer.SetBBScaledPixel(Get.X, Get.Y, Color.Black); } Drawer.Render(); } }
static void FloodFill(Point pos, Color col) { if (pos.X >= Draw.ScaledWidth || pos.Y >= Draw.ScaledHeight) { return; } if (pos.X < 0 || pos.Y < 0) { return; } Color Pixel = Draw.GetBBPixel(pos.X * Draw.Scale, pos.Y * Draw.Scale); bool IsBlack = (Pixel.R == 0 && Pixel.G == 0 && Pixel.B == 0); if (!IsBlack) { return; } Draw.SetBBScaledPixel(pos.X, pos.Y, col); FloodFill(new Point(pos.X + 1, pos.Y), col); FloodFill(new Point(pos.X - 1, pos.Y), col); FloodFill(new Point(pos.X, pos.Y + 1), col); FloodFill(new Point(pos.X, pos.Y - 1), col); }
private void Draw(ref CDrawer drawer, int[,] cellArray, ref Color cellcolor) //draw the canvas { drawer.BBColour = Color.Black; for (int i = 0; i < cellArray.GetLength(0); i++) { for (int j = 0; j < cellArray.GetLength(1); j++) { if (cellArray[i, j] == 1) { drawer.SetBBScaledPixel(i, j, cellcolor); } } } drawer.Render(); }
//Draws the current contents of the specified array //onto the gdi canvas private void DisplayArray(byte[,] arr) { canvas.BBColour = Color.Black; for (int i = 0; i < 80; i++) { for (int j = 0; j < 60; j++) { if (arr[i, j] == 1) { canvas.SetBBScaledPixel(i, j, userColor); } } } canvas.Render(); }
Color DrawColour; // our draw colour /*********************************** * Author: Angelo M Sanches * insih all needed values *************************************/ public DrawModel(int nScale, Form1.Life[,] Colours) { InitializeComponent(); Scale = nScale; trackBar1.Value = Colours.GetLength(1); DrawColour = Color.Red; Drawer = new CDrawer(Scale * trackBar1.Value, Scale * trackBar1.Value, false); Drawer.Scale = Scale; DrawLife = Colours; DrawCheck.Enabled = true; // draws the last thing we had for (int i = 0; i < DrawLife.GetLength(0); i++) { for (int j = 0; j < DrawLife.GetLength(1); j++) { if (DrawLife[i, j].bIsAlive) { Drawer.SetBBScaledPixel(i, j, DrawLife[i, j].Colour); } } } // renders it Drawer.Render(); }
/* ******************************************************************** * Funtion: private MazeInfo Recursive_Method(Point p_, MazeInfo maze_s) * Parameters: Point p_, MazeInfo maze_s * Return: Maze info object that indicates maze is solved or not * Funtionality: Solves the maze recursively if the dead end is reached it backtracks and showing a backtracking * in a different color ***********************************************************************/ private MazeInfo Recursive_Method(Point p_, MazeInfo maze_s) { if (stop == true) { maze_s.solved = true; return(maze_s); } //check if the point is out of bounds if it is return if (p_.X >= canvas.ScaledWidth || p_.X < 0 || p_.Y >= canvas.ScaledHeight || p_.Y < 0) { maze_s.solved = false; return(maze_s); } //check if the point has reached the end if it is return and set solved to true if (p_ == MazeInfo_struct.p_end) { maze_s.solved = true; return(maze_s); } //if there is obstacle wall or the obstacle has been visited set the maze solved to false if ((Obs_array[p_.X, p_.Y] == Obstacle.wall) || ((Obs_array[p_.X, p_.Y] == Obstacle.visited))) { maze_s.solved = false; return(maze_s); } //increase the steps or count the total number of steps it took to solve the masze maze_s.steps++; //if we are checking the point that means it has been visited Obs_array[p_.X, p_.Y] = Obstacle.visited; //set the speed if (p_ != MazeInfo_struct.p_end && p_ != MazeInfo_struct.p_start) { if (numericUpDownSpeed.Value > 0) { maze_s.solved = true; int speed = (int)numericUpDownSpeed.Value * 10; Thread.Sleep(speed); } } //If it is not equal to start draw the correct solution if (p_ != maze_s.p_start) { canvas.SetBBScaledPixel(p_.X, p_.Y, maze_s.Sol_color); canvas.Render(); } //recurse in all directions if the maze is solved set the flag to solved //and return //checks x+1 direction if maze is solved true is returned maze_s = Recursive_Method(new Point(p_.X + 1, p_.Y), maze_s); if (maze_s.solved) { maze_s.solved = true; return(maze_s); } //checks the x -1 direction if maze is solved true is returned maze_s = Recursive_Method(new Point(p_.X - 1, p_.Y), maze_s); if (maze_s.solved) { maze_s.solved = true; return(maze_s); } //checks y +1 direction if maze is solved true is returned maze_s = Recursive_Method(new Point(p_.X, p_.Y + 1), maze_s); if (maze_s.solved) { maze_s.solved = true; return(maze_s); } //checks y -1 direction if maze is solved true is returned maze_s = Recursive_Method(new Point(p_.X, p_.Y - 1), maze_s); if (maze_s.solved) { maze_s.solved = true; return(maze_s); } //if no solution was found that means there is a dead end. //show the dead end in a dead end color //this is basically backtracking. if (p_ != maze_s.p_start) { canvas.SetBBScaledPixel(p_.X, p_.Y, maze_s.Dead_color); canvas.Render(); } //no solution was found return false maze_s.solved = false; return(maze_s); }
/******************************************************* * Funtion: private void CreateCanvas(Bitmap bm) * Parameters: Bitmap bm * Returns : void * Funtionality: It Loads and scaled the new bitmap image on canvas * *****************************************************/ private void CreateCanvas(Bitmap bm, string filename) { //set the appropriate scale // You are required to adjust the drawer scale value to allow for the //mazes to fit on the screen ( after placement ). If a scale of 1 still won't fit, //you may reject the maze at load time. int scale; if ((bm.Height < 50) && (bm.Width < 50)) { scale = 10; } else if ((bm.Height < 100) && (bm.Width < 100)) { scale = 6; } else if (bm.Height < 100 && bm.Width < 200) { scale = 5; } else if ((bm.Height >= 100 && bm.Height < 250) && (bm.Width >= 100 && bm.Width < 250)) { scale = 4; } else if ((bm.Height >= 250 && bm.Height <= 300) && (bm.Width >= 250 && bm.Width < 500)) { scale = 2; } else { scale = 1; } // allocate a new CDrawer of the appropriate size(ie.If bitmap is 40x30, then allocate( 40 * 10, 30 * 10 ) ). canvas = new CDrawer(MazeInfo_struct.width * scale, MazeInfo_struct.height * scale);//create the GDI Drawer canvas.Scale = scale; canvas.Render(); //turn continuous update to false canvas.ContinuousUpdate = false; //and the background to white. canvas.BBColour = Color.White; canvas.Render(); //create a new instance of the 2D array Obs_array = new Obstacle[MazeInfo_struct.width, MazeInfo_struct.height]; for (int row = 0; row < MazeInfo_struct.height; row++) { for (int col = 0; col < MazeInfo_struct.width; col++) { //draw the image onto the canvas //use SetBBScaledPixel() of the drawer to populate the drawer background with our maze canvas.SetBBScaledPixel(col, row, bm.GetPixel(col, row)); canvas.Render();//render to show /* assign your member maze array to a new 2D array of enumeration of dimensions [ maxCol, maxRow ], * //as this will internally represent our maze for processing. * //Our premise will be : value open = open spot to explore * //value wall = wall, can't go there * //value visited = been there, done that, don't go */ if (bm.GetPixel(col, row) == Color.FromArgb(0, 0, 0)) { Obs_array[col, row] = Obstacle.wall;//if the color is black * set that array location in our maze array = 1 ( wall ) } else if (bm.GetPixel(col, row) == Color.FromArgb(255, 255, 255)) { Obs_array[col, row] = Obstacle.open;// if the color is white, set that array location in our maze array = 0 ( open ) } // if the color is green, set the start point member to this X / Y, Col / //Row location indicating the maze start location else if (bm.GetPixel(col, row) == Color.FromArgb(0, 255, 0)) { MazeInfo_struct.p_start.X = col; MazeInfo_struct.p_start.Y = row;; } // if the color is red, set the start //point member to this X / Y, Col / Row location indicating the maze end location else if (bm.GetPixel(col, row) == Color.FromArgb(255, 0, 0)) { MazeInfo_struct.p_end.X = col; MazeInfo_struct.p_end.Y = row; } } } //file is loaded set the enabled to true and able the button solve buttonSolve.Enabled = true; filename_ = filename.Split('\\'); listBoxData.Items.Add($"Loaded: {filename_[7]}"); }
/// <summary> /// When the load button is pressed loading the bitmap into the cdrawer and parcing the information that we need to solve the map /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void UI_btn_Load_Click(object sender, EventArgs e) { //variable that represents the current scale factor on the maze int mapScaling = 10; //initalizing a file dialog to hand OpenFileDialog openFileDialog1 = new OpenFileDialog(); //customizing the filters in the dialog to only show .bmp or all files openFileDialog1.Filter = "All files(*.*)|*.*|bmp files (*.bmp)|*.bmp"; //setting the inital directory openFileDialog1.InitialDirectory = Path.GetFullPath(Environment.CurrentDirectory + @"\..\.."); //opening the file dialog and if the ok button is pressed if (openFileDialog1.ShowDialog() == DialogResult.OK) { try { if (_canvas != null)//trying to close a canvas if the canvas is not null { _canvas.Close(); } //importing the new bitmap from the file dialog Bitmap bm = new Bitmap(openFileDialog1.FileName); //if the bit map is a medium sized bit map setting the scaling appropriately if (bm.Width > 150 || bm.Height > 100) { //throw new Exception("Bitmap Exceeds Size Requirements"); mapScaling = 5; } //if the bit map is larger reducing the scaling to make it fit the screen if (bm.Width > 200 || bm.Height > 150) { mapScaling = 2; } //creating a new enum array set to the width and height of the bitmap mazeArray = new state[bm.Width, bm.Height]; //creating a new canvas set to the height and width of the bitmap scaled with continuous update off, pixel scale set to the scaling and a background of white _canvas = new CDrawer(bm.Width * mapScaling, bm.Height * mapScaling, false, false) { Scale = mapScaling, BBColour = Color.White }; //moving the canvas to be right next to the form _canvas.Position = new Point(Location.X + Width, Location.Y); //moving through the bit maps x and y coords for (int y = 0; y < bm.Height; ++y) { for (int x = 0; x < bm.Width; ++x) { //getting the color of the current pixel _canvas.SetBBScaledPixel(x, y, bm.GetPixel(x, y)); if (bm.GetPixel(x, y) == Color.FromArgb(0, 0, 0))//if its black setting it to a wall state in the enum array { mazeArray[x, y] = state.wall; } if (bm.GetPixel(x, y) == Color.FromArgb(255, 255, 255))//if its white setting it to open state in the array { mazeArray[x, y] = state.open; } if (bm.GetPixel(x, y) == Color.FromArgb(255, 0, 0))//if its red setting that pixel as the maze exit { _maze._mEnd = new Point(x, y); } if (bm.GetPixel(x, y) == Color.FromArgb(0, 255, 0))//if its green setting that pixel as the maze entrance { _maze._mStart = new Point(x, y); } } } //rendering the canvas _canvas.Render(); //setting the name of the form to the file name Text = Path.GetFileName(openFileDialog1.FileName); //displaying that the file has been loaded to the user with the dimensions UI_LB_MessageViewer.Items.Insert(0, $"Loaded: {Path.GetFileName(openFileDialog1.FileName)} file Dimensions {bm.Width} X {bm.Height}"); //saving the file name for later use _file = Path.GetFileName(openFileDialog1.FileName).ToString(); //initialing the maze info struct _maze._xWidth = bm.Width; //setting the maze width _maze._yHeight = bm.Height; //setting the maze height _maze._cSol = UI_BTN_SColor.BackColor; //setting the color of the solution path _maze._cDed = UI_btn_DColor.BackColor; //setting the color of the visited path _maze._steps = 0; //initializing the step counter _maze._solved = false; //setting solved to false } catch (Exception ex) { MessageBox.Show(ex.Message); //catching exceptions during the loading process } UI_btn_Solve.Enabled = true; //enabling the solve button } }
/// <summary> /// moving through the maze recursively to find the correct path through the maze /// </summary> /// <param name="maze">the information about the maze</param> /// <param name="curPo">the starting position of the recursive function</param> /// <returns></returns> private MazeInfo recSolve(MazeInfo maze, Point curPo) { //if the cancel button is pressed escaping the function //setting the steps to zero and that the maze was not solved if (cancel == true) { maze._steps = 0; maze._solved = false; return(maze); } //if the maze exit is reached marking the maze as solve and escaping the function if (curPo == maze._mEnd) { maze._solved = true; return(maze); } //if the current position of the function is out of bounds backing up if ((curPo.X >= maze._xWidth) || (curPo.X < 0) || (curPo.Y >= maze._yHeight) || (curPo.Y < 0)) { return(maze); } //if the current position of the function is in a wall backing up if (mazeArray[curPo.X, curPo.Y] == state.wall) { return(maze); } //if the current position of the function is a pixel that has been visited already backing up if (mazeArray[curPo.X, curPo.Y] == state.visited) { return(maze); } //if the current position is not the start of the maze if (curPo != maze._mStart) { mazeArray[curPo.X, curPo.Y] = state.visited; //setting that pixel to visited _canvas.SetBBScaledPixel(curPo.X, curPo.Y, maze._cSol); //setting the color to the solution color _canvas.Render(); //rendering the canvas } //incrementing the step counter maze._steps += 1; //if the speed is not zero sleeping the solver if (speed != 0) { Thread.Sleep(speed); } //attempting to move the solver in each direction in the order (up, right, down, left) moving down 1 level of recursion if ((maze = recSolve(maze, new Point(curPo.X, curPo.Y + 1)))._solved) { return(maze); } if ((maze = recSolve(maze, new Point(curPo.X + 1, curPo.Y)))._solved) { return(maze); } if ((maze = recSolve(maze, new Point(curPo.X, curPo.Y - 1)))._solved) { return(maze); } if ((maze = recSolve(maze, new Point(curPo.X - 1, curPo.Y)))._solved) { return(maze); } //if the maze wasn't solve moving down the chain of recursion if (curPo != maze._mStart) { _canvas.SetBBScaledPixel(curPo.X, curPo.Y, maze._cDed); //setting the current path to the visited color _canvas.Render(); //rendering the canvas } //decrementing the steps maze._steps -= 1; //moving up 1 level of recursion return(maze); }
//Occurs everytime the 'Load' button is pressed. Attempts to open a bitmap file onto the canvas //Side-Effect: sets the maze's information while scanning the bitmap private void BtnLoad_Click(object sender, EventArgs e) { int x, y; //position of the pixels on bitmap bool good = true; //used to see if the file we are trying to open is valid OpenFileDialog openFile = new OpenFileDialog(); string path = Path.GetFullPath(Environment.CurrentDirectory + @"\..\..\mazes"); //initial settings for the open file dialog openFile.InitialDirectory = path; openFile.Title = "Load Bitmap maze to solve"; openFile.Filter = "Bitmaps (*.bmp)|*.bmp|All files (*.*)|*.*"; Bitmap map = null; _mazeDets = new MazeInfo { livePath = Color.Orange, deadPath = Color.Gray }; //checked to see if the file was able to open try { //user chooses a file to open if (openFile.ShowDialog() == DialogResult.OK) { //loads the bitmap file map = new Bitmap(openFile.FileName); //checks the valid size(x, y) of the bitmap file try {//sets the scale as an attempt to fit the bitmap onto the canvas if (map.Height * map.Width < 10000) { _scale = 10; } else if (map.Height * map.Width < 20000) { _scale = 8; } else if (map.Height * map.Width < 150000) { _scale = 3; } else if (map.Height * map.Width < 450000) { _scale = 2; } else if (map.Height * map.Width < 1260000) { _scale = 1; } else { throw new Exception(); } } //error message for the bitmap file that is too big catch (Exception) { MessageBox.Show("Bitmap size exceeds displayable area", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); good = false; } } //user decided to close the open file dialog else { good = false; } } //error message when the file chosen could not be opened catch (Exception ex) { MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); good = false; } if (good) { //creates a 2D array of enumeration to set the state of the pixel (open, wall, visited) _state = new Wall[map.Height + 1, map.Width + 1]; _mazeDets.mazeHeight = map.Height; _mazeDets.mazeWidth = map.Width; if (_canvas != null) { _canvas.Close(); } //new canvas with appropriately adjusted size _canvas = new CDrawer(map.Width * _scale, map.Height * _scale, false) { Scale = _scale, BBColour = Color.White }; //loads the scaled pixels from bitmap onto CDrawer canvas //depending on the colour of the pixel, decide the state and put it in 2D Enum array for (y = 0; y < map.Height; y++) { for (x = 0; x < map.Width; x++) { //black pixel found? It's a wall if (map.GetPixel(x, y) == Color.FromArgb(255, 0, 0, 0)) { _state[y, x] = Wall.wall; } //white pixel found? It's an open path else if (map.GetPixel(x, y) == Color.FromArgb(255, 255, 255)) { _state[y, x] = Wall.open; } //finds position of start of the maze (green pixel) if (map.GetPixel(x, y) == Color.FromArgb(0, 255, 0)) { _mazeDets.startPos.X = x; _mazeDets.startPos.Y = y; } //finds the position of end of the maze (red pixel) if (map.GetPixel(x, y) == Color.FromArgb(255, 0, 0)) { _mazeDets.endPos.X = x; _mazeDets.endPos.Y = y; } _canvas.SetBBScaledPixel(x, y, map.GetPixel(x, y)); } } //sets the postion of the canvas so it loads right next to the form _canvas.Position = new Point(Location.X + Size.Width + 10, Location.Y); _canvas.Render(); btnSolve.Enabled = true; listMazeLog.Items.Insert(0, $"Loaded: {Path.GetFileName(openFile.FileName)}"); } }
static void Main(string[] args) { Random rng = new Random(); int xVelocity = 1; //the rate at which the ball moves on the X plane int yVelocity = 1; //the rate at which the ball moves on the Y plane int xBall = 80; int yBall = 60; int wallTop = 0; //top boundry of screen/game int wallRight = 0; //right boundry of screen/game int wallBottom = 0; //bottom boundry of screen/game bool playAgain = true; Point playerPosition; //location of mouse so paddle can be appropriately set on the Y plane const int playerPositionX = 0; //the constant postion of the paddle against the left side of screen CDrawer gdi = new CDrawer(); gdi.Scale = 5; gdi.ContinuousUpdate = false; do { while (true) { //sets the boundry for the ball with as a visual for (wallTop = 0; wallTop < 160; wallTop = ++wallTop) { gdi.SetBBScaledPixel(wallTop, 0, Color.SkyBlue); } for (wallRight = 0; wallRight < 120; wallRight = ++wallRight) { gdi.SetBBScaledPixel(wallTop - 1, wallRight, Color.SkyBlue); } for (wallBottom = 0; wallBottom < 160; wallBottom = ++wallBottom) { gdi.SetBBScaledPixel(wallBottom, wallRight - 1, Color.SkyBlue); } //the ball while (xBall < wallRight && yBall < wallTop && yBall > wallBottom) { gdi.AddRectangle(xBall, yBall, 2, 2, Color.Gainsboro); //the paddle gdi.GetLastMousePosition(out playerPosition); //playerPositionYStart = playerPositionYStart + playerPosition; gdi.AddLine(playerPositionX, (playerPosition.Y + 25) / 5, playerPositionX, (playerPosition.Y - 25) / 5, Color.DarkRed, 10); //the delay, new images then removal of old images to create "animation" gdi.Render(); System.Threading.Thread.Sleep(20); gdi.Clear(); xBall += xVelocity; yBall += yVelocity; } } playAgain = false; } while (playAgain); }
// Biased Grid Traverse Thread private void BiasedTraverse() { int steps = 0; CDrawer canvas = new CDrawer(WIDTH, HEIGHT); int[,] grid = new int[X_MAX, Y_MAX]; // 2D backing array of color intensity for the grid Point current = new Point(0, 0); Point previous = new Point(0, 0); // List of valid biased movements List <Point> nextPossiblePoint = new List <Point>() { current }; // List of all points not travelled to List <Point> HaveNotTraversed = new List <Point>(); canvas.Scale = BLOCKSIZE; // Initialization: each grid location with base color intensity // and include all points as not travelled to for (int x = 0; x < X_MAX; ++x) { for (int y = 0; y < Y_MAX; ++y) { grid[x, y] = BASE_RGB_VALUE; HaveNotTraversed.Add(new Point(x, y)); } } while (HaveNotTraversed.Count > 0) { ++steps; HaveNotTraversed.Remove(current); // Increment intensity of current color to max of 255 grid[current.X, current.Y] = grid[current.X, current.Y] + 25 > 255 ? 255 : grid[current.X, current.Y] + 25; // Draw previous point in yellow if (steps != 1) { canvas.SetBBScaledPixel(previous.X, previous.Y, Color.FromArgb(grid[previous.X, previous.Y], grid[previous.X, previous.Y], 0)); } // Draw current point in red canvas.SetBBScaledPixel(current.X, current.Y, Color.Red); previous = current; // Clear list and update biased travel directions and move nextPossiblePoint.Clear(); nextPossiblePoint = ClosestSpace(current, HaveNotTraversed); if (nextPossiblePoint.Count > 0) { current = nextPossiblePoint[_rnd.Next(0, nextPossiblePoint.Count)]; } } // Display number of steps to complete travel canvas.AddText(steps.ToString() + " Steps Taken", 25, Color.Blue); try { Invoke(new delVoidInt(UpdateUI), steps); } catch { System.Diagnostics.Trace.WriteLine("Target thread is dead"); } }