Beispiel #1
0
 // Ctor : provides Map and mode (combat or not). Beware, use a Fight context un fight, and a Map out of fights
 public PathFinder(IMapContext map, bool fight)
 {
     Debug.Assert(fight && map is Fight || !fight && map is IMap);
     _isInFight = fight;
     _map = map;
     _cells = new CellInfo[map.Cells.Count];
     for (int i = 0; i < map.Cells.Count; i++)
         _cells[i] = new CellInfo(map.Cells[i]);
     PathPacker = new MapMovement(_cells);
 }
Beispiel #2
0
        /// <summary>
        /// PathFinding main method
        /// </summary>
        /// <param name="startingCells"></param>
        /// <param name="exitCells"></param>
        /// <param name="selectFartherCells"></param>
        /// <param name="firstStepOnly"></param>
        /// <returns></returns>
        public bool FindPath(short[] startingCells, short[] exitCells, bool selectFartherCells = false, bool firstStepOnly = false, int maxDistanceParam = CellInfo.DEFAULT_DISTANCE)
        {
            Random rnd = new Random();

            if ((startingCells == null) || (startingCells.Length == 0))
            {
                return(false);                                                        // We need at least one starting stCell
            }
            if (!firstStepOnly && (exitCells == null || exitCells.Length == 0))
            {
                return(false);                                                                // We need at least one exit stCell for step 2
            }
            // PC starts at distance of 0. Set 0 to all possible starting cells
            CellInfo[] changed    = new CellInfo[560];
            int        changedPtr = 0;

            CellInfo[] changing    = new CellInfo[560];
            int        changingPtr = 0;

            bool optimizerActiv = !firstStepOnly && !selectFartherCells; // This strong optimization may fail to find a path. In that case, the non-optimized algorithm is run

            while (true)
            {
                ClearLogic(startingCells, exitCells);
                uint EstimatedDistance = CellInfo.DEFAULT_DISTANCE;
                Cell bestStartingCell  = null;
                Cell bestEndingCell    = null;

                foreach (short stCell in startingCells)
                {
                    if (_cells[stCell] != null)
                    {
                        _cells[stCell].DistanceSteps = 0;
                        changed[changedPtr++]        = _cells[stCell];
                        if (!firstStepOnly && !selectFartherCells)
                        {
                            foreach (short exCell in exitCells)
                            {
                                if (exCell == stCell)
                                {
                                    PathResult = new List <short> {
                                        stCell
                                    };
                                    return(true); // Empty path : starting stCell = exit stCell
                                }
                                if (optimizerActiv)
                                {
                                    uint distance = _cells[stCell].Cell.ManhattanDistanceTo(_cells[exCell].Cell);
                                    if (distance < EstimatedDistance)
                                    {
                                        bestStartingCell  = _cells[stCell].Cell;
                                        bestEndingCell    = _cells[exCell].Cell;
                                        EstimatedDistance = distance;
                                    }
                                }
                            }
                        }
                    }
                }
                //    cells[StartingCell].distanceSteps = 0;
                int maxDistance = maxDistanceParam; // We won't search over this distance - this optimization is OK in all cases
                if (optimizerActiv && bestStartingCell == null || bestEndingCell == null)
                {
                    optimizerActiv = false;
                }

                while (changedPtr > 0)
                {
                    changingPtr = 0;
                    // Look at each square on the board.
                    while (changedPtr > 0)
                    {
                        CellInfo curCell = changed[--changedPtr];
                        if (curCell.IsCloseToEnemy && _isCautious)
                        {
                            continue; // Cautious mode (in or out of fight) : Can't move from a cell near an ennemy
                        }
                        if (curCell.DistanceSteps < maxDistance)
                        {
                            if (optimizerActiv) // Strong optimisation
                            {
                                uint lastEstimatedDistance = curCell.Cell.ManhattanDistanceTo(bestEndingCell);
                                uint startDistance         = curCell.Cell.ManhattanDistanceTo(bestStartingCell);
                                if (startDistance + lastEstimatedDistance > EstimatedDistance)
                                {
                                    continue;
                                }
                            }
                            //Debug.Assert((curCell != null && curCell.DistanceSteps < CellInfo.DEFAULT_DISTANCE));
                            short[] cellNeighbours = neighbours[curCell.CellId];
                            for (short i = 0; i < cellNeighbours.Length; i++)
                            {
                                CellInfo newCell = _cells[cellNeighbours[i]];
                                if (newCell == null)
                                {
                                    continue;
                                }
                                if (newCell.DistanceSteps != 0 && !SquareOpen(newCell, null))
                                {
                                    continue;
                                }
                                //uint currentDistance = newCell.Cell.ManhattanDistanceTo(_cells[exitCells[0]].Cell);
                                //if (currentDistance >= EstimatedDistance || currentDistance >= lastEstimatedDistance) continue;

                                int newPass = curCell.DistanceSteps;
                                if (curCell.IsCloseToEnemy)
                                {
                                    newPass++; // Penality when close of an ennemy (same in fight and RP map)
                                }
                                if (_isInFight)
                                {
                                    newPass++;
                                }
                                else
                                {
                                    newPass += newCell.Weight;
                                }

                                if (newCell.DistanceSteps > newPass)
                                {
                                    newCell.DistanceSteps   = newPass;
                                    changing[changingPtr++] = newCell;
                                    if (!firstStepOnly && !selectFartherCells && newPass < maxDistance && exitCells.Any(id => newCell.CellId == id))
                                    {
                                        maxDistance = newPass; // We won't search on distance over closest exit
                                    }
                                }
                            }
                            if (_isInFight)
                            {
                                continue;
                            }
                            cellNeighbours = diagNeighbours[curCell.CellId];
                            for (short i = 0; i < cellNeighbours.Length; i++) // Process diagonals
                            {
                                CellInfo newCell = _cells[cellNeighbours[i]];
                                if (newCell == null)
                                {
                                    continue;
                                }
                                if (newCell.DistanceSteps != 0 && !SquareOpen(newCell, null))
                                {
                                    continue;
                                }

                                int newPass = curCell.DistanceSteps;
                                if (curCell.IsCloseToEnemy)
                                {
                                    newPass++; // Penality when close of an ennemy (same in fight and RP map)
                                }
                                if (_isInFight)
                                {
                                    newPass++;
                                }
                                else
                                {
                                    newPass += (int)(newCell.Weight * 1.414);
                                }

                                if (newCell.DistanceSteps > newPass)
                                {
                                    newCell.DistanceSteps   = newPass;
                                    changing[changingPtr++] = newCell;
                                    if (!firstStepOnly && !selectFartherCells && newPass < maxDistance && exitCells.Any(id => newCell.CellId == id))
                                    {
                                        maxDistance = newPass;  // We won't search on distance over closest exit
                                    }
                                }
                            }
                        }
                    }
                    CellInfo[] tmpChanged = changed;
                    changed    = changing;
                    changedPtr = changingPtr;
                    changing   = tmpChanged;
                }
                if (firstStepOnly)
                {
                    return(true);
                }
                // Step 2
                // Mark the path from Exit to Starting position.
                // if several Exit cells, then get the lowest distance one = the closest from one starting cell
                // (or the highest distance one if selectFartherCells)
                ExitCell = exitCells[0];
                int MinDist = _cells[ExitCell].DistanceSteps;
                foreach (short cell in exitCells)
                {
                    if ((selectFartherCells && _cells[cell].DistanceSteps > MinDist) || (!selectFartherCells && _cells[cell].DistanceSteps < MinDist))
                    {
                        ExitCell = cell;
                        MinDist  = _cells[cell].DistanceSteps;
                    }
                }

                if (optimizerActiv == false || MinDist < CellInfo.DEFAULT_DISTANCE)
                {
                    break;                                                                 // No need to run a second unoptimized algorithm
                }
                else
                {
                    optimizerActiv = false;
                }
            }
            //int no = 0;
            //Debug.WriteLine("PathFinding from {0} ({1}) to {2} ({3})", _cells[startingCells[0]].cell, _cells[startingCells[0]].distanceSteps, _cells[ExitCell].cell, _cells[ExitCell].distanceSteps);

            /*List<Cell> ListMax = new List<Cell>();
             * List<Cell> ListInc = new List<Cell>();
             * foreach (var cell in _cells)
             * {
             *  if (cell.distanceSteps >= CellInfo.DEFAULT_DISTANCE)
             *      ListMax.Add(cell.cell);
             *  if (cell.distanceSteps <= MinDist)
             *      ListInc.Add(cell.cell);
             *  //else
             *  //    continue;
             *  Debug.Write(String.Format("{0} : {1}, ", cell.cell, cell.distanceSteps));
             *  if (no++ == 5)
             *  {
             *      Debug.WriteLine("");
             *      no = 0;
             *  }
             * }*/
            //Debug.WriteLine("");
            //BotManager.Instance.Bots[0].Character.ResetCellsHighlight();
            //BotManager.Instance.Bots[0].Character.HighlightCells(ListMax, Color.Black);
            //BotManager.Instance.Bots[0].Character.HighlightCells(ListMax, Color.DarkGray);
            short CurrentCell = ExitCell;

            PathResult.Add(ExitCell);
            _cells[ExitCell].IsInPath = true;
            CellInfo[] lowestPoints    = changed; // No ned to alloc a new one, this one won't be used anymore
            int        lowestPointsPtr = 0;
            short      lowestPoint;
            int        lowest;

            while (true)
            {
                // Look through each MapNeighbour and find the square
                // with the lowest number of steps marked.
                lowestPoint = CellInfo.CELL_ERROR;
                lowest      = CellInfo.DEFAULT_DISTANCE;
                short[] neighbours = GetNeighbours(CurrentCell, _isInFight);
                for (short i = 0; i < neighbours.Length; i++)
                {
                    //foreach (CellInfo newCell in ValidMoves(curCell, false))
                    CellInfo newCell = _cells[neighbours[i]];
                    if (newCell == null || (newCell.IsCloseToEnemy && _isCautious && newCell.DistanceSteps != 0))
                    {
                        continue;                                                                                           // In cautious mode, don't come close to an enemy
                    }
                    //for (CellInfo NewCell in ValidMoves(_cells[CurrentCell], true))
                    //{
                    int distance = newCell.DistanceSteps;

                    /*if (distance > CellInfo.DEFAULT_DISTANCE)
                     * {
                     *  Debug.Assert(false, "Distance shouldn't be higher than DEFAULT_DISTANCE", "Distance = {0} > Max = {1}", distance, CellInfo.DEFAULT_DISTANCE);
                     *  continue;
                     * }*/
                    if (distance < lowest)
                    {
                        lowestPointsPtr = 1;
                        lowest          = distance;
                        lowestPoints[0] = newCell;
                    }
                    else
                    if (distance == lowest)
                    {
                        lowestPoints[lowestPointsPtr++] = newCell;
                    }
                }
                if (lowest == CellInfo.DEFAULT_DISTANCE)
                {
                    break;               // Can't find a valid way :(
                }
                if (lowestPointsPtr > 1) // Several points with same distance =>> randomly select one of them
                {
                    lowestPoint = lowestPoints[rnd.Next(lowestPointsPtr)].CellId;
                }
                else
                {
                    lowestPoint = lowestPoints[0].CellId;
                }

                // Mark the square as part of the path if it is the lowest
                // number. Set the current position as the square with
                // that number of steps.
                PathResult.Add(lowestPoint);
                if (PathResult.Count > _cells.Length)
                {
                    Debug.Assert(false, "PathFinder can't find a path - overflow");
                    break;
                }
                //Debug.Assert(_cells[lowestPoint].IsInPath == false, "Point already in path", "CurrentCell : {0}, Lowest : {1} - distance : {2}, path : {3}", _cells[CurrentCell].Cell, _cells[lowestPoint].Cell, lowest, string.Join(",", _cells.Where(stCell => stCell.IsInPath)));
                _cells[lowestPoint].IsInPath = true;
                CurrentCell = lowestPoint;


                if (_cells[CurrentCell].DistanceSteps == 0) // Exit reached
                {
                    StartingCell = CurrentCell;
                    // We went from closest Exit to a Starting position, so we're finished.
                    break;
                }
            }
            PathResult.Reverse();
            return(CurrentCell == StartingCell);
        }
 // Return each valid square we can move to.
 private IEnumerable<CellInfo> ValidMoves(CellInfo cell, bool fast)
 {
     CellInfo newCell;
     if ((newCell = getNeighbourCell(cell, 1, 0)) != null) yield return newCell;
     if ((newCell = getNeighbourCell(cell, 0, 1)) != null) yield return newCell;
     if ((newCell = getNeighbourCell(cell, -1, 0)) != null) yield return newCell;
     if ((newCell = getNeighbourCell(cell, 0, -1)) != null) yield return newCell;
     if (!_isInFight)
     {
         if ((newCell = getNeighbourCell(cell, 1, 1)) != null) yield return newCell;
         if ((newCell = getNeighbourCell(cell, 1, -1)) != null) yield return newCell;
         if ((newCell = getNeighbourCell(cell, -1, 1)) != null) yield return newCell;
         if ((newCell = getNeighbourCell(cell, -1, -1)) != null) yield return newCell;
     }
 }
 private CellInfo getNeighbourCell(CellInfo cell, int deltaX, int deltaY)
 {
     int NewCellId = cell.GetNeighbourCell(deltaX, deltaY);
     if (NewCellId == CellInfo.CELL_ERROR) return null;
     return _cells[NewCellId];
 }
        /// <summary>
        /// PathFinding main method
        /// </summary>
        /// <param name="startingCells"></param>
        /// <param name="exitCells"></param>
        /// <param name="selectFartherCells"></param>
        /// <param name="firstStepOnly"></param>
        /// <returns></returns>
        private int SubMapFiller(CellInfo startingCell, byte RegionNb)
        {
            Debug.Assert(RegionNb > 0);

            // If a wrong or non-walkable cell or already with the given Region number, then return 0. 
            if ((startingCell == null) ||
                 !_map.IsCellWalkable(startingCell.Cell, true, null) || !(!_isInFight || startingCell.IsCombatWalkable) ||
                 (startingCell.SubMapId == RegionNb)
              )
                return 0;

            _isInFight = false;
            Random rnd = new Random();

            List<CellInfo> changed = new List<CellInfo>();
            List<CellInfo> changing;

            int cellCounter = 0;
            startingCell.SubMapId = RegionNb;
            changed.Add(startingCell);

            while (changed.Count > 0)
            {
                cellCounter += changed.Count;

                changing = new List<CellInfo>();
                // Look at each square on the board.
                foreach (CellInfo curCell in changed)
                {
                    //Debug.Assert((curCell != null && curCell.distanceSteps < CellInfo.DEFAULT_DISTANCE));
                    foreach (CellInfo newCell in ValidMoves(curCell, true))
                        if (newCell.SubMapId != RegionNb && _map.IsCellWalkable(newCell.Cell, true, null) && (!_isInFight || newCell.IsCombatWalkable))
                        {
                            newCell.SubMapId = RegionNb;
                            changing.Add(newCell);
                        }
                }

                changed = changing;
            }
            return cellCounter;
        }
