コード例 #1
0
ファイル: AITestAgressive.cs プロジェクト: JojoPalambas/AIAnt
    public override Decision OnQueenTurn(TurnInformation info)
    {
        // Setting the defaults
        AntMindset             mindset    = AntMindset.AMS0;
        ChoiceDescriptor       choice     = ChoiceDescriptor.ChooseNone();
        List <PheromoneDigest> pheromones = null;

        // Laying an egg in a random direction
        choice = ChoiceDescriptor.ChooseEgg((HexDirection)Random.Range(1, 8));

        return(new Decision(mindset, choice, pheromones));
    }
コード例 #2
0
    // The Queen leaves four PHER0 pheromones on its tile to show where she is
    public override Decision OnQueenTurn(TurnInformation info)
    {
        ChoiceDescriptor choice = ChoiceDescriptor.ChooseNone();

        // If there is enough energy
        if (info.energy > Value.LOW)
        {
            // If it is the first turn
            if (info.pastTurn == null || info.pastTurn.pastDecision == null || info.pastTurn.pastDecision.choice == null)
            {
                choice = ChoiceDescriptor.ChooseEgg((HexDirection)Random.Range(1, 7));
            }

            // If there was no error
            else if (info.pastTurn.error == TurnError.NONE)
            {
                choice = ChoiceDescriptor.ChooseEgg(info.pastTurn.pastDecision.choice.direction);
            }

            // If there was an error because of auto-egg
            else if (info.pastTurn.pastDecision.choice.direction == HexDirection.CENTER)
            {
                choice = ChoiceDescriptor.ChooseEgg(DirectionManip.RotateDirectionCW((HexDirection)Random.Range(1, 7)));
            }

            // If there was an error
            else
            {
                choice = ChoiceDescriptor.ChooseEgg(DirectionManip.RotateDirectionCW(info.pastTurn.pastDecision.choice.direction));
            }
        }
        else
        {
            choice = ChoiceDescriptor.ChooseEat(HexDirection.CENTER, 100);
        }

        // Puts the pheromone signal on the ground to show its position
        List <PheromoneDigest> pheromoneSignal = new List <PheromoneDigest>();

        for (int i = 0; i < Const.MAX_PHEROMONE_BY_CELL; i++)
        {
            pheromoneSignal.Add(new PheromoneDigest(PheromoneType.PHER0, HexDirection.CENTER));
        }

        return(new Decision(AntMindset.AMS0, choice, pheromoneSignal));
    }
コード例 #3
0
    // Priority #0: If the ant is attacked and is not capital, it fights back (an ant is capital if it has more than or equal to MEDIUM food, or knows where the enemy Queen is (AMS7 or recent analyse))
    // Priority #1: If the ant detects that it is on the spawn tile, it moves away to the right or to the left of the Queen, and leaves three PHER3 in the same direction as the ones under the Queen
    // AMS0 (exploration): If there is 0 pheromone under the ant, it moves straight and turns randomly when there is an obstacle (without going back), and leaves a PHER0
    // AMS0 (exploration): If there is 1 to 3 pheromones under the ant, it follows them without leaving anything, and has a chance to leave the path, leaving a trace
    // AMS0 (exploration): If there is 4 pheromones under the ant, it follows them without leaving anything
    // AMS0 (exploration): If there is 2 to 4 pheromones, if the ant tried to leave the path but found an obstacle, in has to remove its mark
    // AMS0 (exploration): If the ant bumps into an enemy, it analyses it
    public override Decision OnWorkerTurn(TurnInformation info)
    {
        AntMindset             mindset    = info.mindset;
        ChoiceDescriptor       choice     = ChoiceDescriptor.ChooseNone();
        List <PheromoneDigest> pheromones = info.pheromones;

        // Analyses the situation
        bool isImportant = IsImportant(info);
        KeyValuePair <HexDirection, List <PheromoneDigest> > queenPheromones = FindAdjacentQueen(info.adjacentPheromoneGroups);
        HexDirection attackOrigin = HasBeenAttacked(info.eventInputs);

        // Priority #0: Fights back if attacked and not important
        if (attackOrigin != HexDirection.CENTER == !isImportant)
        {
            choice = ChoiceDescriptor.ChooseAttack(attackOrigin);
        }
        // Priority #1: Checks if the Worker is in the spawn tile
        if (queenPheromones.Key != HexDirection.CENTER && queenPheromones.Value != null && queenPheromones.Value[0].direction == DirectionManip.InvertDirection(queenPheromones.Key))
        {
            mindset = AntMindset.AMS0;

            int rand = Random.Range(0, 2);
            if (rand == 0)
            {
                choice = ChoiceDescriptor.ChooseMove(DirectionManip.RotateDirectionCCW(queenPheromones.Key));
            }
            else
            {
                choice = ChoiceDescriptor.ChooseMove(DirectionManip.RotateDirectionCW(queenPheromones.Key));
            }

            pheromones = new List <PheromoneDigest>();
        }
        else
        {
            switch (mindset)
            {
            case AntMindset.AMS0:
                break;
            }
        }

        return(new Decision(mindset, choice, pheromones));
    }
