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); }
int CountOccupiedNeighbors(HexCoord hex) { int neighborCount = 0; foreach (HexCoord nh in hex.Neighbors()) { if (occupiedList.Contains(nh)) { neighborCount++; } } return(neighborCount); }
//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; }
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); }
//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); }