// Removes the wall between 2 cells by looking a their cornerPoints // Once the common corner points are found, we set them as "non-neighbours" public void RemoveBorderBetweenCells(GraphVertex otherGraphVertex) { RegularCell otherCell = (RegularCell)otherGraphVertex; foreach (RegularCell c in this.connectedCells) { // We look for the adjacent cell to remove the border if (c.Equals(otherCell)) { // We look for the corner points which are common to the two cells List <Vertex> commonVertices = new List <Vertex> (); foreach (Vertex v1 in this.cornerPoints) { foreach (Vertex v2 in otherCell.cornerPoints) { if (v1.Equals(v2)) { commonVertices.Add(v1); } } } // We disconnect all the border points which are common to the 2 cells so that the way is open foreach (Vertex v1 in commonVertices) { foreach (Vertex v2 in commonVertices) { v1.RemoveNeighbour(v2); } } } } }
// Connects 2 cells (connects the corner points each other and the cores) public void ConnectToOtherGraphVertex(GraphVertex other) { RegularCell otherCell = (RegularCell)other; List <Pair <Vertex> > pairList = new List <Pair <Vertex> > (); float delta = 0.2f; foreach (Vertex v1 in this.cornerPoints) { foreach (Vertex v2 in otherCell.cornerPoints) { if (Vector2.Distance(v1.Coo, v2.Coo) < delta) { Pair <Vertex> pair = new Pair <Vertex> (v1, v2); if (!pair.AlreadyExists(pairList)) { pairList.Add(pair); } } } } Debug.Assert(pairList.Count == 2); foreach (Pair <Vertex> p in pairList) { // Fusion of the pair elements and their respective neighborhood foreach (Vertex v in p.Ext1.Neighbours.ToArray()) { // We add our neighbours to the other corner point p.Ext2.AddNeighbour(v); } // Replacement of the corner in our cell this.cornerPoints.Remove(p.Ext1); this.cornerPoints.Add(p.Ext2); } // Connection of the cores of each cells core.AddNeighbour(otherCell.core); otherCell.core.AddNeighbour(core); // Add to the connected cells lists if (!this.connectedCells.Contains(otherCell)) { this.connectedCells.Add(otherCell); } if (!otherCell.connectedCells.Contains(this)) { otherCell.connectedCells.Add(this); } }
private Color teleportColor; // color of the teleport (if any) // CONSTRUCTOR // Creates a cell without connected cell nor teleport connexion public RegularCell(Vector2 coreCoo, float cellSize, int nbBorders, float angleOffset) { this.core = new Vertex(coreCoo); this.cellSize = cellSize; this.nbBorders = nbBorders; this.angleOffset = angleOffset; this.cornerPoints = new List <Vertex> (); for (int i = 0; i < nbBorders; i++) { float angle = i * 2 * Mathf.PI / nbBorders + angleOffset; cornerPoints.Add(new Vertex(coreCoo + cellSize * new Vector2(Mathf.Cos(angle), Mathf.Sin(angle)))); } ConnectCorners(); this.connectedCells = new List <RegularCell> (); this.teleportConnexion = null; }
// Generates a grid of QuadCell public static IEnumerable <GraphVertex> GridCellUndirectedGraph(float cellSize, int nbLines, int nbColumns, int nbBorders, bool putTeleporters) { RegularCell[,] vertices = new RegularCell[nbLines, nbColumns]; // Initialization of each cell for (int i = 0; i < nbLines; i++) { for (int j = 0; j < nbColumns; j++) { // For each cell, we calculate its center according to the grid // and the optional offsets due to the shape (square/hexagon) and the line number (odd or even) Pair <float> angleOffsets = UndirectedGraph.DetermineAngleOffsets(nbBorders); Pair <float> axisOffsets = DetermineAxisOffsets(nbBorders, cellSize); float coreX = j * cellSize * 2 * Mathf.Cos(angleOffsets.Ext1); float coreY = i * cellSize * 2 * Mathf.Sin(angleOffsets.Ext2); coreY += axisOffsets.Ext2 * 2 * Mathf.Floor(i / 2); if (i % 2 == 0) { coreX += axisOffsets.Ext1; coreY += axisOffsets.Ext2; } else { coreY += 2 * axisOffsets.Ext2; } Vector2 coreCoo = new Vector2(coreX, coreY); vertices [i, j] = new RegularCell(coreCoo, cellSize, nbBorders, angleOffsets.Ext1); } } // We define the number and random indexes of the teleporters List <Pair <int> > teleportersIndexes = new List <Pair <int> > (); if (putTeleporters) { // Sets the indexes of the cells with a teleporter and the number of pairs of teleporters int nbTeleporters = Mathf.FloorToInt(nbLines * nbColumns / 40); // Find the right amound of distinct indexes for (int k = 0; k < 2 * nbTeleporters; k++) { Pair <int> p = new Pair <int> (Random.Range(0, nbLines - 1), Random.Range(0, nbColumns - 1)); while (p.OrderedValueExistsIn(teleportersIndexes)) { p = new Pair <int> (Random.Range(0, nbLines - 1), Random.Range(0, nbColumns - 1)); } teleportersIndexes.Add(p); } // Add a teleporter in the data of the corresponding cells for (int k = 0; k < 2 * nbTeleporters; k += 2) { Pair <int> id1 = teleportersIndexes [k]; Pair <int> id2 = teleportersIndexes [k + 1]; vertices [id1.Ext1, id1.Ext2].TeleportCell = vertices [id2.Ext1, id2.Ext2]; vertices [id2.Ext1, id2.Ext2].TeleportCell = vertices [id1.Ext1, id1.Ext2]; Color c = Random.ColorHSV(); vertices [id1.Ext1, id1.Ext2].TeleportColor = c; vertices [id2.Ext1, id2.Ext2].TeleportColor = c; } } // Connexion of cells each other (regardless of the walls) if (nbBorders == 4) { SquareConnections(vertices, nbLines, nbColumns, 4); } else { HexagonConnections(vertices, nbLines, nbColumns, 6); } // The cast to IEnumerable<GraphVertex> doesn't work, that's why I use the ArrayExtension class (cf end of file) return(ArrayExtensions.ToEnumerable <GraphVertex> (vertices)); }