private TurnError ActAnalyse(Ant ant, HexDirection direction) { if (direction == HexDirection.CENTER) { return(TurnError.ILLEGAL); } Vector2Int target = CoordConverter.MoveHex(ant.gameCoordinates, direction); TurnError tileError = CheckAnalyzability(target); if (tileError != TurnError.NONE) { return(tileError); } // Set all the fields of the response to 0 TerrainType terrainType = TerrainType.NONE; AntType antType = AntType.NONE; bool isAllied = false; Value foodValue = Value.NONE; bool egg = false; if (terrain[target.x][target.y] == null || terrain[target.x][target.y].tile == null) { } // Leave everything like that else { terrainType = terrain[target.x][target.y].tile.Type; if (terrain[target.x][target.y].ant == null) { } // Leave everything like that else { antType = terrain[target.x][target.y].ant.Type; isAllied = terrain[target.x][target.y].ant.team.teamId == ant.team.teamId; terrain[target.x][target.y].ant.eventInputs.Add(new EventInputBump(CoordConverter.InvertDirection(direction))); } if (terrain[target.x][target.y].food == null) { } // Leave everything like that else { foodValue = ValueConverter.Convert(terrain[target.x][target.y].food.value, Const.FOOD_SIZE); } egg = terrain[target.x][target.y].egg != null; if (egg) { isAllied = terrain[target.x][target.y].egg.team.teamId == ant.team.teamId; } } ant.analyseReport = new AnalyseReport(terrainType, antType, egg, isAllied, foodValue, null); return(TurnError.NONE); }
private TurnError ActMove(Ant ant, HexDirection direction) { if (direction == HexDirection.CENTER) { return(TurnError.ILLEGAL); } Vector2Int newCoord = CoordConverter.MoveHex(ant.gameCoordinates, direction); TurnError tileError = CheckWalkability(newCoord); if (tileError != TurnError.NONE) { if (tileError == TurnError.COLLISION_ANT) { terrain[newCoord.x][newCoord.y].ant.eventInputs.Add(new EventInputBump(CoordConverter.InvertDirection(direction))); } return(tileError); } if (ant.CheckEnergy(Const.MOVE_COST)) { ant.UpdateEnergy(-Const.MOVE_COST); } else { return(TurnError.NO_ENERGY); } terrain[ant.gameCoordinates.x][ant.gameCoordinates.y].ant = null; terrain[newCoord.x][newCoord.y].ant = ant; ant.gameCoordinates = newCoord; return(TurnError.NONE); }
private TurnError ActStock(Ant ant, HexDirection direction, int quantity) { if (direction == HexDirection.CENTER) { return(TurnError.ILLEGAL); } Vector2Int target = CoordConverter.MoveHex(ant.gameCoordinates, direction); TurnError tileError = CheckEdibility(target); if (tileError != TurnError.NONE) { if (tileError != TurnError.COLLISION_VOID && terrain[target.x][target.y].ant != null) { terrain[target.x][target.y].ant.eventInputs.Add(new EventInputBump(CoordConverter.InvertDirection(direction))); } return(tileError); } Food victim = terrain[target.x][target.y].food; int quantityToStock = Mathf.Min(quantity, Const.MAX_STOCK_BY_TURN); quantityToStock = victim.GetFood(quantityToStock); // The ant can eat more than it can store, so that it can remove food from the terrain if needed ant.UpdateStock(quantityToStock); isPermanentModif = true; return(TurnError.NONE); }
private TurnError ActAttack(Ant ant, HexDirection direction) { if (direction == HexDirection.CENTER) { return(TurnError.ILLEGAL); } Vector2Int target = CoordConverter.MoveHex(ant.gameCoordinates, direction); TurnError tileError = CheckAttackability(target, ant); if (tileError != TurnError.NONE) { if (tileError == TurnError.NOT_ENEMY) { terrain[target.x][target.y].ant.eventInputs.Add(new EventInputBump(CoordConverter.InvertDirection(direction))); } return(tileError); } if (ant.CheckEnergy(Const.ATTACK_COST)) { ant.UpdateEnergy(-Const.ATTACK_COST); } else { return(TurnError.NO_ENERGY); } if (terrain[target.x][target.y].ant != null) { Ant victim = terrain[target.x][target.y].ant; if (ant.Type == AntType.QUEEN) { victim.Hurt(Const.QUEEN_ATTACK_DMG); } else { victim.Hurt(Const.WORKER_ATTACK_DMG); } victim.eventInputs.Add(new EventInputAttack(CoordConverter.InvertDirection(direction))); } else if (terrain[target.x][target.y].egg != null) { Egg victim = terrain[target.x][target.y].egg; victim.Die(); } isPermanentModif = true; return(TurnError.NONE); }
private TurnError ActCommunicate(Ant ant, HexDirection direction, AntWord word) { if (direction == HexDirection.CENTER) { return(TurnError.ILLEGAL); } Vector2Int target = CoordConverter.MoveHex(ant.gameCoordinates, direction); TurnError tileError = CheckCommunicability(target, ant); if (tileError != TurnError.NONE) { if (tileError == TurnError.NOT_ALLY) { terrain[target.x][target.y].ant.eventInputs.Add(new EventInputBump(CoordConverter.InvertDirection(direction))); } return(tileError); } if (ant.CheckEnergy(Const.GIVE_COST)) { ant.UpdateEnergy(-Const.GIVE_COST); } else { return(TurnError.NO_ENERGY); } Ant receptor = terrain[target.x][target.y].ant; // Gives the info to the emitter ant.communicateReport = new CommunicateReport( receptor.Type, receptor.mindset, ValueConverter.Convert(receptor.hp), ValueConverter.Convert(receptor.energy), ValueConverter.Convert(receptor.carriedFood), AntWord.NONE); // Gives the cmmunication to the receptor receptor.eventInputs.Add(new EventInputComunicate(CoordConverter.InvertDirection(direction), new CommunicateReport( ant.Type, ant.mindset, ValueConverter.Convert(ant.hp), ValueConverter.Convert(ant.energy), ValueConverter.Convert(ant.carriedFood), word))); return(TurnError.NONE); }
private TurnError ActGive(Ant ant, HexDirection direction, int quantity) { if (direction == HexDirection.CENTER) { return(TurnError.ILLEGAL); } Vector2Int target = CoordConverter.MoveHex(ant.gameCoordinates, direction); TurnError tileError = CheckGivability(target, ant); if (tileError != TurnError.NONE) { if (tileError == TurnError.NOT_ALLY) { terrain[target.x][target.y].ant.eventInputs.Add(new EventInputBump(CoordConverter.InvertDirection(direction))); } return(tileError); } if (ant.CheckEnergy(Const.GIVE_COST)) { ant.UpdateEnergy(-Const.GIVE_COST); } else { return(TurnError.NO_ENERGY); } if (ant.carriedFood <= 0) { return(TurnError.NO_FOOD); } Ant beneficiary = terrain[target.x][target.y].ant; // Calculates how much to give int quantityToGive = Mathf.Min(new int[] { quantity, Const.MAX_GIFT_BY_TURN, ant.carriedFood }); quantityToGive -= ant.UpdateStock(-quantityToGive); // Give the energy to the beneficiary, then gives back the excess to the giver int quantityToGiveBack = Mathf.Abs(beneficiary.UpdateStock(quantityToGive)); ant.UpdateStock(quantityToGiveBack); return(TurnError.NONE); }
private TurnError ActEat(Ant ant, HexDirection direction, int quantity) { int quantityToEat = 0; if (direction == HexDirection.CENTER) { if (ant.carriedFood <= 0) { return(TurnError.NO_FOOD); } // Calculates how much to eat quantityToEat = Mathf.Min(new int[] { quantity, Const.MAX_EAT_BY_TURN, ant.carriedFood }); quantityToEat -= ant.UpdateStock(-quantityToEat); // Transforms the food to energy, then stock back the excess int quantityToStockBack = Mathf.Abs(ant.UpdateEnergy(quantityToEat)); ant.UpdateStock(quantityToStockBack); return(TurnError.NONE); } Vector2Int target = CoordConverter.MoveHex(ant.gameCoordinates, direction); TurnError tileError = CheckEdibility(target); if (tileError != TurnError.NONE) { if (tileError != TurnError.COLLISION_VOID && terrain[target.x][target.y].ant != null) { terrain[target.x][target.y].ant.eventInputs.Add(new EventInputBump(CoordConverter.InvertDirection(direction))); } return(tileError); } Food victim = terrain[target.x][target.y].food; quantityToEat = Mathf.Min(quantity, Const.MAX_EAT_BY_TURN); quantityToEat = victim.GetFood(quantityToEat); // The ant can eat more than it can store, so that it can remove food from the terrain if needed ant.UpdateEnergy(quantityToEat); isPermanentModif = true; return(TurnError.NONE); }
private TurnError ActEgg(Ant ant, HexDirection direction) { if (direction == HexDirection.CENTER) { return(TurnError.ILLEGAL); } if (ant.Type != AntType.QUEEN) { return(TurnError.NOT_QUEEN); } Vector2Int eggCoord = CoordConverter.MoveHex(ant.gameCoordinates, direction); TurnError tileError = CheckWalkability(eggCoord); if (tileError != TurnError.NONE) { if (tileError == TurnError.COLLISION_ANT) { terrain[eggCoord.x][eggCoord.y].ant.eventInputs.Add(new EventInputBump(CoordConverter.InvertDirection(direction))); } return(tileError); } if (ant.CheckEnergy(Const.EGG_COST)) { ant.UpdateEnergy(-Const.EGG_COST); } else { return(TurnError.NO_ENERGY); } Vector3 newEggWorldPosition = CoordConverter.PlanToWorld(CoordConverter.HexToPos(eggCoord), eggPrefab.transform.position.y); Egg newEgg = Instantiate(eggPrefab, newEggWorldPosition, eggPrefab.transform.rotation); newEgg.Init(ant.team, eggCoord, ant.team.color); ant.team.eggs.Add(newEgg); terrain[eggCoord.x][eggCoord.y].egg = newEgg; isPermanentModif = true; return(TurnError.NONE); }
public void RotateToTarget(float elapsedTime, float totalTime) { // The remaining time might be 0 (especially if the animation time by turn is set to 0) if (elapsedTime >= totalTime) { return; } if (displayDirection == HexDirection.CENTER) { return; } float elapsedPercentage = elapsedTime / totalTime; // FIXME Quite inelegant way to rotate slowly to face the next tile Quaternion formerRotation = transform.rotation; transform.LookAt(CoordConverter.PlanToWorld(CoordConverter.HexToPos(CoordConverter.MoveHex(displayCoordinates, displayDirection)), transform.position.y)); transform.rotation = Quaternion.Slerp(formerRotation, transform.rotation, elapsedPercentage); }
public void FixAnimation() { transform.position = CoordConverter.PlanToWorld(CoordConverter.HexToPos(gameCoordinates), transform.position.y); displayCoordinates = gameCoordinates; transform.LookAt(CoordConverter.PlanToWorld(CoordConverter.HexToPos(CoordConverter.MoveHex(displayCoordinates, displayDirection)), transform.position.y)); }
public void UpdateCell(List <PheromoneDescriptor>[][][] pheromoneMaps, int x, int y) { // Removing all the displayers from the cell foreach (List <PheromoneDisplayer>[][] displayMap in displayMaps) { foreach (PheromoneDisplayer displayer in displayMap[x][y]) { Destroy(displayer.gameObject); } displayMap[x][y] = new List <PheromoneDisplayer>(); } // Adding all the needed displayers to the cell for (int i = 0; i < pheromoneMaps.Length; i++) { List <PheromoneDescriptor>[][] pheromoneMap = pheromoneMaps[i]; List <PheromoneDisplayer>[][] displayMap = displayMaps[i]; foreach (PheromoneDescriptor pheromone in pheromoneMap[x][y]) { Color validityColor = CheckValidity(pheromone, i); if (validityColor != NULL_COLOR) { PheromoneDisplayer newDisplayer = Instantiate( displayerPrefab, CoordConverter.PlanToWorld(CoordConverter.HexToPos(new Vector2Int(x, y)), displayerPrefab.transform.position.y), displayerPrefab.transform.rotation); newDisplayer.displayDirection = pheromone.direction; newDisplayer.transform.LookAt(CoordConverter.PlanToWorld(CoordConverter.HexToPos(CoordConverter.MoveHex(new Vector2Int(x, y), newDisplayer.displayDirection)), newDisplayer.transform.position.y)); newDisplayer.SetColor(validityColor); displayMap[x][y].Add(newDisplayer); } } } }
private void MakeAntThink(Ant ant, AntAI ai) { // Inserts the ant randomly in the next turn InsertAntInNextRandomList(ant); // Gets all the pheromones on the current tile List <PheromoneDigest> pheromones = PheromoneDigest.ListFromDescriptorList(pheromoneMaps[ant.team.teamId][ant.gameCoordinates.x][ant.gameCoordinates.y]); // Gets all the surrounding pheromones Dictionary <HexDirection, List <PheromoneDigest> > pheromoneGroups = new Dictionary <HexDirection, List <PheromoneDigest> >(); for (HexDirection direction = (HexDirection)1; (int)direction < 7; direction++) { Vector2Int currentCoord = CoordConverter.MoveHex(ant.gameCoordinates, direction); if (!CheckCoordinatesValidity(currentCoord)) { pheromoneGroups.Add(direction, PheromoneDigest.ListFromDescriptorList(null)); } else { pheromoneGroups.Add(direction, PheromoneDigest.ListFromDescriptorList(pheromoneMaps[ant.team.teamId][currentCoord.x][currentCoord.y])); } } TurnInformation info = new TurnInformation( terrain[ant.gameCoordinates.x][ant.gameCoordinates.y].tile.Type, ant.pastTurn != null ? ant.pastTurn.DeepCopy() : null, ant.mindset, pheromones, pheromoneGroups, ValueConverter.Convert(ant.energy), ValueConverter.Convert(ant.hp), ValueConverter.Convert(ant.carriedFood), ant.analyseReport, ant.communicateReport, ant.eventInputs, ant.GetInstanceID() ); if (ant.Type == AntType.QUEEN) { ant.decision = ai.OnQueenTurn(info); } else if (ant.Type == AntType.WORKER) { ant.decision = ai.OnWorkerTurn(info); } else { Debug.LogError("This ant has an unknown type!"); } if (ant.decision == null) { ant.decision = new Decision(ant.mindset, ChoiceDescriptor.ChooseNone(), pheromones); } ant.displayDirection = ant.decision.choice.direction; ant.ClearInputs(); // The inputs are flushed here so they can be filled up by the resolution of the actions }