EDITOR E GERADOR DE PLANTAS DE CASA RELATÓRIO FINAL Inteligência Artificial: Editor e Gerador de Plantas de Casa Ana Santos Cristina Perfeito Faculdade de Engenharia da Universidade do Porto Departamento de Engenharia Electrotécnica e de Computadores Rua Roberto Frias, s/n, 4200-465 Porto, Portugal Junho de 2003 EDITOR E GERADOR DE PLANTAS DE CASA RELATÓRIO FINAL Inteligência Artificial: Editor e Gerador de Plantas de Casa Ana Santos Cristina Perfeito Alunas da Licenciatura de Engenharia Informática e Computação Pela Faculdade de Engenharia da Universidade do Porto Trabalho realizado no âmbito da disciplina de Inteligência Artificial, do 2.º semestre, do 3.º ano, da Licenciatura em Engenharia Informática e Computação da Faculdade de Engenharia da Universidade do Porto, leccionada por: - Eugénio Oliveira [email protected] - Rui Ferreira da Silva [email protected] Faculdade de Engenharia da Universidade do Porto Departamento de Engenharia Electrotécnica e de Computadores Rua Roberto Frias, s/n, 4200-465 Porto, Portugal Junho de 2003 2 EDITOR E GERADOR DE PLANTAS DE CASA RELATÓRIO FINAL Resumo Este relatório visa documentar um projecto para a disciplina de Inteligência Artificial, que consiste na implementação de um editor e gerador de plantas de casa. A implementação deste projecto será feita em duas partes. O módulo lógico será implementado em Prolog e o módulo gráfico em Java. Neste relatório faremos referência de forma pormenorizada aos dois módulos. Começamos por explicar o objectivo e a motivação para este trabalho. Depois descrevemos as funcionalidades, a estrutura do relatório, os esquemas de representação e conhecimento, a implementação dos esquemas de representação de conhecimento e analisamos a complexidade dos algoritmos utilizados. Descrevemos o ambiente de desenvolvimento usado e fazemos uma avaliação do programa conseguido. Para finalizar explicamos alguns resultados experimentais, dizemos quais as nossas conclusões depois de chegadas ao fim do projecto e apontamos possíveis melhoramentos que achamos importantes. Como conclusão, neste documento daremos uma visão geral de todo o desenvolvimento do projecto. 3 EDITOR E GERADOR DE PLANTAS DE CASA RELATÓRIO FINAL Aos Nossos Pais, pelo apoio e pela compreensão que nos têm dado. Aos Nossos Amigos, com quem sabemos que podemos sempre contar. Aos Nossos Colegas da Faculdade, companheiros de sonhos e de luta. 4 EDITOR E GERADOR DE PLANTAS DE CASA RELATÓRIO FINAL Agradecimentos Os nossos agradecimentos ás nossas famílias pela compreensão que têm tido e por nos terem dado as condições necessárias para realizar este trabalho; à Faculdade de Engenharia da Universidade do Porto por nos ter facultado as condições necessárias para a realização deste trabalho e ao Departamento de Engenharia Electrotécnica e de Computadores pelo excelente ambiente proporcionado; e por fim ao professor Eugénio de Oliveira pelo apoio concedido. De uma forma geral, um obrigado, a todos os que nos apoiaram no desenrolar deste trabalho. 5 EDITOR E GERADOR DE PLANTAS DE CASA RELATÓRIO FINAL Índice 1. Objectivo 9 2. Motivação 10 3. Descrição 11 4. Ambiente de Desenvolvimento 17 5. Avaliação do programa 18 6. Conclusão 19 7. Melhoramentos 20 Apêndices 22 Nome dos elementos do grupo 57 6 EDITOR E GERADOR DE PLANTAS DE CASA RELATÓRIO FINAL Lista de Figuras Fig 1: Janela Inicial do Gerador de Plantas……………………………………………24 Fig 2: Janela Principal do Gerador de Plantas…………………………………………...…….25 Fig 3: Menu das especificações……………………………………………………….26 Fig 4: Tipo de Casa………………………………………………………………….…………26 Fig 5: Desenho de uma planta de uma casa……………………………….…………..27 Fig 6: Menu de definições……………………………………………………..………28 Fig 7: Desenho das plantas…………………………………………...………………..28 7 EDITOR E GERADOR DE PLANTAS DE CASA RELATÓRIO FINAL Lista de Tabelas Tabela 1: Descrição das divisões que compõem cada tipo de casa Tabela 2: Descrição dos diferentes tipos de casas 8 EDITOR E GERADOR DE PLANTAS DE CASA RELATÓRIO FINAL Capítulo 1 1. Objectivo O objectivo deste trabalho é o de implementar um editor e gerador de plantas de casa, ou seja, fazer uma aplicação que determine as configurações possíveis de plantas de uma casa tendo em atenção as especificações que o utilizador indicar e também as especificações internas à aplicação que serão definidas por nós e explicadas mais à frente neste relatório. Esta aplicação terá de ter uma interface, desenvolvida em Java, na qual o utilizador fará as suas escolhas, relativamente ao tipo de casa que pretende, e depois nessa mesma interface serão ilustradas as diferentes configurações possíveis para plantas de uma casa, respeitando as especificações do utilizador, que foram encontradas pelo modulo lógico em Prolog . 9 EDITOR E GERADOR DE PLANTAS DE CASA RELATÓRIO FINAL Capítulo 2 2. Motivação A principal motivação para a realização deste trabalho prendeu-se com o facto deste projecto ter uma aplicação prática muito importante. Logo esta é uma aplicação que não é meramente académica e poderá vir a fazer parte de software de apoio a arquitectos sendo que para isso teria de ter especificações internas que respeitem regras arquitectónicas o que não foi uma prioridade do grupo de trabalho. Outro ponto de interesse para a realização deste projecto foi a inexistência de um algoritmo capaz de dar resposta ao nosso problema, assim foi necessário o cruzamento de um conjunto de conhecimentos para apresentar as várias configurações para cada problema, o que apesar de trazer uma dificuldades acrescentada ao trabalho, vem também servir de motivação para se chegar a uma solução . A principal motivação é sem duvida o facto deste trabalho ter um peso considerável na nota final, já que representa 50% da nota da cadeira. 10 EDITOR E GERADOR DE PLANTAS DE CASA RELATÓRIO FINAL Capítulo 3 3. Descrição Este é um projecto algo complexo principalmente no que respeita a sua primeira fase que envolve a reflexão do problema. Assim este grupo de trabalho começou por pensar muito bem no que pretendia da aplicação e na forma de alcançar os objectivos pretendidos. A fase seguinte foi a de definir as restrições internas associadas à aplicação, fase esta que se prolongou até à conclusão do trabalho já que só na implementação do código propriamente dita é que nos apercebemos de algumas especificações necessárias. Por fim passamos à fase da implementação do módulo lógico do programa em Prolog, que foi a fase mais demorada de todo o projecto. Para a conclusão da aplicação fizemos a interface gráfica que apesar de ser opcional decidimos fazer por acharmos que é muito importante para a compreensão imediata dos resultados obtidos. A interface gráfica foi implementada em Java. 11 EDITOR E GERADOR DE PLANTAS DE CASA RELATÓRIO FINAL Módulo de Prolog Definimos que na interface que comunica com o utilizador lhe será pedido, o tipo de casa que pretende e também a área mínima e máxima da planta. Consoante o tipo de casa que o utilizador escolheu, temos já predefinido o conjunto de divisões que irá compor a casa, tal como é apresentado na tabela que se segue. Tipo de Casa Divisões T1 [quarto1,cozinha, casabanho1 ,sala] T2 [quarto1, quarto2, cozinha, casabanho1, sala] T3 [[quarto1,casabanho1], quarto2, quarto3,cozinha,casabanho2, sala] T4 [[quarto1,casabanho1],[quarto2,casabanho2],quarto3,quarto4,[cozinha, sala1],sala2] Tabela 1: Descrição das divisões que compõem cada tipo de casa Definimos depois algumas restrições internas que foram pensadas por nós para assim reduzirmos as soluções da pesquisa que seriam em número muito elevado caso não o fizéssemos. Para começar, fizemos o predicado Teste, sendo este o predicado principal, uma vez que chama todos os outros predicados, recebe os argumentos e devolve uma lista com todas as plantas possíveis. teste(Nquartos, Areamin, Areamax,ListaFinal) Este predicado recebe os argumentos definidos pelo utilizador e passados pela interface, através da classe Jasper. O Nquartos representa o tipo de casa pretendida (T1,T2,T3,T4) e a Areamin, Areamax representam os limites da área da casa. Por fim a ListaFinal é a Lista que o modo lógico da aplicação retorna contendo as soluções encontradas e que é passada para a interface para ser desenhada e visualizada pelo utilizador. 12 EDITOR E GERADOR DE PLANTAS DE CASA RELATÓRIO FINAL Em seguida fazemos dois predicados que servem unicamente para controlar a evolução do modo lógico da aplicação. define_divisoes(Nquartos,Divisoes), imprime_divisoes(Divisoes) O Predicado define_divisoes vai apenas devolver as divisões que predefinimos para o tipo de casa passado pelo utilizador, deste modo damos como argumento o NQuartos e devolvemos uma lista Divisoes com as divisões. O Predicado imprime_divisoes permite apenas a visualização das Divisoes que recebe como argumento. Em seguida é chamado o predicado areas_possiveis que, tal como o nome indica, devolve todas as áreas possíveis entre a área mínima e máxima definida pelo utilizador na interface. areas_possiveis(Areamin,Areamax,ListaAreas) Areamin é o argumento que contém a área mínima e Areamax contém a área máxima. Por fim, este predicado devolve ListaAreas, uma Lista com todas as áreas possíveis, desde a área mínima é máxima. A seguir apresentamos o predicado que gera todos os lados da planta através da lista da Áreas, obtida no predicado anterior. gerar_lados(ListaAreas,ListaLados) gera_lados recebe como argumento a ListaAreas e devolve uma lista de listas, ListaLados, em que cada lista contem,, respectivamente, a altura e o comprimento da planta. Posteriormente, este predicado chama outro predicado, restringe_lados, que vai fazer uma restrição imposta por nós na ListaLados. Esta restrição tem por objectivo, eliminar na ListaLados plantas, onde a diferença entre altura e comprimento seja muito grande. Em seguida fazemos o predicado define_corredor que, conforme os valores da altura e comprimento da casa, devolve valores, respectivamente, para a altura e comprimento do corredor. define_corredor(ListaLados,LadosCorredor) Este predicado, recebe como argumento a lista dos lados da planta obtida no predicado gerar_lados e devolve uma nova lista, LadosCorredor, que consiste numa lista 13 EDITOR E GERADOR DE PLANTAS DE CASA RELATÓRIO FINAL de listas, semelhante à anterior, mas agora com 4 valores em cada lista, sendo, respectivamente a altura e comprimento da planta e altura e comprimento do corredor. Este predicado também tem restrições semelhantes ás restrições do predicado anterior. A seguir apresentamos o predicado calcula_area_divisoes que devolve uma Lista, que dependendo da Lista das áreas e do número de divisões, devolve uma lista com possíveis áreas de casa divisão. calcula_area_divisoes(Tamanho,LadosCorredor,[],ListaNovaAreas) Este predicado recebe o número de divisões da planta no argumento Tamanho. Recebe também a lista dos lados das plantas com o corredor, LadosCorredor, que foi obtida no predicado anterior e recebe também uma lista vazia, apenas para auxiliar. Por fim, este devolve uma Lista de Listas. Mais uma vez, posteriormente neste predicado, é chamado um predicado que faz restrições feitas por nós. Em seguida colocamos um exemplo da ListaNovaAreas. [[6,9,4,1,[[15,15,12,8],[15,15,12,10]],[5,10,3,2,[[12,12,12,8],[15,12,9,8]] Lista que contem duas opções, em que cada tem duas plantas possiveis Para este predicado foi necessário usufruirmos de outro predicado criado por nós. Este predicado, arranjo, tem por objectivo fazer arranjos com repetição, Este predicado, um dos principais do nosso modo lógico, está definido em baixo. arranjo(Area,Dif,Min,Max,Res) Este predicado recebe um argumento, Area, que serve apenas para facilitar a realização do mesmo. Em seguida recebe o argumento Dif que é o tamanho das listas que o predicado constrói. Min e Max é os valores em vão variar nas listas, ou seja, este predicado faz arranjos de tamanho Dif entre o Min e Max. O resultado deste predicado é devolvido em Res que consiste numa lista de listas com todas as soluções. Este predicado gera, como é imaginável, uma quantidade de listas enorme, provocando, por isso, no nosso predicado arranjo inicial falhas de memória. Como era impossível continuar o nosso modo lógica perante esta falha reformulamos este predicado de modo a essas falhas serem menos frequentes. Deste modo o novo predicado está mais extenso. Como este tipo de visualização da lista é complicada para continuarmos o modo lógico deste trabalho, segue se um predicado que faz uma divisão, de modo a que a nova lista fique mais fácil de manipular. 14 EDITOR E GERADOR DE PLANTAS DE CASA RELATÓRIO FINAL dividir_listas(ListaNovaAreas,ListaNova) Como é possível observar este predicado recebe uma lista, ListaNovaAreas, obtida no predicado anterior e devolve a nova, ListaNova. Por fim, temos o último predicado, fazer_casas, a ser chamado pelo predicado principal, teste. Este predicado tem por objectivo construir uma lista com todas as plantas geradas por este modo lógico, lista essa, que posteriormente será devolvida pela classe Jasper, à interface que fará o desenho das plantas para serem visualizadas pelo utilizador. fazer_casas(ListaNova,ListaFinal) Este predicado recebe a lista devolvida no predicado anterior, ListaNova, e devolve a lista nova, ListaFinal, com todos os valores para a construção das plantas. Em seguida apresentamos uma lista de exemplo da Lista final. [[0,0,6,9],[0,3,4,1],[0,0,4,3],[0,4,3,5],[3,4,3,5],[4,0,2,4]] Este é um exemplo de uma lista de uma planta, mas o predicado devolve uma lista destas listas. A primeira lista, de 4 valores, deste exemplo representa respectivamente a coordenada Y e X da planta, a altura e comprimento da mesma. Os quatro valores seguintes dizem respeito ao corredor e depois as restantes divisões. Para a realização deste predicado final, tivemos de implementar um novo predicado, testa. Que tem como objectivo concluir se uma lista de plantas é válida ou não, ou seja, o predicado fazer_casa desenvolve varias plantas possíveis e, posteriormente estas plantas passarão por um predicado testa que concluirá se é uma planta possível ou não. testa(Lista) Este predicado recebe apenas uma Lista e falha se a lista recebida não for uma planta possível perante as escolhas do utilizador. Durante a realização deste trabalho fomos fazendo várias restrições, nomeadamente, área mínima e máxima de uma divisão, comprimento mínimo e máximo dos lados da planta e comprimento mínimo e máximo dos lados de uma divisão. 15 EDITOR E GERADOR DE PLANTAS DE CASA RELATÓRIO FINAL Módulo de Java Este é o módulo da interface da aplicação que tal como o nome indica é implementado em Java. É esta a parte da aplicação que faz a comunicação entre o módulo lógico e o utilizador. Foi necessário fazer-se a ligação entre este módulo e o anterior, para tal recorremos a classe Jasper tal como iremos explicar mais à frente. Gostaríamos de salientar o facto de a comunicação entre os dois módulos que constituem o programa, não fazer parte da matéria abordada pela disciplina em questão ou por qualquer outra, dai que tivemos de aprender a utilizar esta classe de ligação o que nos levou algum tempo. O módulo da interface é composto por 5 classes, que explicamos em seguida. Entrada.java- Esta é apenas a classe que contem a imagem de abertura da nossa aplicação, que consideramos como uma Jframe e quando clicamos nela chamamos a classe gerador_plantas e temos acesso á aplicação propriamente dita. Gerador_Plantas.java- Esta é a classe principal da aplicação já que esta chama todas as outras classes da interface. Consiste numa Jframe na qual irão ser visualizadas as soluções encontradas. É apartir desta classe que o utilizador tem acesso ao menu onde pode fazer as suas opções para a construção da planta. Inicial.java- Nesta classe temos a implementação do menu chamado pela classe Gerador_Plantas onde o utilizador tem obrigatoriamente de definir o tipo de casa que pretende, através de uma JComboBox que lhe dá a opção de especificar se pretende uma casa tipo T1, T2, T3 OU T4, tipos estes que obedecem à descrição explicada na tabela 1. As outras definições que o utilizador tem de fazer neste menu são as áreas mínimas e máximas que pretende para a planta da casa, definindo numa JTextField um inteiro para cada uma dessas variáveis. É importante referir que são estes os parâmetros que são passados do modulo de Java para o de Prolog para assim serem geradas as soluções tendo em conta as especificações passadas. Planta.java- A classe Plantas.java é a responsável pelo desenho da planta da casa depois de dadas as coordenadas de cada divisão. Começa por desenhar os contornos da casa começando pelo ponto (0,0), depois passa à primeira divisão que lhe é passada na lista vinda do modulo em Prolog, desenha essa divisão, da qual lhe e passada uma lista com a posição inicial e com a altura e comprimento respectivos. Repete a mesma operação para todas as divisões da casa até ter percorrido toda a lista de uma possível casa. Depois faz o mesmo procedimento para todas as possíveis casas até não ter mais casas na lista. 16 EDITOR E GERADOR DE PLANTAS DE CASA RELATÓRIO FINAL Capítulo 4 4. Ambiente de Desenvolvimento A nossa aplicação foi desenvolvida em vários PC’s divididos entre as máquinas do DEEC (laboratórios I120 e I124) e as nossas máquinas pessoais. No DEEC utilizámos PC’S Intel Pentium III a 733 MHz com 512MB de RAM. Em casa desenvolvemos a aplicação numa máquina Intel Pentium III a 833 MHz com 512MB de RAM, e num portátil Compaq Presario 700 com um processador Athlon a 1,29GHz com 256MB de RAM. Os sistemas operativos utilizados foram: Microsoft Windows XP e Microsoft Windows 2000. Para desenvolver o módulo de Prolog utilizamos o editor Edit Plus2 e para compilar recorremos ao SICStus Prolog 3.9.1. Para a parte gráfica da aplicação, que como já foi referido anteriormente, foi desenvolvida em Java, utilizamos simultaneamente JCreator Pro v2.00 e Forte for Java 4.0 CE. 17 EDITOR E GERADOR DE PLANTAS DE CASA RELATÓRIO FINAL Capítulo 5 5. Avaliação do programa Depois de terminado o trabalho, a avaliação que lhe fazemos, e tendo em conta que é um projecto com fim meramente acadêmico, é que corresponde ao que foi proposto. No entanto temos consciência que não seria de grande usabilidade se aplicado como software para arquitectos, já que não obedece a nenhum tipo de regras arquitetônicas para a geração de plantas de casas. Outro dos aspectos que apontamos na nossa auto-avaliação prende-se com o facto da interface não estar mais desenvolvida o que viria a acrescentar muito valor à aplicação. No que respeita às soluções encontradas, tendo em conta as especificações do utilizador e as internas por nós definidas, as soluções são as esperadas e num tempo de execução aceitável. Queríamos por fim salientar que sensivelmente a meio do projecto tivemos de refazer todo o modulo lógico já que tivemos problemas de memória por possíveis lacunas na programação que não conseguimos encontrar e solucionar. Este foi um grande obstáculo que nos veio atrasar o desenvolvimento do projecto, mas que acabamos por conseguir solucionar a tempo. 18 EDITOR E GERADOR DE PLANTAS DE CASA RELATÓRIO FINAL Capítulo 6 6. Conclusão Apesar de este ser um projecto que á partida nos suscitou todo o interesse na fase de escolha dos trabalhos, temos de referir que só mais tarde na fase de reflexão e na posterior fase de implementação, tivemos consciência da complexidade que envolvia o gerador de plantas de casas. O facto de não encontrarmos nenhum algoritmo capaz de resolver o problema trouxe alguma dificuldade. Concluímos também que a linguagem Prolog é muito eficiente e extremamente rápida, quando comparada com outras linguagens de programação com que já trabalhamos, para este tipo de pesquisas que envolvem grande numero de iterações. Chegamos também á conclusão que o Jasper apesar de muito útil, porque nos permite associar uma interface gráfica ao modulo lógico que sem esta representação seria incompreensível para o utilizador normal , encontra-se ainda com alguns problemas, sendo que o principal por nós detectado é o facto de não se encontrar devidamente documentado, facilitando assim a sua utilização. Como conclusão do nosso trabalho podemos dizer que apesar de todos os obstáculos que nos foram surgindo e que tivemos de ultrapassar, o balanço final é positivo, mas precisaríamos de mais tempo para atingir os objectivos que o grupo de trabalho pretendia alcançar. 19 EDITOR E GERADOR DE PLANTAS DE CASA RELATÓRIO FINAL Capítulo 7 7. Melhoramentos Como já normal, num projecto desta complexidade chegadas ao fim do trabalho temos alguns melhoramentos que gostaríamos de poder fazer não fosse os prazos que temos a cumprir. Uma optimização de um projecto com o mesmo objectivo deste trabalho seria uma aplicação que dela resultassem plantas de casas em que o utilizador especifica-se muito mais para além do tipo de casa e áreas aquilo que pretendia, para assim obter uma casa mais aos seus gostos. Outro dos requisitos que traria valor à aplicação, pensando na utilidade pratica desta, seria a inserção de restrições arquitectónicas que ultrapassam os nossos conhecimentos mas que são essenciais para o desenho técnico de uma habitação. Assim a aplicação perderia o estatuto de puramente acadêmica e poder ser um auxilio para profissionais. Outro ponto que podia ser melhorado, era as especificações por nós definidas que deveriam ser um pouco mais flexíveis, como: poder ter mais do que um corredor, ter um hall, e que estes, assim como as restantes divisões da casa, tivessem outras formas que não as de um quadrado ou rectângulo por nos definidas. Neste aspecto faria todo o sentido, a geração de plantas que adquirissem também outras formas geométricas que não a forma rectangular. O principal melhoramento que gostaríamos de ver implementado seria a possibilidade da geração de plantas com dois andares e a construção de um desenho mais rigoroso que ilustrasse todas as especificações dadas. 20 EDITOR E GERADOR DE PLANTAS DE CASA RELATÓRIO FINAL Referências Bibliográficas . "The Art of Prolog", Sterling and Shapiro. . "Artificial Intelligence: A modern approach". Prentice-Hal,l S.Russel, P.Norvig, 1995. 21 EDITOR E GERADOR DE PLANTAS DE CASA RELATÓRIO FINAL Apêndices 22 EDITOR E GERADOR DE PLANTAS DE CASA RELATÓRIO FINAL Manual do Utilizador: Editor e Gerador de Plantas de Casa Ana Santos Cristina Perfeito Faculdade de Engenharia da Universidade do Porto Departamento de Engenharia Electrotécnica e de Computadores Rua Roberto Frias, s/n, 4200-465 Porto, Portugal Junho de 2003 23 EDITOR E GERADOR DE PLANTAS DE CASA RELATÓRIO FINAL Neste Manual do Utilizador pretende-se dar uma visão geral de como funciona a nossa aplicação. Apesar da interface gráfica ser muito intuitiva vamos de seguida explicar todas as possíveis opções inerentes ao manuseamento da aplicação. Tela Inicial Fig 1: Janela Inicial do Gerador de Plantas Esta é a imagem inicial (fig 1) que apresenta a aplicação como Gerador de Plantas. Para termos acesso á aplicação propriamente dita temos de clicar com o rato na imagem, e esta e a única funcionalidade desta imagem. Depois de clicarmos temos então acesso à janela principal, tal como podemos ver na fig 2 que apresentamos a seguir. 24 EDITOR E GERADOR DE PLANTAS DE CASA RELATÓRIO FINAL Fig 2: Janela Principal do Gerador de Plantas Chegados á janela principal do gerador temos de indicar quais as especificações da planta da casa que pretendemos obter. Assim carregando no Menu que se encontra no canto superior esquerdo da janela principal temos a opção Gerar novas plantas que nos dá acesso ao menu onde vamos indicar as especificações que pretendemos (fig 3). 25 EDITOR E GERADOR DE PLANTAS DE CASA RELATÓRIO FINAL Fig 3: Menu das especificações Neste menu começamos por ter de optar pelo tipo de casa que pretendemos. Assim é nos apresentado um conjunto de soluções possíveis como podemos observar na fig 4. Fig 4: Tipo de Casa Os tipos de casa são do conhecimento de todos os utilizadores já que é esta a designação utilizada para definir qualquer casa, no entanto podemos ver a composição de cada tipo de casa na tabela seguinte. Tipo de Casa Descrição T1 quarto,cozinha, casabanho,sala T2 quarto1, quarto2, cozinha, casabanho1, sala T3 quarto1,casabanho1, quarto2, quarto3,cozinha,casabanho2, sala T4 [quarto1,casabanho1],[quarto2,casabanho2],quarto3,quarto4,[cozinha, sala1],sala2 Tabela 2: Descrição dos diferentes tipos de casas 26 EDITOR E GERADOR DE PLANTAS DE CASA RELATÓRIO FINAL Depois de escolhido o tipo de casa pretendido, o utilizador terá obrigatoriamente que definir a área mínima e máxima da casa. O passo seguinte é clicar no botão Nova Planta e assim ver o desenho das possíveis plantas que obedeçam às especificações pedidas. Fig 5: Desenho de uma planta de uma casa 27 EDITOR E GERADOR DE PLANTAS DE CASA RELATÓRIO FINAL Exemplo de uma execução Aqui apresentamos um exemplo de utilização do nosso programa O utilizador coloca os dados na seguinte frame Fig 6: Menu de definições E em seguida visualiza as plantas geradas Fig 7: Desenho das Plantas 28 EDITOR E GERADOR DE PLANTAS DE CASA RELATÓRIO FINAL Listagem do código Código Prolog :-use_module(library(lists)). :-use_module(library(system)). area_div(8,15). area_planta(24,200). lado_planta(4,20). lado_div(2,5). %listas de divisoes para os diferentes tipos de casas lista_t1([sala, cozinha, casabanho1,quarto1]). lista_t2([quarto1, quarto2, cozinha, casabanho1, sala]). lista_t3([[quarto1,casabanho1], quarto2, quarto3,cozinha,casabanho2, sala]). lista_t4([[quarto1,casabanho1],[quarto2,casabanho2],quarto3,quarto4,casabanho3,[cozinha, sala1],sala2]). /**************************************************************************/ /* Predicado pricipal, onde são passados os pedidos do utilizador e onde */ /* é devolvida a Litsa com as plantas possiveis */ /**************************************************************************/ teste(Nquartos, Areamin,Areamax,ListaFinal):nl,nl,nl, write('********Editor e Gerador de plantas de casas********'),nl,nl, write('Numero de quartos- '), write(Nquartos),nl, write('Area maxima- '), write(Areamax),nl, write('Area minima- '), write(Areamin),nl,nl, define_divisoes(Nquartos,Divisoes), imprime_divisoes(Divisoes),nl, length(Divisoes,Tamanho), areas_possiveis(Areamin,Areamax,ListaAreas),nl, write('Lista de Areas possiveis:'),write(ListaAreas), gerar_lados(ListaAreas,ListaLados), define_corredor(ListaLados,LadosCorredor), calcula_area_divisoes(Tamanho,LadosCorredor,[],ListaNovaAreas),nl,nl, dividir_listas(ListaNovaAreas,ListaNova),n write(ListaNova), fazer_casas(ListaNova,ListaFinal), write(ListaFinal),nl,nl. %*********************************************** %gera lista de divisoes para cada planta de casa %*********************************************** define_divisoes(1,Lista) :- lista_t1(Lista). define_divisoes(2,Lista) :- lista_t2(Lista). define_divisoes(3,Lista) :- lista_t3(Lista). 29 EDITOR E GERADOR DE PLANTAS DE CASA RELATÓRIO FINAL define_divisoes(4,Lista) :- lista_t4(Lista). %******************************************************* % Areas possiveis - Entre a area minima e maxima devolve % uma lista com todas as areas possiveis %******************************************************* areas_possiveis(Areamin,Areamax,Lista):Nova_Areamin is Areamin -1, areas_possiveis(Nova_Areamin,Areamax,Areamax,Lista, []). areas_possiveis(Areamin,_,Areamin,Lista, Lista). areas_possiveis(Areamin,Areamax,Aux,Lista, Acc):NovoAux is Aux - 1, areas_possiveis(Areamin, Areamax, NovoAux, Lista, [Aux|Acc]). %*************************************************************** %gera alturas e comprimentos de plantas e respectivas restricoes %*************************************************************** gerar_lados(ListaAreas,Nova_Lista) :lado_planta(Min,Max), gerar_lados(Min,Max,ListaAreas,Lista), restringe_lados(Lista,Nova_Lista). gerar_lados(Min,Max,ListaAreas,Lista) :gerar_lados(Min,Max,ListaAreas,[],Lista). gerar_lados(_,_,[],Lista,Lista). gerar_lados(Min,Max,[H|T],Aux,Lista) :arranjo(H,3,Min,Max,Nova), append(Aux,Nova,Lista_Nova), gerar_lados(Min,Max,T,Lista_Nova,Lista). restringe_lados(Recente_Lista,Nova_Lista):restringe_lados(Recente_Lista,[],Nova_Lista). restringe_lados([],Nova_Lista,Nova_Lista). restringe_lados([[A,B]|T],Resto,Nova_Lista):A =< B, B_aux is B/2, ( A >= B_aux, restringe_lados(T,[[A,B]|Resto],Nova_Lista) ; restringe_lados(T,Resto,Nova_Lista) ). restringe_lados([[A,B]|T],Resto,Nova_Lista):B =< A, A_aux is A/2, ( B >= A_aux, restringe_lados(T,[[A,B]|Resto],Nova_Lista) 30 EDITOR E GERADOR DE PLANTAS DE CASA RELATÓRIO FINAL ; restringe_lados(T,Resto,Nova_Lista) ). %************************************************************************************ * % Gera areas para todas as divisoes apartir da area da planta e respectivas restricoes %************************************************************************************ * calcula_area_divisoes(_,[],Nova,Nova). calcula_area_divisoes(Tamanho,[[A,B,C,D]|T],Aux,Nova) :Area_casa is A*B, Area_corredor is C*D, Area_total is Area_casa-Area_corredor, area_div(Area_div_min,Area_div_max), arranjo(Area_total,Tamanho,Area_div_min,Area_div_max,Lista_Areas_Divisoes), mais_restricoes(Lista_Areas_Divisoes,Lista_Recente), area_valores_inteiros(Lista_Recente,Recente), append([A,B,C,D],[Recente],Lista_Aux),nl, write(Lista_Aux), append([Lista_Aux],Aux,Nova_Aux), calcula_area_divisoes(Tamanho,T,Nova_Aux,Nova). mais_restricoes(Lista,Nova) :mais_restricoes(Lista, [], Nova). mais_restricoes([],Lista,Lista). mais_restricoes([H|T], Aux, Lista) :mais_restricoes(H,T,[],Res), append([H],Aux,Nova), inverter(Nova,ListaNova), mais_restricoes(Res,ListaNova,Lista). mais_restricoes(_,[],Nova,Nova). mais_restricoes(H,[A|B],Aux,Nova) :( permutation(H,A),!, mais_restricoes(H,B,Aux,Nova) ; append(Aux,[A], Lista), mais_restricoes(H,B,Lista,Nova) ). %*************************************************************************** %metodo que restringue as areas das divisoes para lados com valores inteiros %*************************************************************************** area_valores_inteiros(Lista,Nova) :area_valores_inteiros(Lista,[],Nova). area_valores_inteiros([],Nova,Nova). area_valores_inteiros([H|T],Aux,Nova) :area_valores_inteiros_(H,[],Lista_Nova), ( 31 EDITOR E GERADOR DE PLANTAS DE CASA RELATÓRIO FINAL member(0,Lista_Nova),!, area_valores_inteiros(T,Aux,Nova) ; area_valores_inteiros(T,[H|Aux],Nova) ). area_valores_inteiros_([],L,L). area_valores_inteiros_([H|T],Aux,L) :lado_div(Lado_div_min,Lado_div_max), arranjo(0,2,Lado_div_min,Lado_div_max,Lista_lados), confirma(H,Lista_lados,Resultado), append(Aux,[Resultado],Nova), area_valores_inteiros_(T,Nova,L). confirma(_,[],0). confirma(H,[[Lado1,Lado2]|T],Resultado) :Aux is Lado1*Lado2, Aux == H, Resultado is H ; confirma(H,T,Resultado). %************************************************************* % predicado que repoe uma lista de modo a ficar mais acessivel %************************************************************* dividir_listas(Lista,ListaNova) :dividir_listas(Lista, [],ListaNova). dividir_listas([],ListaNova,ListaNova). dividir_listas([H|T],Aux,ListaNova) :dividir_listas_(H,[],Lista), append(Lista,Aux,Lista_Aux), dividir_listas(T,Lista_Aux,ListaNova). dividir_listas_([_,_,_,_,H|_],Nova,Nova) :H == []. dividir_listas_([A,B,C,D,[M|N]],Aux,Nova) :add([A,B,C,D,M],Aux,Lista), dividir_listas_([A,B,C,D,N],Lista,Nova). %***************************************************************************** % Calcula medidas do corredor tendo em conta a largura e comprimento da planta % faz também as respectivas restrições %***************************************************************************** define_corredor(ListaLados,ListaCorredor):define_corredor(ListaLados,[],ListaLadosCorredor), restringe_lados_corredor(ListaLadosCorredor,ListaCorredor). define_corredor([],ListaLadosCorredor,ListaLadosCorredor). define_corredor([[A,B]|Resto],ListaAux,ListaLadosCorredor):Y is integer(A*(3/4)), X is integer(B*(1/5)), define_corredor(Resto,[[A,B,Y,X]|ListaAux],ListaLadosCorredor). 32 EDITOR E GERADOR DE PLANTAS DE CASA RELATÓRIO FINAL restringe_lados_corredor(Recente_Lista,Nova_Lista):restringe_lados_corredor(Recente_Lista,[],Nova_Lista). restringe_lados_corredor([],Nova_Lista,Nova_Lista). restringe_lados_corredor([[M,N,A,B]|T],Resto,Nova_Lista):A =< B, Aux is A/B, ( Aux >= 0.25, restringe_lados_corredor(T,[[M,N,A,B]|Resto],Nova_Lista) ; restringe_lados_corredor(T,Resto,Nova_Lista) ). restringe_lados_corredor([[M,N,A,B]|T],Resto,Nova_Lista):B =< A, Aux is B/A, ( Aux >= 0.25, restringe_lados_corredor(T,[[M,N,A,B]|Resto],Nova_Lista) ; restringe_lados_corredor(T,Resto,Nova_Lista) ). %********************************************************* % Predicado que gera valores para coordenadas das divisoes %********************************************************* fazer_casas(Lista,Nova) :fazer_casas(Lista,[],Nova). fazer_casas([],Nova,Nova). fazer_casas([H|T],Aux,Nova) :fazer_casas_(H,[],Lista), add(Lista,Aux,Lista_Aux), fazer_casas(T,Lista_Aux,Nova). fazer_casas_([[A,B,C,D]|H],Aux,Nova) :append(Aux,[0,0,A,B],Lista_Aux), write(Lista_Aux), lado_div(Min,Max), append(Lista_Aux,[0,Min,C,D],Lista). %************************************************************************** % Predicado que testa se uma planta é válida a partir do predicado anterior %************************************************************************** testa([[M,N,A,B]|T]) :organizar(T,[],Lista), areas_possiveis(0,A,Altura), areas_possiveis(0,B,Comp), separarY(Lista,Altura,[],NovaY), separarX(Lista,Comp,[],NovaX), append([NovaY],[NovaX],Nova),!, faz_teste(Nova,A,B). 33 EDITOR E GERADOR DE PLANTAS DE CASA RELATÓRIO FINAL faz_teste([Y,X],Altura,Comp) :testaYY(Y,[],SomaY,Comp),nl, write(SomaY), testaXX(X,[],SomaX,Altura),nl, write(SomaX),!, todos_iguais(SomaY,Comp), todos_iguais(SomaX,Altura). %************************************************************************************ ********** % Predicado que testa em cada linha de Y se a soma das divisoes coincide com a altura da planta %************************************************************************************ ********** testaYY([],Soma,Soma,_). testaYY([A|B],Aux,Soma,Comp) :testaY(A,0,Res), sobrepostosY(A,Res,NovoRes,Comp), add(NovoRes,Aux,Nova_Aux), testaYY(B,Nova_Aux,Soma,Comp). testaY([],Soma,Soma). testaY([[M,N,O,P]|B],Aux,Soma) :Res is Aux+P, testaY(B,Res,Soma). /*************************************************/ sobrepostosY([],NovoRes,NovoRes,_). sobrepostosY([H|T],Res,NovoRes,Comp) :sobrepostosY(H,T,Res,NovoResultado,Comp), sobrepostosY(T,NovoResultado,NovoRes,Comp). sobrepostosY(_,[],NovoResultado,NovoResultado,Comp). sobrepostosY(A,[B|T],Res,NovoResultado,Comp) :sobreY(A,B,Res,NovoRes,Comp), sobrepostosY(A,T,NovoRes,NovoResultado,Comp). /*************************************************/ sobreY([M,N,O,P],[R,S,T,V],Res,NovoRes,Comp) :Total is P + V, ( S > N, Inicio is S-N ; Inicio is N-S ), Altura1 is N+P, Altura2 is S+V, ( Altura2 > Altura1, Fim is Altura2-Altura1 ; Fim is Altura1-Altura2 ), 34 EDITOR E GERADOR DE PLANTAS DE CASA RELATÓRIO FINAL IniFim is Inicio + Fim, Resultado is Total - IniFim, ResFinal is Resultado//2, ( ResFinal >= Comp, NovoRes is Res ; ( ( Altura1 == S -> NovoRes is Res ; Altura2 == N -> NovoRes is Res ) ; ( ResFinal > 0, NovoRes is Res-ResFinal ; NovoRes is Res ) ) ). /*************************************************/ separarY(_,[],Nova,Nova). separarY(Lista,[A|T],Aux,Nova) :separar_maisY(Lista,A,[],ListaNova), append(Aux,[ListaNova],Lista_Aux), separarY(Lista,T,Lista_Aux,Nova). separar_maisY([],_,Nova,Nova). separar_maisY([[A,B,C]|T],Altura,Aux,Nova) :( member(Altura,B),!, ( append([A],Aux,Nova_Aux), separar_maisY(T,Altura,Nova_Aux,Nova) ) ; separar_maisY(T,Altura,Aux,Nova) ). %************************************************************************************ *************** % Predicado que testa em cada linha de X se a soma das divisoes coincide com o comprimento da planta %************************************************************************************ *************** testaXX([],Soma,Soma,_). testaXX([A|B],Aux,Soma,Altura) :testaX(A,0,Res), sobrepostosX(A,Res,NovoRes,Altura), add(NovoRes,Aux,Nova_Aux), testaXX(B,Nova_Aux,Soma,Altura). testaX([],Soma,Soma). 35 EDITOR E GERADOR DE PLANTAS DE CASA RELATÓRIO FINAL testaX([[M,N,O,P]|B],Aux,Soma) :Res is Aux+O, testaX(B,Res,Soma). /*************************************************/ sobrepostosX([],NovoRes,NovoRes,_). sobrepostosX([H|T],Res,NovoRes,Altura) :sobrepostosX(H,T,Res,NovoResultado,Altura), sobrepostosX(T,NovoResultado,NovoRes,Altura). sobrepostosX(_,[],NovoResultado,NovoResultado,Altura). sobrepostosX(A,[B|T],Res,NovoResultado,Altura) :sobreX(A,B,Res,NovoRes,Altura), sobrepostosX(A,T,NovoRes,NovoResultado,Altura). /*************************************************/ sobreX([M,N,O,P],[R,S,T,V],Res,NovoRes,Altura) :Total is O + T, ( R > M, Inicio is R-M ; Inicio is M-R ), Altura1 is M+O, Altura2 is R+T, ( Altura2 > Altura1, Fim is Altura2-Altura1 ; Fim is Altura1-Altura2 ), IniFim is Inicio + Fim, Resultado is Total - IniFim, ResFinal is Resultado//2, ( ResFinal >= Altura, NovoRes is Res ; ( ( Altura1 == R -> NovoRes is Res ; Altura2 == M -> NovoRes is Res ) ; ( ResFinal > 0, NovoRes is Res-ResFinal ; NovoRes is Res ) ) ). 36 EDITOR E GERADOR DE PLANTAS DE CASA RELATÓRIO FINAL /*************************************************/ separarX(_,[],Nova,Nova). separarX(Lista,[A|T],Aux,Nova) :separar_maisX(Lista,A,[],ListaNova), append(Aux,[ListaNova],Lista_Aux), separarX(Lista,T,Lista_Aux,Nova). separar_maisX([],_,Nova,Nova). separar_maisX([[A,B,C]|T],Comp,Aux,Nova) :( member(Comp,C),!, ( append([A],Aux,Nova_Aux), separar_maisX(T,Comp,Nova_Aux,Nova) ) ; separar_maisX(T,Comp,Aux,Nova) ). /*************************************************/ organizar([],Nova,Nova). organizar([[A,B,C,D]|T],Aux,Nova) :MaxY is A+C, MaxX is B+D, areas_possiveis(A,MaxY,ListaY), areas_possiveis(B,MaxX,ListaX), append([ListaY],[ListaX],Lista), append([[A,B,C,D]],Lista,Nova_Lista), append(Aux,[Nova_Lista],Lista_Aux), organizar(T,Lista_Aux,Nova). %*********************************************************************** %constroi uma lista de listas de tamanho Dif com valores entre Min e Max %*********************************************************************** arranjo(Area,Dif,Min,Max,Res) :areas_possiveis(Min,Max,Lista1), areas_possiveis(Min,Max,Lista2), areas_possiveis(Min,Max,Lista3), areas_possiveis(Min,Max,Lista4), areas_possiveis(Min,Max,Lista5), areas_possiveis(Min,Max,Lista6), areas_possiveis(Min,Max,Lista7), areas_possiveis(Min,Max,Lista8), ( Dif ==2,!, arranjo_2(Lista1,Lista2,Res) ; ( Dif == 4,!, arranjo_t1(Area,Lista1,Lista2,Lista3,Lista4,Res) ; ( 37 EDITOR E GERADOR DE PLANTAS DE CASA RELATÓRIO FINAL Dif == 5,!, arranjo_t2(Area,Lista1,Lista2,Lista3,Lista4,Lista5,Res) ; ( Dif == 6,!, arranjo_t3(Area,Lista1,Lista2,Lista3,Lista4,Lista5,Lista6,Res) ; ( Dif == 7,!, arranjo_t4(Area,Lista1,Lista2,Lista3,Lista4,Lista5,Lista6,Lista7,Res) ; ( Dif == 8,!, arranjo_5(Lista1,Lista2,Lista3,Lista4,Lista5,Lista6,Lista7,Lista8,Res) ; arranjo2__(Area,Lista1,Lista2,Res) ) ) ) ) ) ). /******************************************* Arranjo para 2 ********************************************/ arranjo_2(Lista1,Lista2,Lista) :arranjo2_(Lista1,Lista2,[],Lista). arranjo1_(E,Lista2,_,Res) :arranjo1_(E,Lista2,[],[],Res). arranjo1_(_,[],_,Res,Res). arranjo1_(E,[G|H],Nova,Lista,Res) :append(Nova,[E],Nova1), append(Nova1,[G],Nova2), append([Nova2],Nova,Aux), append(Lista,Aux,Lista_Aux), arranjo1_(E,H,[],Lista_Aux,Res). arranjo2_([],_,Lista,Lista). arranjo2_([E|F],Lista2,Nova,Lista) :arranjo1_(E,Lista2,[],Nova_Lista), append(Nova_Lista,Nova,Aux), arranjo2_(F,Lista2,Aux,Lista). /******************************************* Arranjo para 2 especial ********************************************/ arranjo2__(Area,Lista1,Lista2,Lista) :arranjo2__(Area,Lista1,Lista2,[],Lista). 38 EDITOR E GERADOR DE PLANTAS DE CASA RELATÓRIO FINAL arranjo1__(Area,E,Lista2,_,Res) :arranjo1__(Area,E,Lista2,[],[],Res). arranjo1__(_,_,[],_,Res,Res). arranjo1__(Area,E,[G|H],Nova,Lista,Res) :append(Nova,[E],Nova1), append(Nova1,[G],Nova2), Soma is E*G, ( Soma == Area,!, ( append(Lista,[Nova2],Lista_Aux), arranjo1__(Area,E,H,[],Lista_Aux,Res) ) ; arranjo1__(Area,E,H,[],Lista,Res) ). arranjo2__(_,[],_,Lista,Lista). arranjo2__(Area,[E|F],Lista2,Nova,Lista) :arranjo1__(Area,E,Lista2,[],Nova_Lista), append(Nova_Lista,Nova,Aux), arranjo2__(Area,F,Lista2,Aux,Lista). /******************************************* Arranjo para T1 ********************************************/ arranjo_t1(Max,Lista1,Lista2,Lista3,Lista4,Lista) :arranjo4(Max,Lista1,Lista2,Lista3,Lista4,[],Lista). arranjo1(Max,A,C,E,Lista4,_,Res) :arranjo1(Max,A,C,E,Lista4,[],[],Res). arranjo1(_,_,_,_,[],_,Res,Res). arranjo1(Max,A,C,E,[G|H],Nova,Lista,Res) :append(Nova,[A],Nova1), append(Nova1,[C],Nova2), append(Nova2,[E],Nova3), append(Nova3,[G],Nova4), sum_list(Nova4,Soma), ( Soma == Max,!, ( append(Lista,[Nova4],Lista_Aux), arranjo1(Max,A,C,E,H,[],Lista_Aux,Res) ) ; arranjo1(Max,A,C,E,H,[],Lista,Res) ). arranjo2(_,_,_,[],_,Lista,Lista). arranjo2(Max,A,C,[E|F],Lista4,Nova,Lista) :arranjo1(Max,A,C,E,Lista4,[],Nova_Lista), append(Nova_Lista,Nova,Aux), 39 EDITOR E GERADOR DE PLANTAS DE CASA RELATÓRIO FINAL arranjo2(Max,A,C,F,Lista4,Aux,Lista). arranjo3(_,_,[],_,_,Lista,Lista). arranjo3(Max,A,[C|D],Lista3,Lista4,Nova,Lista) :arranjo2(Max,A,C,Lista3,Lista4,[],Nova_Lista), append(Nova_Lista,Nova,Aux), arranjo3(Max,A,D,Lista3,Lista4,Aux,Lista). arranjo4(_,[],_,_,_,Lista,Lista). arranjo4(Max,[A|B],Lista2,Lista3,Lista4,Nova,Lista) :arranjo3(Max,A,Lista2,Lista3,Lista4,[],Nova_Lista), append(Nova_Lista,Nova,Aux), arranjo4(Max,B,Lista2,Lista3,Lista4,Aux,Lista). /******************************************* Arranjo para T2 ********************************************/ arranjo_t2(Max,Lista1,Lista2,Lista3,Lista4,Lista5,Lista) :arranjo_5(Max,Lista1,Lista2,Lista3,Lista4,Lista5,[],Lista). arranjo_1(Max,M,A,C,E,Lista5,_,Res) :arranjo_1(Max,M,A,C,E,Lista5,[],[],Res). arranjo_1(_,_,_,_,_,[],_,Res,Res). arranjo_1(Max,M,A,C,E,[G|H],Nova,Lista,Res) :append(Nova,[M],Nova1), append(Nova1,[A],Nova2), append(Nova2,[C],Nova3), append(Nova3,[E],Nova4), append(Nova4,[G],Nova5), sum_list(Nova5,Soma), ( Max == 0, ( append(Lista,[Nova5],Aux), arranjo_1(Max,M,A,C,E,H,[],Aux,Res) ) ; ( Soma == Max,!, ( append(Lista,[Nova5],Aux), arranjo_1(Max,M,A,C,E,H,[],Aux,Res) ) ; arranjo_1(Max,M,A,C,E,H,[],Lista,Res) ) ). arranjo_2(_,_,_,_,[],_,Lista,Lista). arranjo_2(Max,M,A,C,[E|F],Lista5,Nova,Lista) :arranjo_1(Max,M,A,C,E,Lista5,[],Nova_Lista), append(Nova_Lista,Nova,Aux), arranjo_2(Max,M,A,C,F,Lista5,Aux,Lista). 40 EDITOR E GERADOR DE PLANTAS DE CASA RELATÓRIO FINAL arranjo_3(_,_,_,[],_,_,Lista,Lista). arranjo_3(Max,M,A,[C|D],Lista4,Lista5,Nova,Lista) :arranjo_2(Max,M,A,C,Lista4,Lista5,[],Nova_Lista), append(Nova_Lista,Nova,Aux), arranjo_3(Max,M,A,D,Lista4,Lista5,Aux,Lista). arranjo_4(_,_,[],_,_,_,Lista,Lista). arranjo_4(Max,M,[A|B],Lista3,Lista4,Lista5,Nova,Lista) :arranjo_3(Max,M,A,Lista3,Lista4,Lista5,[],Nova_Lista), append(Nova_Lista,Nova,Aux), arranjo_4(Max,M,B,Lista3,Lista4,Lista5,Aux,Lista). arranjo_5(_,[],_,_,_,_,Lista,Lista). arranjo_5(Max,[M|N],Lista2,Lista3,Lista4,Lista5,Nova,Lista) :arranjo_4(Max,M,Lista2,Lista3,Lista4,Lista5,[],Nova_Lista), append(Nova_Lista,Nova,Aux), arranjo_5(Max,N,Lista2,Lista3,Lista4,Lista5,Aux,Lista). /******************************************* Arranjo para T3 ********************************************/ arranjo_t3(Max,Lista1,Lista2,Lista3,Lista4,Lista5,Lista6,Lista) :arranjo__6(Max,Lista1,Lista2,Lista3,Lista4,Lista5,Lista6,[],Lista). arranjo__1(Max,O,M,A,C,E,Lista6,_,Res) :arranjo__1(Max,O,M,A,C,E,Lista6,[],[],Res). arranjo__1(_,_,_,_,_,_,[],_,Res,Res). arranjo__1(Max,O,M,A,C,E,[G|H],Nova,Lista,Res) :append(Nova,[O],Nova1), append(Nova1,[M],Nova2), append(Nova2,[A],Nova3), append(Nova3,[C],Nova4), append(Nova4,[E],Nova5), append(Nova5,[G],Nova6), sum_list(Nova6,Soma), ( Max == 0, ( append(Lista,[Nova5],Aux), arranjo__1(Max,O,M,A,C,E,H,[],Aux,Res) ) ; ( Soma == Max,!, ( append(Lista,[Nova6],Aux), arranjo__1(Max,O,M,A,C,E,H,[],Aux,Res) ) ; arranjo__1(Max,O,M,A,C,E,H,[],Lista,Res) ) ). 41 EDITOR E GERADOR DE PLANTAS DE CASA RELATÓRIO FINAL arranjo__2(_,_,_,_,_,[],_,Lista,Lista). arranjo__2(Max,O,M,A,C,[E|F],Lista6,Nova,Lista) :arranjo__1(Max,O,M,A,C,E,Lista6,[],Nova_Lista), append(Nova_Lista,Nova,Aux), arranjo__2(Max,O,M,A,C,F,Lista6,Aux,Lista). arranjo__3(_,_,_,_,[],_,_,Lista,Lista). arranjo__3(Max,O,M,A,[C|D],Lista5,Lista6,Nova,Lista) :arranjo__2(Max,O,M,A,C,Lista5,Lista6,[],Nova_Lista), append(Nova_Lista,Nova,Aux), arranjo__3(Max,O,M,A,D,Lista5,Lista6,Aux,Lista). arranjo__4(_,_,_,[],_,_,_,Lista,Lista). arranjo__4(Max,O,M,[A|B],Lista4,Lista5,Lista6,Nova,Lista) :arranjo__3(Max,O,M,A,Lista4,Lista5,Lista6,[],Nova_Lista), append(Nova_Lista,Nova,Aux), arranjo__4(Max,O,M,B,Lista4,Lista5,Lista6,Aux,Lista). arranjo__5(_,_,[],_,_,_,_,Lista,Lista). arranjo__5(Max,O,[M|N],Lista3,Lista4,Lista5,Lista6,Nova,Lista) :arranjo__4(Max,O,M,Lista3,Lista4,Lista5,Lista6,[],Nova_Lista), append(Nova_Lista,Nova,Aux), arranjo__5(Max,O,N,Lista3,Lista4,Lista5,Lista6,Aux,Lista). arranjo__6(_,[],_,_,_,_,_,Lista,Lista). arranjo__6(Max,[O|P],Lista2,Lista3,Lista4,Lista5,Lista6,Nova,Lista) :arranjo__5(Max,O,Lista2,Lista3,Lista4,Lista5,Lista6,[],Nova_Lista), append(Nova_Lista,Nova,Aux), arranjo__6(Max,P,Lista2,Lista3,Lista4,Lista5,Lista6,Aux,Lista). /******************************************* Arranjo para T4 ********************************************/ arranjo_t4(Max,Lista1,Lista2,Lista3,Lista4,Lista5,Lista6,Lista7,Lista) :arranjo___7(Max,Lista1,Lista2,Lista3,Lista4,Lista5,Lista6,Lista7,[],Lista). arranjo___1(Max,R,O,M,A,C,E,Lista7,_,Res) :arranjo___1(Max,R,O,M,A,C,E,Lista7,[],[],Res). arranjo___1(_,_,_,_,_,_,_,[],_,Res,Res). arranjo___1(Max,R,O,M,A,C,E,[G|H],Nova,Lista,Res) :append(Nova,[R],Nova1), append(Nova1,[O],Nova2), append(Nova2,[M],Nova3), append(Nova3,[A],Nova4), append(Nova4,[C],Nova5), append(Nova5,[E],Nova6), append(Nova6,[G],Nova7), sum_list(Nova7,Soma), ( Max == 0, ( append(Lista,[Nova7],Aux), arranjo___1(Max,R,O,M,A,C,E,H,[],Aux,Res) 42 EDITOR E GERADOR DE PLANTAS DE CASA RELATÓRIO FINAL ) ; ( Soma == Max,!, ( append(Lista,[Nova7],Aux), arranjo___1(Max,R,O,M,A,C,E,H,[],Aux,Res) ) ; arranjo___1(Max,R,O,M,A,C,E,H,[],Lista,Res) ) ). arranjo___2(_,_,_,_,_,_,[],_,Lista,Lista). arranjo___2(Max,R,O,M,A,C,[E|F],Lista7,Nova,Lista) :arranjo___1(Max,R,O,M,A,C,E,Lista7,[],Nova_Lista), append(Nova_Lista,Nova,Aux), arranjo___2(Max,R,O,M,A,C,F,Lista7,Aux,Lista). arranjo___3(_,_,_,_,_,[],_,_,Lista,Lista). arranjo___3(Max,R,O,M,A,[C|D],Lista6,Lista7,Nova,Lista) :arranjo___2(Max,R,O,M,A,C,Lista6,Lista7,[],Nova_Lista), append(Nova_Lista,Nova,Aux), arranjo___3(Max,R,O,M,A,D,Lista6,Lista7,Aux,Lista). arranjo___4(_,_,_,_,[],_,_,_,Lista,Lista). arranjo___4(Max,R,O,M,[A|B],Lista5,Lista6,Lista7,Nova,Lista) :arranjo___3(Max,R,O,M,A,Lista5,Lista6,Lista7,[],Nova_Lista), append(Nova_Lista,Nova,Aux), arranjo___4(Max,R,O,M,B,Lista5,Lista6,Lista7,Aux,Lista). arranjo___5(_,_,_,[],_,_,_,_,Lista,Lista). arranjo___5(Max,R,O,[M|N],Lista4,Lista5,Lista6,Lista7,Nova,Lista) :arranjo___4(Max,R,O,M,Lista4,Lista5,Lista6,Lista7,[],Nova_Lista), append(Nova_Lista,Nova,Aux), arranjo___5(Max,R,O,N,Lista4,Lista5,Lista6,Lista7,Aux,Lista). arranjo___6(_,_,[],_,_,_,_,_,Lista,Lista). arranjo___6(Max,R,[O|P],Lista3,Lista4,Lista5,Lista6,Lista7,Nova,Lista) :arranjo___5(Max,R,O,Lista3,Lista4,Lista5,Lista6,Lista7,[],Nova_Lista), append(Nova_Lista,Nova,Aux), arranjo___6(Max,R,P,Lista3,Lista4,Lista5,Lista6,Lista7,Aux,Lista). arranjo___7(_,[],_,_,_,_,_,_,Lista,Lista). arranjo___7(Max,[R|S],Lista2,Lista3,Lista4,Lista5,Lista6,Lista7,Nova,Lista) :arranjo___6(Max,R,Lista2,Lista3,Lista4,Lista5,Lista6,Lista7,[],Nova_Lista), append(Nova_Lista,Nova,Aux), arranjo___7(Max,S,Lista2,Lista3,Lista4,Lista5,Lista6,Lista7,Aux,Lista). /******************************************* Arranjo para 5 ********************************************/ arranjo_5(Lista1,Lista2,Lista3,Lista4,Lista5,Lista6,Lista7,Lista8,Lista) :arranjo____8(Lista1,Lista2,Lista3,Lista4,Lista5,Lista6,Lista7,Lista8,[],Lista). 43 EDITOR E GERADOR DE PLANTAS DE CASA RELATÓRIO FINAL arranjo____1(U,R,O,M,A,C,E,Lista8,_,Res) :arranjo____1(U,R,O,M,A,C,E,Lista8,[],[],Res). arranjo____1(_,_,_,_,_,_,_,[],_,Res,Res). arranjo____1(U,R,O,M,A,C,E,[G|H],Nova,Lista,Res) :append(Nova,[U],Nova1), append(Nova1,[R],Nova2), append(Nova2,[O],Nova3), append(Nova3,[M],Nova4), append(Nova4,[A],Nova5), append(Nova5,[C],Nova6), append(Nova6,[E],Nova7), append(Nova7,[G],Nova8), append(Lista,[Nova8],Aux), arranjo____1(U,R,O,M,A,C,E,H,[],Aux,Res). arranjo____2(_,_,_,_,_,_,[],_,Lista,Lista). arranjo____2(U,R,O,M,A,C,[E|F],Lista8,Nova,Lista) :arranjo____1(U,R,O,M,A,C,E,Lista8,[],Nova_Lista), append(Nova_Lista,Nova,Aux), arranjo____2(U,R,O,M,A,C,F,Lista8,Aux,Lista). arranjo____3(_,_,_,_,_,[],_,_,Lista,Lista). arranjo____3(U,R,O,M,A,[C|D],Lista7,Lista8,Nova,Lista) :arranjo____2(U,R,O,M,A,C,Lista7,Lista8,[],Nova_Lista), append(Nova_Lista,Nova,Aux), arranjo____3(U,R,O,M,A,D,Lista7,Lista8,Aux,Lista). arranjo____4(_,_,_,_,[],_,_,_,Lista,Lista). arranjo____4(U,R,O,M,[A|B],Lista6,Lista7,Lista8,Nova,Lista) :arranjo____3(U,R,O,M,A,Lista6,Lista7,Lista8,[],Nova_Lista), append(Nova_Lista,Nova,Aux), arranjo____4(U,R,O,M,B,Lista6,Lista7,Lista8,Aux,Lista). arranjo____5(_,_,_,[],_,_,_,_,Lista,Lista). arranjo____5(U,R,O,[M|N],Lista5,Lista6,Lista7,Lista8,Nova,Lista) :arranjo____4(U,R,O,M,Lista5,Lista6,Lista7,Lista8,[],Nova_Lista), append(Nova_Lista,Nova,Aux), arranjo____5(U,R,O,N,Lista5,Lista6,Lista7,Lista8,Aux,Lista). arranjo____6(_,_,[],_,_,_,_,_,Lista,Lista). arranjo____6(U,R,[O|P],Lista4,Lista5,Lista6,Lista7,Lista8,Nova,Lista) :arranjo____5(U,R,O,Lista4,Lista5,Lista6,Lista7,Lista8,[],Nova_Lista), append(Nova_Lista,Nova,Aux), arranjo____6(U,R,P,LLista4,Lista5,Lista6,Lista7,Lista8,Aux,Lista). arranjo____7(_,[],_,_,_,_,_,_,Lista,Lista). arranjo____7(U,[R|S],Lista3,Lista4,Lista5,Lista6,Lista7,Lista8,Nova,Lista) :arranjo____6(U,R,Lista3,Lista4,Lista5,Lista6,Lista7,Lista8,[],Nova_Lista), append(Nova_Lista,Nova,Aux), arranjo____7(U,S,Lista3,Lista4,Lista5,Lista6,Lista7,Lista8,Aux,Lista). arranjo____8([],_,_,_,_,_,_,_,Lista,Lista). 44 EDITOR E GERADOR DE PLANTAS DE CASA RELATÓRIO FINAL arranjo____8([U|V],Lista2,Lista3,Lista4,Lista5,Lista6,Lista7,Lista8,Nova,Lista) :arranjo____7(U,Lista2,Lista3,Lista4,Lista5,Lista6,Lista7,Lista8,[],Nova_Lista), append(Nova_Lista,Nova,Aux), arranjo____8(V,Lista2,Lista3,Lista4,Lista5,Lista6,Lista7,Lista8,Aux,Lista). %*************************************************** % Predicados que servem de auxilio ao nosso programa %*************************************************** imprime_divisoes([]). imprime_divisoes([Divisao|Resto]):write(Divisao),nl, imprime_divisoes(Resto). /*************************************************/ todos_iguais([],_). todos_iguais([A|B],N) :A == N, todos_iguais(B,N). /*************************************************/ add(X,[],[X]). add(X,Lista,Nova):- Nova = [X|Lista]. /*************************************************/ maximo([X], X). maximo([X,Y|T], Max) :maximo([Y|T], M), max(X, M, Max). max(X, Y, X) :- X >= Y. max(X, Y, Y) :- Y > X. /*************************************************/ inverter([], []). inverter([H|T], R) :inverter(T, RT), inserir_cauda(H, RT, R). inserir_cauda(X, [], [X]). inserir_cauda(X, [H|T], [H|T1]) :inserir_cauda(X, T, T1). /*************************************************/ pertence([A|B],[[A|B]|_]). pertence([A|B],[_|T]) :- pertence([A|B],T). 45 EDITOR E GERADOR DE PLANTAS DE CASA RELATÓRIO FINAL Código Java Entrada.java import java.awt.*; public class Entrada extends javax.swing.JFrame { public Entrada() { initComponents(); } private void initComponents() { Entrar = new javax.swing.JButton(); getContentPane().setLayout(new java.awt.GridBagLayout()); setTitle("Gerador de Plantas"); setName("Gerador de Plantas"); addWindowListener(new java.awt.event.WindowAdapter() { public void windowClosing(java.awt.event.WindowEvent evt) { exitForm(evt); } }); Entrar.setIcon(new javax.swing.ImageIcon("Z:\\IA\\IA\\Java\\inicial.JPG")); Entrar.setText("Entrar"); Entrar.setPreferredSize(new java.awt.Dimension(700, 600)); Entrar.addMouseListener(new java.awt.event.MouseAdapter() { public void mousePressed(java.awt.event.MouseEvent evt) { EntrarMouseClicked(evt); } }); getContentPane().add(Entrar, new java.awt.GridBagConstraints()); pack(); Dimension screenSize = getToolkit().getScreenSize(); setLocation((screenSize.width - getSize().width) / 2,(screenSize.height - getSize().height) / 2); } private void EntrarMouseClicked(java.awt.event.MouseEvent evt) { Gerador_Plantas gp = new Gerador_Plantas(); gp.setExtendedState(java.awt.Frame.MAXIMIZED_BOTH); gp.show(); dispose(); } private void exitForm(java.awt.event.WindowEvent evt) { System.exit(0); } 46 EDITOR E GERADOR DE PLANTAS DE CASA RELATÓRIO FINAL public static void main(String args[]) { new Entrada().show(); } private javax.swing.JButton Entrar; } Gerador_Plantas.java import java.awt.*; import java.awt.event.*; public class Gerador_Plantas extends javax.swing.JFrame { Inicial inicial; public Gerador_Plantas() { initComponents(); jButton1.setEnabled(false); jButton2.setEnabled(false); inicial = new Inicial(Plantas); Dimension screenSize = getToolkit().getScreenSize(); Dimension inicialDim = inicial.getSize(); inicial.setLocation((screenSize.width - inicialDim.width) / 2,(screenSize.height - inicialDim.height) / 2); } private void initComponents() { java.awt.GridBagConstraints gridBagConstraints; Plantas = new Planta(); jPanel1 = new javax.swing.JPanel(); jButton2 = new javax.swing.JButton(); jButton1 = new javax.swing.JButton(); jMenu = new javax.swing.JMenuBar(); Menu = new javax.swing.JMenu(); nova_planta = new javax.swing.JMenuItem(); Separador = new javax.swing.JSeparator(); Sair = new javax.swing.JMenuItem(); getContentPane().setLayout(new java.awt.GridBagLayout()); setTitle("Gerador Plantas"); setBackground(new java.awt.Color(204, 204, 204)); setName("Gerador Plantas"); addWindowListener(new java.awt.event.WindowAdapter() { public void windowClosing(java.awt.event.WindowEvent evt) { exitForm(evt); } }); Plantas.setLayout(new java.awt.GridBagLayout()); 47 EDITOR E GERADOR DE PLANTAS DE CASA RELATÓRIO FINAL Plantas.setBorder(new javax.swing.border.MatteBorder(null)); Plantas.setName("Plantas"); Plantas.setPreferredSize(new java.awt.Dimension(500, 500)); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 0; getContentPane().add(Plantas, gridBagConstraints); jButton2.setText("Planta Anterior"); jPanel1.add(jButton2); jButton1.setText("Proxima Planta"); jPanel1.add(jButton1); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 2; getContentPane().add(jPanel1, gridBagConstraints); Menu.setText("Menu"); nova_planta.setText("Gerar novas plantas"); nova_planta.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { inicial.show(); jButton1.setEnabled(true); jButton2.setEnabled(true); } } ); jButton1.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { inicial.nextCasa(); } } ); jButton2.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { inicial.prevCasa(); } } ); 48 EDITOR E GERADOR DE PLANTAS DE CASA RELATÓRIO FINAL Menu.add(nova_planta); Menu.add(Separador); Sair.setText("Sair"); Sair.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { System.exit(0); } }); Menu.add(Sair); jMenu.add(Menu); setJMenuBar(jMenu); pack(); } private void exitForm(java.awt.event.WindowEvent evt) { System.exit(0); } public static void main(String args[]) { new Gerador_Plantas().show(); } private javax.swing.JButton jButton2; private javax.swing.JMenuItem Sair; private javax.swing.JMenuItem nova_planta; private javax.swing.JButton jButton1; private Planta Plantas; private javax.swing.JMenuBar jMenu; private javax.swing.JPanel jPanel1; private javax.swing.JSeparator Separador; private javax.swing.JMenu Menu; } Inicial.java public class Inicial extends javax.swing.JDialog { Ligacao ligacao; Planta planta; public Inicial(Planta planta) { this.planta = planta; initComponents(); } private void initComponents() { 49 EDITOR E GERADOR DE PLANTAS DE CASA RELATÓRIO FINAL java.awt.GridBagConstraints gridBagConstraints; NQuartos = new javax.swing.ButtonGroup(); Obrigatorio = new javax.swing.JPanel(); Area_Max = new javax.swing.JLabel(); Maximo = new javax.swing.JTextField(); Area_Min = new javax.swing.JLabel(); Minimo = new javax.swing.JTextField(); jComboBox1 = new javax.swing.JComboBox(); jLabel1 = new javax.swing.JLabel(); Novas_Plantas = new javax.swing.JPanel(); Nova = new javax.swing.JButton(); getContentPane().setLayout(new java.awt.GridBagLayout()); addWindowListener(new java.awt.event.WindowAdapter() { public void windowClosing(java.awt.event.WindowEvent evt) { exitForm(evt); } }); Obrigatorio.setLayout(new java.awt.GridBagLayout()); Obrigatorio.setBorder(new javax.swing.border.MatteBorder(null)); Obrigatorio.setToolTipText(""); Obrigatorio.setName("Obrigatorio"); Area_Max.setText("Area Maxima"); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 1; gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; gridBagConstraints.ipadx = 10; gridBagConstraints.ipady = 10; Obrigatorio.add(Area_Max, gridBagConstraints); Maximo.setText("0"); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 1; gridBagConstraints.gridy = 1; gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; Obrigatorio.add(Maximo, gridBagConstraints); Area_Min.setText("Area Minima"); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 2; gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; gridBagConstraints.ipadx = 10; gridBagConstraints.ipady = 10; Obrigatorio.add(Area_Min, gridBagConstraints); Minimo.setText("0"); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 1; 50 EDITOR E GERADOR DE PLANTAS DE CASA RELATÓRIO FINAL gridBagConstraints.gridy = 2; gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; Obrigatorio.add(Minimo, gridBagConstraints); jComboBox1.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "T1", "T2", "T3", "T4" })); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 1; gridBagConstraints.gridy = 0; Obrigatorio.add(jComboBox1, gridBagConstraints); jLabel1.setText("Tipo de Casa"); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 0; gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; Obrigatorio.add(jLabel1, gridBagConstraints); getContentPane().add(Obrigatorio, new java.awt.GridBagConstraints()); Novas_Plantas.setLayout(new java.awt.GridBagLayout()); Nova.setText("Nova_Planta"); Nova.addMouseListener(new java.awt.event.MouseAdapter() { public void mouseClicked(java.awt.event.MouseEvent evt) { NovaMouseClicked(evt); } }); Novas_Plantas.add(Nova, new java.awt.GridBagConstraints()); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 1; gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; gridBagConstraints.insets = new java.awt.Insets(15, 0, 0, 0); getContentPane().add(Novas_Plantas, gridBagConstraints); setSize(new java.awt.Dimension(300,200)); } private void NovaMouseClicked(java.awt.event.MouseEvent evt) { int minimo = 50; int maximo =60; int tipo = 2; try{ Integer i = new Integer(Minimo.getText()); minimo = i.intValue(); maximo = Integer.parseInt(Maximo.getText()); tipo = (jComboBox1.getSelectedIndex() + 1); System.out.println(jComboBox1.getSelectedIndex()); 51 EDITOR E GERADOR DE PLANTAS DE CASA RELATÓRIO FINAL } catch(NumberFormatException e){ System.out.println(e.toString()); } System.out.println("Este e' a minima"+minimo); System.out.println("Este e' a maxima"+maximo); System.out.println("Este e' o tipo "+tipo); this.hide(); ligacao =new Ligacao(tipo,minimo,maximo, this.planta); } private void exitForm(java.awt.event.WindowEvent evt) { System.exit(0); } public void nextCasa(){ ligacao.nextCasa(); } public void prevCasa(){ ligacao.prevCasa(); } private javax.swing.JPanel Novas_Plantas; private javax.swing.JLabel jLabel1; private javax.swing.JLabel Area_Min; private javax.swing.JTextField Maximo; private javax.swing.JPanel Obrigatorio; private javax.swing.ButtonGroup NQuartos; private javax.swing.JButton Nova; private javax.swing.JComboBox jComboBox1; private javax.swing.JTextField Minimo; private javax.swing.JLabel Area_Max; } Ligacao.java import se.sics.jasper.*; import se.sics.jasper.Jasper; import se.sics.jasper.Prolog; import se.sics.jasper.Term; import java.util.HashMap; import java.util.*; import javax.swing.*; public class Ligacao { 52 EDITOR E GERADOR DE PLANTAS DE CASA RELATÓRIO FINAL Prolog prolog; SICStus sp; Query query; HashMap wayMap = new HashMap(); Planta planta; LinkedList lista; ListIterator listaItr; int tipo; public Ligacao(int tipo, int minimo, int maximo, Planta planta){ this.tipo = tipo; this.planta = planta; try { prolog = Jasper.newProlog(null,null,"z:\\gerador_plantas.sav"); } catch(Exception e) { JOptionPane.showMessageDialog(null,"Unable to initialize the connection with prolog","",JOptionPane.INFORMATION_MESSAGE); System.exit(1); } try { if(!(prolog.query("teste(" + tipo + "," + minimo + "," + maximo + ",ListaFinal).", wayMap))) { JOptionPane.showMessageDialog(null,"Error: while running the Prolog module ","",JOptionPane.INFORMATION_MESSAGE); System.exit(0); } Term listaFinal = (Term) wayMap.get("ListaFinal"); LinkedList casas = new LinkedList(); StringTokenizer tokenizerCasas = new StringTokenizer(listaFinal.toString(), ",.([])", false); while(tokenizerCasas.hasMoreTokens()) { String actual = tokenizerCasas.nextToken(); System.out.println(actual); casas.addLast(actual); } int divisoes=0; switch(tipo) { case 1: divisoes = 6; break; case 2: divisoes = 7; break; case 3: divisoes = 8; break; case 4: divisoes = 9; break; default: break; } ListIterator itr = casas.listIterator(); lista = new LinkedList(); while(itr.hasNext()){ LinkedList plantaLista = new LinkedList(); 53 EDITOR E GERADOR DE PLANTAS DE CASA RELATÓRIO FINAL for(int i = 0; i < divisoes; i++){ for(int j = 0, k = 0; j < 4; j++, k++){ plantaLista.addLast(itr.next()); } } lista.addLast(plantaLista); System.out.println("planta: "+ plantaLista); } listaItr = lista.listIterator(); } catch(Exception e) { JOptionPane.showMessageDialog(null,"Unable to initialize the connection with prologn" + e,"",JOptionPane.INFORMATION_MESSAGE); System.exit(1); } } public void nextCasa(){ if(listaItr.hasNext()) planta.nextCasa((LinkedList) listaItr.next(), tipo); else javax.swing.JOptionPane.showMessageDialog(planta, " Não existem Plantas disponiveis"); } public void prevCasa(){ if(listaItr.hasPrevious()) planta.nextCasa((LinkedList) listaItr.previous(), tipo); else javax.swing.JOptionPane.showMessageDialog(planta, " Não existem Plantas disponiveis"); } } Planta.java import java.awt.*; import java.util.*; public class Planta extends javax.swing.JPanel { int tipo = 0; LinkedList divisoes; String [] nomes1 = {"","Corredor","Banho","Cozinha","Quarto","Sala"}; String [] nomes2= {"","Corredor","Banho","Cozinha","Quarto1","Quarto2","Sala"}; String [] nomes3 = {"","Corredor","Banho1","Banho2","Cozinha","Quarto1","Quarto2","Quarto3","Sala"}; String [] nomes4 = {"","Corredor","Banho1","Quarto1","Quarto2","Suite1","Suite2","Sala","Sala+Coz"}; 54 EDITOR E GERADOR DE PLANTAS DE CASA RELATÓRIO FINAL Color [] cor = {Color.blue,Color.green,Color.yellow,Color.red,Color.magenta,Color.cyan,Color.white,Color.darkGray,Co lor.orange}; public Planta() { divisoes = new LinkedList(); initComponents(); } private void initComponents() { setLayout(new java.awt.GridBagLayout()); setPreferredSize(new java.awt.Dimension(500, 500)); setBackground(Color.lightGray); } public void paint_aux(Graphics elemento,LinkedList planta, String nome, Color cor){ System.out.println("Novos valores: " + planta); int coord_y=Integer.parseInt((String) planta.get(0)); int coord_x=Integer.parseInt((String) planta.get(1)); int altura=Integer.parseInt((String) planta.get(2)); int largura=Integer.parseInt((String) planta.get(3)); int nova_altura = altura*40; int nova_largura = largura*40; int nova_coord_x= coord_x*40; int nova_coord_y= coord_y*40; elemento.setColor(cor); elemento.fillRect(nova_coord_x,450-nova_coord_y-nova_altura,nova_largura,nova_altura); elemento.setColor(Color.blue); elemento.drawRect(nova_coord_x,450-nova_coord_y-nova_altura,nova_largura,nova_altura); elemento.drawString(nome,nova_coord_x,450-nova_coord_y + (-nova_altura/2)); } public void paint(Graphics elemento){ super.paint(elemento); String nome = ""; int counter = 0; ListIterator itr = divisoes.listIterator(); while(itr.hasNext()){ if(tipo == 1) nome = nomes1[counter]; if(tipo == 2) nome = nomes2[counter]; if(tipo == 3) nome = nomes3[counter]; if(tipo == 4) nome = nomes4[counter]; paint_aux(elemento, (LinkedList) itr.next(),nome,cor[counter]); counter ++; 55 EDITOR E GERADOR DE PLANTAS DE CASA RELATÓRIO FINAL } } public void nextCasa(LinkedList casa, int tipo){ this.tipo = tipo; this.divisoes = new LinkedList(); ListIterator itr = casa.listIterator(); while(itr.hasNext()){ LinkedList planta = new LinkedList(); for(int j=0; j <4; j++){ planta.addLast((String) itr.next()); } divisoes.addLast(planta); } repaint(); } } 56 EDITOR E GERADOR DE PLANTAS DE CASA RELATÓRIO FINAL Nome dos elementos do grupo Ana Cláudia Pereira Santos [email protected] Cristina Maria dos Santos Perfeito [email protected] 57