예제 #1
0
        /// <summary>TODO</summary>
        /// <param name="radius"></param>
        /// <param name="heightObserver"></param>
        /// <param name="isOnboard"></param>
        /// <param name="heightTarget"></param>
        /// <param name="heightTerrain"></param>
        /// <param name="setFieldOfView"></param>
        private static void ComputeFieldOfViewInDodecantZero(
            int radius,
            int heightObserver,
            Func <HexCoords, bool> isOnboard,
            Func <HexCoords, int> heightTarget,
            Func <HexCoords, Hexside, int> heightTerrain,
            Action <HexCoords> setFieldOfView
            )
        {
            var currentCoords = HexCoords.NewCanonCoords(0, 1);

            if (!isOnboard(currentCoords))
            {
                return;
            }

            if (radius > 0)
            {
                setFieldOfView(currentCoords);
            }

            var queue   = new FovConeQueue();
            var current = new FovCone(
                2,
                IntVector2D.New(1, 2),
                IntVector2D.New(0, 1),
                new RiseRun(2 * (heightTerrain(currentCoords, Hexside.North) - heightObserver), 1));

            while (current.Range <= radius)
            {
                current = ComputeFoVForRange(heightObserver, isOnboard, heightTarget, heightTerrain, setFieldOfView, queue, current);
            }
        }
예제 #2
0
    // Use this for initialization
    private void Awake()
    {
        Collider2D = GetComponent <BoxCollider2D>();

        RaycastOrigins = new RectangleVertices(GetExpandedBounds());
        RayCount       = new IntVector2D(4, 4);
    }
예제 #3
0
    private GameEntity GetSelectedNeighbourOfPosition(IntVector2D position)
    {
        var positionN = new IntVector2D(position.x, position.y + 1);

        if (IsSelectedOnPosition(positionN))
        {
            return(_contexts.game.GetTileWithPosition(positionN));
        }

        positionN = new IntVector2D(position.x, position.y - 1);
        if (IsSelectedOnPosition(positionN))
        {
            return(_contexts.game.GetTileWithPosition(positionN));
        }

        positionN = new IntVector2D(position.x + 1, position.y);
        if (IsSelectedOnPosition(positionN))
        {
            return(_contexts.game.GetTileWithPosition(positionN));
        }

        positionN = new IntVector2D(position.x - 1, position.y);
        if (IsSelectedOnPosition(positionN))
        {
            return(_contexts.game.GetTileWithPosition(positionN));
        }

        return(null);
    }
예제 #4
0
    List <IntVector2D> PlanPathToLocForAvatar(IntVector2D goalPos, Char2D avatar, bool sendThereIfPossible)
    {
        List <IntVector2D> list        = null;
        PlaneOrientation   orientation = avatar.Orientation;

        if (WorldManager.g.IsInBounds2D(goalPos, orientation))
        {
            IntVector2D lastLoc = avatar.Location;
            list = WorldManager.g.PlanPath(avatar, lastLoc, goalPos);
            if (list != null)
            {
                for (int i = list.Count - 1; i >= 0; i--)
                {
                    IntVector2D nextLoc = list[i];
                    Vector3     a       = WorldManager.g.WorldPosFromIntVec(lastLoc, orientation);
                    Vector3     b       = WorldManager.g.WorldPosFromIntVec(nextLoc, orientation);
                    Debug.DrawLine(a, b, Color.red);
                    lastLoc = nextLoc;
                }
                if (sendThereIfPossible)
                {
                    avatar.DesiredPath = list;
                }
            }
            else
            {
                // Debug.Log("NO VALID PATH FOR "+orientation.ToString()+"!");
            }
        }
        return(list);
    }
 /// <summary>Construct a new FovCone instance.</summary>
 internal FovCone(int range, IntVector2D top, IntVector2D bottom, RiseRun riseRun) : this()
 {
     Range        = range;
     RiseRun      = riseRun;
     VectorTop    = top;
     VectorBottom = bottom;
 }
 public FovCone(int range, IntVector2D top, IntVector2D bottom, RiseRun riseRun) : this()
 {
     this.Range        = range;
     this.VectorTop    = top;
     this.VectorBottom = bottom;
     this.RiseRun      = riseRun;
 }
