public virtual void ShowEventMarker(GridLocation gl, bool show, bool responseSuccess = false, bool responseCasualty = false) { if(show) { if(icon != null) { icon.SetActive(true); } else { Vector3 point = Vector3.zero; GameUtils.SphericalToCartesian(1110f, gl.spawnLocation.y * Mathf.Deg2Rad, gl.spawnLocation.x * Mathf.Deg2Rad, out point); GameObject locationMarker = GameObject.Instantiate(Resources.Load("AnomalousLocationMarker"), point, Quaternion.identity) as GameObject; locationMarker.transform.localScale = new Vector3(75f, 75f, 75f); locationMarker.transform.forward = -(locationMarker.transform.position - new Vector3(0, 0, 0)).normalized; locationMarker.transform.parent = GameObject.Find("Earth").transform; LeanTween.rotateZ(locationMarker, 720f, 3.5f).setLoopClamp().setLoopCount(-1); LeanTween.rotateZ(locationMarker.transform.FindChild("Outer").gameObject, -720f, 2.75f).setLoopClamp().setLoopCount(-1); locationMarker.transform.FindChild("Outer").GetComponent<EventPopUpDialog>().EventIndex = ID; locationMarker.transform.FindChild("Outer").GetComponent<EventPopUpDialog>().GridLocationIndex = gridNumToLocations.IndexOf(gl); locationMarker.transform.FindChild("Outer").GetComponent<EventPopUpDialog>().ResponseTeamSuccess = responseSuccess; locationMarker.transform.FindChild("Outer").GetComponent<EventPopUpDialog>().ResponseTeamCasualties = responseCasualty; locationMarker.transform.FindChild("Outer").name = "EV-" + ID; icon = locationMarker; } } else if(icon != null) { icon.SetActive(false); } }
/// <summary> /// Gets the accessible adjacent locations of a specified location. /// A location is accessible if it's top, bottom, left or right of the location within the grid's ranges and is not a treasure. /// </summary> /// <returns>The accessible adjacent locations.</returns> /// <param name="gameGrid">Game grid.</param> /// <param name="location">Location.</param> /// <param name="ignoreLocation">Ignore this location no matter what type of treasure it has.</param> /// <param name="currentActiveTreasure">The current active treasure is never considered a wall.</param> public static List<GridLocation> GetAccessibleAdjacentLocations(GameFieldGrid gameGrid, GridLocation location, TreasureType currentActiveTreasure, GridLocation ignoreLocation = null) { var checkLocations = new List<GridLocation> (); // Check the item to the top. if(location.Row > 0) { var targetLocation = new GridLocation (location.Row - 1, location.Column); bool ignore = ignoreLocation != null && targetLocation.Equals (ignoreLocation); bool isActiveTreasure = gameGrid.GetItem (targetLocation).Treasure == currentActiveTreasure; if (isActiveTreasure || ignore || IsPassableTreasureType (targetLocation, gameGrid)) { checkLocations.Add (targetLocation); } } // Check the item below. if(location.Row < gameGrid.Rows - 1) { var targetLocation = new GridLocation (location.Row + 1, location.Column); var ignore = ignoreLocation != null && targetLocation.Equals (ignoreLocation); bool isActiveTreasure = gameGrid.GetItem (targetLocation).Treasure == currentActiveTreasure; if (isActiveTreasure || ignore || IsPassableTreasureType (targetLocation, gameGrid)) { checkLocations.Add (targetLocation); } } // Check the item to the left. if(location.Column > 0) { var targetLocation = new GridLocation (location.Row, location.Column - 1); var ignore = ignoreLocation != null && targetLocation.Equals (ignoreLocation); bool isActiveTreasure = gameGrid.GetItem (targetLocation).Treasure == currentActiveTreasure; if (isActiveTreasure || ignore || IsPassableTreasureType (targetLocation, gameGrid)) { checkLocations.Add (targetLocation); } } // Check the item to the right. if(location.Column < gameGrid.Columns - 1) { var targetLocation = new GridLocation (location.Row, location.Column + 1); var ignore = ignoreLocation != null && targetLocation.Equals (ignoreLocation); bool isActiveTreasure = gameGrid.GetItem (targetLocation).Treasure == currentActiveTreasure; if (isActiveTreasure || ignore || IsPassableTreasureType (targetLocation, gameGrid)) { checkLocations.Add (targetLocation); } } return checkLocations; }
public InterceptAction(int index, GridLocation location, GoIBase GOI) { destination = location; eventIndex = index; interceptGroup = GOI; Debug.Log("GOI passed in: " + GOI.name); allowsMultiple = true; startingPoint = null; }
public GridLocation GenerateGridLocation(int gridCell) { GridLocation gl = new GridLocation(); gl.gridCell = gridCell; gl.spawnLocation = GenerateSpawnLocation(gridCell); gl.regionCode = FindRegionNum(gridCell); gl.statusCode = 0; return gl; }
private SerialisableTileObstacleAttribute TryAddEdgeObstacle(GridLocation gridLocation) { if (gridLocation.X == 0) { if (gridLocation.Y == 0) // Bottom left { return(new SerialisableTileObstacleAttribute( new TileConnectionScoreInfo(8))); } else if (gridLocation.Y == _gridHeight - 1) // Top left { return(new SerialisableTileObstacleAttribute( new TileConnectionScoreInfo(6))); } else // Colomn left { return(new SerialisableTileObstacleAttribute( new TileConnectionScoreInfo(10))); } } else if (gridLocation.X == _gridWidth - 1) { if (gridLocation.Y == 0) // Bottom right { return(new SerialisableTileObstacleAttribute( new TileConnectionScoreInfo(11))); } else if (gridLocation.Y == _gridHeight - 1) // Top right { return(new SerialisableTileObstacleAttribute( new TileConnectionScoreInfo(9))); } else // Colomn right { return(new SerialisableTileObstacleAttribute( new TileConnectionScoreInfo(10))); } } else if (gridLocation.Y == 0) // Bottom row { return(new SerialisableTileObstacleAttribute( new TileConnectionScoreInfo(7))); } else if (gridLocation.Y == _gridHeight - 1) // Top row { return(new SerialisableTileObstacleAttribute( new TileConnectionScoreInfo(7))); } return(null); }
public override bool checkProceduralPrecondition(HashSet<KeyValuePair<string, object>> worldState) { float bestDistance = 100000000; foreach(GOIHQBase baseLocation in interceptGroup.headQuarters.Values) { float distance = GameUtils.CalculateDistance(destination.spawnLocation, baseLocation.Location.spawnLocation); if(startingPoint == null || distance < bestDistance) { startingPoint = baseLocation.Location; bestDistance = distance; } } if(startingPoint != null) return true; else return false; }
public void SendPlayerCollidesWithMusicInstrumentCaseEvent(GridLocation tileLocation, PlayerCharacter playerCharacter) { object[] content = new object[] { tileLocation.X, tileLocation.Y, playerCharacter.PlayerNumber }; RaiseEventOptions raiseEventOptions = new RaiseEventOptions { Receivers = ReceiverGroup.All }; PhotonNetwork.RaiseEvent(PlayerCollidesWithMusicInstrumentCaseEventCode, content, raiseEventOptions, SendOptions.SendReliable); Logger.Log("sent PlayerCollidesWithMusicInstrumentCaseEvent"); }
public void ObtenerDatos(int Id) { Cliente cli = new Cliente(); DataTable dt = new DataTable(); try { if (cli.Buscar(Id)) { // DateTime date = Convert.ToDateTime(cli.FechaNacimiento); tbxNombre.Text = cli.Nombre; tbxCedula.Text = cli.Cedula; tbxTelefono.Text = cli.Cedula; tbxFecha.Visible = false; tbxFecha2.Visible = true; lblEdad.Text = "Edad"; tbxFecha2.Text = Utilitario.ObtenerEdad(cli.FechaNacimiento); tbxDireccion.Text = cli.Direccion; tbxVehiculo.Text = cli.Vehiculo.ToString(); tbxDireccionTrabajo.Text = cli.DireccionTrabajo; tbxTelefonoTrabajo.Text = cli.TelefonoTrabajo; tbxHijo.Text = cli.Hijo.ToString(); tbxIngreo.Text = cli.Ingreso.ToString(); tbxRemesa.Text = cli.Remesa.ToString(); dt = Utilitario.Lista(" Descripcion,Latitude,Longitude ", " from Ubicacion ", " where ClienteId = " + Id); GridLocation.DataSource = dt; GridLocation.DataBind(); ViewState["Detalle"] = dt; ObtenerGridView(); if (cli.EstadoCivil > 0) { radCasado.Checked = true; } else { radSoltero.Checked = true; } } } catch (Exception e) { throw e; } }
/// <summary> /// OutsideBounds /// Returns True if GridLocation specified is outside allowed grid size /// </summary> /// <param name="grid"></param> /// <param name="gridLocation"></param> /// <returns></returns> public static bool OutsideBounds(this char[,] grid, GridLocation gridLocation) { if (gridLocation.Row > grid.MaxRow() || gridLocation.Row < 1) { return(true); } if (gridLocation.Column > grid.MaxColumn() || gridLocation.Column < 1) { return(true); } return(false); }
public static GridLocation OffsetGridLocationWithPathNode(GridLocation location, RelativePathNode relativePathNode) { var(colOffset, rowOffset) = relativePathNode.Direction switch { CardinalDirection.North => (0, 1), CardinalDirection.South => (0, -1), CardinalDirection.East => (1, 0), CardinalDirection.West => (-1, 0), _ => throw new ArgumentOutOfRangeException() }; return(new GridLocation(location.Row + relativePathNode.Distance * rowOffset, location.Column + relativePathNode.Distance * colOffset)); }
public void SendEnemyCollidesWithMusicInstrumentCaseEvent(GridLocation tileLocation, EnemyCharacter enemyCharacter) { object[] content = new object[] { tileLocation.X, tileLocation.Y, enemyCharacter.PhotonView.ViewID }; RaiseEventOptions raiseEventOptions = new RaiseEventOptions { Receivers = ReceiverGroup.All }; PhotonNetwork.RaiseEvent(EnemyCollidesWithMusicInstrumentCaseEventCode, content, raiseEventOptions, SendOptions.SendReliable); Logger.Log("sent EnemyCollidesWithMusicInstrumentCaseEvent"); }
public bool IsLocationAvailable(GridLocation location) { bool withinBoundsRow = (location.row < gridSize) && (location.row >= 0); bool withinBoundsCol = (location.col < gridSize) && (location.col >= 0); if (withinBoundsRow && withinBoundsCol) { return(grid[location.row][location.col] == null); } else { return(false); } }
public void MovePlayer(DIRECTION direction, PlayerController player) { GridLocation currentPosition = playerPositions[player]; Vector2 dir = DirectionToVector(direction); GridLocation destination = new GridLocation(currentPosition.row + (int)dir.y, currentPosition.col + (int)dir.x); if (IsLocationAvailable(destination)) { ClearLocation(currentPosition); MovePlayerToLocation(player, destination); } }
private void CheckPointerInput() { if (HasCalculatedTarget) { return; } Vector2 tempFingerPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition); GridLocation closestGridLocation = GridLocation.FindClosestGridTile(tempFingerPosition); if (closestGridLocation.X == CurrentGridLocation.X && closestGridLocation.Y == CurrentGridLocation.Y) { return; } GridLocation newLocomotionTarget = CurrentGridLocation; Vector2 direction = tempFingerPosition - (Vector2)transform.position; float angle = Vector2.SignedAngle(Vector2.up, direction) * -1; new GridLocation(CurrentGridLocation.X, CurrentGridLocation.Y); ObjectDirection moveDirection = ObjectDirection.Right; if (angle <= -135) // go down { newLocomotionTarget = new GridLocation(CurrentGridLocation.X, CurrentGridLocation.Y - 1); moveDirection = ObjectDirection.Down; } else if (angle <= -45) // go left { newLocomotionTarget = new GridLocation(CurrentGridLocation.X - 1, CurrentGridLocation.Y); moveDirection = ObjectDirection.Left; } else if (angle <= 45) // go up { newLocomotionTarget = new GridLocation(CurrentGridLocation.X, CurrentGridLocation.Y + 1); moveDirection = ObjectDirection.Up; } else if (angle <= 135) // go right { newLocomotionTarget = new GridLocation(CurrentGridLocation.X + 1, CurrentGridLocation.Y); moveDirection = ObjectDirection.Right; } else // go down { newLocomotionTarget = new GridLocation(CurrentGridLocation.X, CurrentGridLocation.Y - 1); moveDirection = ObjectDirection.Down; } SetPointerLocomotionTarget(GridLocation.GridToVector(newLocomotionTarget), moveDirection); }
private static void AddGridLocationRefDataToDb(DataRow row) { try { using (SdmDbContext dbc = new SdmDbContext()) { String rowBuildingCode = row.Field <String>("building"); var floorObject = dbc.Floors.Where(x => x.Building.Code == rowBuildingCode); var filteredFloor = floorObject.ToArray().First(); GridLocation grl = new GridLocation() { GridLocationValue = row.Field <String>("grid_location"), CreatedDt = DateTime.Now, CreatedBy = 0, UpdatedDt = DateTime.Now, UpdatedBy = 0, Floor = filteredFloor }; // if this record already exists in db, dont save it (this is a reference table) if (dbc.GridLocations.Any(o => o.GridLocationValue == grl.GridLocationValue)) { //match! todo: fix this if else } else { dbc.GridLocations.Add(grl); dbc.SaveChanges(); } }; } catch (DbEntityValidationException e) { foreach (var eve in e.EntityValidationErrors) { Console.WriteLine("Entity of type \"{0}\" in state \"{1}\" has the following validation errors:", eve.Entry.Entity.GetType().Name, eve.Entry.State); foreach (var ve in eve.ValidationErrors) { Console.WriteLine("- Property: \"{0}\", Value: \"{1}\", Error: \"{2}\"", ve.PropertyName, eve.Entry.CurrentValues.GetValue <object>(ve.PropertyName), ve.ErrorMessage); } } throw; } }
/// <summary> /// Returns a full list of path nodes which the enemies /// will have to transverse. This method will return every /// single node that is on the path. /// </summary> /// <returns></returns> public IEnumerable<IEnemyPathNode> GetIntermediateValues() { // still a problem though, because the entry node is still going // to be calculated in the loop. // return the entry node. var loc = startingLocation; CardinalDirection? lastOutgoingDirection = null; // this is fine, because we don't actually start // out with a path node, rather we start out at the // starting location. foreach (var pathNode in pathNodes) { // cache a few variables on the stack, // because they're small and could optimize lookup times. var outgoingDirection = pathNode.Direction; var oppositeOutgoingDirection = outgoingDirection.Opposite(); var directionLocationSign = outgoingDirection.GetGridLocationSign(); // ----- CALCULATE THE POSITION AND ATTRIBUTES OF THE TURN NODE ---- // yield return new SimpleEnemyPathNode(loc, lastOutgoingDirection?.Opposite(), outgoingDirection); // ---- CALCULATE THE NODES IN BETWEEN THIS TURN NODE AND WHAT WILL EITHER ---- // // ---- BE THE END OR THE NEXT NODE ---- // // remember to not calculate the turn node more than once, // and if we iterated all the say to distance we'd be doing that. // we only really want to evaluate the values *in between* // the two given nodes. var extrapolatedLoc = loc; for (var i = 1; i < pathNode.Distance; i++) { extrapolatedLoc = GridLocation.Add(extrapolatedLoc, directionLocationSign); yield return new SimpleEnemyPathNode(extrapolatedLoc, oppositeOutgoingDirection, outgoingDirection); } // calculate the length of the upcoming path loc = GridLocation.Add(loc, GridLocation.Scale(directionLocationSign, pathNode.Distance)); // don't forget to update the state for the next iteration. lastOutgoingDirection = outgoingDirection; } // var exitNodeLocation = GridLocation.Add(loc, GridLocation.Scale(lastTurnNode.Direction.GetGridLocationSign(), lastTurnNode.Distance)); yield return new SimpleEnemyPathNode(loc, lastOutgoingDirection?.Opposite(), null); }
void UpdateSelectorStatus(out GridLocation cent) { int gridwidth = levelgridwidths[Globals.gCurrentLevel - 1]; int gridheight = levelgridheights[Globals.gCurrentLevel - 1]; Vector2 mp = Input.mousePosition; Vector3 mouseworld = cam.ScreenToWorldPoint(mp); mouseworld += new Vector3(gridentrysize / 2f, gridentrysize / 2f); GridLocation center = null; int j = 0; for (int i = 0; i < gridwidth * gridheight; ++i) { if (i > 0 && i % gridwidth == 0) { j++; } // -- check intersection with this gridloc if (MouseInside(mouseworld, grid[i % gridwidth, j])) { center = grid[i % gridwidth, j]; break; } } if (center != null) { // -- set selector attrib selector.gameObject.SetActive(true); selector.transform.position = center.anchorpoint; // -- anchor next furniture sprite to selector GridSpace nextitemspace = currentlevelqueue.GetNextItemCost(); selector.SetSelectorFor(currentlevelqueue.GetNextItemCost()); Vector3 fo = GetOffsetForFurniture(nextitemspace.widthoffset, nextitemspace.heightoffset); currentlevelqueue.GetNextItem().transform.position = selector.transform.position + fo; } else { selector.gameObject.SetActive(false); } UpdatePlaceableStatus(center); cent = center; }
public static GridLocation Right(GridLocation loc) { int gridwidth = instance.levelgridwidths[Globals.gCurrentLevel - 1]; if (loc == null) { return(null); } if (loc.x + 1 > gridwidth - 1) { return(null); } return(instance.grid[loc.x + 1, loc.y]); }
public static GridLocation Below(GridLocation loc) { int gridheight = instance.levelgridheights[Globals.gCurrentLevel - 1]; if (loc == null) { return(null); } if (loc.y + 1 > gridheight - 1) { return(null); } return(instance.grid[loc.x, loc.y + 1]); }
/// <summary> /// Instantiates a new tile /// This method will translate the location /// in local grid space, into word space /// coordinates and then instantiate a tile /// there, after which it will initialize /// all the tile's components with all the /// data that they may need. /// </summary> /// <param name="grid"></param> /// <param name="location"> the local grid space location </param> /// <returns> a newly instantiated tile </returns> public virtual Tile.Tile CreateInstance(PrefabGrid <Tile.Tile> grid, GridLocation location) { var spawnLoco = GridSpaceGlobalSpaceConverter.FromLocation(location, -0.15f); var currentTile = Object.Instantiate(grid.Prefab, spawnLoco, Quaternion.identity, tileSelectionManager.transform); // initializing the components. currentTile.GetComponent <ITileSelectionInteractor>().Init(gameManager.GetEnergyCounter(), gameManager.GetTurretShop(), tileSelectionManager, tileFocusManager); currentTile.GetComponent <ITileFocusDisplay>().Init(gameManager.focus); currentTile.GetComponent <IPrefabGridPositionedItem>().SetLocation(location); currentTile.GetComponent <IExclusiveFocusInteractor>().SetManager(tileFocusManager); return(currentTile); }
public void RemoveBlock() { GameObject possibleBlock = look.collider ? look.collider.gameObject : null; if (possibleBlock != null) { var block = possibleBlock.GetComponent <Block>(); if (block != null) { GridLocation location = block.Location; location.Grid.RemoveBlock(location.GridVector); Destroy(block.gameObject); } } }
/// <inheritdoc/> public override void Create(GridLocation gridLocation) { // if room is close to center if (Mathf.Abs(gridLocation.X) < 5 && Mathf.Abs(gridLocation.Y) < 5) { MinDoors = 1; MaxDoors = 2; } else { MinDoors = 0; MaxDoors = 1; } base.Create(gridLocation); }
void UpdateGrid(GridLocation center, out bool breakoccur) { breakoccur = false; GridSpace nextitemspace = currentlevelqueue.GetNextItemCost(); switch (rotationpreview) { case 0: for (int i = 0; i < nextitemspace.shape.Length; ++i) { if (nextitemspace.shape[i]) { PlaceOnGrid0Rot(center, i, nextitemspace.walkable, nextitemspace.breakable, out breakoccur); } } break; case 90: for (int i = 0; i < nextitemspace.shape.Length; ++i) { if (nextitemspace.shape[i]) { PlaceOnGrid90Rot(center, i, nextitemspace.walkable, nextitemspace.breakable, out breakoccur); } } break; case 180: for (int i = 0; i < nextitemspace.shape.Length; ++i) { if (nextitemspace.shape[i]) { PlaceOnGrid180Rot(center, i, nextitemspace.walkable, nextitemspace.breakable, out breakoccur); } } break; case 270: for (int i = 0; i < nextitemspace.shape.Length; ++i) { if (nextitemspace.shape[i]) { PlaceOnGrid270Rot(center, i, nextitemspace.walkable, nextitemspace.breakable, out breakoccur); } } break; } }
public void SetDirection(GridLocation spawnLocation, CardinalDirection direction) { if (direction == CardinalDirection.North || direction == CardinalDirection.South) { Zone = new RectangleExclusionZone( new GridLocation(spawnLocation.Row - verticalWidth / 2, spawnLocation.Column - horizontalWidth / 2), new GridLocation(spawnLocation.Row + verticalWidth / 2, spawnLocation.Column + horizontalWidth + 2)); } else { Zone = new RectangleExclusionZone( new GridLocation(spawnLocation.Row - horizontalWidth / 2, spawnLocation.Column - verticalWidth / 2), new GridLocation(spawnLocation.Row + horizontalWidth / 2, spawnLocation.Column + verticalWidth / 2) ); } }
/* * Sets the corresponding bit in the grid and returns the coordinates */ public int[] findAndSetPointInGrid(Improbable.Vector3f point) { int[] coord = findGridCoordinatesOfPoint(point); GridLocation loc = new GridLocation(coord[0], coord[1]); foreach (var n in GeneralNeighbours(loc, SimulationSettings.NFZ_PADDING)) { if (getGridCell(n.x, n.z) != GridType.IN) { setGridCell(n.x, n.z, GridType.NEAR); } } setGridCell(coord[0], coord[1], GridType.IN); return(coord); }
/// <summary> /// IsWordPlacementValid /// Given a hidden word, check that it can fit into the grid given its length /// and starting position within the grid /// </summary> /// <param name="grid"></param> /// <param name="hiddenWord"></param> /// <returns></returns> public static bool IsWordPlacementValid(char[,] grid, HiddenWord hiddenWord) { if (hiddenWord != null) { var gridLocation = new GridLocation(hiddenWord.Start); foreach (var letter in hiddenWord.Word) { if (!CanLetterBePlaced(letter, gridLocation, grid)) { return(false); } gridLocation = GridLocation.GetNextLetterGridLocation(gridLocation, hiddenWord.Direction); } } return(true); }
protected override void VerifyLocation(GridLocation oldLocation, GridLocation newLocation) { if (oldLocation.Grid == newLocation.Grid) { return; } BlockGrid grid = newLocation.Grid; GridDriver driver = grid.GetComponent <GridDriver>(); if (!driver) { driver = grid.gameObject.AddComponent <GridDriver>(); driver.Grid = grid; } Driver = driver; }
public double ComputeCost(GridLocation start, GridLocation end, Dictionary <GridLocation, GridLocation> cameFrom, Dictionary <GridLocation, double> costSoFar, ref bool usingLOS, Bitmap bitmap) { Debug.Assert(bitmap != null); var parent = cameFrom[start]; if (parent != null && bitmap.lineOfSight(parent, end)) { ++LOSchecks; usingLOS = true; return(costSoFar[parent] + parent.distanceTo(end)); } double c = (Math.Abs(start.x - end.x) == 1 && Math.Abs(start.z - end.z) == 1) ? Math.Sqrt(2) : 1; return(costSoFar[start] + c); }
public HashSet <GridLocation> GeneralNeighbours(GridLocation current, int layers) { HashSet <GridLocation> set = new HashSet <GridLocation>(); for (int i = -layers; i <= layers; ++i) { for (int j = -layers; j <= layers; ++j) { if ((i != 0 || j != 0) && InGridBounds(current.x + i, current.z + j) && (getGridCell(current.x + i, current.z + j) == GridType.OUT)) { set.Add(new GridLocation(current.x + i, current.z + j)); } } } return(set); }
public static List <GridLocation> RebuildPath(GridLocation goal, Dictionary <GridLocation, GridLocation> cameFrom) { //Debug.LogWarning("GS: rebuild path"); GridLocation end = goal; List <GridLocation> path = new List <GridLocation>(); //Debug.LogWarning("TS: rebuild while BEGIN"); while (end != null) { path.Add(end); end = cameFrom[end]; } //Debug.LogWarning("TS: reverse path"); path.Reverse(); //Debug.LogWarning("TS: return path"); return(path); }
/// <summary> /// This method Creates structure of the room. This also creates Doors. Here you can place structural things in to the room for example pillars or bolders. /// </summary> public virtual void Create(GridLocation gridLocation) { Location = gridLocation; var doorNumber = Random.Range(MinDoors, MaxDoors + 1); IEnumerable <DoorLocation> doors; var doorValues = Enum.GetValues(typeof(DoorLocation)).Cast <int>().Where(x => x != 0).ToList(); var doorsToEliminate = doorValues.Count - doorNumber; for (var i = 0; i < doorsToEliminate; i++) { doorValues.RemoveAt(Random.Range(0, doorValues.Count)); } doors = doorValues.Count > 0 ? doorValues.Cast <DoorLocation>() : null; Doors = doors?.Aggregate((a, b) => a | b) ?? DoorLocation.None; transform.position = new Vector3(gridLocation.X * 18, gridLocation.Y * 10); }
// Used when player builds a new object. Not used for the default objects that already are part of the room, as they do not need a separate GO instantiation. public void BuildRoomObject(RoomObjectBlueprint roomObjectBlueprint, GridLocation roomObjectLocation, Room parentRoom) { Logger.Log("Trying to put a {0} in the room", roomObjectBlueprint.Name); GridLocation rotationTranslatedObjectLocation = TranslateObjectLocationForRoomRotation(roomObjectLocation, parentRoom); Vector2 roomObjectLocalLocation = GridHelper.GridToVectorLocation(rotationTranslatedObjectLocation); Vector2 roomObjectWorldPosition = new Vector2(parentRoom.RoomCorners[Direction.Down].x + roomObjectLocalLocation.x, parentRoom.RoomCorners[Direction.Down].y + roomObjectLocalLocation.y); GameObject roomObjectGO = GameManager.Instance.InstantiatePrefab( BuilderManager.Instance.PlaceableRoomObjectPrefabs[roomObjectBlueprint.RoomObjectName][ObjectRotation.Rotation0], parentRoom.RoomObjectsContainer.transform, roomObjectWorldPosition); RoomObjectGO roomObject = roomObjectGO.GetComponent <RoomObjectGO>(); roomObject.Initialise(roomObjectBlueprint, parentRoom.RoomRotation, parentRoom); parentRoom.RoomObjectsContainer.AddRoomObject(roomObject); }
public static bool PartOf(this GridLocation loc, GridDirection dir) { switch (loc) { case GridLocation.TOP: return(dir == GridDirection.VERT); case GridLocation.BOTTOM: return(dir == GridDirection.VERT); case GridLocation.LEFT: return(dir == GridDirection.HORIZ); case GridLocation.RIGHT: return(dir == GridDirection.HORIZ); } return(false); }
/// <summary> /// PlaceWordInGrid /// Places the given word in the grid /// </summary> /// <param name="grid"></param> /// <param name="hiddenWord"></param> /// <returns></returns> public bool PlaceWordInGrid(char[,] grid, HiddenWord hiddenWord) { var placed = false; if (placed = PlacementValidator.IsWordPlacementValid(grid, hiddenWord)) { var gridLocation = new GridLocation(hiddenWord.Start); foreach (var letter in hiddenWord.Word) { grid[gridLocation.Row - 1, gridLocation.Column - 1] = letter; gridLocation = GridLocation.GetNextLetterGridLocation(gridLocation, hiddenWord.Direction); } // return true; } return(placed); }
/// <summary> /// GetNextGridLocation /// Returns the GridLocation of the next grid character location /// </summary> /// <param name="grid"></param> /// <param name="gridLocation"></param> /// <returns></returns> public static GridLocation GetNextGridLocation(this char[,] grid, GridLocation gridLocation) { var row = gridLocation.Row; var column = gridLocation.Column + 1; if (column > grid.MaxColumn()) { column = 1; row++; if (row > grid.MaxRow()) { row = 1; } } return(new GridLocation(row, column)); }
private void BuildKeyList(Int32 columns, Int32 rows) { //At least 1 if(columns < 1 || rows < 1) throw new ArgumentOutOfRangeException(); //Can't be greater than number of pixels if(columns > TiledTexture.Texture.Width || rows > TiledTexture.Texture.Height) throw new ArgumentOutOfRangeException(); //Must be evenly divisible if(TiledTexture.Texture.Width % columns != 0 || TiledTexture.Texture.Height % rows != 0) throw new ArgumentOutOfRangeException(); Int32 tileWidth = TiledTexture.Texture.Width / columns; Int32 tileHeight = TiledTexture.Texture.Height / rows; for(Int32 r = 0; r < rows; r++) { for(Int32 c = 0; c < columns; c++) { Int32 left = c * tileWidth; Int32 right = left + tileWidth; Int32 top = r * tileHeight; Int32 bottom = top + tileHeight; Texture2dArea area = new Texture2dArea(left, top, right, bottom, TiledTexture.Texture.Width, TiledTexture.Texture.Height); GridLocation loc = new GridLocation(c, r); GridKey key = new GridKey(this, c, r, area); Keys.Add(loc, key); } } }
public void UpdatePlayer(GameMoveType move, TreasureType treasure, GridLocation location) { }
public void UpdatePlayer(GameMoveType move, TreasureType treasure, GridLocation location) { // TODO: Implementation required? this.visualizationService.Write(this.visualizationService.screen.Rows - 1, 0, ConsoleColor.White, "Other player's move '{0}' discovered item {1} at location {2}", move, treasure, location); }
public GridLocation GenerateGridLocation(List<int> GridSquares) { GridLocation gl = new GridLocation(); int gridCell = GenerateGridNum(GridSquares); gl.gridCell = gridCell; gl.spawnLocation = GenerateSpawnLocation(gridCell); gl.regionCode = FindRegionNum(gridCell); gl.statusCode = 0; return gl; }
public override void reset() { base.reset(); startingPoint = null; }
/// <summary> /// Gets the fields that have to be followed to come to a specific location. /// </summary> /// <returns>The path to location.</returns> /// <param name="fromLocation">the location from where to start path finding. Must be the same that was passed to PreparePathGrid()</param> /// <param name="toLocation">the location to find the path to starting at the unused location.</param> /// <param name="gameGrid">Game grid.</param> /// <param name="pathGrid">Populated path grid.</param> /// <param name="currentActiveTreasure">The current active treasre can always be stepped onto.</param> public static List<GridLocation> GetPathToLocation(GameFieldGrid gameGrid, Grid2D<int> pathGrid, GridLocation fromLocation, GridLocation toLocation, TreasureType currentActiveTreasure) { if(gameGrid == null) { throw new ArgumentNullException ("gameGrid"); } if(pathGrid == null) { throw new ArgumentNullException ("pathGrid"); } if(toLocation == null) { throw new ArgumentNullException ("toLocation"); } // This will hold the reversed path. var path = new List<GridLocation> { // The target always belongs to the path. new GridLocation (toLocation.Row, toLocation.Column) }; // Loop until the path has been completed. while(true) { // From the current target location check all possible moves. The algorithm works its way from the target to the start, so the path will be reversed. var checkLocations = AIHelpers.GetAccessibleAdjacentLocations (gameGrid, toLocation, currentActiveTreasure, fromLocation); // Loop the possible moves and remember the one with the lowest distance towards the start location. int lowestDistance = pathFindingMaxVal; GridLocation lowestLocation = null; foreach(var adjacentLocation in checkLocations) { int distance = pathGrid.GetItem (adjacentLocation); if(distance < lowestDistance) { lowestDistance = distance; lowestLocation = adjacentLocation; // The new target location is the lowest of the possible locations. toLocation = lowestLocation; } } if(lowestLocation != null) { // Insert at 0 to have the path in the correct reversed order. path.Insert(0, lowestLocation); if(lowestLocation.Equals(fromLocation)) { // Reached the start location. break; } } else { // No lowest location found. Bail out. break; } } return path; }
/// <summary> /// Converts the aciont queue to server command format for minimal network load. /// </summary> /// <param name="loc">Location of the unit that is acting.</param> /// <param name="actionQueue">Action queue</param> private void serealizeActionQueueAndSendToAllClients(GridLocation loc, LinkedList<ActionScript> actionQueue){ int numberOfActions = actionQueue.Count; byte[] actionType = new byte[numberOfActions]; byte[] actionAmount = new byte[numberOfActions]; ushort[] locX = new ushort[numberOfActions]; ushort[] locY = new ushort[numberOfActions]; int count = 0; SerializedCompletedAction sca; foreach( ActionScript item in actionQueue ){ sca = item.serializeAction(); actionType[count] = getActionByte(sca.actionType); actionAmount[count] = (byte)sca.actionAmountInt; locX[count] = (ushort)sca.locationToPerformAction.x; locY[count++] = (ushort)sca.locationToPerformAction.y; } Cmd_receaveUnitActionsOverNetwork((ushort)loc.x, (ushort)loc.y, actionType, actionAmount, locX, locY); }
/// <summary> /// Figures out if a specific item location is considered a "wall" for the path finding algorithm. /// A wall is defined as a treasure that is not the current active treasure card. /// The prediction is not 100% correct because the AI is not supposed to know the location of each and /// every treasure. Randomization and statistics are used to reduce the chance the AI will detect a wall. /// </summary> /// <returns><c>true</c> if the AI thinks it can move to the location otherwise, <c>false</c>.</returns> /// <param name="location">Location to check.</param> /// <param name="gameField">Game field to use.</param> public static bool IsPassableTreasureType(GridLocation location, GameFieldGrid gameField) { var item = gameField.GetItem (location.Row, location.Column); // A location can be moved to if the treasure is "None". if(item.Treasure != TreasureType.None) { // It's a wall. AI cannot go there. return false; } // It is not a wall. AI can go there. return true; }
/// <summary> /// Gets a random move. Used if the AI does not know what to do and is guessing. /// </summary> /// <returns>The random move.</returns> /// <param name="gameGrid">Game grid.</param> /// <param name="fromLocation">From location.</param> /// <param name="currentActiveTreasure">The current active treasure. This can also be stepped onto.</param> public static GameMoveType GetRandomMove(GameFieldGrid gameGrid, GridLocation fromLocation, TreasureType currentActiveTreasure) { var possibleTargetLocations = AIHelpers.GetAccessibleAdjacentLocations (gameGrid, fromLocation, currentActiveTreasure); var platformServices = ServiceContainer.Resolve<IPlatformServices> (); // Pick a random target location. var toLocation = possibleTargetLocations [platformServices.GetRandomNumber (0, possibleTargetLocations.Count)]; // Return the required move to get to the picked location. var randomMove = AIHelpers.GetMoveToAdjacentLocation (fromLocation, toLocation); return randomMove; }
//For loading a base or creating one in a specific location public StandardHQ(string GOIShortName, Color pColor, bool pTrueHQ, string iconPrefabID, GridLocation pLocation) { Location = pLocation; SpawnBase(GOIShortName, pColor, pTrueHQ, iconPrefabID); }
/// <summary> /// Serializes the unit. /// Primaraly used to insure network instances are synced /// </summary> /// <returns>The unit.</returns> public UnitSaving serializeUnit(){ UnitSaving serl = new UnitSaving(); //serl.controlType = controlType; serl.currentAttackPow = currentAttackPower; serl.currentMaxAttackActions = currentMaxPosibleAttackActions; serl.currentMaxLength = maxProgramLength; serl.currentMaxMove = maximumMovment; serl.unitNameToLoad = name; serl.currentUnitTimer = unitTimer; GridLocation[] BL = new GridLocation[blockList.Count]; int count = 0; foreach( var item in blockList ){ BL[count++] = item.gridLocation; } return serl; }
/// <summary> /// Learns about a treasure that has been discovered. /// </summary> /// <param name="treasure">Treasure.</param> /// <param name="location">Location.</param> protected void LearnAboutTreasure(TreasureType treasure, GridLocation location) { var loggingService = ServiceContainer.Resolve<ILoggingService> (); // Check if we already know about the treasure at the discovered location. TreasureChanceInfo treasureInfo = FindTreasureChanceByLocation (location); if(treasureInfo == null) { // Treasure is unknown. Remember now. treasureInfo = new TreasureChanceInfo () { treasureChance = ChanceRememberAnyTreasureJustUncovered, // Specific chance is not used for 'None'. specificTreasureChance = treasure == TreasureType.None ? 0f : ChanceRememberSpecificTreasureJustUncovered, location = location, treasure = treasure }; this.treasureChances.Add (treasureInfo); #if EXTENSIVE_LOGGING loggingService.Log ("AI just learned about {0} at location {1}.", treasure, location); #endif } else { // Item was seen before. AI fully remembers where the treasure is. Update memory. treasureInfo.specificTreasureChance = treasure == TreasureType.None ? 0f : ChanceRememberSpecificTreasureJustUncovered; treasureInfo.treasureChance = ChanceRememberAnyTreasureJustUncovered; #if EXTENSIVE_LOGGING loggingService.Log ("AI updated memory about {0} at location {1}.", treasure, location); #endif } }
protected virtual void SetupHQs(JSONNode N) { if (N["currentHqs"] != null) { //Currently Doesn't load old location only the number of facilities foreach (JSONNode hq in N["currentHqs"].AsArray) { GridLocation gl = new GridLocation(GameUtils.ParseVector2(hq["spawnLocation"]), hq["gridNum"].AsInt, hq["regionNum"].AsInt, hq["statusCode"].AsInt); SpawnHQ(gl); } } else { SpawnHQ(); } foreach (GOIHQBase hq in headQuarters.Values) { agentCoverage[hq.Location.regionCode] = 30f; } }
/// <summary> /// Gets the move that is required to get from one location an adjacent location. /// This does not check if the locations really are adjacent. If they are not, the result will be undefined. /// </summary> /// <returns>The move to location.</returns> /// <param name="fromLocation">From location.</param> /// <param name="toLocation">To location.</param> public static GameMoveType GetMoveToAdjacentLocation(GridLocation fromLocation, GridLocation toLocation) { if(fromLocation.Column == toLocation.Column) { if(fromLocation.Row < toLocation.Row) { return GameMoveType.MoveItemBelow; } else { return GameMoveType.MoveItemAbove; } } else { if(fromLocation.Column < toLocation.Column) { return GameMoveType.MoveItemRight; } else { return GameMoveType.MoveItemLeft; } } }
public GridKey GetKey(Int32 column, Int32 row) { GridLocation loc = new GridLocation(column, row); return Keys[loc]; }
public virtual int SpawnHQ(GridLocation gl) { int id = hqGen; try { GOIHQBase newBase = (GOIHQBase)System.Activator.CreateInstance(System.Type.GetType(hqType), shortName, color, true, hqIconPrefabID, gl); headQuarters.Add(hqGen++, newBase); return id; } catch (System.Exception e) { Debug.Log("Non-Existent HQ Type Declared: " + hqType + " " + e.StackTrace + " " + e.InnerException); return -1; } }
public virtual void UpdatePlayer(GameMoveType move, TreasureType treasure, GridLocation location) { // If it's the other player's turn, we can't have a target to move to. this.currentPath = null; // Forget a bit about treasures every time a move was made. this.ForgetTreasures (); // Remember the treasure that has just been discoverd fully. this.LearnAboutTreasure (treasure, location); }
/// <summary> /// Does some dice rolling to calculate if a specific location has a treasure or not. /// </summary> /// <returns><c>true</c> if this instance has location treasure the specified location; otherwise, <c>false</c>.</returns> /// <param name="location">Location.</param> protected virtual LocationMemory HasLocationPresumablyTreasure(GridLocation location) { var treasureChance = this.FindTreasureChanceByLocation (location); if(treasureChance == null) { // The location is unknown to the AI. return LocationMemory.DontKnow; } // The location is known to the AI. Roll the dice to decide if the AI remembers what is hidden at the location. var platformService = ServiceContainer.Resolve<IPlatformServices>(); float randomPercentage = (float)platformService.GetRandomNumber (); // Get the chance that indicates how well the AI remembers the location. float requiredPercentage = treasureChance.treasureChance; if(randomPercentage <= requiredPercentage) { // The AI remembers what is at the location. return treasureChance.treasure == TreasureType.None ? LocationMemory.HasNothing : LocationMemory.HasTreasure; } // The AI would know, but the dice rolling returned that it currently does not remember. return LocationMemory.DontKnow; }
/// <summary> /// Generates a maze to use as a basis for the map. /// </summary> private Grid<MazeCell> GenerateMaze() { // Initialize variables Random.seed = Seed; Stack<GridLocation> cellsVisited = new Stack<GridLocation>(); Grid<MazeCell> grid = new Grid<MazeCell>(Width, Height); int crawlDistance = 0; int maxCrawlDistance = 0; // Select initial cell position, flag it as the initial cell, // and push it onto the stack. GridLocation cellPos = grid.WrapCoordinates((int)InitialPosition.x, (int)InitialPosition.y); grid.GetCellAt(cellPos).IsStartCell = true; cellsVisited.Push(cellPos); // Recursively crawl the maze. while (cellsVisited.Count > 0) { // Flag the cell as visited. MazeCell cell = grid.GetCellAt(cellPos); cell.Flagged = true; cell.CrawlDistance = crawlDistance; // Calculate valid exits from the current cell position. MazeCellExits validExits = MazeCellExits.None; if ((Wrap || cellPos.x != 0) && !grid.GetCellAt(cellPos.x - 1, cellPos.y).Flagged) { validExits = validExits | MazeCellExits.West; } if ((Wrap || cellPos.x != Width - 1) && !grid.GetCellAt(cellPos.x + 1, cellPos.y).Flagged) { validExits = validExits | MazeCellExits.East; } if ((Wrap || cellPos.y != 0) && !grid.GetCellAt(cellPos.x, cellPos.y - 1).Flagged) { validExits = validExits | MazeCellExits.North; } if ((Wrap || cellPos.y != Height - 1) && !grid.GetCellAt(cellPos.x, cellPos.y + 1).Flagged) { validExits = validExits | MazeCellExits.South; } // When valid exits are found, flag the tile with a random // exit and select the next tile. Otherwise backtrack through the // stack looking for the most recently visited tile with valid // exits. if (validExits != MazeCellExits.None) { // Increment crawlDistance crawlDistance++; // Add the cell to the stack so we can return to it later for // recursive exit checking. cellsVisited.Push(cellPos); // Choose a random exit from the available exits. MazeCellExits exit = GetRandomExit(validExits); cell.Exits = cell.Exits | exit; // Select the next tile. if (exit == MazeCellExits.North) { cellPos = new GridLocation(cellPos.x, cellPos.y - 1); exit = MazeCellExits.South; } else if (exit == MazeCellExits.South) { cellPos = new GridLocation(cellPos.x, cellPos.y + 1); exit = MazeCellExits.North; } else if (exit == MazeCellExits.West) { cellPos = new GridLocation(cellPos.x - 1, cellPos.y); exit = MazeCellExits.East; } else if (exit == MazeCellExits.East) { cellPos = new GridLocation(cellPos.x + 1, cellPos.y); exit = MazeCellExits.West; } // Create an exit back to the previous tile. cell = grid.GetCellAt(cellPos); cell.Exits = cell.Exits | exit; } else { // Update max crawl distance. if (maxCrawlDistance < crawlDistance) { maxCrawlDistance = crawlDistance; } // Decrement crawlDistance crawlDistance--; if(cell.NumberOfExits == 1) { cell.IsDeadEnd = true; } // No valid exits so backtrack through the stack. cellPos = cellsVisited.Pop(); } } foreach(MazeCell cell in grid.CellArray) { cell.NormalizedDistance = (float)cell.CrawlDistance / (float)maxCrawlDistance; } for(int count = grid.CellArray.Length - 1; count >= 0; count-- ) { MazeCell currCell = grid.CellArray[count]; if((currCell.CrawlDistance >= maxCrawlDistance) && currCell.NumberOfExits == 1) { currCell.IsEndCell = true; break; } } return grid; }
/// <summary> /// Finds a treasure chance by location. /// </summary> /// <returns>The treasure chance by treasure. NULL, if the AI does not know anything about the treasure.</returns> /// <param name="location">Location.</param> TreasureChanceInfo FindTreasureChanceByLocation(GridLocation location) { return this.treasureChances.FirstOrDefault (info => info.location.Equals (location)); }
public GridBlock gridLocationToGameGrid(GridLocation gl){ if(gl.x < 0 || gl.y < 0 || gl.x >= gridSize || gl.y >= gridSize){ return null; } return gameGrid[gl.x, gl.y]; }
private void AddAnomalousEvent(bool isHerring = false) { //Select random event JSONNode anEvent = anomalousEventJson[anomalousEventFileName].AsArray[Random.Range(0, anomalousEventJson["anomalousEvents"].AsArray.Count)]; //Setup AnomalousEvent tempEvent = new AnomalousEvent(IDGenerator++, anEvent["descriptionText"], "AnomalousLocationMarker", isHerring); //Read in tag data foreach (JSONNode tag in anEvent["tags"].AsArray) { tempEvent.tags.Add(tag.ToString()); } Debug.Log(anomalousEventJson); Debug.Log(anomalousEventJson[anomalousEventFileName]); Debug.Log(anEvent); //Set spawn locations for (int i = 0; i < anEvent["numberOfSpawns"].AsInt; i++) { GridLocation location = new GridLocation(); if (anEvent["worldWide"].AsBool) { Debug.Log("worldwide spawn"); location = GeoscapeVariables.WM.GenerateGridLocation(); } else if (!anEvent["specificGrid"].AsBool) { Debug.Log("region spawn"); List<int> tempGridList = new List<int>(); foreach (JSONNode region in anEvent["regions"].AsArray) tempGridList.AddRange(GeoscapeVariables.WM.RegionList[region.AsInt].gridSquares); location = GeoscapeVariables.WM.GenerateGridLocation(tempGridList); } else { Debug.Log("specific grid spawn"); location = GeoscapeVariables.WM.GenerateGridLocation(anEvent["gridLocations"].AsArray[i].AsInt); } tempEvent.regions.Add(location.regionCode); tempEvent.gridNumToLocations.Add(location); } EventList.Add(tempEvent.ID, tempEvent); }
/// <summary> /// Gets a random location on the board and avoids treasures. /// </summary> /// <returns>The random location avoiding treasures.</returns> /// <param name="gameState">Game state.</param> protected virtual GridLocation GetRandomLocationAvoidingTreasures(GameState gameState) { var platformServices = ServiceContainer.Resolve<IPlatformServices> (); var loggingService = ServiceContainer.Resolve<ILoggingService> (); GridLocation location; bool continueRandomization = false; // Loop until a (presumably) empty location was found. do { // Get a location that has not been visited recently. bool isRememberedLocation = false; do { location = new GridLocation (platformServices.GetRandomNumber (0, gameState.GameField.Rows), platformServices.GetRandomNumber (0, gameState.GameField.Columns)); isRememberedLocation = this.lastVisitedLocations.Contains (location); #if EXTENSIVE_LOGGING loggingService.Log("Randomized location '{0}' was picked previously? {1}.", location, isRememberedLocation); #endif } while(isRememberedLocation); // Remember the location to prevent visiting it again immediately. this.lastVisitedLocations.Enqueue (location); // Now check if the location has a treasure. If yes, we don't want to go there unless it is the current active treasure. var treasureMemory = this.HasLocationPresumablyTreasure(location); // We want to pick a location that we don't know about. if(treasureMemory == LocationMemory.DontKnow) { // Let's head there if the AI does not know about the location. continueRandomization = false; #if EXTENSIVE_LOGGING loggingService.Log("Randomized location. AI does not know what's at '{0}'. Active treasure: {1}.", location, gameState.GetActiveCard()); #endif } else if(treasureMemory == LocationMemory.HasNothing) { // If the AI knows that there is nothing at the location, it won't go there. continueRandomization = true; #if EXTENSIVE_LOGGING loggingService.Log("Randomized location. AI knows that there is nothing at '{0}'. Active treasure: {1}.", location, gameState.GetActiveCard()); #endif } else if(treasureMemory == LocationMemory.HasTreasure) { // If there is a treasure, the AI will avoid it, untless it is the current searched treasure. var treasureItem = gameState.GameField.GetItem(location).Treasure; if(treasureItem == gameState.GetActiveCard()) { continueRandomization = false; } else { // Keep searching a new random location. continueRandomization = true; } #if EXTENSIVE_LOGGING loggingService.Log("Randomized location. AI knows there is a treasure '{0}'. Active treasure: {1}.", location, gameState.GetActiveCard()); #endif } } while(continueRandomization); return location; }
/// <summary> /// Returns a two dimensional grid where each field contains the distance from the start point (the empty field). /// </summary> /// <returns>The path.</returns> /// <param name="gameGrid">Game grid.</param> /// <param name="fromLocation">the location to start from.</param> /// <param name="currentActiveTreasure">The current active treasre can always be stepped onto.</param> public static Grid2D<int> PreparePathGrid(GameFieldGrid gameGrid, GridLocation fromLocation, TreasureType currentActiveTreasure) { if(gameGrid == null) { throw new ArgumentNullException ("gameGrid"); } if(fromLocation == null) { throw new ArgumentNullException ("fromLocation"); } // Create a grid as big as the game field. The content of each item is the distance from the staring point (the empty spot). var pathGrid = new Grid2D<int> (gameGrid.Rows, gameGrid.Columns, pathFindingMaxVal); // Use a Disjkstra algorithm to find a path from the empty spot to the current active treasure. // First, set the presumed target location to a distance of 0. pathGrid.SetItem (fromLocation, 0); // Start calculating distances. while(true) { // Set to true if at least one field was changed. If nothing is changed during one loop, we're done. bool gridChanged = false; // Loop all fields until each field contains a distance value. for (int row = 0; row < gameGrid.Rows; row++) { for (int col = 0; col < gameGrid.Columns; col++) { // Distance is one more than it was at the current location. Set for the surrounding fields. int newDistance = pathGrid.GetItem (row, col); if(newDistance != pathFindingMaxVal) { newDistance++; } var checkLocations = AIHelpers.GetAccessibleAdjacentLocations(gameGrid, new GridLocation(row, col), currentActiveTreasure); foreach(var checkLocation in checkLocations) { // Remember the distance to the start point. int currentDistance = pathGrid.GetItem (checkLocation); if(newDistance < currentDistance) { pathGrid.SetItem (checkLocation, newDistance); gridChanged = true; } } } } // Bail out of the algorithm if we visited all nodes. if(!gridChanged) { break; } } return pathGrid; }