/** <summary> Gets if the specified quadrant is solid. </summary> */ public bool IsQuadrantSolid(Point point) { if (point.X < 0 || point.X >= this.blocks.GetLength(0) * 2 || point.Y < 0 || point.Y >= this.blocks.GetLength(1) * 2) { return(true); } MazeBlock block = this.blocks[point.X / 2, point.Y / 2]; if (point.Y % 2 == 0) { if (point.X % 2 == 0) { return(block.Walls.HasFlag(MazeWalls.QuadrantNorthWest)); } else { return(block.Walls.HasFlag(MazeWalls.QuadrantNorthEast)); } } else { if (point.X % 2 == 0) { return(block.Walls.HasFlag(MazeWalls.QuadrantSouthWest)); } else { return(block.Walls.HasFlag(MazeWalls.QuadrantSouthEast)); } } }
/** <summary> Gets if the specified wall is solid. </summary> */ public bool IsWallYSolid(Point point) { if (point.X < 0 || point.X >= this.blocks.GetLength(0) * 2 || point.Y < 0 || point.Y >= this.blocks.GetLength(1) * 2) { return(true); } MazeBlock block = this.blocks[point.X / 2, point.Y / 2]; if (point.X % 2 == 0) { if (point.Y % 2 == 0) { return(block.Walls.HasFlag(MazeWalls.NorthMiddle)); } else { return(block.Walls.HasFlag(MazeWalls.SouthMiddle)); } } else { if (point.Y % 2 == 0) { return(block.Walls.HasFlag(MazeWalls.EastTop)); } else { return(block.Walls.HasFlag(MazeWalls.EastBottom)); } } }
/** <summary> Gets if the specified wall is solid. </summary> */ public bool IsWallXSolid(Point point) { if (point.X < 0 || point.X >= this.blocks.GetLength(0) * 2 || point.Y < 0 || point.Y >= this.blocks.GetLength(1) * 2) { return(true); } MazeBlock block = this.blocks[point.X / 2, point.Y / 2]; if (point.Y % 2 == 0) { if (point.X % 2 == 0) { return(block.Walls.HasFlag(MazeWalls.WestMiddle)); } else { return(block.Walls.HasFlag(MazeWalls.EastMiddle)); } } else { if (point.X % 2 == 0) { return(block.Walls.HasFlag(MazeWalls.SouthLeft)); } else { return(block.Walls.HasFlag(MazeWalls.SouthRight)); } } }
//=========== EDITING ============ #region Editing /** <summary> Resizes the maze to the new specified size. </summary> */ public void ResizeMaze(Size newSize) { MazeBlock[,] newBlocks = new MazeBlock[Math.Max(1, newSize.Width), Math.Max(1, newSize.Height)]; for (int x = 0; x < newBlocks.GetLength(0); x++) { for (int y = 0; y < newBlocks.GetLength(1); y++) { if (x < this.blocks.GetLength(0) && y < this.blocks.GetLength(1)) { newBlocks[x, y] = this.blocks[x, y]; } else { newBlocks[x, y] = new MazeBlock(); } } } this.blocks = newBlocks; this.Invalidate(); }
/** <summary> Translates the maze by the specified distance. </summary> */ public void TranslateMaze(Point distance) { MazeBlock[,] newBlocks = new MazeBlock[this.blocks.GetLength(0), this.blocks.GetLength(1)]; for (int x = 0; x < newBlocks.GetLength(0); x++) { for (int y = 0; y < newBlocks.GetLength(1); y++) { if (x - distance.X < this.blocks.GetLength(0) && y - distance.Y < this.blocks.GetLength(1)) { newBlocks[x, y] = this.blocks[x - distance.X, y - distance.Y]; } else { newBlocks[x, y] = new MazeBlock(); } } } this.blocks = newBlocks; this.Invalidate(); }
/** <summary> Paints the control. </summary> */ protected override void OnPaint(PaintEventArgs e) { Graphics g = e.Graphics; int P = this.pathWidth; int W = this.wallWidth; int WW = P + W * 3; int WO = P + W * 1; int WO2 = P * 2 + W * 3; int PO = P + W * 3; int TW = P * 2 + W * 4; for (int x = 0; x < this.blocks.GetLength(0); x++) { for (int y = 0; y < this.blocks.GetLength(1); y++) { MazeBlock block = this.blocks[x, y]; Point pos = new Point(x * (P * 2 + W * 4), y * (P * 2 + W * 4)); if (block.Empty) { Pen p = new Pen(GrassOutlineColor); g.DrawRectangle(p, new Rectangle(pos.X, pos.Y, TW - 1, TW - 1)); p.Dispose(); } else if (block.IsEntrance || block.IsExit) { Brush b = new SolidBrush(BuildingColor); g.FillRectangle(b, new Rectangle(pos, new Size(P * 2 + W * 4, P * 2 + W * 4))); b.Dispose(); if (block.IsEntrance) { b = new SolidBrush(BuildingColor2); g.FillRectangle(b, new Rectangle(pos.X + W + P / 2, pos.Y + W + P / 2, P + W * 2, P + W * 2)); b.Dispose(); } b = new SolidBrush(BuildingOutlineColor); g.FillRectangle(b, new Rectangle(pos.X, pos.Y, TW, W)); g.FillRectangle(b, new Rectangle(pos.X, pos.Y, W, TW)); g.FillRectangle(b, new Rectangle(pos.X, pos.Y + WO2, TW, W)); g.FillRectangle(b, new Rectangle(pos.X + WO2, pos.Y, W, TW)); b.Dispose(); b = new SolidBrush(BuildingDoorColor); switch (block.BuildingDirection) { case MazeBuildingDirections.South: g.FillRectangle(b, new Rectangle(pos.X + (TW - P) / 2, pos.Y, P, P)); break; case MazeBuildingDirections.East: g.FillRectangle(b, new Rectangle(pos.X, pos.Y + (TW - P) / 2, P, P)); break; case MazeBuildingDirections.North: g.FillRectangle(b, new Rectangle(pos.X + (TW - P) / 2, pos.Y + TW - P, P, P)); break; case MazeBuildingDirections.West: g.FillRectangle(b, new Rectangle(pos.X + TW - P, pos.Y + (TW - P) / 2, P, P)); break; } b.Dispose(); } else { Brush b = new SolidBrush(PathColor); g.FillRectangle(b, new Rectangle(pos, new Size(P * 2 + W * 4, P * 2 + W * 4))); b.Dispose(); b = new SolidBrush(WallColors[wallStyle]); if (block.Walls.HasFlag(MazeWalls.QuadrantNorthEast)) { g.FillRectangle(b, new Rectangle(pos.X + PO, pos.Y + W, P, P)); } if (block.Walls.HasFlag(MazeWalls.QuadrantSouthEast)) { g.FillRectangle(b, new Rectangle(pos.X + PO, pos.Y + PO, P, P)); } if (block.Walls.HasFlag(MazeWalls.QuadrantSouthWest)) { g.FillRectangle(b, new Rectangle(pos.X + W, pos.Y + PO, P, P)); } if (block.Walls.HasFlag(MazeWalls.QuadrantNorthWest)) { g.FillRectangle(b, new Rectangle(pos.X + W, pos.Y + W, P, P)); } if (block.Walls.HasFlag(MazeWalls.NorthLeft)) { g.FillRectangle(b, new Rectangle(pos.X, pos.Y, WW, W)); } if (block.Walls.HasFlag(MazeWalls.NorthMiddle)) { g.FillRectangle(b, new Rectangle(pos.X + WO, pos.Y, W * 2, WW)); } if (block.Walls.HasFlag(MazeWalls.NorthRight)) { g.FillRectangle(b, new Rectangle(pos.X + WO, pos.Y, WW, W)); } if (block.Walls.HasFlag(MazeWalls.SouthLeft)) { g.FillRectangle(b, new Rectangle(pos.X, pos.Y + WO2, WW, W)); } if (block.Walls.HasFlag(MazeWalls.SouthMiddle)) { g.FillRectangle(b, new Rectangle(pos.X + WO, pos.Y + WO, W * 2, WW)); } if (block.Walls.HasFlag(MazeWalls.SouthRight)) { g.FillRectangle(b, new Rectangle(pos.X + WO, pos.Y + WO2, WW, W)); } if (block.Walls.HasFlag(MazeWalls.EastTop)) { g.FillRectangle(b, new Rectangle(pos.X + WO2, pos.Y, W, WW)); } if (block.Walls.HasFlag(MazeWalls.EastMiddle)) { g.FillRectangle(b, new Rectangle(pos.X + WO, pos.Y + WO, WW, W * 2)); } if (block.Walls.HasFlag(MazeWalls.EastBottom)) { g.FillRectangle(b, new Rectangle(pos.X + WO2, pos.Y + WO, W, WW)); } if (block.Walls.HasFlag(MazeWalls.WestTop)) { g.FillRectangle(b, new Rectangle(pos.X, pos.Y, W, WW)); } if (block.Walls.HasFlag(MazeWalls.WestMiddle)) { g.FillRectangle(b, new Rectangle(pos.X, pos.Y + WO, WW, W * 2)); } if (block.Walls.HasFlag(MazeWalls.WestBottom)) { g.FillRectangle(b, new Rectangle(pos.X, pos.Y + WO, W, WW)); } if (IsWallXSolid(new Point(x * 2 - 1, y * 2 - 1)) || IsWallYSolid(new Point(x * 2 - 1, y * 2 - 1))) { g.FillRectangle(b, new Rectangle(pos.X, pos.Y, W, W)); } if (IsWallXSolid(new Point(x * 2 + 2, y * 2 - 1)) || IsWallYSolid(new Point(x * 2 + 1, y * 2 - 1))) { g.FillRectangle(b, new Rectangle(pos.X + WO2, pos.Y, W, W)); } if (IsWallXSolid(new Point(x * 2 - 1, y * 2 + 1)) || IsWallYSolid(new Point(x * 2 - 1, y * 2 + 2))) { g.FillRectangle(b, new Rectangle(pos.X, pos.Y + WO2, W, W)); } if (IsWallXSolid(new Point(x * 2 + 2, y * 2 + 1)) || IsWallYSolid(new Point(x * 2 + 1, y * 2 + 2))) { g.FillRectangle(b, new Rectangle(pos.X + WO2, pos.Y + WO2, W, W)); } if (IsWallXSolid(new Point(x * 2 - 1, y * 2))) { g.FillRectangle(b, new Rectangle(pos.X, pos.Y + WO, W, W * 2)); } if (IsWallYSolid(new Point(x * 2, y * 2 - 1))) { g.FillRectangle(b, new Rectangle(pos.X + WO, pos.Y, W * 2, W)); } if (IsWallXSolid(new Point(x * 2 + 2, y * 2))) { g.FillRectangle(b, new Rectangle(pos.X + WO2, pos.Y + WO, W, W * 2)); } if (IsWallYSolid(new Point(x * 2, y * 2 + 2))) { g.FillRectangle(b, new Rectangle(pos.X + WO, pos.Y + WO2, W * 2, W)); } b.Dispose(); } } } if (hoverType != MazeWallTypes.None) { int PW2 = (pathWidth + wallWidth * 2); int W2 = wallWidth * 2; Brush b = new SolidBrush(HighlightColor); switch (hoverType) { case MazeWallTypes.WallX: g.FillRectangle(b, new Rectangle(W + hoverPoint.X * PW2, W + hoverPoint.Y * PW2 + P, P, W2)); break; case MazeWallTypes.WallY: g.FillRectangle(b, new Rectangle(W + hoverPoint.X * PW2 + P, W + hoverPoint.Y * PW2, W2, P)); break; case MazeWallTypes.Quadrant: g.FillRectangle(b, new Rectangle(W + hoverPoint.X * PW2, W + hoverPoint.Y * PW2, P, P)); break; } b.Dispose(); } if (drawGrid) { int XL1 = (P * 2 + W * 2); int YL1 = (P * 2 + W * 2); int XL2 = (P * 2 + W * 4); int YL2 = (P * 2 + W * 4); Brush b = new SolidBrush(GridColor); for (int x = 0; x < this.blocks.GetLength(0); x++) { for (int y = 0; y < this.blocks.GetLength(1); y++) { if (this.blocks[x, y].Empty || this.blocks[x, y].IsEntrance || this.blocks[x, y].IsExit) { continue; } Point pos = new Point(x * (P * 2 + W * 4), y * (P * 2 + W * 4)); //g.FillRectangle(b, new Rectangle(pos.X - W, pos.Y, 1, YL)); int yl = YL1; if (y + 1 < this.blocks.GetLength(1) && !this.blocks[x, y + 1].Empty && !this.blocks[x, y + 1].IsEntrance && !this.blocks[x, y + 1].IsExit) { yl = YL2; } g.FillRectangle(b, new Rectangle(pos.X + W, pos.Y + W, 1, yl)); g.FillRectangle(b, new Rectangle(pos.X + WO - 1, pos.Y + W, 1, yl)); g.FillRectangle(b, new Rectangle(pos.X + PO, pos.Y + W, 1, yl)); g.FillRectangle(b, new Rectangle(pos.X + WO2 - 1, pos.Y + W, 1, yl)); int xl = XL1; if (x + 1 < this.blocks.GetLength(0) && !this.blocks[x + 1, y].Empty && !this.blocks[x + 1, y].IsEntrance && !this.blocks[x + 1, y].IsExit) { xl = XL2; } g.FillRectangle(b, new Rectangle(pos.X + W, pos.Y + W, xl, 1)); g.FillRectangle(b, new Rectangle(pos.X + W, pos.Y + WO - 1, xl, 1)); g.FillRectangle(b, new Rectangle(pos.X + W, pos.Y + PO, xl, 1)); g.FillRectangle(b, new Rectangle(pos.X + W, pos.Y + WO2 - 1, xl, 1)); } } b.Dispose(); } }
/** <summary> Sets if the specified quadrant is solid. </summary> */ public void SetQuadrantSolid(Point point, bool solid) { if (point.X < 0 || point.X >= this.blocks.GetLength(0) * 2 || point.Y < 0 || point.Y >= this.blocks.GetLength(1) * 2) { return; } MazeBlock block = this.blocks[point.X / 2, point.Y / 2]; if (point.Y % 2 == 0) { if (point.X % 2 == 0) { if (solid) { block.Walls |= MazeWalls.QuadrantNorthWest; } else { block.Walls &= ~MazeWalls.QuadrantNorthWest; } } else { if (solid) { block.Walls |= MazeWalls.QuadrantNorthEast; } else { block.Walls &= ~MazeWalls.QuadrantNorthEast; } } } else { if (point.X % 2 == 0) { if (solid) { block.Walls |= MazeWalls.QuadrantSouthWest; } else { block.Walls &= ~MazeWalls.QuadrantSouthWest; } } else { if (solid) { block.Walls |= MazeWalls.QuadrantSouthEast; } else { block.Walls &= ~MazeWalls.QuadrantSouthEast; } } } if (solid) { SetWallXSolid(point, true); SetWallXSolid(Point.Add(point, new Size(0, -1)), true); SetWallYSolid(point, true); SetWallYSolid(Point.Add(point, new Size(-1, 0)), true); } }
/** <summary> Sets if the specified wall is solid. </summary> */ public void SetWallYSolid(Point point, bool solid) { if (point.X < 0 || point.X >= this.blocks.GetLength(0) * 2 || point.Y < 0 || point.Y >= this.blocks.GetLength(1) * 2) { return; } MazeBlock block = this.blocks[point.X / 2, point.Y / 2]; if (point.X % 2 == 0) { if (point.Y % 2 == 0) { if (solid) { block.Walls |= MazeWalls.NorthMiddle; } else { block.Walls &= ~(MazeWalls.NorthMiddle | MazeWalls.QuadrantNorthWest | MazeWalls.QuadrantNorthEast); } } else { if (solid) { block.Walls |= MazeWalls.SouthMiddle; } else { block.Walls &= ~(MazeWalls.SouthMiddle | MazeWalls.QuadrantSouthWest | MazeWalls.QuadrantSouthEast); } } } else { if (point.Y % 2 == 0) { if (solid) { block.Walls |= MazeWalls.EastTop; GetNormalBlock(new Point(point.X / 2 + 1, point.Y / 2)).Walls |= MazeWalls.WestTop; } else { block.Walls &= ~(MazeWalls.EastTop | MazeWalls.QuadrantNorthEast); GetNormalBlock(new Point(point.X / 2 + 1, point.Y / 2)).Walls &= ~(MazeWalls.WestTop | MazeWalls.QuadrantNorthWest); } } else { if (solid) { block.Walls |= MazeWalls.EastBottom; GetNormalBlock(new Point(point.X / 2 + 1, point.Y / 2)).Walls |= MazeWalls.WestBottom; } else { block.Walls &= ~(MazeWalls.EastBottom | MazeWalls.QuadrantSouthEast); GetNormalBlock(new Point(point.X / 2 + 1, point.Y / 2)).Walls &= ~(MazeWalls.WestBottom | MazeWalls.QuadrantSouthWest); } } } }
/** <summary> Sets if the specified wall is solid. </summary> */ public void SetWallXSolid(Point point, bool solid) { if (point.X < 0 || point.X >= this.blocks.GetLength(0) * 2 || point.Y < 0 || point.Y >= this.blocks.GetLength(1) * 2) { return; } MazeBlock block = this.blocks[point.X / 2, point.Y / 2]; if (point.Y % 2 == 0) { if (point.X % 2 == 0) { if (solid) { block.Walls |= MazeWalls.WestMiddle; } else { block.Walls &= ~(MazeWalls.WestMiddle | MazeWalls.Quadrant4 | MazeWalls.Quadrant3); } } else { if (solid) { block.Walls |= MazeWalls.EastMiddle; } else { block.Walls &= ~(MazeWalls.EastMiddle | MazeWalls.Quadrant1 | MazeWalls.Quadrant2); } } } else { if (point.X % 2 == 0) { if (solid) { block.Walls |= MazeWalls.SouthLeft; GetNormalBlock(new Point(point.X / 2, point.Y / 2 + 1)).Walls |= MazeWalls.NorthLeft; } else { block.Walls &= ~(MazeWalls.SouthLeft | MazeWalls.Quadrant3); GetNormalBlock(new Point(point.X / 2, point.Y / 2 + 1)).Walls &= ~(MazeWalls.NorthLeft | MazeWalls.Quadrant4); } } else { if (solid) { block.Walls |= MazeWalls.SouthRight; GetNormalBlock(new Point(point.X / 2, point.Y / 2 + 1)).Walls |= MazeWalls.NorthRight; } else { block.Walls &= ~(MazeWalls.SouthRight | MazeWalls.Quadrant2); GetNormalBlock(new Point(point.X / 2, point.Y / 2 + 1)).Walls &= ~(MazeWalls.NorthRight | MazeWalls.Quadrant1); } } } }