Beispiel #6
0
 static public double GetFlightDistance(CellInfo StartCell, CellInfo EndCell, bool isInFight)
 {
     int dx = Math.Abs(StartCell.X - EndCell.X);
     int dy = Math.Abs(StartCell.Y - EndCell.Y);
     if (isInFight)
         return dx + dy;
     if (dx > dy)
         return dy * 1.414 /* diagonale part */ + /* straight line part */ dx - dy;
     else
         return dx * 1.414 /* diagonale part */ + /* straight line part */ dy - dx;
 }
Beispiel #7
0
 CellInfo getNeighbourCell(CellInfo cell, int deltaX, int deltaY, bool fast)
 {
     int NewCellId = cell.GetNeighbourCell(deltaX, deltaY);
     CellInfo NewCell = NewCellId == CellInfo.CELL_ERROR ? null : _cells[NewCellId];
     if (fast || NewCell == null || NewCell.DistanceSteps == 0) return NewCell;
     if (!SquareOpen(NewCell, cell)) return null;
     NewCell.IsDiagonal = deltaX != 0 && deltaY != 0;
     return NewCell;
 }
Beispiel #8
0
        private bool SquareOpen(CellInfo cell, CellInfo originCell = null)
        {
            if (cell == null) return false;

            if (cell.IsOpen == null)
                if (_isInFight)
                    cell.IsOpen = cell.IsCombatWalkable && _map.IsCellWalkable(cell.Cell, false, originCell == null ? null : originCell.Cell)/* && !cell.IsCloseToEnemy*/;
                else
                    cell.IsOpen = _map.IsCellWalkable(cell.Cell, !_isCautious, originCell == null ? null : originCell.Cell)/* && (!_isCautious || !cell.IsCloseToEnemy)*/;
            return cell.IsOpen.Value;
        }
