示例#1
0
        /// <summary>
        /// adds heapcell to the heap using the given sort-value
        /// </summary>
        /// <param name="cell">heapcell to be used</param>
        private void add(HeapCell <T> cell)
        {
            _Size++;

            if ((_Size * 2 + 1) >= _Length)
            {
                grow(_Size);
            }

            _Data[_Size] = cell;

            int i = _Size;

            //do any needed swapping
            while (i != 1)
            {
                //compare cells
                if (_Data[i].Value <= _Data[i / 2].Value)
                {
                    //if i is less than i/2, swap
                    HeapCell <T> temp = _Data[i / 2];
                    _Data[i / 2] = _Data[i];
                    _Data[i]     = temp;
                    i            = i / 2;
                }
                else//otherwise break
                {
                    break;
                }
            }
        }
示例#2
0
        public BinaryHeap(int length)
        {
            _Size   = 0;
            _Length = length * 2 + 2;
            _Data   = new HeapCell <T> [_Length];

            for (int i = 0; i < _Length; i++)
            {
                _Data[i] = new HeapCell <T>();
            }
        }
示例#3
0
        public HeapCell <T> removeFirst()
        {
            HeapCell <T> retVal = _Data[1];

            //move last item to 1st position, reduce size by 1
            _Data[1]     = _Data[_Size];
            _Data[_Size] = null;
            _Size--;

            int u, v;

            v = 1;

            //sort the heap
            while (true)
            {
                u = v;

                //if both children exist
                if ((2 * u + 1) <= _Size)
                {
                    //select lowest child
                    if (_Data[u].Value >= _Data[2 * u].Value)
                    {
                        v = 2 * u;
                    }
                    if (_Data[v].Value >= _Data[2 * u + 1].Value)
                    {
                        v = 2 * u + 1;
                    }
                }//if only one child exists
                else if (2 * u <= _Size)
                {
                    if (_Data[u].Value >= _Data[2 * u].Value)
                    {
                        v = 2 * u;
                    }
                }

                //do we need to swap or exit?
                if (u != v)
                {
                    HeapCell <T> temp = _Data[u];
                    _Data[u] = _Data[v];
                    _Data[v] = temp;
                }
                else
                {
                    break;//we've re-sorted the heap, so exit
                }
            }

            return(retVal);
        }
示例#4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="size"></param>
        private void grow(int size)
        {
            int length = size * 2 + 2;

            HeapCell <T>[] data = new HeapCell <T> [length];

            Array.Copy(_Data, data, _Length);

            _Data   = data;
            _Length = length;

            return;
        }
示例#5
0
        /// <summary>
        /// finds the adjacent cells
        /// </summary>
        /// <param name="cell"></param>
        /// <returns></returns>
        private List <Cell> findAdjacentCells(Cell cell)
        {
            //setup temps
            Terrain     terrain;
            List <Cell> goodAdjacents = new List <Cell>();

            //search ajacent tiles
            for (int i = -1; i <= 1; i++)
            {
                for (int j = -1; j <= 1; j++)
                {
                    //skip this cell since we already have it
                    if ((i == 0) && (j == 0))
                    {
                        continue;
                    }

                    //get the terrain
                    terrain = _GameMap.getTerrain((int)cell.Position.X + i, (int)cell.Position.Y + j); //);
                    //is terrain valid?
                    if (terrain == null)
                    {
                        continue;
                    }

                    //is it blocking?
                    if (terrain.IsBlocking)
                    {
                        _BlockingSet.Add(createCell((int)cell.Position.X + i, (int)cell.Position.Y + j));
                        continue;
                    }

                    //create the cell
                    Cell newCell = createCell((int)cell.Position.X + i, (int)cell.Position.Y + j);

                    //if we've already got it, ignore it
                    if (contains(newCell, _ClosedSet) >= 0)
                    {
                        continue;
                    }

                    //set its parent
                    newCell.Parent = cell;

                    //set its G cost since we can do that here

                    if ((i == -1 && j == -1) || (i == -1 && j == 1) || (i == 1 && j == -1) || (i == 1 && j == 1))
                    {
                        //since diagonal cell, do tests to see if its a valid move (not cutting a corner)

                        //check UL cell
                        if ((i == -1 && j == -1))
                        {
                            if (cellIsBlocking((int)cell.Position.X, (int)cell.Position.Y - 1) &&
                                cellIsBlocking((int)newCell.Position.X + 1, (int)newCell.Position.Y))
                            {
                                continue;
                            }
                            if (cellIsBlocking((int)cell.Position.X - 1, (int)cell.Position.Y) &&
                                cellIsBlocking((int)newCell.Position.X, (int)newCell.Position.Y + 1))
                            {
                                continue;
                            }
                        }

                        //check LL cell
                        if ((i == -1 && j == 1))
                        {
                            if (cellIsBlocking((int)cell.Position.X - 1, (int)cell.Position.Y) &&
                                cellIsBlocking((int)newCell.Position.X, (int)newCell.Position.Y - 1))
                            {
                                continue;
                            }
                            if (cellIsBlocking((int)cell.Position.X, (int)cell.Position.Y + 1) &&
                                cellIsBlocking((int)newCell.Position.X + 1, (int)newCell.Position.Y))
                            {
                                continue;
                            }
                        }

                        //check LR cell
                        if ((i == 1) && (j == 1))
                        {
                            if (cellIsBlocking((int)cell.Position.X, (int)cell.Position.Y + 1) &&
                                cellIsBlocking((int)newCell.Position.X - 1, (int)newCell.Position.Y))
                            {
                                continue;
                            }
                            if (cellIsBlocking((int)cell.Position.X + 1, (int)cell.Position.Y) &&
                                cellIsBlocking((int)newCell.Position.X, (int)newCell.Position.Y - 1))
                            {
                                continue;
                            }
                        }

                        //check UR cell
                        if ((i == 1) && (j == -1))
                        {
                            if (cellIsBlocking((int)cell.Position.X + 1, (int)cell.Position.Y) &&
                                cellIsBlocking((int)newCell.Position.X, (int)newCell.Position.Y + 1))
                            {
                                continue;
                            }
                            if (cellIsBlocking((int)cell.Position.X, (int)cell.Position.Y - 1) &&
                                cellIsBlocking((int)newCell.Position.X - 1, (int)newCell.Position.Y))
                            {
                                continue;
                            }
                        }

                        //valid move, so get G cost
                        newCell.G = diaCost + cell.G;
                    }
                    else
                    {
                        newCell.G = linCost + cell.G;
                    }

                    //newCell.G = linCost + cell.G;

                    //finds this cell's cost
                    newCell.F = findCost(newCell);


                    //check to see if we already have this one on an open list
                    int pos = heapContains(newCell, _OpenSet);
                    if (pos >= 0)
                    {
                        Cell temp = _OpenSet[pos].Data;

                        //is cell a better path?
                        if (cell.G + (temp.G - temp.Parent.G) < temp.G)
                        {
                            temp.G -= temp.Parent.G;

                            //yes, so update it, re-calc cost, and continue;
                            temp.Parent = cell;

                            temp.G += temp.Parent.G;

                            temp.F = findCost(temp);

                            _OpenSet[pos] = new HeapCell <Cell>(temp.F, temp);
                            continue;
                        }
                        else
                        {
                            continue;
                        }
                    }

                    //_OpenSet.add(newCell.F, newCell);

                    //add its location to the list as a good candidate
                    goodAdjacents.Add(newCell);
                }
            }
            //return list
            return(goodAdjacents);
        }