public void Test(int depth, int tx, int ty, int answer1, int answer2) { var map = new Map(depth, (tx, ty)); int riskLevel = 0; for (var x = 0; x <= tx; x++) { for (var y = 0; y <= ty; y++) { var material = map.At(x, y); riskLevel += (int)material; } } Assert.AreEqual(answer1, riskLevel, "answer 1"); if (answer2 > 100 && App.IsFast) { return; // takes 21 minutes } var from = new CostMap.Phase(0, 0, Tool.Torch); var to = new CostMap.Phase(tx, ty, Tool.Torch); var MAX = 3 * (tx + ty); //this is the upper bond (simplest algorithm) var shortestPath = new CostMap().Path(from, to, map, MAX); Assert.AreEqual(answer2, shortestPath, "answer 2"); }
public void Read(Stream input, Endian endian = Endian.Little) { RoadGraphRoadToJunctionEdgeMappingCount = input.ReadValueU16(endian); RoadGraphEdgeCount = input.ReadValueU16(endian); for (int i = 0; i < RoadGraphEdgeCount; i++) { RoadGraphEdges.Add(new Tuple <ushort, ushort>(input.ReadValueU16(endian), input.ReadValueU16(endian))); } ushort roadCount = input.ReadValueU16(endian); for (int i = 0; i < roadCount; i++) { var road = new RoadDefinitionDe(); road.Read(input, endian); Roads.Add(road); } for (int i = 0; i < RoadGraphEdgeCount; i++) { var costMapping = new CostMapEntryDe(); costMapping.Read(input, endian); CostMap.Add(costMapping); } byte magic0 = input.ReadValueU8(); byte magic1 = input.ReadValueU8(); byte magic2 = input.ReadValueU8(); byte magic3 = input.ReadValueU8(); if (magic0 != 0x11 && magic1 != 0x11 && magic2 != 0x11 && magic3 != 0) { throw new IOException($"Unexpected magic values ({magic0}, {magic1}, {magic2}, {magic3})"); } ushort splineCount = input.ReadValueU16(endian); for (int i = 0; i < splineCount; i++) { var spline = new RoadSplineDe(); spline.Read(input, endian); Splines.Add(spline); } for (int i = 0; i < roadCount * 2; i++) { RoadToCrossroadMapping.Add(input.ReadValueU16(endian)); } ushort crossroadCount = input.ReadValueU16(endian); for (int i = 0; i < crossroadCount; i++) { var crossroad = new CrossroadDe(); crossroad.Read(input, endian); Crossroads.Add(crossroad); } }
// Update is called once per frame void Update() { if (Input.GetKeyDown(KeyCode.Q)) { Item pickaxe = ItemObjectFactory.Instance.GetItemObject(4).CreateItem(1); pack.AddItem(pickaxe); } if (Input.GetMouseButtonDown(0)) { if (!EventSystem.current.IsPointerOverGameObject()) { UseItem(true); } } if (Input.GetMouseButtonUp(0)) { if (!EventSystem.current.IsPointerOverGameObject()) { UseItem(false); } } if (Input.GetKeyDown(KeyCode.R)) { CostMap costs = Navigation.CreateCostMapFromBlockMap(new Vector3Int(0, 0, 0), new Vector3Int(31, 31, 0), 1); Vector3Int[] path = Navigation.FindPath(new Vector3Int(0, 0, 0), new Vector3Int(31, 31, 0), costs); for (int i = 0; i < path.Length; i++) { GameObject go = BlockMap.Instance.GetBlockGameObject(path[i]); SpriteRenderer sr = go.GetComponent <SpriteRenderer>(); sr.color = Color.blue; } } if (Input.GetKeyDown(KeyCode.E)) { if (PackUIController.Instance.Expanded) { PackUIController.Instance.Collapse(); RecipeListUIController.Instance.gameObject.SetActive(false); } else { PackUIController.Instance.Expand(); RecipeListUIController.Instance.gameObject.SetActive(true); RecipeListUIController.Instance.UpdateUI(RecipeFactory.Instance.getRecipes()); } } SelectPackSlot(); }
private IEnumerable <Wait> RoutineTakeTurn(Turn turn) { FindAggroTarget(); if (AggroTarget != null) { FaceTowards(AggroTarget); } Skill usableSkill = GetUsableSkill(); foreach (Skill skill in Skills) { skill.Update(this); } if (usableSkill != null) { var target = usableSkill.GetEnemyTarget(this); CurrentActions.Add(Scheduler.Instance.RunAndWait(RoutineUseSkill(usableSkill, target))); if (usableSkill.WaitUse) { yield return(CurrentActions); } } else { var move = new[] { Facing.North, Facing.East, Facing.South, Facing.West }.Pick(Random).ToOffset(); if (AggroTarget != null) { var movementType = this.GetMovementType(); var costMap = new CostMap(Map, this, movementType.GetTileCost); costMap.SetMask(Mask); costMap.Recalculate(); var targetPoints = Mask.Select(o => new Point(AggroTarget.X, AggroTarget.Y) - o).ToList(); var dijkstra = Util.Dijkstra(new Point[] { new Point(X, Y) }, targetPoints, Map.Width, Map.Height, new Rectangle(X - 20, Y - 20, 41, 41), double.MaxValue, costMap, movementType.GetNeighbors()); var path = dijkstra.FindPath(targetPoints.Pick(Random)); if (path.Any()) { move = path.First() - new Point(X, Y); } else { move = new Point(0, 0); } } if (move != Point.Zero) //No move to self { CurrentActions.Add(Scheduler.Instance.RunAndWait(RoutineMove(move.X, move.Y))); } } }
void initCostMaps() { List<Vector3Int> playerBases = tilePosByType[SpriteRepository.TileType.TILE_TYPE_PLAYER_BASE]; costMapsByCell = new Dictionary<Vector3Int, CostMap>(); foreach (Vector3Int playerBase in playerBases) { CostMap costMap = new CostMap(); costMap.playerBase = mapTileDictionary[playerBase]; costMap.grassTilesByCost = new Dictionary<int, List<MapTile>>(); PathFindingAlg.Dijkstra(mapTileDictionary[playerBase], mapTileDictionary, ref costMap.grassTilesByCost); if (!costMapsByCell.ContainsKey(playerBase)) costMapsByCell.Add(playerBase, costMap); } }
// Coloca recursos simétricos void placeSymmetricResources() { List<Vector3Int> playerBases = tilePosByType[SpriteRepository.TileType.TILE_TYPE_PLAYER_BASE]; List<List<int>> playerBaseCosts = new List<List<int>>(); foreach (Vector3Int playerBase in playerBases) { playerBaseCosts.Add(new List<int>(costMapsByCell[playerBase].grassTilesByCost.Keys)); } // Conseguimos los costes comunes List<int> commonCosts = new List<int>(); foreach(List<int> playerCosts in playerBaseCosts) { if (commonCosts.Count == 0) { commonCosts = playerCosts; continue; } commonCosts = commonCosts.Intersect(playerCosts).ToList<int>(); } commonCosts.Sort((x, y) => x.CompareTo(y)); // Comprobamos si hay costes comunes if (commonCosts.Count == 0) { //Debug.Log("No hay costes comunes!!!"); return; } // Ponemos fábricas aliadas for (int i = 0; i < alliedResourceCount; i++) { int randomCost = commonCosts[0]; //Debug.Log("El coste elegido es " + randomCost); foreach (Vector3Int playerBase in playerBases) { CostMap baseCostMap = costMapsByCell[playerBase]; List<MapTile> tilesByCost = baseCostMap.grassTilesByCost[randomCost]; int randomListIndex = Random.Range(0, tilesByCost.Count); if(tilesByCost.ElementAtOrDefault(randomListIndex) == null) { //Debug.Log("Aquí paso algo"); break; } updateMapTileType(tilesByCost[randomListIndex].position, tilesByCost[randomListIndex], SpriteRepository.TileType.TILE_TYPE_FACTORY); tilesByCost.RemoveAt(randomListIndex); if (tilesByCost.Count == 0) { //Debug.Log("Ahora esta vacío"); commonCosts.RemoveAt(0); } } } List<Vector3Int> neutralPositions = new List<Vector3Int>(tilePosByType[SpriteRepository.TileType.TILE_TYPE_BUILDING]); List<float> neutralCosts = new List<float>(); List<float> neutralRates = new List<float>(); foreach (Vector3Int playerBase in playerBases) { foreach (Vector3Int neutral in neutralPositions) { neutralCosts.Add(mapTileDictionary[neutral].distanceToPlayerBase[mapTileDictionary[playerBase]]); neutralRates.Add(mapTileDictionary[neutral].getSimmetricRate()); } } float minCost = neutralCosts.Average(); float minRate = neutralRates.Min(); commonCosts.RemoveAll(x => x > minCost); commonCosts.RemoveAll(x => x < minCost / 2); //Debug.Log("El coste mínimo a una base de los recursos neutrales es " + minCost); bool adjustingValue = false; int previousCost = -1; bool limitReached = false; // Ponemos fábricas neutrales for (int i = 0; i < neutralResourceCount; i++) { previousCost = -1; foreach (Vector3Int playerBase in playerBases) { do { List<MapTile> validTiles = new List<MapTile>(); foreach (MapTile mapTile in mapTileDictionary.Values) { if (mapTile.tileType == SpriteRepository.TileType.TILE_TYPE_GRASS || mapTile.tileType == SpriteRepository.TileType.TILE_TYPE_FOREST) { if (!mapTile.buildable) continue; if (previousCost == -1) { if (mapTile.distanceToPlayerBase[mapTileDictionary[playerBase]] < minCost * minRate && mapTile.distanceToPlayerBase[mapTileDictionary[playerBase]] > 2) validTiles.Add(mapTile); } else { if (mapTile.distanceToPlayerBase[mapTileDictionary[playerBase]] == previousCost) validTiles.Add(mapTile); } } } int randomIndex = Random.Range(0, validTiles.Count); if (validTiles.Count == 0) { previousCost--; // si llegamos al tope recomenzamos por el máximo if (previousCost <= 0) { if (limitReached) return; else { previousCost = Mathf.RoundToInt(minCost) - 1; limitReached = true; } } adjustingValue = true; continue; } MapTile chosenTile = validTiles[randomIndex]; List<Vector3Int> neis = getNeighbourList(chosenTile.position); foreach (Vector3Int nei in neis) mapTileDictionary[nei].buildable = false; List<SpriteRepository.TileType> possibleResources = new List<SpriteRepository.TileType>(); possibleResources.Add(SpriteRepository.TileType.TILE_TYPE_HANGAR); possibleResources.Add(SpriteRepository.TileType.TILE_TYPE_FACTORY); if (getNeighbourListOfType(chosenTile.position, SpriteRepository.TileType.TILE_TYPE_WATER).Count > 0) { // Double probability possibleResources.Add(SpriteRepository.TileType.TILE_TYPE_SHIPYARD); possibleResources.Add(SpriteRepository.TileType.TILE_TYPE_SHIPYARD); } int randomBuilding = Random.Range(0, possibleResources.Count); updateMapTileType(chosenTile.position, chosenTile, possibleResources[randomBuilding]); previousCost = Mathf.RoundToInt(chosenTile.distanceToPlayerBase[mapTileDictionary[playerBase]]); //Debug.Log("El coste elegido es" + previousCost); adjustingValue = false; } while(adjustingValue); } } //Debug.Log("Salí"); }