예제 #1
0
    private void SpawnTerrainTile(int i, int j)
    {
        if (groundTilePrefab != null)
        {
            Vector2 currentTilePosition = CoordConverter.HexToPos(new Vector2Int(i, j));

            float rand = Random.Range(0f, 1f);

            // Water is placed if the random number picked it AND the tile is not protected
            Tile newTile = null;
            Food newFood = null;
            if (!protectedTiles.Contains(new Vector2Int(i, j)) && rand < waterProbability)
            {
                newTile = Instantiate(waterTilePrefab, CoordConverter.PlanToWorld(currentTilePosition, waterTilePrefab.transform.position.y), waterTilePrefab.transform.rotation);
            }
            else
            {
                newTile = Instantiate(groundTilePrefab, CoordConverter.PlanToWorld(currentTilePosition, groundTilePrefab.transform.position.y), groundTilePrefab.transform.rotation);

                rand = Random.Range(0f, 1f);
                // Food is placed if the random number picked it AND the tile is not protected (AND the tile is not water)
                if (!protectedTiles.Contains(new Vector2Int(i, j)) && rand < foodProbability)
                {
                    newFood = Instantiate(foodPrefab, CoordConverter.PlanToWorld(currentTilePosition, foodPrefab.transform.position.y), foodPrefab.transform.rotation);
                    foods.Add(newFood);
                }
            }

            terrain[i][j] = new TileContent(newTile, newFood);
        }
    }
예제 #2
0
파일: Ant.cs 프로젝트: JojoPalambas/AIAnt
    public void MoveToTarget(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;
        }

        float elapsedPercentage = elapsedTime / totalTime;

        Vector3 targetPosition = CoordConverter.PlanToWorld(CoordConverter.HexToPos(gameCoordinates), transform.position.y);

        transform.position = Vector3.Slerp(transform.position, targetPosition, elapsedPercentage);
    }
예제 #3
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);
    }
예제 #4
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);
    }
예제 #5
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);
                }
            }
        }
    }
예제 #6
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));
 }
예제 #7
0
    private void Act()
    {
        // Get the new turn order
        randomOrderAntList     = nextRandomOrderAntList;
        nextRandomOrderAntList = new List <Ant>();

        // Makes the queen and all the workers resolve their actions
        foreach (Ant ant in randomOrderAntList)
        {
            ResolveDecision(ant);
        }

        // Manages the eggs of all the teams
        foreach (Team team in teams)
        {
            // Makes all the eggs get older, and make the ready ones open
            List <int> emptyIndexes = new List <int>();
            for (int i = 0; i < team.eggs.Count; i++)
            {
                Egg egg = team.eggs[i];

                egg.roundsBeforeCracking--;
                if (egg.roundsBeforeCracking <= 0)
                {
                    Vector3 newAntWorldPosition = CoordConverter.PlanToWorld(CoordConverter.HexToPos(egg.gameCoordinates), workerPrefab.transform.position.y);
                    Worker  newWorker           = Instantiate(workerPrefab, newAntWorldPosition, workerPrefab.transform.rotation);

                    terrain[egg.gameCoordinates.x][egg.gameCoordinates.y].ant = newWorker;
                    newWorker.Init(egg.team, egg.gameCoordinates, egg.team.color);
                    team.workers.Add(newWorker);

                    egg.Die();
                    team.eggs[i] = null;
                    emptyIndexes.Add(i);
                }
            }
            for (int i = emptyIndexes.Count - 1; i >= 0; i--)
            {
                if (team.eggs[i] != null)
                {
                    Debug.Log("Wait. That's illegal.");
                }

                team.eggs.RemoveAt(i);
            }
        }
        // Check which teams have ended
        List <Team> finishedTeams = new List <Team>();

        foreach (Team team in teams)
        {
            // Makes all the ands that shoudl die die
            if (team.queen.shouldDie)
            {
                finishedTeams.Add(team);
            }

            List <Worker> toDie = new List <Worker>();
            foreach (Worker worker in team.workers)
            {
                if (worker.shouldDie)
                {
                    toDie.Add(worker);
                }
            }
            foreach (Worker worker in toDie)
            {
                team.workers.Remove(worker);
                Destroy(worker.gameObject);
            }
        }
        foreach (Team team in finishedTeams)
        {
            team.Die();
            teams.Remove(team);
        }
    }