예제 #7
0
    public bool CanMoveByDelta(WorldEntity2D e, IntVector2D v)
    {
        IntVector2D        resLoc        = e.Location + v;
        List <IntVector2D> occupiedAfter = e.AbsoluteLocations(resLoc);

        // TODO(Julian): Take more than just shadows into account!

        int i;

        switch (e.Orientation)
        {
        case PlaneOrientation.XY:
            for (i = 0; i < occupiedAfter.Count; i++)
            {
                if (!PassableAtXY(occupiedAfter[i]))
                {
                    return(false);
                }
            }
            break;

        case PlaneOrientation.ZY:
            for (i = 0; i < occupiedAfter.Count; i++)
            {
                if (!PassableAtZY(occupiedAfter[i]))
                {
                    return(false);
                }
            }
            break;
        }

        return(true);
    }
예제 #8
0
    private bool CanExistOn(List <IntVector2D> relativeLocations, IntVector2D on, PlaneOrientation orientation)
    {
        int i;

        switch (orientation)
        {
        case PlaneOrientation.XY:
            for (i = 0; i < relativeLocations.Count; i++)
            {
                if (!PassableAtXY(relativeLocations[i] + on))
                {
                    return(false);
                }
            }
            break;

        case PlaneOrientation.ZY:
            for (i = 0; i < relativeLocations.Count; i++)
            {
                if (!PassableAtZY(relativeLocations[i] + on))
                {
                    return(false);
                }
            }
            break;
        }
        return(true);
    }
예제 #9
0
    public bool CanJumpByDelta(WorldEntity2D e, IntVector2D v)
    {
        // First Move Up, then Sideways!

        int maxHoriz = v[0];
        int maxVert  = v[1];

        int vertDir  = Mathf.RoundToInt(Mathf.Sign(maxVert));
        int horizDir = Mathf.RoundToInt(Mathf.Sign(maxHoriz));

        int vert = 0;

        while (Mathf.Abs(vert) < Mathf.Abs(maxVert))
        {
            vert += vertDir;
            if (!CanMoveByDelta(e, new IntVector2D(0, vert)))
            {
                return(false);
            }
        }
        int horiz = 0;

        while (Mathf.Abs(horiz) < Mathf.Abs(maxHoriz))
        {
            horiz += horizDir;
            if (!CanMoveByDelta(e, new IntVector2D(horiz, vert)))
            {
                return(false);
            }
        }
        return(true);
    }
예제 #10
0
    // Adapted From http://stackoverflow.com/questions/10983110/a-star-a-and-generic-find-method
    public List <IntVector2D> PlanPath(Char2D entity, IntVector2D start, IntVector2D destination)
    {
        PlaneOrientation   orientation       = entity.Orientation;
        List <IntVector2D> relativeLocations = entity.AbsoluteLocations(new IntVector2D(0, 0));
        var closed = new HashSet <IntVector2D>();
        var queue  = new PriorityQueue <Path <IntVector2D>, float>();

        queue.Enqueue(new Path <IntVector2D>(start), 0f);
        while (!queue.IsEmpty)
        {
            var path = queue.Dequeue();
            if (closed.Contains(path.LastStep))
            {
                continue;
            }
            if (path.LastStep == destination)
            {
                return(path.AsList);
            }
            IntVector2D leafNode = path.LastStep;
            closed.Add(leafNode);
            List <IntVector2D> neighbors = ConnectedNodesForRelativeLocations(relativeLocations, leafNode, orientation);
            for (int i = 0; i < neighbors.Count; i++)
            {
                IntVector2D n        = neighbors[i];
                float       stepCost = CostBetween(path.LastStep, n);
                var         newPath  = path.AddStep(n, stepCost);
                queue.Enqueue(newPath, newPath.TotalCost + HeuristicCostEstimate(n, destination));
            }
        }
        return(null);
    }
예제 #11
0
        private void InitializeTileButtonTablePanel()
        {
            tileButtonTablePanel.ColumnCount = gridColumns;
            tileButtonTablePanel.RowCount    = gridRows;

            tileButtonTablePanel.ColumnStyles.Clear();
            tileButtonTablePanel.RowStyles.Clear();

            for (int i = 0; i < gridColumns; i++)
            {
                tileButtonTablePanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100 / gridColumns));
            }
            for (int i = 0; i < gridRows; i++)
            {
                tileButtonTablePanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100 / gridRows));
            }

            //Populate
            ButtonGrid = new ButtonGrid(gridColumns, gridRows);
            ButtonGrid.ButtonClicked += ButtonGrid_ButtonClicked;

            for (int column = 0; column < ButtonGrid.ColumnCount; column++)
            {
                for (int row = 0; row < ButtonGrid.RowCount; row++)
                {
                    var position = new IntVector2D(row, column);
                    var button   = ButtonGrid.GetCellAt(position);
                    tileButtonTablePanel.Controls.Add(button);
                    button.Width  = tileWidth;
                    button.Height = tileHeight;
                    button.Text   = position.ToString();
                    button.Dock   = DockStyle.Fill;
                }
            }
        }
