示例#1
0
    private IEnumerable <TileAndDepth> iterateTilesNearUnit(Unit unit, int maxDepth)
    {
        Vector2 mapPos = map.gameToMap(unit.getPosition());

        // TODO: handle out-of-bounds units
        yield return(new TileAndDepth(mapPos, 0));

        RandomSet <Vector2> tilesInfluencedByThisUnit = new RandomSet <Vector2>();
        RandomSet <Vector2> previousIterationTiles    = new RandomSet <Vector2>();

        tilesInfluencedByThisUnit.Add(mapPos);
        previousIterationTiles.Add(mapPos);
        for (int iteration = 1; iteration <= maxDepth; iteration++)
        {
            RandomSet <Vector2> currentIterationTiles = new RandomSet <Vector2>();
            foreach (Vector2 tile in previousIterationTiles)
            {
                currentIterationTiles.UnionWith(map.getValidNeighbour4(tile, walkableTiles));
            }
            currentIterationTiles.DifferenceWith(tilesInfluencedByThisUnit);
            tilesInfluencedByThisUnit.UnionWith(currentIterationTiles);
            playerInfluencedTiles.UnionWith(currentIterationTiles);
            foreach (Vector2 tile in currentIterationTiles)
            {
                yield return(new TileAndDepth(tile, iteration));
            }
            previousIterationTiles = currentIterationTiles;
        }
    }
示例#2
0
    // Returns neighbours of currentTile that are also present in validTiles.
    public RandomSet <Vector2> getValidNeighbour8(Vector2 currentTile, ICollection <Vector2> validTiles)
    {
        RandomSet <Vector2> potentialNeighbours = new RandomSet <Vector2>();

        potentialNeighbours.UnionWith(getNeighbours8(currentTile));
        potentialNeighbours.IntersectWith(validTiles);
        return(potentialNeighbours);
    }
示例#3
0
        public void GivenRandomSet_InsertAndGet_ShouldReturnTheInsertedNumber()
        {
            var randomSet = new RandomSet();

            randomSet.Insert(0);
            var result = randomSet.GetRandom();

            Assert.IsTrue(result == 0);
        }
示例#4
0
    public UnitGroup split()
    {
        if (units.Count == 1)
        {
            return(null);
        }
        // k-means clustering
        RandomSet <Unit> unitset = new RandomSet <Unit>(units);

        List <Unit>[] kgroups = new List <Unit> [2];
        Vector2[]     kmeans  = new Vector2[2];
        for (int k = 0; k < 2; ++k)
        {
            kgroups[k] = new List <Unit>();
        }
        for (int repetition = 0; repetition < 10; ++repetition)
        {
            for (int k = 0; k < 2; ++k)
            {
                if (kgroups[k].Count == 0)
                {
                    kmeans[k] = unitset.getRandom().transform.position;
                }
                else
                {
                    kmeans[k] = avgPos(kgroups[k]);
                }
                kgroups[k].Clear();
            }
            foreach (Unit u in units)
            {
                int   closest = 0;
                float mindd   = float.MaxValue;
                for (int k = 0; k < 2; ++k)
                {
                    float dd = (kmeans[k] - (Vector2)u.transform.position).sqrMagnitude;
                    if (dd < mindd)
                    {
                        mindd   = dd;
                        closest = k;
                    }
                }
                kgroups[closest].Add(u);
            }
        }
        // TODO: prefer equally sized groups
        UnitGroup newGroup    = Scene.get().createUnitGroup(kgroups[1]);
        Vector2   groupOffset = (kmeans[1] - kmeans[0]).normalized;

        newGroup.setDest(dest + groupOffset / 2, false);
        setDest(dest - groupOffset / 2, false);
        return(newGroup);
    }
示例#5
0
    private Vector2 GenerateStartingVelocity()
    {
        float x = rnd.Next(3, 5);
        float y = rnd.Next(2, 4);

        RandomSet <int> directions = new RandomSet <int>(new int[] { -1, 1 });

        float xDir = directions.Next();
        float yDir = directions.Next();

        return(new Vector2(x * xDir, y * yDir));
    }