コード例 #4
0
    public override Decision OnWorkerTurn(TurnInformation info)
    {
        ChoiceDescriptor choice = ChoiceDescriptor.ChooseNone();

        // If there is no past turn, or if somehow the past turn does not contiain a decision or a choice, the ant moves to the left
        if (info.pastTurn == null || info.pastTurn.pastDecision == null || info.pastTurn.pastDecision.choice == null)
        {
            choice = ChoiceDescriptor.ChooseMove((HexDirection)Random.Range(1, 7));
        }
        else
        {
            switch (info.pastTurn.pastDecision.choice.type)
            {
            case ActionType.MOVE:
                if (info.pastTurn.error == TurnError.NONE)
                {
                    choice = ChoiceDescriptor.ChooseMove(info.pastTurn.pastDecision.choice.direction);
                }
                else
                {
                    choice = ChoiceDescriptor.ChooseAnalyse(info.pastTurn.pastDecision.choice.direction);
                }
                break;

            case ActionType.ANALYSE:
                if (info.pastTurn.error == TurnError.NONE)
                {
                    choice = ChoiceDescriptor.ChooseMove(RotateDirection(info.pastTurn.pastDecision.choice.direction));
                }
                else
                {
                    choice = ChoiceDescriptor.ChooseMove(RotateDirection(info.pastTurn.pastDecision.choice.direction));
                }
                break;

            default:
                choice = ChoiceDescriptor.ChooseMove(RotateDirection(info.pastTurn.pastDecision.choice.direction));
                break;
            }
        }

        return(new Decision(AntMindset.AMS0, choice, info.pheromones));
    }
コード例 #5
0
    public override Decision OnQueenTurn(TurnInformation info)
    {
        ChoiceDescriptor choice = ChoiceDescriptor.ChooseNone();

        // If there is no past turn, or if somehow the past turn does not contiain a decision or a choice, the ant moves to the left
        if (info.pastTurn == null || info.pastTurn.pastDecision == null || info.pastTurn.pastDecision.choice == null)
        {
            choice = ChoiceDescriptor.ChooseEgg((HexDirection)Random.Range(1, 7));
        }
        else if (info.pastTurn.error != TurnError.NONE)
        {
            choice = ChoiceDescriptor.ChooseEgg(RotateDirection(info.pastTurn.pastDecision.choice.direction));
        }
        else
        {
            choice = ChoiceDescriptor.ChooseEgg(info.pastTurn.pastDecision.choice.direction);
        }

        return(new Decision(AntMindset.AMS0, choice, info.pheromones));
    }
コード例 #6
0
    // AMS0 - AMS1 - AMS2: The Queen tries to find the center of the three free tiles to lay her eggs in
    // AMS0: The Queen is rotating CCW in order to find a out-of-bounds tile ; the first out-of-bounds tile makes the Queen become AMS1
    // AMS1: An out-of-bound tile has been found, now the Queen is rotating CW to find the first free tile
    // AMS1: When the Queen has found the first free time, it places four PHER3 showing the next tile CW, which is the center of the three free tiles to lay eggs in ; the Queen goes AMS2
    // AMS2: The Queen spawns eggs randomly in the center free tile
    // AMS2: If the Queen has a low energy, it eats if it has carried food, or else tries to lay eggs
    public override Decision OnQueenTurn(TurnInformation info)
    {
        AntMindset             mindset    = info.mindset;
        ChoiceDescriptor       choice     = ChoiceDescriptor.ChooseNone();
        List <PheromoneDigest> pheromones = info.pheromones;

        if (info.pastTurn == null)
        {
            mindset = AntMindset.AMS0;
            choice  = ChoiceDescriptor.ChooseAnalyse((HexDirection)Random.Range(1, 7));
            Debug.Log(choice.direction);
        }
        else
        {
            switch (mindset)
            {
            case AntMindset.AMS0:

                switch (info.pastTurn.error)
                {
                case TurnError.NONE:         // The out-of-bounds tile has not been found

                    choice = ChoiceDescriptor.ChooseAnalyse(DirectionManip.RotateDirectionCCW(info.pastTurn.pastDecision.choice.direction));

                    break;

                case TurnError.COLLISION_VOID:         // The out-of-bounds tile has been found

                    mindset = AntMindset.AMS1;
                    choice  = ChoiceDescriptor.ChooseAnalyse(DirectionManip.RotateDirectionCW(info.pastTurn.pastDecision.choice.direction));

                    break;

                default:         // Should not happen

                    choice = ChoiceDescriptor.ChooseNone();

                    break;
                }

                break;

            case AntMindset.AMS1:

                switch (info.pastTurn.error)
                {
                case TurnError.COLLISION_VOID:         // The free tile has not been found

                    choice = ChoiceDescriptor.ChooseAnalyse(DirectionManip.RotateDirectionCW(info.pastTurn.pastDecision.choice.direction));

                    break;

                case TurnError.NONE:         // The out-of-bounds tile has been found

                    mindset = AntMindset.AMS2;
                    HexDirection freeCenter = DirectionManip.RotateDirectionCW(info.pastTurn.pastDecision.choice.direction);

                    pheromones = new List <PheromoneDigest>();
                    for (int i = 0; i < 4; i++)
                    {
                        pheromones.Add(new PheromoneDigest(PheromoneType.PHER3, freeCenter));
                    }

                    choice = ChoiceDescriptor.ChooseEgg(freeCenter);

                    break;

                default:         // Should not happen

                    choice = ChoiceDescriptor.ChooseNone();

                    break;
                }

                break;

            case AntMindset.AMS2:

                if (info.energy >= Value.MEDIUM)
                {
                    HexDirection freeCenter = FindFreeCenter(info.pheromones);
                    choice = ChoiceDescriptor.ChooseEgg(freeCenter);
                }
                else if (info.carriedFood > Value.NONE)
                {
                    choice = ChoiceDescriptor.ChooseEat(HexDirection.CENTER, 100);
                }
                else
                {
                    HexDirection freeCenter = FindFreeCenter(info.pheromones);
                    choice = ChoiceDescriptor.ChooseEgg(freeCenter);
                }

                break;
            }
        }

        return(new Decision(mindset, choice, pheromones));
    }
