コード例 #1
0
    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);
    }
コード例 #2
0
    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);
    }
コード例 #3
0
    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);
    }
コード例 #4
0
    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);
    }
コード例 #5
0
    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);
    }
コード例 #6
0
    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);
    }
コード例 #7
0
    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);
    }
コード例 #8
0
    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);
    }
コード例 #9
0
ファイル: Ant.cs プロジェクト: JojoPalambas/AIAnt
    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);
    }
コード例 #10
0
ファイル: Ant.cs プロジェクト: JojoPalambas/AIAnt
 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));
 }
コード例 #11
0
    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);
                }
            }
        }
    }
コード例 #12
0
    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
    }