예제 #12
0
 private void Fall()
 {
     _currStateInfo.lastLoc = Location;
     Location += new IntVector2D(0, -1);
     _currStateInfo.fractionComplete = 0f;
     _currStateInfo.state            = Char2DState.Falling;
 }
예제 #13
0
    public void ReplacePosition(IntVector2D newValue)
    {
        var index     = GameComponentsLookup.Position;
        var component = CreateComponent <PositionComponent>(index);

        component.value = newValue;
        ReplaceComponent(index, component);
    }
예제 #14
0
 /// <summary>
 /// Initializes the game's Board with its starting cards.
 /// </summary>
 private void InitializeBoard()
 {
     for (int i = 0; i < NUM_INITIAL_CARDS; i++)
     {
         IntVector2D cell = GetRandomEmptyCell();
         _board[cell] = DrawNextCard();
     }
 }
예제 #15
0
 private void MoveInDirTo(FacingDir dir, IntVector2D dest)
 {
     _currStateInfo.lastLoc = Location;
     Location                        = dest;
     _currStateInfo.state            = Char2DState.Walking;
     _currStateInfo.facingDirection  = dir;
     _currStateInfo.fractionComplete = 0f;
 }
예제 #16
0
 private void JumpInDirBy(FacingDir dir, IntVector2D deltaLoc)
 {
     _currStateInfo.lastLoc = Location;
     Location                       += deltaLoc;
     _currStateInfo.state            = Char2DState.Jumping;
     _currStateInfo.facingDirection  = dir;
     _currStateInfo.fractionComplete = 0f;
 }
예제 #17
0
        internal static int Estimate(Func <int, int> heuristic, IntVector2D vectorGoal, HexCoords goal,
                                     HexCoords hex, int totalCost)
        {
            var estimate   = (int)heuristic(goal.Range(hex)) + totalCost;
            var preference = Preference(vectorGoal, goal, hex);

            return((estimate << 16) + preference);
        }
        static int Estimate(Func <int, int> heuristic, IntVector2D vectorGoal, HexCoords start,
                            HexCoords hex, int totalCost)
        {
            var estimate   = heuristic(start.Range(hex)) + totalCost;
            var preference = Preference(vectorGoal, start.Canon - hex.Canon);

            return((estimate << 16) + preference);
        }
예제 #19
0
    public List <IntVector2D> AbsoluteLocations(IntVector2D location)
    {
        List <IntVector2D> absoluteLocations = new List <IntVector2D>();

        for (int i = 0; i < _identityLocations.Count; i++)
        {
            absoluteLocations.Add(_identityLocations[i] + location);
        }
        return(absoluteLocations);
    }
예제 #20
0
    void moveDown(GameEntity e, IntVector2D position)
    {
        var nextRowPos = _context.GetNextEmptyRow(position, _contexts);

        if (nextRowPos != position.y)
        {
            _fallExecuted = true;
            e.ReplacePosition(new IntVector2D(position.x, nextRowPos));
        }
    }
예제 #21
0
    void Action(int column, int row)
    {
        var position = new IntVector2D(column, row);
        var entity   = _context.GetTileWithPosition(position);

        if (entity != null && !entity.isDestroyed)
        {
            moveDown(entity, position);
        }
    }
예제 #22
0
 static int XFromVector(int y, IntVector2D v, bool isTop)
 {
     if (isTop)
     {
         return((-2 * v.Y + v.X * (3 * y + 1) + (3 * v.Y) - 1) / (3 * v.Y));
     }
     else
     {
         return((+2 * v.Y + v.X * (3 * y - 1)) / (3 * v.Y));
     }
 }
예제 #23
0
    private bool IsSelectedOnPosition(IntVector2D position)
    {
        var entity = _contexts.game.GetTileWithPosition(position);

        if (entity != null && entity.isSelected)
        {
            return(true);
        }

        return(false);
    }
예제 #24
0
    private void Remove2DEntityFrom(IntVector2D v, PlaneOrientation planeOrientation, WorldEntity2D t)
    {
        HashSet <WorldEntity2D>[,] mapToModify = Map2DForOrientation(planeOrientation);
        var contents = mapToModify[v[0], v[1]];

        if (contents == null)
        {
            contents = new HashSet <WorldEntity2D>();
            mapToModify[v[0], v[1]] = contents;
        }
        contents.Remove(t);
    }
