示例#1
0
    /// <summary></summary>
    /// <remarks>
    /// Takes a circle in the form of a center point and radius, and a function
    /// that can tell whether a given cell is opaque. Calls the setFoV action on
    /// every cell that is both within the radius and visible from the center. 
    /// </remarks>
    /// <param name="observerCoords">Cordinates of observer;s hex.</param>
    /// <param name="radius">Maximum radius for Field-of-View.</param>
    /// <param name="observerHeight">Height (ASL) of the observer's eyes.</param>
    /// <param name="isOnBoard">Is this hex on the baoard.</param>
    /// <param name="targetHeight">Returns ground level (ASL) of supplied hex.</param>
    /// <param name="terrainHeight">Returns height (ASL) of terrain in supplied hex.</param>
    /// <param name="setFoV">Sets a hex as visible in the Field-of-View.</param>
    public static void ComputeFieldOfView(
      ICoordsCanon            observerCoords, 
      int                     radius, 
      int                     observerHeight,
      Func<ICoordsCanon,bool> isOnBoard,
      Func<ICoordsCanon,int>  targetHeight, 
      Func<ICoordsCanon,int>  terrainHeight,
      Action<ICoordsCanon>    setFoV
    ) {
      #if TraceFOV
        TraceFlag.FieldOfView.Trace(true, " - Coords = " + observerCoords.User.ToString());
      #endif
      var matrixOrigin = new IntMatrix2D(observerCoords.Vector);

      setFoV(observerCoords);    // Always visible to self!
      #if TraceFoV
        for (int dodecant = 3; dodecant < 4; dodecant++) {
          TraceFlag.FieldOfView.Trace(true," - Dodecant: {0}", dodecant);
      #else
        Parallel.For (0, matrices.Count, dodecant => {
      #endif
          var matrix = matrices[dodecant] * matrixOrigin;
          ComputeFieldOfViewInDodecantZero(
            radius,
            observerHeight,
            TranslateDodecant(matrix, isOnBoard),
            TranslateDodecant(matrix, targetHeight),
            TranslateDodecant(matrix, terrainHeight),
            TranslateDodecant(matrix, setFoV));
        }
      #if !TraceFoV
        );
      #endif
    }
        protected override int Range(ICoordsCanon coords)
        {
            var deltaX = coords.X - VectorCanon.X;
            var deltaY = coords.Y - VectorCanon.Y;

            return((Math.Abs(deltaX) + Math.Abs(deltaY) + Math.Abs(deltaX - deltaY)) / 2);
        }
        protected override IEnumerable <NeighbourCoords> GetNeighbours(Hexside hexsides)
        {
            ICoordsCanon coords = this;

            foreach (Hexside hexside in Enum.GetValues(typeof(Hexside)))
            {
                if (hexside != Hexside.None && hexsides.HasFlag(hexside))
                {
                    yield return(new NeighbourCoords(hexside, coords.StepOut(hexside)));
                }
            }
        }
 public override IMapGridHex this[ICoordsCanon coords] {
     get { return(this[coords.User]); }
 }
 int ICoordsCanon.Range(ICoordsCanon coords)
 {
     return(Range(coords));
 }
 public NeighbourCoords(Hexside direction, ICoordsCanon coords) : this()
 {
     Direction = direction; Coords = coords;
 }
示例#7
0
 protected abstract int Range(ICoordsCanon coords);
示例#8
0
 static IntVector2D VectorHexTop(ICoordsCanon hex)
 {
     return(hex.Vector * matrixHexTop);
 }
示例#9
0
 static IntVector2D VectorHexBottom(ICoordsCanon hex)
 {
     return(hex.Vector * matrixHexBottom);
 }
        public static IPath <ICoordsCanon> FindPath(
            ICoordsCanon start,
            ICoordsCanon goal,
            Func <ICoordsCanon, Hexside, int> stepCost,
            Func <ICoordsCanon, int> range,
            Func <ICoordsCanon, bool> isOnBoard
            )
        {
            var vectorGoal = goal.Vector - start.Vector;
            var closed     = new HashSet <ICoordsUser>();
            var queue      = goal.Range(start) > RangeCutoff
          ? (IPriorityQueue <uint, Path <ICoordsCanon> >) new HeapPriorityQueue <uint, Path <ICoordsCanon> >()
          : (IPriorityQueue <uint, Path <ICoordsCanon> >) new DictPriorityQueue <uint, Path <ICoordsCanon> >();

      #if DEBUG
            TraceFlag.FindPath.Trace(true, "Find path from {0} to {1}; vectorGoal = {0}",
                                     start.User, goal.User, vectorGoal);
      #endif

            queue.Enqueue(0, new Path <ICoordsCanon>(start));

            while (!queue.IsEmpty)
            {
                var oldPref = queue.Peek().Key & 0xFFFF;
                var path    = queue.Dequeue();
                if (closed.Contains(path.LastStep.User))
                {
                    continue;
                }

        #if DEBUG
                var previous = (path.PreviousSteps) == null ? HexCoords.EmptyCanon : path.PreviousSteps.LastStep;
                TraceFlag.FindPath.Trace("Dequeue Path at {0} from {3} w/ cost={1,4}:{2,3}.",
                                         path.LastStep, path.TotalCost, oldPref, previous);
        #endif
                if (path.LastStep != null && path.LastStep.Equals(goal))
                {
                    return(path);
                }

                closed.Add(path.LastStep.User);

                foreach (var neighbour in path.LastStep.GetNeighbours(~Hexside.None))
                {
                    if (isOnBoard(neighbour.Coords))
                    {
                        var cost = stepCost(path.LastStep, neighbour.Direction);
                        if (cost > 0)
                        {
                            var preference = (ushort)Math.Abs(vectorGoal ^ (goal.Vector - neighbour.Coords.Vector));
                            var newPath    = path.AddStep(neighbour.Coords.User.Canon, (ushort)cost, neighbour.Direction);
                            var estimate   = ((uint)range(neighbour.Coords.User.Canon) + (uint)newPath.TotalCost) << 16;
                            queue.Enqueue(estimate + preference, newPath);
              #if DEBUG
                            TraceFlag.FindPath.Trace("   Enqueue {0}: {1,4}:{2,3}",
                                                     neighbour.Coords, estimate >> 16, preference);
              #endif
                        }
                    }
                }
            }
            return(null);
        }
示例#11
0
 private static int GetRange(ICoordsCanon coords)
 {
     return(HexCoords.EmptyCanon.Range(coords));
 }
示例#12
0
 public abstract int  StepCost(ICoordsCanon coords, Hexside hexSide);
示例#13
0
 public abstract IMapGridHex this[ICoordsCanon coords] {
     get;
 }
示例#14
0
 IGridHex IBoard <IGridHex> .this[ICoordsCanon coords] {
     get { return(this[coords]); }
 }
示例#15
0
 public override int    StepCost(ICoordsCanon coords, Hexside hexSide)
 {
     return(IsOnBoard(coords.User) && this[coords.StepOut(hexSide)].Value == '.' ? 1 : -1);
 }
 public override int    StepCost(ICoordsCanon coords, Hexside hexSide)
 {
     return(this[coords].StepCost);
 }