Beispiel #9
0
        /// <summary>
        /// PathFinding main method
        /// </summary>
        /// <param name="startingCells"></param>
        /// <param name="exitCells"></param>
        /// <param name="selectFartherCells"></param>
        /// <param name="firstStepOnly"></param>
        /// <returns></returns>
        public bool FindPath(short[] startingCells, short[] exitCells, bool selectFartherCells = false, bool firstStepOnly = false, int maxDistanceParam = CellInfo.DEFAULT_DISTANCE)
        {
            Random rnd = new Random();
            if ((startingCells == null) || (startingCells.Length == 0)) return false; // We need at least one starting stCell
            if (!firstStepOnly && (exitCells == null || exitCells.Length == 0)) return false; // We need at least one exit stCell for step 2

            // PC starts at distance of 0. Set 0 to all possible starting cells
            CellInfo[] changed = new CellInfo[560];
            int changedPtr = 0;
            CellInfo[] changing = new CellInfo[560];
            int changingPtr = 0;

            bool optimizerActiv = !firstStepOnly && !selectFartherCells; // This strong optimization may fail to find a path. In that case, the non-optimized algorithm is run 

            while (true)
            {
                ClearLogic(startingCells, exitCells);
                uint EstimatedDistance = CellInfo.DEFAULT_DISTANCE;
                Cell bestStartingCell = null;
                Cell bestEndingCell = null;

                foreach (short stCell in startingCells)
                    if (_cells[stCell] != null)
                    {
                        _cells[stCell].DistanceSteps = 0;
                        changed[changedPtr++] = _cells[stCell];
                        if (!firstStepOnly && !selectFartherCells)
                            foreach (short exCell in exitCells)
                            {
                                if (exCell == stCell)
                                {
                                    PathResult = new List<short> { stCell };
                                    return true; // Empty path : starting stCell = exit stCell
                                }
                                if (optimizerActiv)
                                {
                                    uint distance = _cells[stCell].Cell.ManhattanDistanceTo(_cells[exCell].Cell);
                                    if (distance < EstimatedDistance)
                                    {
                                        bestStartingCell = _cells[stCell].Cell;
                                        bestEndingCell = _cells[exCell].Cell;
                                        EstimatedDistance = distance;
                                    }
                                }
                            }
                    }
                //    cells[StartingCell].distanceSteps = 0;
                int maxDistance = maxDistanceParam; // We won't search over this distance - this optimization is OK in all cases
                if (optimizerActiv && bestStartingCell == null || bestEndingCell == null)
                    optimizerActiv = false;

                while (changedPtr > 0)
                {
                    changingPtr = 0;
                    // Look at each square on the board.
                    while (changedPtr > 0)
                    {
                        CellInfo curCell = changed[--changedPtr];
                        if (curCell.IsCloseToEnemy && _isCautious)
                            continue; // Cautious mode (in or out of fight) : Can't move from a cell near an ennemy

                        if (curCell.DistanceSteps < maxDistance)
                        {
                            if (optimizerActiv) // Strong optimisation
                            {
                                uint lastEstimatedDistance = curCell.Cell.ManhattanDistanceTo(bestEndingCell);
                                uint startDistance = curCell.Cell.ManhattanDistanceTo(bestStartingCell);
                                if (startDistance + lastEstimatedDistance > EstimatedDistance) continue;
                            }
                            //Debug.Assert((curCell != null && curCell.DistanceSteps < CellInfo.DEFAULT_DISTANCE));
                            short[] cellNeighbours = neighbours[curCell.CellId];
                            for (short i = 0; i < cellNeighbours.Length; i++)
                            {
                                CellInfo newCell = _cells[cellNeighbours[i]];
                                if (newCell == null) continue;
                                if (newCell.DistanceSteps != 0 && !SquareOpen(newCell, null)) continue;
                                //uint currentDistance = newCell.Cell.ManhattanDistanceTo(_cells[exitCells[0]].Cell);                            
                                //if (currentDistance >= EstimatedDistance || currentDistance >= lastEstimatedDistance) continue;

                                int newPass = curCell.DistanceSteps;
                                if (curCell.IsCloseToEnemy)
                                    newPass++; // Penality when close of an ennemy (same in fight and RP map)
                                if (_isInFight)
                                    newPass++;
                                else
                                    newPass += newCell.Weight;

                                if (newCell.DistanceSteps > newPass)
                                {
                                    newCell.DistanceSteps = newPass;
                                    changing[changingPtr++] = newCell;
                                    if (!firstStepOnly && !selectFartherCells && newPass < maxDistance && exitCells.Any(id => newCell.CellId == id))
                                        maxDistance = newPass; // We won't search on distance over closest exit
                                }
                            }
                            if (_isInFight) continue;
                            cellNeighbours = diagNeighbours[curCell.CellId];
                            for (short i = 0; i < cellNeighbours.Length; i++) // Process diagonals
                            {
                                CellInfo newCell = _cells[cellNeighbours[i]];
                                if (newCell == null) continue;
                                if (newCell.DistanceSteps != 0 && !SquareOpen(newCell, null)) continue;

                                int newPass = curCell.DistanceSteps;
                                if (curCell.IsCloseToEnemy)
                                    newPass++; // Penality when close of an ennemy (same in fight and RP map)

                                if (_isInFight)
                                    newPass++;
                                else
                                    newPass += (int)(newCell.Weight * 1.414);

                                if (newCell.DistanceSteps > newPass)
                                {
                                    newCell.DistanceSteps = newPass;
                                    changing[changingPtr++] = newCell;
                                    if (!firstStepOnly && !selectFartherCells && newPass < maxDistance && exitCells.Any(id => newCell.CellId == id))
                                        maxDistance = newPass;  // We won't search on distance over closest exit
                                }
                            }
                        }
                    }
                    CellInfo[] tmpChanged = changed;
                    changed = changing;
                    changedPtr = changingPtr;
                    changing = tmpChanged;
                }
                if (firstStepOnly)
                    return true;
                // Step 2
                // Mark the path from Exit to Starting position.
                // if several Exit cells, then get the lowest distance one = the closest from one starting cell
                // (or the highest distance one if selectFartherCells)
                ExitCell = exitCells[0];
                int MinDist = _cells[ExitCell].DistanceSteps;
                foreach (short cell in exitCells)
                    if ((selectFartherCells && _cells[cell].DistanceSteps > MinDist) || (!selectFartherCells && _cells[cell].DistanceSteps < MinDist))
                    {
                        ExitCell = cell;
                        MinDist = _cells[cell].DistanceSteps;
                    }

                if (optimizerActiv == false || MinDist < CellInfo.DEFAULT_DISTANCE) break; // No need to run a second unoptimized algorithm
                else
                    optimizerActiv = false;
            }
            //int no = 0;
            //Debug.WriteLine("PathFinding from {0} ({1}) to {2} ({3})", _cells[startingCells[0]].cell, _cells[startingCells[0]].distanceSteps, _cells[ExitCell].cell, _cells[ExitCell].distanceSteps);
            /*List<Cell> ListMax = new List<Cell>();
            List<Cell> ListInc = new List<Cell>();
            foreach (var cell in _cells)
            {
                if (cell.distanceSteps >= CellInfo.DEFAULT_DISTANCE)
                    ListMax.Add(cell.cell);
                if (cell.distanceSteps <= MinDist)
                    ListInc.Add(cell.cell);
                //else
                //    continue;
                Debug.Write(String.Format("{0} : {1}, ", cell.cell, cell.distanceSteps));
                if (no++ == 5)
                {
                    Debug.WriteLine("");
                    no = 0;
                }
            }*/
            //Debug.WriteLine("");
            //BotManager.Instance.Bots[0].Character.ResetCellsHighlight();
            //BotManager.Instance.Bots[0].Character.HighlightCells(ListMax, Color.Black);
            //BotManager.Instance.Bots[0].Character.HighlightCells(ListMax, Color.DarkGray);
            short CurrentCell = ExitCell;
            PathResult.Add(ExitCell);
            _cells[ExitCell].IsInPath = true;
            CellInfo[] lowestPoints = changed; // No ned to alloc a new one, this one won't be used anymore
            int lowestPointsPtr = 0;
            short lowestPoint;
            int lowest;

            while (true)
            {
                // Look through each MapNeighbour and find the square
                // with the lowest number of steps marked.
                lowestPoint = CellInfo.CELL_ERROR;
                lowest = CellInfo.DEFAULT_DISTANCE;
                short[] neighbours = GetNeighbours(CurrentCell, _isInFight);
                for (short i = 0; i < neighbours.Length; i++)
                {
                    //foreach (CellInfo newCell in ValidMoves(curCell, false))
                    CellInfo newCell = _cells[neighbours[i]];
                    if (newCell == null || (newCell.IsCloseToEnemy && _isCautious && newCell.DistanceSteps != 0)) continue; // In cautious mode, don't come close to an enemy

                    //for (CellInfo NewCell in ValidMoves(_cells[CurrentCell], true))
                    //{
                    int distance = newCell.DistanceSteps;
                    /*if (distance > CellInfo.DEFAULT_DISTANCE)
                    {
                        Debug.Assert(false, "Distance shouldn't be higher than DEFAULT_DISTANCE", "Distance = {0} > Max = {1}", distance, CellInfo.DEFAULT_DISTANCE);
                        continue;
                    }*/
                    if (distance < lowest)
                    {
                        lowestPointsPtr = 1;
                        lowest = distance;
                        lowestPoints[0] = newCell;
                    }
                    else
                        if (distance == lowest)
                            lowestPoints[lowestPointsPtr++] = newCell;
                }
                if (lowest == CellInfo.DEFAULT_DISTANCE) break; // Can't find a valid way :(

                if (lowestPointsPtr > 1) // Several points with same distance =>> randomly select one of them
                    lowestPoint = lowestPoints[rnd.Next(lowestPointsPtr)].CellId;
                else
                    lowestPoint = lowestPoints[0].CellId;

                // Mark the square as part of the path if it is the lowest
                // number. Set the current position as the square with
                // that number of steps.
                PathResult.Add(lowestPoint);
                if (PathResult.Count > _cells.Length)
                {
                    Debug.Assert(false, "PathFinder can't find a path - overflow");
                    break;
                }
                //Debug.Assert(_cells[lowestPoint].IsInPath == false, "Point already in path", "CurrentCell : {0}, Lowest : {1} - distance : {2}, path : {3}", _cells[CurrentCell].Cell, _cells[lowestPoint].Cell, lowest, string.Join(",", _cells.Where(stCell => stCell.IsInPath)));
                _cells[lowestPoint].IsInPath = true;
                CurrentCell = lowestPoint;


                if (_cells[CurrentCell].DistanceSteps == 0) // Exit reached            
                {
                    StartingCell = CurrentCell;
                    // We went from closest Exit to a Starting position, so we're finished.
                    break;
                }
            }
            PathResult.Reverse();
            return CurrentCell == StartingCell;
        }
