Beispiel #1
0
    public IEnumerable GetNeighbors(HexCoord hex)
    {
        // Return the neighbors of a given hexcoord
        //Debug.Log(pos);
        IEnumerable neighbors = hex.Neighbors();

        return(neighbors);
    }
    //Used for the second placement of the game. Hexes neighboring 0,0 are eligible;
    public void GetEligibleSecondPlacement()
    {
        eligibleList.Clear();
        HexCoord originHex = HexCoord.AtPosition(new Vector2(0, 0));

        foreach (HexCoord nh in originHex.Neighbors())
        {
            eligibleList.Add(nh);   //Add all neighbors
        }

        hexController.HighlightEligible(eligibleList);
    }
Beispiel #3
0
    int CountOccupiedNeighbors(HexCoord hex)
    {
        int neighborCount = 0;

        foreach (HexCoord nh in hex.Neighbors())
        {
            if (occupiedList.Contains(nh))
            {
                neighborCount++;
            }
        }
        return(neighborCount);
    }
Beispiel #4
0
    //Checks whether moving a piece from start hex to test hex will be jumping a gap or not.
    //I.e. Most pieces can't make a move that would have them not be in contact with the hive
    //during the move
    bool IsMoveGapJumping(HexCoord initial, HexCoord current, HexCoord test)
    {
        bool            gapJumped        = true; //Initialize as true. Must be proved to be false
        List <HexCoord> currentNeighbors = new List <HexCoord>();
        List <HexCoord> testNeighbors    = new List <HexCoord>();
        List <HexCoord> occupiedListMod  = new List <HexCoord>(occupiedList); //Copy list

        occupiedListMod.Remove(initial);                                      //Exclude piece in question from neighbor search

        //Find all neighbor pieces at current location
        foreach (HexCoord nh in current.Neighbors())
        {
            if (occupiedListMod.Contains(nh))   //If neighbor hex is occupied
            {
                currentNeighbors.Add(nh);       //Add to current neighbors list
            }
        }

        //Find all neighbor pieces at current location
        foreach (HexCoord nh in test.Neighbors())
        {
            if (occupiedListMod.Contains(nh)) //If neighbor hex is occupied
            {
                testNeighbors.Add(nh);        //Add to test neighbors list
            }
        }

        //If no neighbors are the same at new location then the piece WOULD be jumping a gap
        foreach (HexCoord hex in testNeighbors)
        {
            if (currentNeighbors.Contains(hex))
            {
                gapJumped = false;
            }
        }

        return(gapJumped);
    }
    /// <summary>
    /// Randomly generate a hex grid that would fill the given BoxCollider.
    /// </summary>
    private void GenerateHexGrid()
    {
        if (_hexPrefab == null)
        {
            throw new ArgumentNullException("_prefab");
        }
        if (Board == null)
        {
            throw new ArgumentNullException("_board");
        }

        float boardWidth      = Board.bounds.size.x;
        float boardHeight     = Board.bounds.size.z;
        float gameObjectScale = (boardWidth / WidthInHexes);

        //Multiply with height to width ratio.
        float sideToSideSize = gameObjectScale / (Mathf.Sqrt(3) / 2f);

        _hexPrefab.transform.localScale = Vector3.one * (sideToSideSize);

        //Size of a single side
        float sideSize = _hexPrefab.transform.localScale.z / 2f;

        //Save hex scale factor for later use.
        _hexScaleFactor = 1f / sideSize;

        //2 Vertical hexagons coupled together for ease of calculation.
        float totalHexHeightCoupled = Mathf.RoundToInt(boardHeight / (sideSize * 3));

        //Find total hexagon count.
        _heightInHexes = (int)(totalHexHeightCoupled * 2);

        //Find total hexagon height. 1 for odds, 2 for evens.
        float totalHexHeight = totalHexHeightCoupled * sideSize * 3;

        //Clip overflow.
        if (totalHexHeight > boardHeight)
        {
            if (HeightInHexes % 2 != 0)
            {
                totalHexHeight -= sideSize * 2;
            }
            else
            {
                totalHexHeight -= sideSize;
            }
            _heightInHexes = HeightInHexes - 1;
        }

        //Center the grid vertically.
        float verticalPadding = Mathf.Max(0, (boardHeight - totalHexHeight) / 2f);

        //Offset grid to being from the corner instead of center.
        _startPos = _transform.position -
                    new Vector3((boardWidth - gameObjectScale) * 0.5f,
                                0,
                                (boardHeight - sideToSideSize) * 0.5f - verticalPadding);

        _hexGrid = new HexTile[HeightInHexes][];

        for (int r = 0; r < HeightInHexes; r++)
        {
            //Prevent overflow on odd columns.
            int tempWidth = r % 2 == 0 ? WidthInHexes : WidthInHexes - 1;
            _hexGrid[r] = new HexTile[tempWidth];
            for (int q = 0; q < tempWidth; q++)
            {
                //Scale and position Hex.
                HexCoord newHexCoord = new HexCoord(q - (r - (r & 1)) / 2, r);

                //Spawn and parent Hex.
                GameObject spawnedHex =
                    Instantiate(_hexPrefab, GetWorldPositionOfHex(newHexCoord), Quaternion.identity) as GameObject;
                spawnedHex.transform.parent = _transform;

                //Initialize Hex.
                HexTile hexTile = spawnedHex.GetComponent <HexTile>();
                bool    isPassable;
                //An easy way to make sure board is traversable from side to side.
                if (newHexCoord.Neighbors().Where(IsCordinateValid).Any(tile =>
                {
                    HexTile hexTileTemp = GetHexTile(tile);
                    return(hexTileTemp != null && !hexTileTemp.IsPassable);
                }))
                {
                    isPassable = true;
                }
                else
                {
                    isPassable = !(UnityEngine.Random.value < _roadBlockChance && r > 1 && HeightInHexes - r > 2);
                }
                hexTile.SetCoord(newHexCoord, isPassable);
                _hexGrid[r][q] = hexTile;
            }
        }
    }
    //Checks whether moving a piece from start hex to test hex will be jumping a gap or not.
    //I.e. Most pieces can't make a move that would have them not be in contact with the hive
    //during the move
    bool IsMoveGapJumping(HexCoord initial, HexCoord current, HexCoord test)
    {
        bool gapJumped = true;      //Initialize as true. Must be proved to be false
        List<HexCoord> currentNeighbors = new List<HexCoord>();
        List<HexCoord> testNeighbors = new List<HexCoord>();
        List<HexCoord> occupiedListMod = new List<HexCoord>(occupiedList);  //Copy list
        occupiedListMod.Remove(initial);                                   //Exclude piece in question from neighbor search

        //Find all neighbor pieces at current location
        foreach (HexCoord nh in current.Neighbors())
        {
            if (occupiedListMod.Contains(nh))   //If neighbor hex is occupied
            {
                currentNeighbors.Add(nh);       //Add to current neighbors list
            }
        }

        //Find all neighbor pieces at current location
        foreach (HexCoord nh in test.Neighbors())
        {
            if (occupiedListMod.Contains(nh))   //If neighbor hex is occupied
            {
                testNeighbors.Add(nh);       //Add to test neighbors list
            }
        }

        //If no neighbors are the same at new location then the piece WOULD be jumping a gap
        foreach (HexCoord hex in testNeighbors)
        {
            if (currentNeighbors.Contains(hex))
            {
                gapJumped = false;
            }
        }

        return gapJumped;
    }
 int CountOccupiedNeighbors(HexCoord hex)
 {
     int neighborCount = 0;
     foreach (HexCoord nh in hex.Neighbors())
     {
         if (occupiedList.Contains(nh))
         {
             neighborCount++;
         }
     }
     return neighborCount;
 }
    //Returns a list of eligible moves for a given piece
    public List<HexCoord> EligibleMovesByPiece(HexCoord start, UnitType type)
    {
        Debug.Log("Eligible Start " + start);
        //Start with outer hexes
        List<HexCoord> eligibleList = GetOuterHexes(start);
        List<HexCoord> eligibleListMod = new List<HexCoord>();    //Make a blank list
        switch (type)
        {
            case UnitType.Ant:
                //Copy eligible list. Ant can move to any outer position.
                eligibleListMod = new List<HexCoord>(eligibleList);
                RemoveUnreachableHexes(eligibleListMod);                //Next remove unreachable locations.
                ////Currently I don't check to see whether a move would have the ant squeeze through a hole that's too small
                ////A way to implement this would be to check space by space in a move chain. If any space is unreachable then
                ////the chain would stop.
                break;

            case UnitType.Queen:
                //Queen can only move one hex away from start. Check for overlap between outer cells and neighbors to start
                foreach (HexCoord nh in start.Neighbors())
                {
                    if (eligibleList.Contains(nh) && !IsMoveGapJumping(start, start, nh))
                        eligibleListMod.Add(nh);
                }
                RemoveUnreachableHexes(eligibleListMod);                //Next remove unreachable locations.
                break;

            case UnitType.Beetle:
                //Beetles move one space, but can also move on top of other pieces
                //No restrictions on unreachable hexes
                foreach (HexCoord nh in start.Neighbors())
                {
                    if (beetleDict.ContainsKey(start))
                    {
                        if (beetleDict[start] > 0)      //If this is a beetle moving from on top of the hive, all neighbors will be eligible
                        {
                            eligibleListMod.Add(nh);
                        }

                        else if (eligibleList.Contains(nh) && !IsMoveGapJumping(start, start, nh))  //Add all unnoccupied neighbors that are eligible
                        {
                            eligibleListMod.Add(nh);
                        }
                        else if (occupiedList.Contains(nh))
                        {
                                eligibleListMod.Add(nh);    //Add all occupied neighbors
                        }
                    }
                    //Might not need to repeat these
                    else if (eligibleList.Contains(nh) && !IsMoveGapJumping(start, start, nh))  //Add all unnoccupied neighbors that are eligible
                    {
                        eligibleListMod.Add(nh);

                        if (occupiedList.Contains(nh))
                            eligibleListMod.Add(nh);    //Add all occupied neighbors
                    }
                }
                break;

            case UnitType.Spider:
                //Spiders move exactly 3 spaces following the outer edge of the hive
                //Use outer hex list as a starting point. All outer hexes at exactly 3 spaces from starting point should be eligible
                List<HexCoord> outerHexes = GetOuterHexes(start);

                List<HexCoord> iterList = new List<HexCoord>();
                List<HexCoord> firstSpaces = new List<HexCoord>();
                List<HexCoord> secondSpaces = new List<HexCoord>();
                List<HexCoord> thirdSpaces = new List<HexCoord>();

                for (int i = 1; i < 4; i++)
                {
                    switch (i)
                    {
                        case 1:    //For the first move check neighbors of the start hex
                            iterList.Add(start);
                            break;
                        case 2:     //For the second move check neighbors of each eligible first move space
                            iterList = new List<HexCoord>(firstSpaces);

                            break;
                        case 3:     //For the third move check neighbors of each eligible second move space
                            iterList = new List<HexCoord>(secondSpaces);
                            break;
                    }

                    foreach (HexCoord hex in iterList)
                    {

                        foreach (HexCoord nh in hex.Neighbors())          //First find occupied neighbors
                        {
                            //space must be an outer hex and reachable and the move must not be jumping a gap
                            if (outerHexes.Contains(nh) && !IsHexUnreachable(nh) && !IsMoveGapJumping(start,hex,nh))
                            {
                                switch (i)
                                {
                                    case 1:
                                        firstSpaces.Add(nh);
                                        break;
                                    case 2:
                                        secondSpaces.Add(nh);
                                        break;
                                    case 3:
                                        thirdSpaces.Add(nh);
                                        break;
                                }
                            }
                        }
                    }

                }

                eligibleListMod = new List<HexCoord>(thirdSpaces);      //All eligible third spaces are the full eligible list
                //Remove all first spaces and second spaces. This is an attempt to eliminate back tracking.
                //Since backtracking isn't allowed I don't think there's any way that any
                //first space could also be a valid third space. Same reasoning applies to second spaces
                //although I'm not as sure about the second spaces. Needs testing
                foreach (HexCoord spc in firstSpaces)
                    eligibleListMod.Remove(spc);
                foreach (HexCoord spc in secondSpaces)
                    eligibleListMod.Remove(spc);

                break;

            case UnitType.Grasshopper:
                //Grasshopper jumps in a straight line over other pieces
                //No restrictions on unreachable hexes
                int neighborIndex = 0;
                HexCoord option;
                foreach (HexCoord nh in start.Neighbors())          //First find occupied neighbors
                {
                    if (occupiedList.Contains(nh))                  //If direct neighbor is occupied
                    {
                        option = nh;                                //Initialize option
                        bool solutionFound = false;                 //Initialize bool
                        while (!solutionFound)                      //Repeat until solution is found
                        {
                            option = option.Neighbor(neighborIndex);    //Option might be next neighbor in same direction

                            if (!occupiedList.Contains(option))     //Check if occupied.
                            {
                                eligibleListMod.Add(option);        //If not occupied then add to eligible list
                                solutionFound = true;
                            }
                                                                    //If occupied then keep looking in the same direction. Stay in while loop
                        }
                    }
                    neighborIndex++;
                }
                break;

            default:
                eligibleListMod = eligibleList;
                break;

        }

        return eligibleListMod;
    }
    public IEnumerable GetNeighbors(HexCoord hex)
    {
        // Return the neighbors of a given hexcoord
        //Debug.Log(pos);
        IEnumerable neighbors = hex.Neighbors();

        return neighbors;
    }
