// 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));
    }