package animal.
dino;
import infra.Enclos;
public abstract class Dinosaure {
private int force = 4;
private Enclos<? extends Dinosaure> enclos = null;
public abstract void manger() throws LooseDinosaureException;
public Dinosaure(){
public Dinosaure(int force) {
this.force=force;
}
public Enclos<? extends Dinosaure> getEnclos() {
return enclos;
}
public void setEnclos(Enclos<? extends Dinosaure> enclos) {
this.enclos = enclos;
}
public int getForce() {
return force;
}
package animal.dino;
public class LooseDinosaureException extends Exception {
private Dinosaure d;
public Dinosaure getD() {
return d;
}
public LooseDinosaureException(Dinosaure d) {
super(d + "is on the loose!");
this.d = d;
}
public LooseDinosaureException() {
// TODO Auto-generated constructor stub
}
public LooseDinosaureException(String message) {
super(message);
// TODO Auto-generated constructor stub
}
public LooseDinosaureException(Throwable cause) {
super(cause);
// TODO Auto-generated constructor stub
}
public LooseDinosaureException(String message, Throwable cause) {
super(message, cause);
// TODO Auto-generated constructor stub
}
public LooseDinosaureException(String message, Throwable cause, boolean
enableSuppression,
boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
// TODO Auto-generated constructor stub
}
package animal.dino;
public class Ornitischien extends Dinosaure {
public Ornitischien() {
}
public Ornitischien(int force) {
super(force);
}
@Override
public void manger() {
System.out.println(this + " is eating grass: Om Nom Nom");
}
package animal.dino;
import java.util.Iterator;
public class Theropode extends Dinosaure {
public Theropode() {
// TODO Auto-generated constructor stub
}
public Theropode(int force) {
super(force);
// TODO Auto-generated constructor stub
}
@Override
public void manger() throws LooseDinosaureException {
//tout nouvel appel à la méthode lancera l'exception
//on lance l'exception si un carnivore essaie de manger pas dans un
enclose
if(this.getEnclos()==null) throw new LooseDinosaureException(this);
@SuppressWarnings("unchecked")
Iterator<Dinosaure> it = (Iterator<Dinosaure>)
this.getEnclos().getDinos().iterator();
boolean eaten = false;
Dinosaure d = null;
while(it.hasNext() && !eaten) {
d = it.next();
if(d instanceof Ornitischien && d.getForce()<this.getForce()) {
it.remove();
d.setEnclos(null);
System.out.println(this + "just ate " + d + " !");
}
}
if(!eaten && this.getForce()>this.getEnclos().getRobustesse()) {
throw new LooseDinosaureException(this);
}
package animal.humains;
public class Employe extends Humain {
private String fonction;
public Employe(String nom, String fonction) {
super(nom);
this.fonction=fonction;
}
public Employe(String nom) {
this(nom,"");
}
public Employe() {
this("","");
}
}
package animal.humains;
public class Humain {
String nom;
public Humain() {
}
public Humain(String nom) {
this.nom = nom;
}
public String getNom() {
return nom;
}
public void setNom(String nom) {
this.nom = nom;
}
package animal.humains;
public class Visiteur {
private static int count = 0;
private final int id = count++;
public int getId() {
return id;
}
package infra;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import animal.dino.Dinosaure;
import animal.humains.Employe;
import animal.humains.Visiteur;
public class Case {
//Pas forcément utile, juste pour le print,
// id de case
private static int countCase = 0;
private final int id = countCase ++;
//Contenu de la case
Set<Visiteur> mesVisiteurs = new HashSet<>();
Set<Dinosaure> mesDinos = new HashSet<>();
//pour chercher des Employés en fonction de leur fonction
Map<String,Set<Employe>> mesEmployes = new HashMap<>();
public Set<Dinosaure> getMesDinos(){
return mesDinos;
public int getId() {
return this.id;
public void setMesEmployes(Map<String,Set<Employe>> emp ) {
this.mesEmployes=emp;
}
public void setMesVisiteurs(Set<Visiteur> vis) {
this.mesVisiteurs=vis;
public Map<String, Set<Employe>> getMesEmployes() {
return mesEmployes;
public Set<Visiteur> getMesVisiteurs(){
return this.mesVisiteurs;
public String toString() {
String s = new String();
s+= "----------Case" + this.id + "----------\n";
s+="Employes \t ";
for(Set<Employe> c : mesEmployes.values()) {
for(Employe e : c) s+= e +"\t";
s+="\nVisiteurs \t";
for(Visiteur v : mesVisiteurs) s+= v +"\t";
s+="\nDinosaures \t";
for(Dinosaure d : mesDinos) s+= d +"\t";
s +="\n\n";
return s;
}
public void setMesDinos(Set<Dinosaure> mesDinos) {
this.mesDinos = mesDinos;
package infra;
import java.util.HashSet;
import java.util.Set;
import animal.dino.Dinosaure;
import animal.dino.LooseDinosaureException;
public class Enclos<T extends Dinosaure> {
private Set<T> dinos = new HashSet<>();
private int robustesse = 5;
private Case adjacente;
public Case getAdjacente() {
return adjacente;
public void setAdjacente(Case adjacente) {
this.adjacente = adjacente;
}
public Enclos() {
public Enclos(int r) {
robustesse = r;
public Set<T> getDinos() {
return dinos;
public void setDinos(Set<T> dinos) {
this.dinos = dinos;
public int getRobustesse() {
return robustesse;
public void setRobustesse(int robustesse) {
this.robustesse = robustesse;
}
//Exception à gérer dans le tour de jeu
public void nourrirTous() throws LooseDinosaureException {
//on fait une copie de la collection pour éviter un parcours imbriqué avec modification
// on suppose que l'ordre dans lequel les dinos mangent importe peu
Set<T> mesDinos = new HashSet<> (dinos);
for(T t : mesDinos) t.manger();
public void addDino(T dino) {
dinos.add(dino);
dino.setEnclos(this);
//un peu de cosmétique
public String toString() {
String s = new String();
s= "-------Enclos----------- \n";
s+= "accès Case"+adjacente.getId() + "\n";
for(Dinosaure d : dinos) s += d + "\n";
s+="------------------------ \n";
return s;
package infra;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import animal.dino.Dinosaure;
import animal.dino.LooseDinosaureException;
import animal.humains.Employe;
import animal.humains.Visiteur;
public class Zoo {
private Set<Enclos<? extends Dinosaure>> enclos = new HashSet<>();
private List<Case> cases = new ArrayList<Case>();
// lors d'un tour, si des dinos doivent changer de case, on les stockera ici
private Map<Case, List<Dinosaure>> dinosToMove = new HashMap<>();
public List<Case> getCases() {
return cases;
public void setCases(List<Case> cases) {
this.cases = cases;
public Set<Enclos<? extends Dinosaure>> getEnclos() {
return enclos;
public void setEnclos(Set<Enclos<? extends Dinosaure>> enclos) {
this.enclos = enclos;
public String toString() {
String s = new String();
s += "\n***** ZOO *****\n";
for(Case c : cases)s+=c.toString();
for(Enclos<?> e : enclos) s+= e.toString();
return s;
public void tourDeJeu() {
Random rnd = new Random();
System.out.println("Nouveau tour");
//Les visiteurs avancent && gestion des dinos en dehors des enclos
ListIterator<Case> it = cases.listIterator(cases.size());
Case c = cases.getLast();
Case cp = null;
while(it.hasPrevious()) {
//les visiteurs avancent
cp = it.previous();
c.setMesVisiteurs(cp.getMesVisiteurs());
c = cp;
it = cases.listIterator(cases.size());
while(it.hasPrevious()) {
c = it.previous();
//on fait manger les dinos sur la case
for(Dinosaure d : c.getMesDinos()) {
System.out.println(d + " is on Case" + c.getId());
try {
d.manger();
} catch (LooseDinosaureException e) {
System.out.println("Loose dino!");
this.gererLooseDino(d, c);
// il n'y a plus de dinos sur la case (tués ou bougés)
c.setMesDinos(new HashSet<>());
// On mets les dinos dans leur nouvelle case
for(Case c2 : dinosToMove.keySet()) {
for(Dinosaure d2: dinosToMove.get(c2)) c2.getMesDinos().add(d2);
dinosToMove = new HashMap<>();
// Entrée des nouveaux visiteurs
int i = rnd.nextInt(4);
HashSet<Visiteur> visiteurs = new HashSet<>();
for(int j=0; j<i; j++) visiteurs.add(new Visiteur());
cp.setMesVisiteurs(visiteurs);
// Les dinosaures dans les enclos mangent
for(Enclos<?> e : enclos )
try {
e.nourrirTous();
} catch (LooseDinosaureException e1) {
//on retire le dino de son enclos et on le mets dans la case adjacente à
l'enclos
e1.getD().setEnclos(null);
e.getDinos().remove(e1.getD());
e.getAdjacente().getMesDinos().add(e1.getD());
//le dino ne mange pas à ce tour
// Si un chasseur est assez proche, il tue le dino
//Sinon le dino mange et se déplace + on cherche des chasseurs
//méthode cracra qui mériterait d'être split
private void gererLooseDino(Dinosaure d, Case c) {
int index = this.getCases().indexOf(c);
ListIterator<Case> it1 = this.getCases().listIterator(index+1);
ListIterator<Case> it2 = this.getCases().listIterator(index);
Case pcase = c;
Case ncase = c;
if(it1.hasNext()) ncase = it1.next();
if(it2.hasPrevious()) pcase = it2.previous();
if(c.getMesEmployes().containsKey("Chasseur") ||
ncase.getMesEmployes().containsKey("Chasseur") || pcase.getMesEmployes().containsKey("Chasseur")
){
//on tue le dino!
//il sera remove dans la méthode appelante
System.out.println("PAN " + d);
return;
else {
// le dino mange le premier visiteur
if(!(c.getMesVisiteurs()).isEmpty()) {
Visiteur v = c.getMesVisiteurs().iterator().next();
c.getMesVisiteurs().remove(v);
System.out.println(d + " just ate " + v);
//le dino se déplace.
//idem on ne gere pas le cas où la case est la sortie ou l'entrée
Case newCase = pcase;
Random rd = new Random();
if(rd.nextBoolean()) newCase = ncase;
//on mettra le dino dans newCase dans tour de jeu après le parcours des cases
System.out.println("moving to " + newCase);
dinosToMove.putIfAbsent(newCase, new ArrayList<Dinosaure>());
dinosToMove.get(newCase).add(d);
//on ramene les chasseurs
boolean found=false;
Set<Employe> chasseurs;
while(it1.hasNext()&&!found) {
ncase = it1.next();
if(ncase.getMesEmployes().containsKey("Chasseur") ) {
found = true;
chasseurs = ncase.getMesEmployes().remove("Chasseurs");
it1.previous().getMesEmployes().put("Chasseur", chasseurs);
while(it2.hasPrevious()&&!found) {
pcase = it2.previous();
if(pcase.getMesEmployes().containsKey("Chasseur") ) {
found = true;
chasseurs = pcase.getMesEmployes().remove("Chasseurs");
it2.next().getMesEmployes().put("Chasseur", chasseurs);