예제 #25
0
    public HashSet <WorldEntity2D> Contents2DAt(IntVector2D v, PlaneOrientation planeOrientation)
    {
        var map      = Map2DForOrientation(planeOrientation);
        var contents = map[v[0], v[1]];

        if (contents == null)
        {
            contents        = new HashSet <WorldEntity2D>();
            map[v[0], v[1]] = contents;
        }
        return(contents);
    }
예제 #26
0
        /// <summary>
        /// Returns a random empty cell on the game board.
        /// </summary>
        private IntVector2D GetRandomEmptyCell()
        {
            IntVector2D ret;

            do
            {
                ret = new IntVector2D(
                    _rand.Int32(0, _board.Width - 1),
                    _rand.Int32(0, _board.Height - 1));
            }while(_board[ret] != null);
            return(ret);
        }
예제 #27
0
    public static GameEntity GetTileWithPosition(this GameContext context, IntVector2D position)
    {
        var entities = context.GetEntitiesWithPosition(position);

        foreach (var entity in entities)
        {
            if (entity.isGameTile)
            {
                return(entity);
            }
        }
        return(null);
    }
예제 #28
0
        static void TestMatrices()
        {
            var vector_0_1 = new IntVector2D(0, 1);
            var vector_1_2 = new IntVector2D(1, 2);

            for (var dodecant = 0; dodecant < matrices.Count; dodecant++)
            {
                TraceFlag.FieldOfView.Trace(true,
                                            "Dodecant #{0,2} canons:  (0,1) to {1}; (1,2) to {2}", dodecant,
                                            (vector_0_1 * matrices[dodecant]).ToString(),
                                            (vector_1_2 * matrices[dodecant]).ToString());
            }
        }
 static IntVector2D LogAndEnqueue(Action <FovCone> enqueue, int range, IntVector2D top,
                                  IntVector2D bottom, RiseRun riseRun, int code
                                  )
 {
     if (top.GT(bottom))
     {
         var cone = new FovCone(range + 1, top, bottom, riseRun);
         FieldOfViewTrace(false, "  EQ: ({0}) code: {1}", cone, code);
         enqueue(cone);
         return(bottom);
     }
     else
     {
         return(top);
     }
 }
예제 #30
0
        /// <summary>
        /// Modifies this Board in-place by shifting those cards that can be shifted or merged in the specified direction.
        /// </summary>
        /// <param name="newCardCells">If not null, the possible locations for a new card will be added to this list.</param>
        /// <returns>Whether anything was able to be shifted.</returns>
        public bool Shift(ShiftDirection dir, IList <IntVector2D> newCardCells)
        {
            bool        ret           = false;
            IntVector2D increment     = GetShiftIncrement(dir);
            int         widthOrHeight = GetShiftWidthOrHeight(dir);

            foreach (IntVector2D startCell in GetShiftStartCells(dir))
            {
                bool shifted = ShiftRowOrColumn(startCell, increment, widthOrHeight);
                if (shifted && newCardCells != null)
                {
                    newCardCells.Add(startCell - increment * (widthOrHeight - 1));
                }
                ret = ret || shifted;
            }
            return(ret);
        }
 static IntVector2D LogAndEnqueue(Action<FovCone> enqueue, int range, IntVector2D top,
         IntVector2D bottom, RiseRun riseRun, int code
 )
 {
     if (top.GT(bottom))
     {
         var cone = new FovCone(range + 1, top, bottom, riseRun);
     #if TraceFOV
       TraceFlag.FieldOfView.Trace(false, "  EQ: ({0}) code: {1}",cone,code);
     #endif
         enqueue(cone);
         return bottom;
     }
     else
     {
         return top;
     }
 }
        BidirectionalPathfinder(IHex start, IHex goal,
          LandmarkCollection landmarks, HashSet<HexCoords> closed, Func<double> getBestSoFar
        )
        {
            _start = start;
            _goal = goal;
            _getBestSoFar = getBestSoFar;
            _vectorGoal = goal.Coords.Canon - start.Coords.Canon;
            _open = new Dictionary<HexCoords, DirectedPath>();
            _closed = closed;
            _queue = new HotPriorityQueue<DirectedPath>(16);
            _landmark = landmarks
                    .OrderByDescending(l => l.HexDistance(goal.Coords) - l.HexDistance(start.Coords))
                    .FirstOrDefault();
            _heuristic = c => _landmark.HexDistance(c) - _landmark.HexDistance(start.Coords);

            var path = new DirectedPath(goal);
            _open.Add(goal.Coords, path);
            _queue.Enqueue(0, path);
        }