示例#6
0
        public void GivenRandomSet_InsertAndDelete_ShouldNotThrowException()
        {
            var randomSet = new RandomSet();

            randomSet.Insert(0);
            randomSet.Insert(2);

            Assert.IsTrue(randomSet.Count == 2);

            randomSet.Delete(0);
            Assert.IsTrue(randomSet.Count == 1);
        }
示例#7
0
    // Called before the Start() method
    void Awake()
    {
        // sets current AP to total AP
        currentAP = totalAP;

        // retrieves a reference to the Room Manager
        roomManager = Camera.main.GetComponent <RoomManager>();

        // gets text block component
        notifPopUp      = GameObject.FindGameObjectWithTag("NotifPopUp").GetComponent <Text>();
        notifPopUp.text = "";

        // Generate random murderer ID(s)
        murdererIDs = RandomSet.RandomSetOfInts(0, numOfCharacters, numOfKillers, true);

        // create a fresh set of characters with one murderer
        for (int i = 0; i < numOfCharacters; i++)
        {
            bool flaggedAsKiller = false;   // flag marking whether new character is killer

            // instantiate new character and pair it with name in dictionary
            GameObject newChar = Instantiate(characterPrefab);
            suspects.Add((CharacterList)i, newChar);

            // if i matches one of murderer IDs, set char's status to be murderer
            foreach (int ID in murdererIDs)
            {
                if (i == ID)
                {
                    newChar.GetComponent <Character>().SetData((CharacterList)i, true);
                    newChar.AddComponent <Murderer>();
                    newChar.tag     = "murderer";
                    flaggedAsKiller = true;

                    // add reference of new murderer to list of murderers
                    murderers.Add(newChar);
                }
            }

            // if character wasn't marked as killer
            if (!flaggedAsKiller)
            {
                // set char's status to be non-murderer
                newChar.GetComponent <Character>().SetData((CharacterList)i, false);
            }
        }
    }
示例#8
0
        /// <summary>
        /// 初始化牌庫(新局時)
        /// </summary>
        public void Init()
        {
            var cards = new List <Card>(144);
            int gid   = 0;

            // generate all cards
            foreach (CardType type in Enum.GetValues(typeof(CardType)))
            {
                switch (type)
                {
                case CardType.萬:
                case CardType.索:
                case CardType.筒:
                    for (int value = 1; value <= 9; value++)
                    {
                        for (int count = 0; count < 4; count++)
                        {
                            cards.Add(new NCard(gid++, type, value));
                        }
                    }
                    break;

                case CardType.風向及花牌:

                    //風
                    for (int value = 1; value <= 7; value++)
                    {
                        for (int count = 0; count < 4; count++)
                        {
                            cards.Add(new SCard(gid++, value));
                        }
                    }

                    //花
                    for (int value = 11; value <= 18; value++)
                    {
                        cards.Add(new SCard(gid++, value));
                    }
                    break;

                default:
                    throw new NotSupportedException();
                }
            }

            this._cards = new RandomSet(cards);
        }
示例#9
0
 private void initializeHeatmap()
 {
     heatmap               = new List <List <int> >();
     walkableTiles         = new RandomSet <Vector2>();
     playerInfluencedTiles = new RandomSet <Vector2>();
     enemyInfluencedTiles  = new RandomSet <Vector2>();
     for (int x = 0; x < map.mapWidth; ++x)
     {
         heatmap.Add(new List <int>());
         for (int y = 0; y < map.mapHeight; ++y)
         {
             heatmap[x].Add(0);
             if (map.isWalkable(map.getTile(x, y)))
             {
                 walkableTiles.Add(new Vector2(x, y));
             }
         }
     }
 }
