Numa casa de campo existem vários animais.
Alguns animais são domésticos: cães, gatos e pássaros (canários, etc.). Os donos acreditam em dar liberdade completa aos animais, o que causa alguns problemas de interacção nem sempre do agrado geral.
Outros animais, embora vivam na casa ou perto dela, não são oficialmente considerados animais domésticos: ratos, cobras, insectos, aranhas, etc. Estes animais também se deslocam pela propriedade, livre mas nem sempre impunemente.
Todos os animais podem correr (e os pássaros voar), consumindo energia para o efeito. Quando a energia termina, não podem correr mais e têm de dormir para recuperar forças.
Além do repouso, os cães e os gatos podem recuperar energia comendo ratos. Um rato devorado perde, claro está, toda a energia (é transferida para o predador). Os gatos, por serem ágeis, também conseguem comer pássaros (com efeitos muito semelhantes aos da relação gato-rato).
Por vezes, os cães perdem a paciência e atacam os gatos. Ambos perdem energia no processo.
Modele os conceitos "cão", "gato", "pássaro" e "rato". Além da energia, os cães e os gatos têm nome (uma cadeia de caracteres).
Considere que a energia disponível inicialmente para os cães, gatos, pássaros e ratos é, respectivamente, de 1000, 500, 20 e 50 unidades. Quando os animais correm, gastam, respectivamente, 50, 25, 5 e 2 unidades. Um pássaro, quando voa, gasta apenas 2 unidades. Um cão que ataque um gato gasta 100 unidades e faz com que o gato perca 25.
Para um predador comer uma presa tem de a perseguir para a capturar (podendo a perseguição ser ou não bem sucedida). Um cão consegue capturar um rato em cada 25 tentativas. Para os gatos, o rácio é 1 em 5 (ratos) e 1 em 10 (pássaros). A perseguição consome a mesma energia que correr (para cada interveniente), mas a presa recebe um bónus de 5 unidades se escapar. Se a presa estiver a dormir, é apanhada 1 em cada 2 tentativas.
Construa uma aplicação onde existem 2 cães ("Piloto" e "Átila"), 3 gatos ("Tareco", "Pantufa" e "Kitty"), 20 pássaros e 50 ratos (os pássaros e ratos podem ser organizados em arrays).
Neste cenário, os gatos correm, perseguem pássaros e ratos e são atacados pelos cães, que também podem correr e perseguir e comer ratos. Os animais dormem automaticamente se ficam sem energia (excepto quando são devorados: nesse caso devem ser considerados mortos).
Apresente o estado inicial dos animais (métodos toString) e o estado final (depois de algumas interacções).
(Pode utilizar parte do resultado do Exercício 01 na resolução deste exercicio.)
A solução apresentada procura manter-se simples e a um nível que ainda não implica utilizar abstracção de propriedade comuns, como por exemplo, a energia, ou de conceitos mais básicos (o de Animal, por exemplo). Estes aspectos, necessários numa boa definição de solução, são objecto de estudo em fases mais adiantadas da exposição da matéria.
Neste caso, como se escolheu (dada a fase introdutória) não representar os conceitos hierarquizados, apenas existem relações de dependência entre as classes (representadas pelas setas a tracejado).
Existem opções de desenho sub-óptimas. Consegue detectá-las?
BUG: o método "escaped" deveria ter como tipo de retorno "void" e não "boolean".
Diagrama de classes |
---|
Ficheiro Dog.java |
---|
{{{2}}} |
Ficheiro Cat.java |
---|
{{{2}}} |
Ficheiro Mouse.java |
---|
{{{2}}} |
Ficheiro Bird.java |
---|
{{{2}}} |
Este programa implementa o cenário descrito no enunciado do problema. <java5> @SuppressWarnings("nls") public class Application {
/** * @param args */ public static void main(String[] args) { Dog d1 = new Dog("Piloto"); Dog d2 = new Dog("Átila");
Cat c1 = new Cat("Tareco"); Cat c2 = new Cat("Pantufa"); Cat c3 = new Cat("Kitty");
Bird[] birds = new Bird[20]; for (int ix = 0; ix < birds.length; ix++) birds[ix] = new Bird();
Mouse[] mice = new Mouse[50]; for (int ix = 0; ix < mice.length; ix++) mice[ix] = new Mouse();
// snapshot: present everything System.out.println("BEFORE"); System.out.println(d1); System.out.println(d2); System.out.println(c1); System.out.println(c2); System.out.println(c3);
for (int ix = 0; ix < birds.length; ix++) System.out.println(birds[ix]);
for (int ix = 0; ix < mice.length; ix++) System.out.println(mice[ix]);
// run, chase, eat, sleep, etc.
for (int ix = 0; ix < birds.length; ix++) birds[ix].fly();
d1.run(); d2.attackCat(c1); c2.eatBird(birds[2]); c3.eatBird(birds[9]); c3.eatMouse(mice[0]); d2.eatMouse(mice[1]); mice[3].run();
// snapshot: present everything System.out.println("AFTER"); System.out.println(d1); System.out.println(d2); System.out.println(c1); System.out.println(c2); System.out.println(c3);
for (int ix = 0; ix < birds.length; ix++) System.out.println(birds[ix]);
for (int ix = 0; ix < mice.length; ix++) System.out.println(mice[ix]);
} } </java5>
A compilação processa-se como indicado (poder-se-ia compilar ficheiro a ficheiro):
javac Dog.java Cat.java Mouse.java Bird.java javac Application.java
De facto, a compilação do ficheiro Application.java seria suficiente para causar a compilação de todos os outros, já que são referidos a partir dele (o compilador de Java é capaz de seguir dependências explícitas entre classes).
O programa começa a sua execução na função main da classe escolhida para iniciar a aplicação (neste caso, Application):
java Application