Beispiel #10
0
    public bool DrawCurrentMap(PictureBox pictureBox, bool isCombatMap, bool showAllCells, CellInfo.FieldNames SelectedInfo)
    {
      if (mapMngr.MapData == null) return false;
      g.Clear(Color.CadetBlue);
      g.SmoothingMode = SmoothingMode.HighQuality;
      Debug.Assert(mapMngr.MapData.Cells.Count == 560);
      int x = 0;
      int y = 0;
      //P.x = cellId % MAP_WIDTH + (cellId / MAP_WIDTH)/2
      //P.y = cellId % MAP_WIDTH - (cellId / MAP_WIDTH)/2
      for (int j = 0; j <= 39; j++)
        for (int i = 0; i <= 13; i++)
        {
          x = i * 64 + 32;
          if ((j & 1) == 1) x += 32;
          int cellId = j * 14 + i;
          y = j * 18 + 18;
          Color couleur = cells[cellId].color;
          Point center = new Point(x, y);
          //couleur = Color.Chartreuse;
          if ((/*!isCombatMap && */!cells[cellId].isWalkable) || (isCombatMap && !cells[cellId].isCombatWalkable))
            couleur = Color.Black;
          if (PathFindingDone)
          {
            //if (mapMngr.CellsInfos[cellId].isInPath1)
            // couleur = Color.Blue;
            //if ((cellId == StartingCell) || (cellId == ExitCell))
            //  couleur = Color.LightBlue;
          }
          if (mapMngr.CellsInfos[cellId].drawable || showAllCells)
          {

            DrawPolygon(center, couleur, cells[cellId].isInPath1, cells[cellId].isInPath2, (cellId == StartingCell), (cellId == ExitCell), StartingCells != null && StartingCells.Contains(cellId), ExitCells != null && ExitCells.Contains(cellId));
            if (SelectedInfo != CellInfo.FieldNames.Nothing)
            {
              center = new Point(center.X - 10, center.Y - 7);

              g.DrawString(cells[cellId].getValue(SelectedInfo), Control.DefaultFont, Brushes.AliceBlue, center);
            }
            //g.DrawString(CellsInfos[cellId].speed.ToString(), Font, Brushes.AliceBlue, center);
          }
        }
      //mise en picturebox
      //pictureBox.Invalidate();
      pictureBox.Image = (Image)b.Clone();
      return true;
    }
Beispiel #11
0
 public MapMovement(CellInfo[] _cells)
 {
     cells = _cells;
 }