示例#10
0
    private void updateHeatmap()
    {
        if (heatmap == null && map.hasBeenGenerated)
        {
            initializeHeatmap();
        }
        // Construct a heatmap. Each tile is hot if near a friendly warship and cold if near an enemy warship.
        timeSinceHeatmapUpdate += Time.deltaTime;
        if (timeSinceHeatmapUpdate < 0.4f)
        {
            return;
        }
        for (int x = 0; x < map.mapWidth; ++x)
        {
            for (int y = 0; y < map.mapHeight; ++y)
            {
                heatmap[x][y] = 0;
            }
        }
        playerInfluencedTiles.Clear();
        enemyInfluencedTiles.Clear();
        RandomSet <Vector2> allInfluencedTiles = new RandomSet <Vector2>();
        int influenceDepth = 4;

        foreach (Unit u in aiPlayer.units)
        {
            if (!u.capableOfAttack())
            {
                continue;
            }
            foreach (TileAndDepth tileAndDepth in iterateTilesNearUnit(u, influenceDepth))
            {
                updateHeatmapTile(tileAndDepth.tile, influenceDepth - tileAndDepth.depth);
            }
        }
        foreach (Unit u in iterateEnemyUnits(false, true))
        {
            foreach (TileAndDepth tileAndDepth in iterateTilesNearUnit(u, influenceDepth))
            {
                updateHeatmapTile(tileAndDepth.tile, -(influenceDepth - tileAndDepth.depth));
            }
        }
    }
示例#11
0
    // Use this for initialization
    void Start()
    {
        points = 0;

        WordField.text   = "";
        PointsField.text = points.ToString();

        lettersgrid[0] = 0;
        lettersgrid[1] = 0;

        checkwords.Clear();

        IsSwipeTyping = false;

        CheckWord("");
        checkwords.Add("");

        RandomSet.GetData();

        InstantiateLetters();
    }