예제 #33
0
파일: Game.cs 프로젝트: Chin-I/Threesus
 /// <summary>
 /// Returns a random empty cell on the game board.
 /// </summary>
 private IntVector2D GetRandomEmptyCell()
 {
     IntVector2D ret;
     do
     {
         ret = new IntVector2D(
             _rand.Int32(0, _board.Width - 1),
             _rand.Int32(0, _board.Height - 1));
     }
     while(_board[ret] != null);
     return ret;
 }
 static int Preference(IntVector2D vectorGoal, HexCoords goal, HexCoords hex)
 {
     return (0xFFFF & Math.Abs(vectorGoal ^ (goal.Canon - hex.Canon) ));
 }
 private void AssaignRaycastCount()
 {
     RayCount = new IntVector2D(Mathf.Clamp(RayCount.X, 2, int.MaxValue),
                              Mathf.Clamp(RayCount.Y, 2, int.MaxValue));
 }
 internal static int Estimate(Func<int,int> heuristic, IntVector2D vectorGoal, HexCoords goal, 
     HexCoords hex, int totalCost)
 {
     var estimate   = (int)heuristic(goal.Range(hex)) + totalCost;
       var preference = Preference(vectorGoal, goal, hex);
       return (estimate << 16) + preference;
 }
예제 #37
0
파일: Board.cs 프로젝트: Chin-I/Threesus
 /// <summary>
 /// Gets or sets the card in the specified board cell.
 /// </summary>
 public Card this[IntVector2D cell]
 {
     get { return _cards[cell.X, cell.Y]; }
     set { _cards[cell.X, cell.Y] = value; }
 }
예제 #38
0
파일: Board.cs 프로젝트: Chin-I/Threesus
        /// <summary>
        /// Shifts the row or column containing the specified startCell by the specified increment,
        /// shifting and merging cards where possible.
        /// </summary>
        /// <returns>Whether anything was able to be shifted.</returns>
        private bool ShiftRowOrColumn(IntVector2D startCell, IntVector2D increment, int widthOrHeight)
        {
            bool ret = false;

            // Impossible to shift the start cell, so just skip it.
            IntVector2D prevCell = startCell;
            IntVector2D curCell = startCell - increment;

            // Try to shift each cell one-by-one.
            for(int i = 1; i < widthOrHeight; i++)
            {
                Card curCard = this[curCell];
                if(curCard != null)
                {
                    Card prevCard = this[prevCell];
                    if(prevCard == null)
                    {
                        this[prevCell] = curCard;
                        this[curCell] = null;
                        ret = true;
                    }
                    else
                    {
                        // Try to merge on top of the previous card.
                        Card merged = curCard.GetMergedWith(prevCard);
                        if(merged != null)
                        {
                            this[prevCell] = merged;
                            this[curCell] = null;
                            ret = true;
                        }
                    }
                }

                prevCell = curCell;
                curCell -= increment;
            }

            return ret;
        }
 static int XFromVector(int y, IntVector2D v)
 {
     return (-2 * v.Y + v.X * (3 * y + 1) + (3 * v.Y) - 1) / (3 * v.Y);
 }
 /// <summary>TODO</summary>
 /// <param name="vectorGoal"></param>
 /// <param name="vectorHex"></param>
 /// <returns></returns>
 static int Preference(IntVector2D vectorGoal, IntVector2D vectorHex)
 {
     return (0xFFFF & Math.Abs(vectorGoal ^ vectorHex));
 }
 static int Estimate(Func<int, int> heuristic, IntVector2D vectorGoal, HexCoords start,
         HexCoords hex, double totalCost)
 {
     var estimate = heuristic(start.Range(hex)) + (int)totalCost;
     var preference = Preference(vectorGoal, start.Canon - hex.Canon);
     return (estimate << 16) + preference;
 }
 //static IntVector2D VectorMin(IntVector2D lhs, IntVector2D rhs) {
 //  return lhs.LE(rhs) ? lhs : rhs;
 //}
 private static bool GT(this IntVector2D lhs, IntVector2D rhs)
 {
     return lhs.X * rhs.Y > lhs.Y * rhs.X;
 }
 // These are here (instead of IntVector2D.cs) because they are "upside-down" for regular use.
 static IntVector2D VectorMax(IntVector2D lhs, IntVector2D rhs)
 {
     return lhs.GT(rhs) ? lhs : rhs;
 }
    // Use this for initialization
    private void Awake()
    {
        Collider2D = GetComponent<BoxCollider2D>();

        RaycastOrigins = new RectangleVertices(GetExpandedBounds());
        RayCount = new IntVector2D(4, 4);
    }
 private static bool LE(this IntVector2D lhs, IntVector2D rhs)
 {
     return !lhs.GT(rhs);
 }