// função que seleciona um elemento da tabela periódica // para ser representado na tela public void AtribuiBotao(string btn) { // pega o nome do elemento selecionado btn1 = btn; int indice = BD.Banco(btn, atomos); Atomos atomo = atomos[indice]; // pega o sprite do átomo System.Reflection.FieldInfo campo = this.GetType().GetField(btn); Sprite result = (Sprite)campo.GetValue(this); // atribui o sprite ao plano GameObject card = GameObject.Find("Plano"); card.GetComponent <Renderer>().enabled = true; card.GetComponent <SpriteRenderer>().sprite = result; // gera o modelo (GM*) do átomo nomeAtomo = "atomo_" + atomo.valencia + "e"; GameObject objPrefab = Resources.Load(nomeAtomo) as GameObject; GameObject gm = Instantiate(objPrefab) as GameObject; gm.name = "GMConsulta"; gm.transform.position = new Vector3(315, 803, -450); gm.transform.localScale = new Vector3(500 * (float)atomo.tamanho, 500 * (float)atomo.tamanho, 500 * (float)atomo.tamanho); string cor = atomo.cor; gm.GetComponent <Renderer>().material.color = (Color)typeof(Color).GetProperty(cor.ToLowerInvariant()).GetValue(null, null); // carrega modelo da letra do átomo molecula = true; GameObject letra = Resources.Load(atomo.nome) as GameObject; GameObject GMletra = Instantiate(letra) as GameObject; GMletra.transform.parent = GameObject.Find(gm.name).transform; GMletra.name = "Letra" + atomo.nome; GMletra.transform.localPosition = new Vector3(-(((float)0.5 - (float)atomo.tamanho) * (float)0.25 + (float)0.10), 0, (float)-(GameObject.Find(gm.name).GetComponent <SphereCollider>().radius)); GMletra.transform.localRotation = new Quaternion((float)0, (float)0, (float)0, 0); GMletra.transform.Rotate(0, 180, 0); GMletra.transform.localScale = new Vector3((float)0.03, (float)0.03, (float)0.03); // coloca na tela o botão invisível para mostrar // as informações do átomo GameObject bt = GameObject.Find("btnInfo"); bt.transform.localPosition = new Vector3((float)0, (float)-1500, (float)0); tabela.transform.localPosition = new Vector2(0, 10000); btnLixo.transform.localPosition = new Vector2((float)1.2, 550); }
// função que atribui um elemento da tabela periódica // ao card selecionado public void AtribuiBotao(string btn) { int indice = BD.Banco(btn, atomos); Atomos atm = atomos[indice]; QRs qr = new QRs(atm); qrs.Add(qr); System.Reflection.FieldInfo campo = this.GetType().GetField(btn); Sprite result = (Sprite)campo.GetValue(this); qr.Cadastrar(btn, result); voltar(); tabela.transform.localPosition = new Vector2(0, 10000); }
// construtor da classe, inicializa a lista de atomos public QRs(Atomos atm) { atomo = new List <Atomos>(); atomo.Add(atm); }
public static bool reacao(Atomos[] lista, int tamanho) { int separador = 0; // se existirem dois grupos de elementos if (lista[0].nome != lista[tamanho - 1].nome) { // varre o array e encontra o início do segundo grupo for (separador = 0; ; separador++) { if (!lista[separador].nome.Equals(lista[0].nome)) { break; } } } // separador = inicio do segundo grupo, ou zero se não houver int sucessos = 0; int fracassos = 0; Ligacao[] listaLigacao = new Ligacao[20]; Ligacao novaLigacao = new Ligacao(); // se existirem dois grupos if (separador != 0) { int grupo1_atual = 0; int grupo2_atual = separador; while ((lista[separador - 1].eletronsAtuais != 8 || lista[separador - 1].eletronsAtuais != 2) && (lista[tamanho - 1].eletronsAtuais != 8 || lista[tamanho - 1].eletronsAtuais != 2) && fracassos < 10) { novaLigacao = criarLigacao(lista, grupo1_atual, grupo2_atual); //Debug.Log(novaLigacao.primeiro.eletronsAtuais); //Debug.Log(novaLigacao.segundo.eletronsDisponiveis); if (novaLigacao.tipo != TipoLigacao.ERRO) { listaLigacao[sucessos] = novaLigacao; sucessos++; } else { fracassos++; } // checa se os indices são maiores que seus limites // se sim, retornar ao valor original if ((lista[grupo1_atual].eletronsAtuais == 8 || lista[grupo1_atual].eletronsAtuais == 2) || lista[grupo1_atual].ligado == 2) { ++grupo1_atual; } if (grupo1_atual >= separador) { grupo1_atual = 0; } if ((lista[grupo2_atual].eletronsAtuais == 8 || lista[grupo2_atual].eletronsAtuais == 2) || lista[grupo1_atual].ligado == 2) { ++grupo2_atual; } if (grupo2_atual >= tamanho) { grupo2_atual = separador; } } } // dativa if (separador != 0 && (!lista[0].nome.Equals("H") && !lista[tamanho - 1].nome.Equals("H"))) { // checa a existência de elementos não ligados Atomos[] resto = new Atomos[10]; int indiceResto = 0; for (int i = 0; i < tamanho; i++) { if (lista[i].eletronsAtuais != 8 && lista[i].eletronsAtuais != 2) { resto[indiceResto] = lista[i]; indiceResto++; } } // dativa com o primeiro recebendo if (indiceResto != 0 && ((lista[0].eletroNeg > lista[tamanho - 1].eletroNeg && resto[0].nome == lista[0].nome) || (lista[0].nome.Equals("C") && lista[0].eletronsDisponiveis >= 2))) { int recebeAtual = 0; int daAtual = separador; while ((resto[recebeAtual].ligado == 0 || resto[recebeAtual].eletronsAtuais != 8) && lista[daAtual].eletronsDisponiveis >= 2) { resto[recebeAtual].eletronsAtuais += 2; lista[daAtual].eletronsDisponiveis -= 2; resto[recebeAtual].ligado++; lista[daAtual].ligado++; listaLigacao[sucessos].primeiro = resto[recebeAtual]; listaLigacao[sucessos].segundo = lista[daAtual]; listaLigacao[sucessos].tipo = TipoLigacao.DATIVA; sucessos++; // checa se os indices são maiores que seus limites // se sim, retornar ao valor original if (daAtual < tamanho) { daAtual++; } if (daAtual >= tamanho) { daAtual = separador; } if (recebeAtual < indiceResto) { recebeAtual++; } if (recebeAtual >= indiceResto) { recebeAtual = 0; } } } // dativa com o segundo recebendo if (indiceResto != 0 && ((lista[0].eletroNeg < lista[tamanho - 1].eletroNeg && resto[0].nome == lista[tamanho - 1].nome) || (lista[tamanho - 1].nome.Equals("C") && lista[0].eletronsDisponiveis >= 2))) { int recebeAtual = 0; int daAtual = 0; while ((lista[recebeAtual].ligado == 0 || lista[recebeAtual].eletronsAtuais != 8) && resto[daAtual].eletronsDisponiveis >= 2) { resto[daAtual].eletronsAtuais -= 2; lista[recebeAtual].eletronsDisponiveis += 2; resto[daAtual].ligado++; lista[recebeAtual].ligado++; listaLigacao[sucessos].primeiro = resto[daAtual]; listaLigacao[sucessos].segundo = lista[recebeAtual]; listaLigacao[sucessos].tipo = TipoLigacao.DATIVA; sucessos++; // checa se os indices são maiores que seus limites // se sim, retornar ao valor original if (daAtual < indiceResto) { daAtual++; } if (daAtual >= indiceResto) { daAtual = 0; } if (recebeAtual < separador) { recebeAtual++; } if (recebeAtual >= separador) { recebeAtual = 0; } } } } int grupo = -1; int[] naoBalanceado = new int[4]; naoBalanceado[0] = -1; naoBalanceado[1] = -1; naoBalanceado[2] = -1; naoBalanceado[3] = -1; // se existe apenas um grupo de elementos if (separador == 0) { for (int i = 0, j = 0; i < tamanho; i++) { if (lista[i].eletronsDisponiveis > 0 && lista[i].eletronsAtuais != 8) { grupo = 0; naoBalanceado[j] = i; j++; } } } // se um grupo já está balanceado, varrer ambos os grupos, encontrando // quaisquer elementos não balanceados, e adicionando eles a um array else { int j = 0; for (int i = 0; i < separador; i++) { if (lista[i].eletronsDisponiveis > 0 && lista[i].eletronsAtuais != 8 && lista[i].eletronsAtuais != 2) { grupo = 0; naoBalanceado[j] = i; j++; } } if (grupo == -1) { j = 0; for (int i = separador; i < tamanho; i++) { if (lista[i].eletronsDisponiveis > 0 && lista[i].eletronsAtuais != 8 && lista[i].eletronsAtuais != 2) { grupo = separador; naoBalanceado[j] = i; j++; } } } } // criar uma ligação entre os elementos de mesmo tipo se necessário if (grupo != -1 && naoBalanceado[0] != -1 && naoBalanceado[1] != -1 && lista[naoBalanceado[0]].ligado == 0 && lista[naoBalanceado[1]].ligado == 0) { novaLigacao = criarLigacao(lista, grupo + naoBalanceado[0], grupo + naoBalanceado[1]); if (novaLigacao.tipo != TipoLigacao.ERRO) { listaLigacao[sucessos++] = novaLigacao; } } int numeroUm = separador; int numeroDois = tamanho - separador; int numeroLig = sucessos; int div; for (div = 6; div > 1; div--) { if (separador % div == 0 && (tamanho - separador) % div == 0 && sucessos % div == 0) { numeroUm = numeroUm / div; numeroDois = numeroDois / div; numeroLig = numeroLig / div; break; } } int numeroDativa = 0; for (int i = 0; i < sucessos; i++) { if (listaLigacao[i].tipo == TipoLigacao.DATIVA) { numeroDativa++; } } Ligacao[] listaLigacaoFinal = new Ligacao[20]; int k = 0; for (int i = 0; i < numeroLig - numeroDativa; i++) { listaLigacaoFinal[k] = listaLigacao[i]; k++; } for (int i = numeroLig - numeroDativa; i < numeroLig - (numeroDativa / div); i++) { listaLigacaoFinal[k] = listaLigacao[i]; k++; } for (int i = 0; i < tamanho; i++) { if ((lista[i].eletronsDisponiveis != 0 && lista[i].eletronsAtuais < 8) || lista[i].ligado == 0) { return(false); } } return(true); }
// função repetida todo segundo, que checa se dois ou mais QRs // entraram em colisão para ocorrer a reação private void colisaoupdate() { bool existenoelementosreacao = false; bool podeaddlista = false; // atravessa todos os QRs cadastrados for (int a = 0; a < qrs.Count; a++) { if (qrs[a].card == null) { continue; } // se o QR tem um átomo atrelado a ele else { // se o QR estiver fora de cena, remove da lista if (!qrs[a].card.GetComponent <SpriteRenderer>().enabled) { elementosreacao.Remove("PL" + qrs[a].qrName); continue; } // pega todos os colisores próximos ao QR de indice "a", // num raio definido pelo "Vector3" Collider[] hitColliders = Physics.OverlapBox(qrs[a].card.transform.position, new Vector3((float)90, (float)90, (float)90)); // se o próprio QR for o único elemento da lista, remove-o // pare impedir uma reação desnecessária if (hitColliders.Length == 1) { bool tanalista = false; int b = 0; for (; b < elementosreacao.Count; b++) { if (hitColliders[0].gameObject.name.Equals(elementosreacao[b])) { tanalista = true; break; } } if (tanalista) { elementosreacao.RemoveAt(b); } } // atravessa o array com todos os colisores pegos for (int i = 0; i < hitColliders.Length; i++) { // se o colisor pertencer a um card (PL*) dentro de cena if (hitColliders[i].gameObject.name.Contains("PL") && hitColliders[i].gameObject.activeInHierarchy && qrs[a].card.activeInHierarchy) { // se for o primeiro elemento da lista, // simplesmente adicioná-lo if (elementosreacao.Count == 0) { elementosreacao.Add("PL" + qrs[a].qrName); } // se não for o único elemento, checa se esse QR // já está presente na lista antes de adicioná-lo else { for (int n = 0; n < elementosreacao.Count; n++) { for (int j = 0; j < hitColliders.Length; j++) { if (hitColliders[j].gameObject.name.Contains(elementosreacao[n])) { podeaddlista = true; break; } } if (podeaddlista) { break; } } if (!podeaddlista) { continue; } podeaddlista = false; for (int x = 0; x < elementosreacao.Count; x++) { if (hitColliders[i].gameObject.name.Contains(elementosreacao[x])) { existenoelementosreacao = true; break; } } if (existenoelementosreacao) { existenoelementosreacao = false; continue; } // adiciona elementosreacao.Add(hitColliders[i].gameObject.name); } } } } } // se não houve alteração na lista "elementosreacao", // ou se ela tiver apenas um elemento, retornar if (elementosreacao.Equals(elementosreacaoaux) || elementosreacao.Count == 1) { return; } else { // inicializa a lista dos átomos atomosdareacao = new List <Atomos>(); // pega os objetos (cards) identificados pelos nomes // na lista "elementosreacao" for (int b = 0; b < elementosreacao.Count; b++) { for (int n = 0; n < qrs.Count; n++) { if (qrs[n].card.name.Contains(elementosreacao[b])) { // cada átomo guardado no objeto de um QR // que participa da reação é colocado em um novo objeto // e salvo na lista "atomosdareacao" for (int j = 0; j < qrs[n].atomo.Count; j++) { Atomos novoAtomo = new Atomos(); novoAtomo.nome = qrs[n].atomo[j].nome; novoAtomo.cor = qrs[n].atomo[j].cor; novoAtomo.tamanho = qrs[n].atomo[j].tamanho; novoAtomo.valencia = qrs[n].atomo[j].valencia; novoAtomo.nox = qrs[n].atomo[j].nox; novoAtomo.tipo = qrs[n].atomo[j].tipo; novoAtomo.eletroNeg = qrs[n].atomo[j].eletroNeg; novoAtomo.eletronsAtuais = qrs[n].atomo[j].valencia; novoAtomo.eletronsDisponiveis = qrs[n].atomo[j].valencia; atomosdareacao.Add(novoAtomo); } } } } // se não houverem ao menos dois átomos para reagir, retornar if (atomosdareacao.Count <= 1) { return; } bool fazreacao = true; // checa se existem no máximo dois tipos // de atomos diferentes para a reação string atomo1 = "", atomo2 = ""; for (int a = 0; a < atomosdareacao.Count; a++) { if (a == 0) { atomo1 = atomosdareacao[0].nome; } else if (!atomosdareacao[a].nome.Equals(atomo1)) { if (atomo2.Equals("")) { atomo2 = atomosdareacao[a].nome; } else if (!atomosdareacao[a].nome.Equals(atomo2)) { fazreacao = false; } } } // array equivalente à lista "atomosdareacao" Atomos[] atomosreaction; // se houverem apenas dois tipos de átomo, // executar a reação if (fazreacao) { // organiza a "atomosdareacao" em ordem alfabética // e a converte em array atomosdareacao.Sort((x, y) => string.Compare(x.nome, y.nome, System.StringComparison.Ordinal)); atomosreaction = atomosdareacao.ToArray(); // executa a reação bool reagiu = ReacaoQuimica.reacao(atomosreaction, atomosdareacao.Count); // se a reação for bem sucedida if (reagiu) { int diferenca = 0; string eleanterior = ""; nomeproduto = ""; // guarda os membros do "atomosdareacao" // na string "nomeproduto" (em ordem alfabética) for (int i = 0; i < atomosdareacao.Count; i++) { nomeproduto = nomeproduto + atomosdareacao[i].nome; } QRs final = qrs.Find(x => elementosreacao[0].Contains(x.qrName)); novocard = elementosreacao[0]; elementosreacao.RemoveAt(0); List <int> indexremover = new List <int>(); // indica quais QRs serão limpos for (int a = 0; a < qrs.Count; a++) { for (int b = 0; b < elementosreacao.Count; b++) { if (qrs[a].qrName != null && elementosreacao[b].Contains(qrs[a].qrName)) { for (int m = 0; m < qrs[a].atomo.Count; m++) { qrs.Find(x => novocard.Contains(x.qrName)).atomo.Add(qrs[a].atomo[m]); } indexremover.Add(a); } } } // organiza os QRs a limpar indexremover.Sort(); // limpa os QRs for (int i = indexremover.Count - 1; i >= 0; i--) { // indica que o QR pode ser usado para uma nova reação GameObject qrLivreReacao = GameObject.Find("IT" + qrs[indexremover[i]].qrName); qrLivreReacao.GetComponent <DefaultTrackableEventHandler>().qrlivre = true; // corrige os filhos de cada QR foreach (Transform child in GameObject.Find("IT" + qrs[indexremover[i]].qrName).transform) { // apaga o modelo e o botão invisível if (child.gameObject.name.Contains("GM") || child.gameObject.name.Equals("botao")) { Destroy(child.gameObject); } // limpa o texto e o sprite else if (child.gameObject.name.Contains("PL")) { GameObject.Find(child.gameObject.name).GetComponent <SpriteRenderer>().sprite = null; GameObject.Find(child.gameObject.name).GetComponentInChildren <TextMeshPro>().text = ""; } } // remove da lista de QRs cadastrados qrs.RemoveAt(indexremover[i]); } // limpa a lista e adiciona o QR do produto a ela elementosreacao.Clear(); elementosreacao.Add(novocard); nomeproduto = nomeproduto.ToUpper(); // carrega o modelo da molécula if (produto = Resources.Load("GM" + nomeproduto) as GameObject) { // apaga o modelo (GM*) e o botão do card foreach (Transform child in GameObject.Find("IT" + novocard.Remove(0, 2)).transform) { if (child.gameObject.name.Contains("GM")) { Destroy(child.gameObject); } if (child.gameObject.name.Contains("botao")) { Destroy(child.gameObject); } if (child.gameObject.name.Contains("RP")) { Destroy(child.gameObject); } } // instancia o modelo da molécula como filho // do QR e corrige sua posição qrs.Find(x => novocard.Contains(x.qrName)).gm = produto; GameObject gm = Instantiate(produto) as GameObject; gm.name = "GM" + nomeproduto; gm.transform.parent = GameObject.Find("IT" + novocard.Remove(0, 2)).transform; gm.transform.localPosition = new Vector3(0, 1, 0); gm.transform.localScale = new Vector3((float)1, (float)1, (float)1); // carrega o sprite com o nome do elemento // em cima do QR System.Reflection.FieldInfo campo = this.GetType().GetField("PL" + nomeproduto); Sprite result = (Sprite)campo.GetValue(this); GameObject.Find(novocard).GetComponent <SpriteRenderer>().sprite = result; GameObject.Find(novocard).transform.localScale = new Vector3((float)0.15, (float)0.15, (float)0.15); qrs.Find(x => novocard.Contains(x.qrName)).card = GameObject.Find(novocard); // carrega a representação gráfica da molécula // e a mostra temporáriamente if (GameObject.Find("RP" + nomeproduto) == null) { if (representacao = Resources.Load("RP" + nomeproduto) as GameObject) { StartCoroutine("Wait"); } } // cria um botão invisível para registrar // o clique que abre o cartão com informações // da molécula GameObject botao = new GameObject(); botao.name = "botao"; botao.transform.parent = gm.transform.parent; botao.transform.rotation = new Quaternion(0, 0, 0, 0); botao.transform.localRotation = new Quaternion(0, 0, 0, 0); botao.transform.localPosition = new Vector3(0, (float)0.3, 0); botao.transform.localScale = new Vector3(1, 1, 1); botao.AddComponent <InfoElemento>(); BoxCollider botaoCollider = botao.AddComponent <BoxCollider>(); botaoCollider.size = new Vector3(1, (float)0.4, 1); } // se não houver uma representação gráfica da molécula else { Wait3(3); string ultimo = ""; if (atomosdareacao[0].eletroNeg > atomosdareacao[diferenca].eletroNeg) { int val = atomosdareacao.Count - diferenca; ultimo = atomosdareacao[diferenca].nome + val + atomosdareacao[0].nome + diferenca; } else if (atomosdareacao[0].eletroNeg < atomosdareacao[diferenca].eletroNeg) { int val = atomosdareacao.Count - diferenca; ultimo = atomosdareacao[0].nome + diferenca + atomosdareacao[diferenca].nome + val; } else if (diferenca == 0) { ultimo = atomosdareacao[0].nome + atomosdareacao.Count; } foreach (Transform child in GameObject.Find("IT" + novocard.Remove(0, 2)).transform) { if (child.gameObject.name.Contains("GM")) { Destroy(child.gameObject); break; } } // cria card genérico System.Reflection.FieldInfo camp = this.GetType().GetField("cardlaranja"); Sprite cardorange = (Sprite)camp.GetValue(this); GameObject.Find(novocard).GetComponent <SpriteRenderer>().sprite = cardorange; GameObject.Find(novocard).transform.localScale = new Vector3((float)0.15, (float)0.15, (float)0.15); qrs.Find(x => novocard.Contains(x.qrName)).card = GameObject.Find(novocard); // escreve o nome da molécula acima do card criado foreach (Transform child in GameObject.Find(novocard).transform) { if (child.gameObject.name.Contains("Text")) { child.gameObject.GetComponent <TextMeshPro>().text = ultimo; return; } } } } else { // se não reagiu naoReage.transform.localPosition = new Vector2(0, 0); } } } }