コード例 #7
0
    // The Worker first goes away from the queen (mindset AMS0), leaving the PHER0 (for exploration) pheromone behind
    // The Queen can be found because it leaves four PHER0 pheromones on her tile
    // When an obstacle is hit, its mindset changes and the ant comes back to the queen, changing the pheromone to a pheromone describing the obstacle:
    // - AMS1 and PHER1 mean FOOD
    public override Decision OnWorkerTurn(TurnInformation info)
    {
        ChoiceDescriptor       choice     = ChoiceDescriptor.ChooseNone();
        AntMindset             mindset    = AntMindset.AMS0;
        List <PheromoneDigest> pheromones = info.pheromones;

        // If this is the first turn
        if (info.pastTurn == null)
        {
            // The Worker tries to find the Queen
            HexDirection queenDirection = HexDirection.CENTER;
            foreach (KeyValuePair <HexDirection, List <PheromoneDigest> > entry in info.adjacentPheromoneGroups)
            {
                if (IsQueenSignal(entry.Value))
                {
                    queenDirection = entry.Key;
                    break;
                }
            }

            if (queenDirection == HexDirection.CENTER)
            {
                // Logger.Info("The Queen is missing!");
            }
            else
            {
                choice     = ChoiceDescriptor.ChooseMove(DirectionManip.InvertDirection(queenDirection));
                mindset    = AntMindset.AMS0;
                pheromones = MarkExploration(DirectionManip.InvertDirection(queenDirection));
            }
        }
        else
        {
            switch (info.mindset)
            {
            case AntMindset.AMS0:     // FLEES THE QUEEN
                if (info.pastTurn.error == TurnError.NONE)
                {
                    choice     = ChoiceDescriptor.ChooseMove(info.pastTurn.pastDecision.choice.direction);
                    mindset    = AntMindset.AMS0;
                    pheromones = MarkExploration(info.pastTurn.pastDecision.choice.direction);
                }
                else if (info.pastTurn.error == TurnError.COLLISION_FOOD)
                {
                    //choice = ChoiceDescriptor.ChooseMove(DirectionManip.InvertDirection(info.pastTurn.pastDecision.choice.direction));
                    choice     = ChoiceDescriptor.ChooseStock(info.pastTurn.pastDecision.choice.direction, 100);
                    mindset    = AntMindset.AMS1;
                    pheromones = info.pheromones;     // Because theoretically the tile has been marked during the previous turn
                }
                else
                {
                    choice     = ChoiceDescriptor.ChooseMove(DirectionManip.RotateDirectionCW(info.pastTurn.pastDecision.choice.direction));
                    mindset    = AntMindset.AMS0;
                    pheromones = MarkExploration(DirectionManip.RotateDirectionCW(info.pastTurn.pastDecision.choice.direction));
                }
                break;

            case AntMindset.AMS1:                                               // COMES BACK WITH FOOD
                if (info.pastTurn.pastDecision.choice.type == ActionType.STOCK) // Stock => go back
                {
                    choice     = ChoiceDescriptor.ChooseMove(GoBackExploration(info.adjacentPheromoneGroups));
                    mindset    = AntMindset.AMS1;
                    pheromones = MarkFood(info.pastTurn.pastDecision.choice.direction);
                }
                else if (info.pastTurn.error == TurnError.NONE)     // No error => go back (if cannot, give food)
                {
                    HexDirection direction = GoBackExploration(info.adjacentPheromoneGroups);
                    choice     = ChoiceDescriptor.ChooseMove(direction != HexDirection.CENTER ? direction : info.pastTurn.pastDecision.choice.direction);
                    mindset    = AntMindset.AMS1;
                    pheromones = MarkFood(info.pastTurn.pastDecision.choice.direction);
                }
                else if (info.pastTurn.error == TurnError.COLLISION_ANT)     // No error => go back
                {
                    choice     = ChoiceDescriptor.ChooseGive(info.pastTurn.pastDecision.choice.direction, 100);
                    mindset    = AntMindset.AMS1;
                    pheromones = MarkFood(info.pastTurn.pastDecision.choice.direction);
                }
                else     // Error => still try to go back
                {
                    choice     = ChoiceDescriptor.ChooseMove(GoBackExploration(info.adjacentPheromoneGroups));
                    mindset    = AntMindset.AMS1;
                    pheromones = MarkFood(info.pastTurn.pastDecision.choice.direction);
                }
                break;

            default:
                choice     = ChoiceDescriptor.ChooseNone();
                mindset    = AntMindset.AMS0;
                pheromones = info.pheromones;
                break;
            }
        }

        return(new Decision(mindset, choice, pheromones));
    }
