IEnumerator GeraPorDivisaoEConquistaVariavel(Celula pivot, int maximoComprimento, int maximoAltura, bool vertical)
    {
        int myId = coroutineId++;

        coroutinesIds.Add(myId);

        Transform fundoPivot = pivot.gameObject.transform.GetChild(1);

        fundoPivot.gameObject.GetComponent <MeshRenderer>().material.color = Color.cyan;

        Celula pivotAux = pivot;

        int novoMaximoComprimento = maximoComprimento;
        int novoMaximoAltura      = maximoAltura;

        vertical = maximoComprimento > maximoAltura;
        Transform fundo;

        //Posicionamento central do pivot
        if (vertical)                                                  //se o corte for vertical
        {
            if (maximoComprimento > 0)                                 // se o pivot puder andar pra direita
            {
                novoMaximoComprimento = r.Next(maximoComprimento - 1); //escolhe um numero aleatório
                for (int i = 1; i <= novoMaximoComprimento; i++)       //anda pra direita até o numero aleatorio
                {
                    pivotAux = pivotAux.vizinhoDireito();
                }

                for (int j = 0; j <= maximoAltura; j++)
                {
                    foreach (Parede p in pivotAux.paredes)
                    {
                        if (p.direcao == 1)
                        {
                            p.gameObject.SetActive(true);
                            foreach (Parede p2 in pivotAux.vizinhoDireito().paredes)
                            {
                                if (p2.direcao == 3)
                                {
                                    p2.gameObject.SetActive(true);
                                    Celula x = pivotAux.vizinhoAbaixo();
                                    if (j == maximoAltura)
                                    {
                                        break;
                                    }

                                    fundo = pivotAux.gameObject.transform.GetChild(1);
                                    fundo.gameObject.GetComponent <MeshRenderer>().material.color = Color.white;

                                    fundo = pivotAux.vizinhoDireito().gameObject.transform.GetChild(1);
                                    fundo.gameObject.GetComponent <MeshRenderer>().material.color = Color.white;

                                    pivotAux = x;
                                    fundo    = pivotAux.gameObject.transform.GetChild(1);
                                    fundo.gameObject.GetComponent <MeshRenderer>().material.color = Color.red;
                                    break;
                                }
                            }
                            break;
                        }
                    }
                    if (!instantaneo)
                    {
                        yield return(new WaitForSeconds(velocidade));
                    }
                }


                int       abertura = r.Next(0, maximoAltura + 1);
                Transform fundox   = pivotAux.vizinhoDireito().gameObject.transform.GetChild(1);
                fundox.gameObject.GetComponent <MeshRenderer>().material.color = Color.white;

                for (int j = 0; j < maximoAltura; j++)
                {
                    if (j == abertura)
                    {
                        pivotAux.removeParedesEntre(pivotAux.vizinhoDireito());
                    }
                    fundo = pivotAux.gameObject.transform.GetChild(1);
                    fundo.gameObject.GetComponent <MeshRenderer>().material.color = Color.white;
                    pivotAux = pivotAux.vizinhoAcima();
                    fundo    = pivotAux.gameObject.transform.GetChild(1);
                    fundo.gameObject.GetComponent <MeshRenderer>().material.color = Color.red;
                    if (!instantaneo)
                    {
                        yield return(new WaitForSeconds(velocidade));
                    }
                }
                if (abertura == maximoAltura)
                {
                    pivotAux.removeParedesEntre(pivotAux.vizinhoDireito());
                }


                fundoPivot = pivotAux.gameObject.transform.GetChild(1);
                fundoPivot.gameObject.GetComponent <MeshRenderer>().material.color = Color.white;
                pivotAux   = pivotAux.vizinhoDireito();
                fundoPivot = pivotAux.gameObject.transform.GetChild(1);
                fundoPivot.gameObject.GetComponent <MeshRenderer>().material.color = Color.cyan;
                if (maximoComprimento > 0)
                {
                    int par1;
                    int par2;
                    int par3;
                    int par4;

                    par1 = novoMaximoComprimento;
                    par2 = maximoAltura;
                    par3 = maximoComprimento - 1 - novoMaximoComprimento;
                    par4 = maximoAltura;

                    if (!instantaneo)
                    {
                        if (!paralelo)
                        {
                            yield return(StartCoroutine(GeraPorDivisaoEConquistaVariavel(pivot, par1, par2, !vertical)));

                            yield return(StartCoroutine(GeraPorDivisaoEConquistaVariavel(pivotAux, par3, par4, !vertical)));
                        }
                        else
                        {
                            StartCoroutine(GeraPorDivisaoEConquistaVariavel(pivot, par1, par2, !vertical));
                            yield return(StartCoroutine(GeraPorDivisaoEConquistaVariavel(pivotAux, par3, par4, !vertical)));
                        }
                    }
                    else
                    {
                        StartCoroutine(GeraPorDivisaoEConquistaVariavel(pivot, par1, par2, !vertical));
                        StartCoroutine(GeraPorDivisaoEConquistaVariavel(pivotAux, par3, par4, !vertical));
                    }
                }
            }
            else
            {
                fundoPivot = pivot.gameObject.transform.GetChild(1);
                fundoPivot.gameObject.GetComponent <MeshRenderer>().material.color = Color.white;
            }
        }
        else                      //se o corte for horizontal
        {
            if (maximoAltura > 0) // se o pivot puder andar pra baixo
            {
                novoMaximoAltura = r.Next(maximoAltura - 1);
                for (int i = 1; i <= novoMaximoAltura; i++)   //anda pra baixo até a metade
                {
                    pivotAux = pivotAux.vizinhoAbaixo();
                }

                for (int j = 0; j <= maximoComprimento; j++)
                {
                    foreach (Parede p in pivotAux.paredes)
                    {
                        if (p.direcao == 2)
                        {
                            p.gameObject.SetActive(true);
                            foreach (Parede p2 in pivotAux.vizinhoAbaixo().paredes)
                            {
                                if (p2.direcao == 0)
                                {
                                    p2.gameObject.SetActive(true);
                                    Celula x = pivotAux.vizinhoDireito();
                                    if (j == maximoComprimento)
                                    {
                                        break;
                                    }

                                    fundo = pivotAux.gameObject.transform.GetChild(1);
                                    fundo.gameObject.GetComponent <MeshRenderer>().material.color = Color.white;

                                    fundo = pivotAux.vizinhoAbaixo().gameObject.transform.GetChild(1);
                                    fundo.gameObject.GetComponent <MeshRenderer>().material.color = Color.white;

                                    pivotAux = x;
                                    fundo    = pivotAux.gameObject.transform.GetChild(1);
                                    fundo.gameObject.GetComponent <MeshRenderer>().material.color = Color.red;
                                    break;
                                }
                            }
                            break;
                        }
                    }
                    if (!instantaneo)
                    {
                        yield return(new WaitForSeconds(velocidade));
                    }
                }


                int       abertura = r.Next(0, maximoComprimento + 1);
                Transform fundox   = pivotAux.vizinhoAbaixo().gameObject.transform.GetChild(1);
                fundox.gameObject.GetComponent <MeshRenderer>().material.color = Color.white;
                for (int j = 0; j < maximoComprimento; j++)
                {
                    if (j == abertura)
                    {
                        pivotAux.removeParedesEntre(pivotAux.vizinhoAbaixo());
                    }
                    fundo = pivotAux.gameObject.transform.GetChild(1);
                    fundo.gameObject.GetComponent <MeshRenderer>().material.color = Color.white;
                    pivotAux = pivotAux.vizinhoEsquerdo();
                    fundo    = pivotAux.gameObject.transform.GetChild(1);
                    fundo.gameObject.GetComponent <MeshRenderer>().material.color = Color.red;
                    if (!instantaneo)
                    {
                        yield return(new WaitForSeconds(velocidade));
                    }
                }
                if (abertura == maximoComprimento)
                {
                    pivotAux.removeParedesEntre(pivotAux.vizinhoAbaixo());
                }


                fundoPivot = pivotAux.gameObject.transform.GetChild(1);
                fundoPivot.gameObject.GetComponent <MeshRenderer>().material.color = Color.white;
                pivotAux   = pivotAux.vizinhoAbaixo();
                fundoPivot = pivotAux.gameObject.transform.GetChild(1);
                fundoPivot.gameObject.GetComponent <MeshRenderer>().material.color = Color.cyan;
                if (maximoAltura > 0)
                {
                    int par1;
                    int par2;
                    int par3;
                    int par4;


                    par1 = maximoComprimento;
                    par2 = novoMaximoAltura;
                    par3 = maximoComprimento;
                    par4 = maximoAltura - 1 - novoMaximoAltura;

                    if (!instantaneo)
                    {
                        if (!paralelo)
                        {
                            yield return(StartCoroutine(GeraPorDivisaoEConquistaVariavel(pivot, par1, par2, !vertical)));

                            yield return(StartCoroutine(GeraPorDivisaoEConquistaVariavel(pivotAux, par3, par4, !vertical)));
                        }
                        else
                        {
                            StartCoroutine(GeraPorDivisaoEConquistaVariavel(pivot, par1, par2, !vertical));
                            yield return(StartCoroutine(GeraPorDivisaoEConquistaVariavel(pivotAux, par3, par4, !vertical)));
                        }
                    }
                    else
                    {
                        StartCoroutine(GeraPorDivisaoEConquistaVariavel(pivot, par1, par2, !vertical));
                        StartCoroutine(GeraPorDivisaoEConquistaVariavel(pivotAux, par3, par4, !vertical));
                    }
                }
            }
            else
            {
                fundoPivot = pivot.gameObject.transform.GetChild(1);
                fundoPivot.gameObject.GetComponent <MeshRenderer>().material.color = Color.white;
                yield return(null);
            }
        }

        coroutinesIds.Remove(myId);

        yield return(null);
    }
    IEnumerator GeraPorDivisaoEConquistaConstante(Celula pivot, int maximoComprimento, int maximoAltura, bool vertical)
    {
        int myId = coroutineId++;

        coroutinesIds.Add(myId);

        Transform fundoPivot = pivot.gameObject.transform.GetChild(1);

        fundoPivot.gameObject.GetComponent <MeshRenderer>().material.color = Color.cyan;

        Celula    pivotAux = pivot;
        Transform fundo;
        int       novoMaximoComprimento = maximoComprimento;
        int       novoMaximoAltura      = maximoAltura;

        vertical = maximoComprimento > maximoAltura;
        //Posicionamento central do pivot
        if (vertical)                  //se o corte for vertical
        {
            if (maximoComprimento > 0) // se o pivot puder andar pra direita
            {
                novoMaximoComprimento = maximoComprimento / 2;
                for (int i = 1; i <= maximoComprimento / 2; i++)   //anda pra direita até a metade
                {
                    pivotAux = pivotAux.vizinhoDireito();
                }
                if (maximoComprimento > 0 && maximoComprimento % 2 == 0 && r.NextDouble() > 0.5)  //se for par, tem que decidir qual faixa do meio
                {
                    novoMaximoComprimento -= 1;
                    pivotAux = pivotAux.vizinhoEsquerdo();
                }

                for (int j = 0; j <= maximoAltura; j++)
                {
                    foreach (Parede p in pivotAux.paredes)
                    {
                        if (p.direcao == 1)
                        {
                            p.gameObject.SetActive(true);
                            foreach (Parede p2 in pivotAux.vizinhoDireito().paredes)
                            {
                                if (p2.direcao == 3)
                                {
                                    p2.gameObject.SetActive(true);
                                    Celula x = pivotAux.vizinhoAbaixo();
                                    if (j == maximoAltura)
                                    {
                                        break;
                                    }

                                    fundo = pivotAux.gameObject.transform.GetChild(1);
                                    fundo.gameObject.GetComponent <MeshRenderer>().material.color = Color.white;

                                    fundo = pivotAux.vizinhoDireito().gameObject.transform.GetChild(1);
                                    fundo.gameObject.GetComponent <MeshRenderer>().material.color = Color.white;

                                    pivotAux = x;
                                    fundo    = pivotAux.gameObject.transform.GetChild(1);
                                    fundo.gameObject.GetComponent <MeshRenderer>().material.color = Color.red;
                                    break;
                                }
                            }
                            break;
                        }
                    }
                    if (!instantaneo)
                    {
                        yield return(new WaitForSeconds(velocidade));
                    }
                }


                int abertura = r.Next(0, maximoAltura + 1);
                fundo = pivotAux.vizinhoDireito().gameObject.transform.GetChild(1);
                fundo.gameObject.GetComponent <MeshRenderer>().material.color = Color.white;
                for (int j = 0; j < maximoAltura; j++)
                {
                    if (j == abertura)
                    {
                        pivotAux.removeParedesEntre(pivotAux.vizinhoDireito());
                    }
                    fundo = pivotAux.gameObject.transform.GetChild(1);
                    fundo.gameObject.GetComponent <MeshRenderer>().material.color = Color.white;
                    pivotAux = pivotAux.vizinhoAcima();
                    fundo    = pivotAux.gameObject.transform.GetChild(1);
                    fundo.gameObject.GetComponent <MeshRenderer>().material.color = Color.red;
                    if (!instantaneo)
                    {
                        yield return(new WaitForSeconds(velocidade));
                    }
                }
                if (abertura == maximoAltura)
                {
                    pivotAux.removeParedesEntre(pivotAux.vizinhoDireito());
                }


                fundoPivot = pivotAux.gameObject.transform.GetChild(1);
                fundoPivot.gameObject.GetComponent <MeshRenderer>().material.color = Color.white;
                pivotAux   = pivotAux.vizinhoDireito();
                fundoPivot = pivotAux.gameObject.transform.GetChild(1);
                fundoPivot.gameObject.GetComponent <MeshRenderer>().material.color = Color.cyan;
                if (maximoComprimento > 0)
                {
                    int par1;
                    int par2;
                    int par3;
                    int par4;

                    if (maximoComprimento % 2 != 0)  //se for ímpar,manda recursivo simplesmente pela metade
                    {
                        par1 = novoMaximoComprimento;
                        par2 = novoMaximoAltura;
                        par3 = novoMaximoComprimento;
                        par4 = novoMaximoAltura;
                    }
                    else     // se for par, ver se ele foi pra esquerda
                    {
                        if (novoMaximoComprimento == maximoComprimento / 2)
                        {
                            par1 = novoMaximoComprimento;
                            par2 = novoMaximoAltura;
                            par3 = novoMaximoComprimento - 1;
                            par4 = novoMaximoAltura;
                        }
                        else
                        {
                            par1 = novoMaximoComprimento;
                            par2 = novoMaximoAltura;
                            par3 = novoMaximoComprimento + 1;
                            par4 = novoMaximoAltura;
                        }
                    }
                    if (!instantaneo)
                    {
                        if (!paralelo)
                        {
                            yield return(StartCoroutine(GeraPorDivisaoEConquistaConstante(pivot, par1, par2, !vertical)));

                            yield return(StartCoroutine(GeraPorDivisaoEConquistaConstante(pivotAux, par3, par4, !vertical)));
                        }
                        else
                        {
                            StartCoroutine(GeraPorDivisaoEConquistaConstante(pivot, par1, par2, !vertical));
                            yield return(StartCoroutine(GeraPorDivisaoEConquistaConstante(pivotAux, par3, par4, !vertical)));
                        }
                    }
                    else
                    {
                        StartCoroutine(GeraPorDivisaoEConquistaConstante(pivot, par1, par2, !vertical));
                        StartCoroutine(GeraPorDivisaoEConquistaConstante(pivotAux, par3, par4, !vertical));
                    }
                }
            }
            else
            {
                fundoPivot = pivot.gameObject.transform.GetChild(1);
                fundoPivot.gameObject.GetComponent <MeshRenderer>().material.color = Color.white;
            }
        }
        else                      //se o corte for horizontal
        {
            if (maximoAltura > 0) // se o pivot puder andar pra baixo
            {
                novoMaximoAltura = maximoAltura / 2;
                for (int i = 1; i <= maximoAltura / 2; i++)   //anda pra baixo até a metade
                {
                    pivotAux = pivotAux.vizinhoAbaixo();
                }
                if (maximoAltura > 0 && maximoAltura % 2 == 0 && r.NextDouble() > 0.5)  //se for par, tem que decidir qual faixa do meio
                {
                    pivotAux          = pivotAux.vizinhoAcima();
                    novoMaximoAltura -= 1;
                }

                for (int j = 0; j <= maximoComprimento; j++)
                {
                    foreach (Parede p in pivotAux.paredes)
                    {
                        if (p.direcao == 2)
                        {
                            p.gameObject.SetActive(true);
                            foreach (Parede p2 in pivotAux.vizinhoAbaixo().paredes)
                            {
                                if (p2.direcao == 0)
                                {
                                    p2.gameObject.SetActive(true);
                                    Celula x = pivotAux.vizinhoDireito();
                                    if (j == maximoComprimento)
                                    {
                                        break;
                                    }

                                    fundo = pivotAux.gameObject.transform.GetChild(1);
                                    fundo.gameObject.GetComponent <MeshRenderer>().material.color = Color.white;

                                    fundo = pivotAux.vizinhoAbaixo().gameObject.transform.GetChild(1);
                                    fundo.gameObject.GetComponent <MeshRenderer>().material.color = Color.white;

                                    pivotAux = x;
                                    fundo    = pivotAux.gameObject.transform.GetChild(1);
                                    fundo.gameObject.GetComponent <MeshRenderer>().material.color = Color.red;
                                    break;
                                }
                            }
                            break;
                        }
                    }
                    if (!instantaneo)
                    {
                        yield return(new WaitForSeconds(velocidade));
                    }
                }


                int abertura = r.Next(0, maximoComprimento + 1);
                fundo = pivotAux.vizinhoAbaixo().gameObject.transform.GetChild(1);
                fundo.gameObject.GetComponent <MeshRenderer>().material.color = Color.white;
                for (int j = 0; j < maximoComprimento; j++)
                {
                    if (j == abertura)
                    {
                        pivotAux.removeParedesEntre(pivotAux.vizinhoAbaixo());
                    }
                    fundo = pivotAux.gameObject.transform.GetChild(1);
                    fundo.gameObject.GetComponent <MeshRenderer>().material.color = Color.white;
                    pivotAux = pivotAux.vizinhoEsquerdo();
                    fundo    = pivotAux.gameObject.transform.GetChild(1);
                    fundo.gameObject.GetComponent <MeshRenderer>().material.color = Color.red;
                    if (!instantaneo)
                    {
                        yield return(new WaitForSeconds(velocidade));
                    }
                }
                if (abertura == maximoComprimento)
                {
                    pivotAux.removeParedesEntre(pivotAux.vizinhoAbaixo());
                }


                fundoPivot = pivotAux.gameObject.transform.GetChild(1);
                fundoPivot.gameObject.GetComponent <MeshRenderer>().material.color = Color.white;
                pivotAux   = pivotAux.vizinhoAbaixo();
                fundoPivot = pivotAux.gameObject.transform.GetChild(1);
                fundoPivot.gameObject.GetComponent <MeshRenderer>().material.color = Color.cyan;
                if (maximoAltura > 0)
                {
                    int par1;
                    int par2;
                    int par3;
                    int par4;

                    if (maximoAltura % 2 != 0)  //se for ímpar,manda recursivo simplesmente pela metade
                    {
                        par1 = novoMaximoComprimento;
                        par2 = novoMaximoAltura;
                        par3 = novoMaximoComprimento;
                        par4 = novoMaximoAltura;
                    }
                    else     // se for par, ver se ele foi pra esquerda
                    {
                        if (novoMaximoAltura == maximoAltura / 2)
                        {
                            par1 = novoMaximoComprimento;
                            par2 = novoMaximoAltura;
                            par3 = novoMaximoComprimento;
                            par4 = novoMaximoAltura - 1;
                        }
                        else
                        {
                            par1 = novoMaximoComprimento;
                            par2 = novoMaximoAltura;
                            par3 = novoMaximoComprimento;
                            par4 = novoMaximoAltura + 1;
                        }
                    }
                    if (!instantaneo)
                    {
                        if (!paralelo)
                        {
                            yield return(StartCoroutine(GeraPorDivisaoEConquistaConstante(pivot, par1, par2, !vertical)));

                            yield return(StartCoroutine(GeraPorDivisaoEConquistaConstante(pivotAux, par3, par4, !vertical)));
                        }
                        else
                        {
                            StartCoroutine(GeraPorDivisaoEConquistaConstante(pivot, par1, par2, !vertical));
                            yield return(StartCoroutine(GeraPorDivisaoEConquistaConstante(pivotAux, par3, par4, !vertical)));
                        }
                    }
                    else
                    {
                        StartCoroutine(GeraPorDivisaoEConquistaConstante(pivot, par1, par2, !vertical));
                        StartCoroutine(GeraPorDivisaoEConquistaConstante(pivotAux, par3, par4, !vertical));
                    }
                }
            }
            else
            {
                fundoPivot = pivot.gameObject.transform.GetChild(1);
                fundoPivot.gameObject.GetComponent <MeshRenderer>().material.color = Color.white;
            }
        }


        coroutinesIds.Remove(myId);
        yield return(null);
    }