public CellArray1(int size) { cells = new Cell[size]; fixed(Cell *c = &cells[0]) { _data = c; } }
/// <summary> /// Initializes a new instance of maze cell with locations /// </summary> /// <param name="location">The location on the graphics surface</param> /// <param name="position">The location on the 2d array</param> public unsafe Cell(Point location, Point position) { this.location = location; this.position = position; // initially, all walls are intact this.LeftWall = true; this.RightWall = true; this.UpWall = true; this.DownWall = true; this.Path = Paths.None; // must be initialized, since it is a member of a struct this.Visited = false; this.Previous = null; }
static unsafe void ReadOrientations(Cell[] cells, byte[] bytes, Stream stream) { long position = stream.Position; fixed(Cell *fixedCells = cells) fixed(byte *fixedBytes = bytes) { byte *src = fixedBytes + position; Cell *cell = fixedCells; for (int i = 0; i < cells.Length; ++i) { cell->orientation = *src; src += 4; ++cell; } } stream.Seek(4 * cells.Length, SeekOrigin.Current); }
/// <summary> /// Solves a maze with recursive backtracking DFS - /// DON'T USE! IT IS FOR DEMONSTRATING PURPOSES ONLY! /// </summary> /// <param name="start">The start of the maze cell</param> /// <param name="end">The end of the maze cell</param> /// <returns>returrns true if the path is found</returns> private unsafe bool depthFirstSearchSolve(Cell *st, ref Cell end) { // base condition if (st->Position == end.Position) { // make it visited in order to be drawed with green this.maze[st->Position.Y, st->Position.X].Visited = true; // add end point to the foundPath this.foundPath.Add(*st); return(true); } // has been visited alread, return if (this.maze[st->Position.Y, st->Position.X].Visited) { return(false); } // for the graphics this.currentSolvePos = st->Position; // used to slow the process Thread.SpinWait(this.Sleep * sleepPeriod); // mark as visited this.maze[st->Position.Y, st->Position.X].Visited = true; // Check every neighbor cell // If it exists (not outside the maze bounds) // and if there is no wall between start and it // recursive call this method with it // if it returns true, add the current start to foundPath and return true too // else complete // Left if (st->Position.X - 1 >= 0 && !this.maze[st->Position.Y, st->Position.X - 1].RightWall) { this.maze[st->Position.Y, st->Position.X].Path = Cell.Paths.Left; fixed(Cell *ptr = &this.maze[st->Position.Y, st->Position.X - 1]) { if (this.depthFirstSearchSolve(ptr, ref end)) { this.foundPath.Add(*st); return(true); } } } // for the graphics this.currentSolvePos = st->Position; // used to slow the process Thread.SpinWait(this.Sleep * sleepPeriod); // Right if (st->Position.X + 1 < this.width && !this.maze[st->Position.Y, st->Position.X + 1].LeftWall) { this.maze[st->Position.Y, st->Position.X].Path = Cell.Paths.Right; fixed(Cell *ptr = &this.maze[st->Position.Y, st->Position.X + 1]) { if (this.depthFirstSearchSolve(ptr, ref end)) { this.foundPath.Add(*st); return(true); } } } // for the graphics this.currentSolvePos = st->Position; // used to slow the process Thread.SpinWait(this.Sleep * sleepPeriod); // Up if (st->Position.Y - 1 >= 0 && !this.maze[st->Position.Y - 1, st->Position.X].DownWall) { this.maze[st->Position.Y, st->Position.X].Path = Cell.Paths.Up; fixed(Cell *ptr = &this.maze[st->Position.Y - 1, st->Position.X]) { if (this.depthFirstSearchSolve(ptr, ref end)) { this.foundPath.Add(*st); return(true); } } } // for the graphics this.currentSolvePos = st->Position; // used to slow the process Thread.SpinWait(this.Sleep * sleepPeriod); // Down if (st->Position.Y + 1 < this.height && !this.maze[st->Position.Y + 1, st->Position.X].UpWall) { this.maze[st->Position.Y, st->Position.X].Path = Cell.Paths.Down; fixed(Cell *ptr = &this.maze[st->Position.Y + 1, st->Position.X]) { if (this.depthFirstSearchSolve(ptr, ref end)) { this.foundPath.Add(*st); return(true); } } } this.maze[st->Position.Y, st->Position.X].Path = Cell.Paths.None; return(false); }
/// <summary> /// Retrieves a value indicating whether the pixel at the specified /// coordinate is covered. /// </summary> /// <param name="tx">The x-coordinate to test.</param> /// <param name="ty">The y-coordinate to test.</param> /// <returns>true if the pixel at the specified coordinate is covered: false otherwise.</returns> public bool HitTest(int tx, int ty) { if (m_outline.CellCount == 0) { return(false); } Cell[] cells = m_outline.GetCells(); int cellCount = m_outline.CellCount; int x, y; int cover; int alpha; int area; cover = 0; fixed(Cell *cellsRef = &cells[0]) { Cell *cells_ptr = cellsRef; Cell *cur_cell = cells_ptr++; for (; ;) { Cell *start_cell = cur_cell; int coord = cur_cell->PackedCoord; x = cur_cell->X; y = cur_cell->Y; if (y > ty) { return(false); } area = start_cell->Area; cover += start_cell->Cover; while ((cur_cell = cells_ptr++) != null) { if (cur_cell->PackedCoord != coord) { break; } area += cur_cell->Area; cover += cur_cell->Cover; } if (area > 0) { alpha = CalculateAlpha((cover << (PolyBase.Shift + 1)) - area); if (alpha > 0) { if (tx == x && ty == y) { return(true); } } x++; } if (cur_cell == null) { break; } if (cur_cell->X > x) { alpha = CalculateAlpha(cover << (PolyBase.Shift + 1)); if (alpha > 0) { if (ty == y && tx >= x && tx <= cur_cell->X) { return(true); } } } } } return(false); }
/// <summary> /// Renders the current outline using the specified renderer and color. /// </summary> /// <typeparam name="Renderer">The type of the renderer.</typeparam> /// <param name="renderer">The renderer.</param> /// <param name="color">The color.</param> /// <param name="dx"></param> /// <param name="dy"></param> public void Render <Renderer>(Renderer renderer, Color color, int dx, int dy) where Renderer : IRenderer { if (m_outline.CellCount == 0) { return; } Cell[] cells = m_outline.GetCells(); int cellCount = m_outline.CellCount; m_scanline.Reset(m_outline.MinX, m_outline.MaxX, dx, dy); int cover = 0; fixed(Cell *cellsRef = &cells[0]) { Cell *cells_ptr = cellsRef; Cell *cur_cell = cells_ptr++; for (; ;) { Cell *start_cell = cur_cell; int coord = cur_cell->PackedCoord; int x = cur_cell->X; int y = cur_cell->Y; int area = start_cell->Area; cover += start_cell->Cover; // accumulate all start cells while ((cur_cell = cells_ptr++) != null && cellCount-- > 0) { if (cur_cell->PackedCoord != coord) { break; } area += cur_cell->Area; cover += cur_cell->Cover; } int alpha; if (area > 0) { alpha = CalculateAlpha((cover << (PolyBase.Shift + 1)) - area); if (alpha > 0) { if (m_scanline.IsReady(y) == true) { renderer.Render(m_scanline, color); m_scanline.ResetSpans(); } m_scanline.AddCell(x, y, m_gamma[alpha]); } x++; } if (cur_cell == null || cellCount <= 0) { break; } if (cur_cell->X > x) { alpha = CalculateAlpha(cover << (PolyBase.Shift + 1)); if (alpha > 0) { if (m_scanline.IsReady(y) == true) { renderer.Render(m_scanline, color); m_scanline.ResetSpans(); } m_scanline.AddSpan(x, y, cur_cell->X - x, m_gamma[alpha]); } } } } if (m_scanline.SpanCount > 0) { renderer.Render(m_scanline, color); } }
public long CopyTo(Cell *destination) => Cells.CopyTo(destination);