예제 #8
0
    /*
     * HEXAGONAL TERRAIN REPRESENTATION
     *
     * Hex form:
     *     A   B   C
     *   D   E   F
     * G   H   I
     *
     * Hex coordinates:
     *       (0|0) (1|0) (2|0)
     *    (0|1) (1|1) (2|1)
     * (0|2) (1|2) (2|2)
     *
     * Terrain table form:
     * A D G
     * B E H
     * C F I
     *
     * Terrain table coordinates :
     * (0|0) (0|1) (0|2)
     * (1|0) (1|1) (1|2)
     * (2|0) (2|1) (2|2)
     */

    // Start is called before the first frame update
    void Start()
    {
        // If the map too small
        if (terrainSideLength < 5)
        {
            return;
        }

        // Just a convenient variable
        terrainLength = 2 * terrainSideLength - 1;

        // Creates the protected tiles
        protectedTiles = new List <Vector2Int>();
        int index = 0;

        // Stores the six corner sanctuaries of the map
        Dictionary <HexDirection, List <Vector2Int> > possibleSanctuaries = BuildSanctuaries();

        // Gives a starting position for each future queen and declares the protected tiles (cannot contain food or water)
        List <Vector2Int> currSanct;
        List <Vector2Int> queenPositions = new List <Vector2Int>();

        switch (aisToCompete.Count)
        {
        case 1:

            currSanct = possibleSanctuaries[HexDirection.UPLEFT];
            queenPositions.Add(currSanct[0]);
            protectedTiles.AddRange(currSanct);

            break;

        case 2:

            currSanct = possibleSanctuaries[HexDirection.UPLEFT];
            queenPositions.Add(currSanct[0]);
            protectedTiles.AddRange(currSanct);

            currSanct = possibleSanctuaries[HexDirection.DOWNRIGHT];
            queenPositions.Add(currSanct[0]);
            protectedTiles.AddRange(currSanct);

            break;

        case 3:

            currSanct = possibleSanctuaries[HexDirection.UPLEFT];
            queenPositions.Add(currSanct[0]);
            protectedTiles.AddRange(currSanct);

            currSanct = possibleSanctuaries[HexDirection.DOWNLEFT];
            queenPositions.Add(currSanct[0]);
            protectedTiles.AddRange(currSanct);

            currSanct = possibleSanctuaries[HexDirection.RIGHT];
            queenPositions.Add(currSanct[0]);
            protectedTiles.AddRange(currSanct);

            break;

        case 4:

            currSanct = possibleSanctuaries[HexDirection.UPLEFT];
            queenPositions.Add(currSanct[0]);
            protectedTiles.AddRange(currSanct);

            currSanct = possibleSanctuaries[HexDirection.DOWNRIGHT];
            queenPositions.Add(currSanct[0]);
            protectedTiles.AddRange(currSanct);

            currSanct = possibleSanctuaries[HexDirection.LEFT];
            queenPositions.Add(currSanct[0]);
            protectedTiles.AddRange(currSanct);

            currSanct = possibleSanctuaries[HexDirection.RIGHT];
            queenPositions.Add(currSanct[0]);
            protectedTiles.AddRange(currSanct);

            break;

        case 5:

            currSanct = possibleSanctuaries[HexDirection.UPLEFT];
            queenPositions.Add(currSanct[0]);
            protectedTiles.AddRange(currSanct);

            currSanct = possibleSanctuaries[HexDirection.DOWNRIGHT];
            queenPositions.Add(currSanct[0]);
            protectedTiles.AddRange(currSanct);

            currSanct = possibleSanctuaries[HexDirection.LEFT];
            queenPositions.Add(currSanct[0]);
            protectedTiles.AddRange(currSanct);

            currSanct = possibleSanctuaries[HexDirection.RIGHT];
            queenPositions.Add(currSanct[0]);
            protectedTiles.AddRange(currSanct);

            currSanct = possibleSanctuaries[HexDirection.DOWNLEFT];
            queenPositions.Add(currSanct[0]);
            protectedTiles.AddRange(currSanct);

            break;

        case 6:

            currSanct = possibleSanctuaries[HexDirection.UPLEFT];
            queenPositions.Add(currSanct[0]);
            protectedTiles.AddRange(currSanct);

            currSanct = possibleSanctuaries[HexDirection.DOWNRIGHT];
            queenPositions.Add(currSanct[0]);
            protectedTiles.AddRange(currSanct);

            currSanct = possibleSanctuaries[HexDirection.LEFT];
            queenPositions.Add(currSanct[0]);
            protectedTiles.AddRange(currSanct);

            currSanct = possibleSanctuaries[HexDirection.RIGHT];
            queenPositions.Add(currSanct[0]);
            protectedTiles.AddRange(currSanct);

            currSanct = possibleSanctuaries[HexDirection.DOWNLEFT];
            queenPositions.Add(currSanct[0]);
            protectedTiles.AddRange(currSanct);

            currSanct = possibleSanctuaries[HexDirection.UPRIGHT];
            queenPositions.Add(currSanct[0]);
            protectedTiles.AddRange(currSanct);

            break;

        default:
            break;
        }

        // Fills the terrain with tiles
        terrain = new TileContent[terrainLength][];
        foods   = new List <Food>();
        for (int i = 0; i < terrainLength; i++)
        {
            terrain[i] = new TileContent[terrainLength];

            for (int j = 0; j < terrainSideLength; j++)
            {
                // The condition trucates a part of the map, to shape it like an hexagon
                if (i < terrainSideLength + j)
                {
                    SpawnTerrainTile(i, j);
                }
            }

            for (int j = terrainSideLength; j < terrainLength; j++)
            {
                // The condition trucates a part of the map, to shape it like an hexagon
                if (i > j - terrainSideLength)
                {
                    SpawnTerrainTile(i, j);
                }
            }
        }

        nextRandomOrderAntList = new List <Ant>();

        // Instantiate the teams (number inferior or equal to 4)
        teams = new List <Team>();
        index = 0;
        foreach (AntAI ai in aisToCompete)
        {
            if (index >= Const.MAX_PLAYERS)
            {
                break;
            }

            Vector2Int queenPosition = queenPositions[index];

            Vector3 queenWorldPosition = CoordConverter.PlanToWorld(CoordConverter.HexToPos(queenPosition), queenPrefab.transform.position.y);
            Queen   newQueen           = Instantiate(queenPrefab, queenWorldPosition, queenPrefab.transform.rotation);

            terrain[queenPosition.x][queenPosition.y].ant = newQueen;

            Color teamColor = teamColors.Count > index ? teamColors[index] : new Color(255, 255, 255);
            Team  newTeam   = new Team(ai.GetType().ToString() + index, index, newQueen, ai, teamColor);
            teams.Add(newTeam);

            newQueen.Init(newTeam, queenPosition, teamColor);

            index++;
        }

        // Create all the pheromone maps
        pheromoneMaps = new List <PheromoneDescriptor> [teams.Count][][];
        foreach (Team team in teams)
        {
            List <PheromoneDescriptor>[][] pheromoneMap = new List <PheromoneDescriptor> [terrainLength][];
            pheromoneMaps[team.teamId] = pheromoneMap;

            for (int i = 0; i < terrainLength; i++)
            {
                pheromoneMap[i] = new List <PheromoneDescriptor> [terrainLength];

                for (int j = 0; j < terrainSideLength; j++)
                {
                    // The condition trucates a part of the map, to shape it like an hexagon
                    if (i < terrainSideLength + j)
                    {
                        pheromoneMap[i][j] = new List <PheromoneDescriptor>();
                    }
                }

                for (int j = terrainSideLength; j < terrainLength; j++)
                {
                    // The condition trucates a part of the map, to shape it like an hexagon
                    if (i > j - terrainSideLength)
                    {
                        pheromoneMap[i][j] = new List <PheromoneDescriptor>();
                    }
                }
            }
        }
        tornamentManager.InitLeaderboard(teams);

        pheromoneMapDisplayer.InitMap(teams, terrainLength, terrainLength);
    }