/// <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); } }
// Use this for initialization private void Awake() { Collider2D = GetComponent <BoxCollider2D>(); RaycastOrigins = new RectangleVertices(GetExpandedBounds()); RayCount = new IntVector2D(4, 4); }
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); }
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; }
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); }
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); }
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); }
// 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); }
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; } } }
private void Fall() { _currStateInfo.lastLoc = Location; Location += new IntVector2D(0, -1); _currStateInfo.fractionComplete = 0f; _currStateInfo.state = Char2DState.Falling; }
public void ReplacePosition(IntVector2D newValue) { var index = GameComponentsLookup.Position; var component = CreateComponent <PositionComponent>(index); component.value = newValue; ReplaceComponent(index, component); }
/// <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(); } }
private void MoveInDirTo(FacingDir dir, IntVector2D dest) { _currStateInfo.lastLoc = Location; Location = dest; _currStateInfo.state = Char2DState.Walking; _currStateInfo.facingDirection = dir; _currStateInfo.fractionComplete = 0f; }
private void JumpInDirBy(FacingDir dir, IntVector2D deltaLoc) { _currStateInfo.lastLoc = Location; Location += deltaLoc; _currStateInfo.state = Char2DState.Jumping; _currStateInfo.facingDirection = dir; _currStateInfo.fractionComplete = 0f; }
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); }
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); }
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)); } }
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); } }
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)); } }
private bool IsSelectedOnPosition(IntVector2D position) { var entity = _contexts.game.GetTileWithPosition(position); if (entity != null && entity.isSelected) { return(true); } return(false); }
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); }
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); }
/// <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); }
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); }
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); } }
/// <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); }
/// <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; }
/// <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; } }
/// <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); }