Beispiel #10
0
    public void CheckHiveContinuity2()
    {
        validMovePieces.Clear();               //

        foreach (HexCoord hex in occupiedList) //For every occupied cell
        {
            //Debug.Log("Test Hex" + hex);
            //Test whether this piece could be moved by checking hive with out it
            if (beetleDict[hex] == 0)   //Only consider pieces that aren't covered by a beetle
            {
                //Is hive continuous without this piece?
                //Choose any piece in the occupied list except for the chosen piece. Find continuous island from random piece
                List <HexCoord> occupiedListMod = new List <HexCoord>(occupiedList);
                occupiedListMod.Remove(hex);
                List <HexCoord> island = new List <HexCoord>(); // Create a new island list or reset;

                if (occupiedListMod.Count != 0)
                {
                    foreach (HexCoord neighbor in occupiedListMod[0].Neighbors())
                    {
                        if (occupiedListMod.Contains(neighbor))                  //If direct neighbor is occupied
                        {
                            if (!island.Contains(neighbor))
                            {
                                island.Add(neighbor);                       //Start by adding the neighbor
                            }

                            bool solutionFound = false;                   //Initialize bool

                            while (!solutionFound)                        //Repeat until entire island is found
                            {
                                HexCoord        nh = neighbor;            //Initialize nh variable
                                List <HexCoord> newNeighborList = new List <HexCoord>();
                                foreach (HexCoord secondNeighbor in nh.Neighbors())
                                {
                                    //If direct neighbor is occupied and island list doesn't already have that hex, then add it to the list
                                    if (occupiedListMod.Contains(secondNeighbor) && !island.Contains(secondNeighbor))
                                    {
                                        island.Add(secondNeighbor); //Add occupied neighbors to the island list
                                        nh = secondNeighbor;        //If a new neighbor was found set nh to new neighbor and repeat loop
                                        newNeighborList.Add(secondNeighbor);
                                    }
                                }

                                if (newNeighborList.Count == 0)
                                {
                                    solutionFound = true;
                                }                                                           //If there were no new neighbors then entire connected island has been found
                            }


                            //Check island size. Is it equal to total number of occupied hexes - 1?
                            //If so, that particular branch meets hive continuity. Add piece to eligible list
                            //If not, then hive would be split.
                            //This piece is not eligible
                            //Note, only need to check first occupied neighbor that is found. Then break to next piece
                            //break;
                        }
                    }

                    Debug.Log("Island Count: " + island.Count);
                    if (island.Count == occupiedList.Count - 1) //Full hive was continuous
                    {
                        validMovePieces.Add(hex);
                    }
                }
            }
        }

        Debug.Log("Valid move pieces: " + validMovePieces.Count);
    }