示例#12
0
    public void generateMap(List <Player> players, int width = 16, int height = 16, int tilesBetweenIslands = 2)
    {
        hasBeenGenerated = true;
        mapWidth         = width;
        mapHeight        = height;
        tileMap          = new List <List <Tile> >();
        buildings        = new List <Building>();

        // Default the entire map to water.
        RandomSet <Vector2> waterTiles = new RandomSet <Vector2>();

        for (int x = 0; x < mapWidth; ++x)
        {
            tileMap.Add(new List <Tile>());
            for (int y = 0; y < mapHeight; ++y)
            {
                tileMap[x].Add(Tile.WATER);
                // The border of the map is water, but we don't want to spawn islands that touch the edge.
                if (x > 0 && x < mapWidth - 1 && y > 0 && y < mapHeight - 1)
                {
                    waterTiles.Add(new Vector2(x, y));
                }
            }
        }

        // Terrain
        int numislands    = 12;     //15;
        int islandSizeMin = 3;
        int islandSizeMax = 18;
        int treeDensity   = 4;
        int numcolonies   = 20;

        //Random.seed =
        for (int islandsCreated = 0; islandsCreated < numislands && waterTiles.Count > 0; islandsCreated++)
        {
            Vector2 initialTile = waterTiles.popRandom();

            // A set of water values that could be made into land
            RandomSet <Vector2> adjacentWater = new RandomSet <Vector2>();
            RandomSet <Vector2> islandTiles   = new RandomSet <Vector2>();
            adjacentWater.Add(initialTile);

            int islandSize = Random.Range(islandSizeMin, islandSizeMax + 1);
            for (int n = 0; n < islandSize && adjacentWater.Count > 0; n++)
            {
                Vector2 randTile = adjacentWater.popRandom();
                waterTiles.Remove(randTile);
                adjacentWater.UnionWith(getValidNeighbour4(randTile, waterTiles));

                setTile(randTile, Tile.GRASS);
                GameObject island = Instantiate(islandObject);
                island.transform.parent        = transform;
                island.transform.localPosition = mapToGame(randTile);
                islandTiles.Add(randTile);
            }
            // Remove water tiles near the island from the available water tiles for future island generation.
            for (int i = 0; i < tilesBetweenIslands; i++)
            {
                RandomSet <Vector2> temporarySet = new RandomSet <Vector2>();
                foreach (Vector2 tile in islandTiles)
                {
                    temporarySet.UnionWith(getValidNeighbour8(tile, waterTiles));
                }
                islandTiles = temporarySet;
                waterTiles.DifferenceWith(islandTiles);
            }
        }

        // Floodfill water tiles that are reachable from the corner of the map.
        // For each tile, count the number of adjacent land tiles.
        // Any water tile with 1-2 adjacent land tiles is a valid place for a dock.
        // The set of land tiles adjacent to validDockTiles is the set of validBuildingTiles.
        HashSet <Vector2>   seen               = new HashSet <Vector2>();
        Queue <Vector2>     todo               = new Queue <Vector2>();
        HashSet <Vector2>   validDockTiles     = new HashSet <Vector2>();
        RandomSet <Vector2> validBuildingTiles = new RandomSet <Vector2>();

        // since I excluded the outer border, it is definitely water
        todo.Enqueue(new Vector2(0, 0));
        seen.Add(todo.Peek());
        while (todo.Count > 0)
        {
            Vector2           randTile       = todo.Dequeue();
            HashSet <Vector2> adjacentCoasts = new HashSet <Vector2>();
            foreach (Vector2 adj in getNeighbours4(randTile))
            {
                if (isWater(getTile(adj)))
                {
                    if (!seen.Contains(adj))
                    {
                        todo.Enqueue(adj);
                    }
                }
                else
                {
                    adjacentCoasts.Add(adj);
                }
                seen.Add(adj);
            }
            if (adjacentCoasts.Count > 0 && adjacentCoasts.Count < 3)
            {
                validDockTiles.Add(randTile);
                validBuildingTiles.UnionWith(adjacentCoasts);
            }
        }

        // Put each player's base at the potential tile closest to their side of the map. Player1 should spawn at -y
        // Player 0 is neutral. Player 1 should spawn at +y.
        for (int playerIndex = 1; playerIndex < players.Count; playerIndex++)
        {
            float   angleFromCenter = (Mathf.PI / 2f) + (playerIndex * 2f * Mathf.PI / (players.Count - 1));
            Vector2 preferredTile   = 0.9f * new Vector2(
                mapWidth * (0.5f + 0.5f * Mathf.Cos(angleFromCenter)),
                mapHeight * (0.5f + 0.5f * Mathf.Sin(angleFromCenter)));
            float   minDistFromPreferred = float.MaxValue;
            Vector2 buildingPos          = Vector2.zero;
            foreach (Vector2 possibleTile in validBuildingTiles)
            {
                // TODO: ignore docks that face away from the center of the map.
                // (The dot product of dockDirection and angleFromCenter should be negative)
                float distFromPreferred = (possibleTile - preferredTile).sqrMagnitude;
                if (distFromPreferred < minDistFromPreferred)
                {
                    minDistFromPreferred = distFromPreferred;
                    buildingPos          = possibleTile;
                }
            }
            validBuildingTiles.Remove(buildingPos);
            Vector2 dockTile = getValidNeighbour4(buildingPos, validDockTiles).popRandom();
            setTile(buildingPos, Tile.BUILDING);
            Building building = Instantiate(baseObject).GetComponent <Building>();
            building.init(buildingPos, dockTile, BuildingType.BASE);
            building.setOwner(players[playerIndex]);
            buildings.Add(building);
        }

        // colonies
        for (int i = 0; i < numcolonies && validBuildingTiles.Count > 0; i++)
        {
            Vector2 buildingPos = validBuildingTiles.popRandom();
            Vector2 dockTile    = getValidNeighbour4(buildingPos, validDockTiles).popRandom();
            setTile(buildingPos, Tile.BUILDING);
            Building building = Instantiate(buildingObject).GetComponent <Building>();
            building.init(buildingPos, dockTile, BuildingType.COLONY);
            building.setOwner(players[0]);             // Neutral
            buildings.Add(building);
        }
        Pathing.updateMap(this);

        // Spawn trees.
        for (int x = 0; x < mapWidth; ++x)
        {
            for (int y = 0; y < mapHeight; ++y)
            {
                if (tileMap[x][y] == Tile.GRASS)
                {
                    for (int tr = 0; tr < treeDensity; ++tr)
                    {
                        GameObject tree = Instantiate(treeObject);
                        tree.transform.parent = transform;
                        // z = -0.2f puts the tree in front of the sand
                        tree.transform.localPosition = mapToGame(x, y) + new Vector3(
                            Random.Range(-tileSize * 0.45f, tileSize * 0.45f),
                            Random.Range(-tileSize * 0.45f, tileSize * 0.45f),
                            -0.45f);
                        float sz = Random.Range(tileSize * 0.8f, tileSize * 1.2f);                         // tree radius is about 0.29 by default
                        tree.transform.localScale = new Vector3(sz, sz, 1f);
                    }
                }
            }
        }
    }