コード例 #8
0
ファイル: Decision.cs プロジェクト: JojoPalambas/AIAnt
 public Decision(AntMindset newMindset, ChoiceDescriptor choice, List <PheromoneDigest> pheromones)
 {
     this.newMindset = newMindset;
     this.choice     = choice;
     this.pheromones = pheromones;
 }
コード例 #9
0
ファイル: AITestNone.cs プロジェクト: JojoPalambas/AIAnt
    public override Decision OnQueenTurn(TurnInformation info)
    {
        ChoiceDescriptor choice = ChoiceDescriptor.ChooseNone();

        return(new Decision(AntMindset.AMS0, choice, info.pheromones));
    }
コード例 #10
0
ファイル: AITestAgressive.cs プロジェクト: JojoPalambas/AIAnt
    public override Decision OnWorkerTurn(TurnInformation info)
    {
        // Setting the defaults
        AntMindset             mindset    = AntMindset.AMS0;
        ChoiceDescriptor       choice     = ChoiceDescriptor.ChooseNone();
        List <PheromoneDigest> pheromones = null;


        HexDirection attackDirection = HexDirection.CENTER;

        if (info.pastTurn != null)
        {
            attackDirection = GetAttackDirection(info.eventInputs);
        }

        if (info.pastTurn == null)
        {
            choice = ChoiceDescriptor.ChooseMove((HexDirection)Random.Range(1, 8));
        }

        else if (attackDirection != HexDirection.CENTER)
        {
            choice = ChoiceDescriptor.ChooseAttack(attackDirection);
        }

        else
        {
            switch (info.pastTurn.pastDecision.choice.type)
            {
            case ActionType.MOVE:

                switch (info.pastTurn.error)
                {
                case TurnError.NONE:
                    int rand = Random.Range(0, 10);
                    if (rand < 8)
                    {
                        choice = ChoiceDescriptor.ChooseMove(info.pastTurn.pastDecision.choice.direction);
                    }
                    else
                    {
                        choice = ChoiceDescriptor.ChooseMove((HexDirection)Random.Range(1, 8));
                    }
                    break;

                case TurnError.COLLISION_ANT:
                    choice = ChoiceDescriptor.ChooseAttack(info.pastTurn.pastDecision.choice.direction);
                    break;

                default:
                    choice = ChoiceDescriptor.ChooseMove((HexDirection)Random.Range(1, 8));
                    break;
                }

                break;

            case ActionType.ATTACK:

                switch (info.pastTurn.error)
                {
                case TurnError.NONE:
                    choice = ChoiceDescriptor.ChooseAttack(info.pastTurn.pastDecision.choice.direction);
                    break;

                default:
                    choice = ChoiceDescriptor.ChooseMove((HexDirection)Random.Range(1, 8));
                    break;
                }

                break;

            default:
                choice = ChoiceDescriptor.ChooseMove((HexDirection)Random.Range(1, 8));
                break;
            }
        }

        if (choice.type == ActionType.MOVE)
        {
            pheromones = new List <PheromoneDigest>();
            pheromones.Add(new PheromoneDigest(PheromoneType.PHER0, choice.direction));
        }

        return(new Decision(mindset, choice, pheromones));
    }
コード例 #11
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
    }