Beispiel #11
0
    //Returns a list of eligible moves for a given piece
    public List <HexCoord> EligibleMovesByPiece(HexCoord start, UnitType type)
    {
        Debug.Log("Eligible Start " + start);
        //Start with outer hexes
        List <HexCoord> eligibleList    = GetOuterHexes(start);
        List <HexCoord> eligibleListMod = new List <HexCoord>();    //Make a blank list

        switch (type)
        {
        case UnitType.Ant:
            //Copy eligible list. Ant can move to any outer position.
            eligibleListMod = new List <HexCoord>(eligibleList);
            RemoveUnreachableHexes(eligibleListMod);                    //Next remove unreachable locations.
            ////Currently I don't check to see whether a move would have the ant squeeze through a hole that's too small
            ////A way to implement this would be to check space by space in a move chain. If any space is unreachable then
            ////the chain would stop.
            break;

        case UnitType.Queen:
            //Queen can only move one hex away from start. Check for overlap between outer cells and neighbors to start
            foreach (HexCoord nh in start.Neighbors())
            {
                if (eligibleList.Contains(nh) && !IsMoveGapJumping(start, start, nh))
                {
                    eligibleListMod.Add(nh);
                }
            }
            RemoveUnreachableHexes(eligibleListMod);                    //Next remove unreachable locations.
            break;

        case UnitType.Beetle:
            //Beetles move one space, but can also move on top of other pieces
            //No restrictions on unreachable hexes
            foreach (HexCoord nh in start.Neighbors())
            {
                if (beetleDict.ContainsKey(start))
                {
                    if (beetleDict[start] > 0)          //If this is a beetle moving from on top of the hive, all neighbors will be eligible
                    {
                        eligibleListMod.Add(nh);
                    }

                    else if (eligibleList.Contains(nh) && !IsMoveGapJumping(start, start, nh))      //Add all unnoccupied neighbors that are eligible
                    {
                        eligibleListMod.Add(nh);
                    }
                    else if (occupiedList.Contains(nh))
                    {
                        eligibleListMod.Add(nh);            //Add all occupied neighbors
                    }
                }
                //Might not need to repeat these
                else if (eligibleList.Contains(nh) && !IsMoveGapJumping(start, start, nh))      //Add all unnoccupied neighbors that are eligible
                {
                    eligibleListMod.Add(nh);

                    if (occupiedList.Contains(nh))
                    {
                        eligibleListMod.Add(nh);        //Add all occupied neighbors
                    }
                }
            }
            break;

        case UnitType.Spider:
            //Spiders move exactly 3 spaces following the outer edge of the hive
            //Use outer hex list as a starting point. All outer hexes at exactly 3 spaces from starting point should be eligible
            List <HexCoord> outerHexes = GetOuterHexes(start);

            List <HexCoord> iterList     = new List <HexCoord>();
            List <HexCoord> firstSpaces  = new List <HexCoord>();
            List <HexCoord> secondSpaces = new List <HexCoord>();
            List <HexCoord> thirdSpaces  = new List <HexCoord>();

            for (int i = 1; i < 4; i++)
            {
                switch (i)
                {
                case 1:            //For the first move check neighbors of the start hex
                    iterList.Add(start);
                    break;

                case 2:             //For the second move check neighbors of each eligible first move space
                    iterList = new List <HexCoord>(firstSpaces);

                    break;

                case 3:             //For the third move check neighbors of each eligible second move space
                    iterList = new List <HexCoord>(secondSpaces);
                    break;
                }

                foreach (HexCoord hex in iterList)
                {
                    foreach (HexCoord nh in hex.Neighbors())              //First find occupied neighbors
                    {
                        //space must be an outer hex and reachable and the move must not be jumping a gap
                        if (outerHexes.Contains(nh) && !IsHexUnreachable(nh) && !IsMoveGapJumping(start, hex, nh))
                        {
                            switch (i)
                            {
                            case 1:
                                firstSpaces.Add(nh);
                                break;

                            case 2:
                                secondSpaces.Add(nh);
                                break;

                            case 3:
                                thirdSpaces.Add(nh);
                                break;
                            }
                        }
                    }
                }
            }

            eligibleListMod = new List <HexCoord>(thirdSpaces);         //All eligible third spaces are the full eligible list
            //Remove all first spaces and second spaces. This is an attempt to eliminate back tracking.
            //Since backtracking isn't allowed I don't think there's any way that any
            //first space could also be a valid third space. Same reasoning applies to second spaces
            //although I'm not as sure about the second spaces. Needs testing
            foreach (HexCoord spc in firstSpaces)
            {
                eligibleListMod.Remove(spc);
            }
            foreach (HexCoord spc in secondSpaces)
            {
                eligibleListMod.Remove(spc);
            }

            break;

        case UnitType.Grasshopper:
            //Grasshopper jumps in a straight line over other pieces
            //No restrictions on unreachable hexes
            int      neighborIndex = 0;
            HexCoord option;
            foreach (HexCoord nh in start.Neighbors())              //First find occupied neighbors
            {
                if (occupiedList.Contains(nh))                      //If direct neighbor is occupied
                {
                    option = nh;                                    //Initialize option
                    bool solutionFound = false;                     //Initialize bool
                    while (!solutionFound)                          //Repeat until solution is found
                    {
                        option = option.Neighbor(neighborIndex);    //Option might be next neighbor in same direction

                        if (!occupiedList.Contains(option))         //Check if occupied.
                        {
                            eligibleListMod.Add(option);            //If not occupied then add to eligible list
                            solutionFound = true;
                        }
                        //If occupied then keep looking in the same direction. Stay in while loop
                    }
                }
                neighborIndex++;
            }
            break;

        default:
            eligibleListMod = eligibleList;
            break;
        }

        return(eligibleListMod);
    }