Problème programme Java [Débutant]

Fermé
mystiikk70 Messages postés 2 Date d'inscription mardi 12 mai 2015 Statut Membre Dernière intervention 12 mai 2015 - 12 mai 2015 à 20:37
luckydu43 Messages postés 3992 Date d'inscription vendredi 9 janvier 2015 Statut Membre Dernière intervention 2 janvier 2025 - 12 mai 2015 à 22:21
Bonjour, je requiert votre aide car je n'arrive pas a faire fonctionner mon programme.. Je vous expose donc le problème : Il faut réaliser un programme permettant la simulation de l'évacuation d'une salle. Une salle est modélisée par un rectangle de n sur m mètres (n*m m2). La salle est décomposée en un damier de n*m cellules carrées de 1 mètre sur 1 mètre. Chacune de ces cellules peut contenir au maximum 8 personnes. La contenance de la salle est donc d'au maximum n*m*8 personnes.
nb personnes sont réparties au hasard dans la salle (nb < n*m*8) en respectant la règle des 8 occupants maximum par cellule. Le mur nord est percé de l'unique porte de sortie de la salle. Celle-ci fait 2 mètres de large et est placée au milieu du mur (Figure 3a).
On cherche à savoir combien de temps est nécessaire à l'évacuation complète de la salle par ses occupants. Le pas de temps choisi pour la simulation est de 1 seconde. A chaque seconde, les événements suivants sont évalués et gérés:
- Tous les occupants situés dans les cellules adjacentes à la sortie sortent et disparaissent de la simulation.
- Les autres occupants sont traités en ordre aléatoire.
- Lorsqu'un occupant est traité, il essaie de rejoindre la cellule adjacente à la cellule où il est placé qui le rapproche le plus de la sortie. Le nombre maximum d'occupants par cellule ne pouvant pas dépasser 8, sa tentative de déplacement peut échouer.
Avant de lancer la simulation, l'utilisateur devra donner les paramètres suivants:
- Dimensions en x et en y de la salle (en mètres)
- Nombre d'occupants initialement placés dans la salle
Le simulateur sera implanté sous la forme d'une boucle infinie de gestion de ce qui se passe seconde après seconde. Ainsi, à chaque seconde divers événements peuvent arriver qu'il convient de gérer:
- Sortie des occupants situés à coté de la porte
- Déplacement des autres occupants

Voilà le problème assez bien détailler.

Maintenant voici mon programme complet, avec javadoc et indications et un maximum de variables/nom de fonctions explicites. Si vous avez des questions n'hésitez pas... Je suis débutant en programmation donc je prendrai en compte toute les critiques/aides possibles.. Merci pour votre aide.

/**
@autor REUTER Lucas et GABRIEL Arnaud
**/
public class Sujet3 {

//Constante
    public static final int MAXPERSONNE = 8;
	
/**
Type structure de description d'une position
**/
    static class Position {
        int x=1;
        int y=1;
    }
    
/**
Type structure de description d'une salle
**/
    static class Damier {
        Cellule[] cellules;
        int nbPersonnes;
        private static int N;
        private static int M;
    }
    
/**
Type structure de description d'une cellule
**/
    static class Cellule {
        Personne[] personnes;
        Position p;
        int id;
        int nbOccupant;
        boolean adjacentSortie;
    }
    
/**
Type structure de description d'une personne
**/
    static class Personne {
        Cellule c;
        boolean sortie=false;
    }
    
/**
*Fonction qui récupère les cellules adjacentes
*qui rapproche de la porte de sortie.
*@param c La cellule étudiée.
*@param N La longeur de la salle.
*@param M La largeur de la salle.
*@return solution Tableau  des cellules  adjacentes.
**/ 
    public static int[] recupererCelluleAdjacente(Cellule c) {
        int N;
        N=Damier.N;
        int[] solution = new int[6];
        int ligneDuHaut = c.id - N;
        solution[0] = c.id - 1; //recuperer cellule de gauche
        solution[1] = c.id + 1; //recuperer cellule de droite
        solution[2] = ligneDuHaut; //ecuperer cellule du haut
        solution[3] = ligneDuHaut - 1; //diagonale haut gauche
        solution[4] = ligneDuHaut + 1; //diagonale haut droite

        return solution;
    }
    
/**
*Fonction qui récupère la meilleur des 
*cellules adjacente a la cellule étudiée.
*@param solution Tableau des cellules adjacentes.
*@param damier Damier décrivant la salle.
*@param sorti1 Cellule de sortie numéro 1.
*@param sorti2 Cellule de sortie numéro 2.
*@param N La longeur de la salle.
*@param M La largeur de la salle.
*@return meilleurCellule La meilleur cellule possible. 
**/ 
    public static Cellule recupererMeilleurChoixCellule(int[] solution, Damier damier, Position sortie1, Position sortie2) {

        int cout = 0;
        Cellule meilleurCellule = new Cellule();
        meilleurCellule.id = -1;
        int i;
        for (i = 1; i < solution.length; i++) { // parcours toute les cases
            if (solution[i] > 0 && solution[i] < Damier.N * Damier.M) { // savoir si case courante est dans le tableau
                Cellule cell = rechercheCellule(damier, i); // recherche la cellule dans le damier grace a son id
                if (cell.nbOccupant < MAXPERSONNE) { //cellule pas pleine
                    if (cell.adjacentSortie) { // cellule adjacente a la sortie
                        meilleurCellule = cell; //si cest le cas on la prend
                        break;
                    } else {
                        int coutTmp = 0; // il faut calculer le meilleur cout
                        if (cout == 0) {        //initialise objets
                            meilleurCellule = cell;
                            cout = meilleurCout(cell, sortie1, sortie2);
                        } else { // on recupere le cout de la case suivante
                            coutTmp = meilleurCout(cell, sortie1, sortie2);
                        }
                        if (coutTmp < cout) { // on compare le nombre de cout d'avant et le courant (tmp=courant)
                            cout = coutTmp;
                            meilleurCellule = cell;
                        }
                    }
                }

            }
        }
        return meilleurCellule;
    }

/**
*Fonction qui recherche toute les cellules du damier
*@param damier Le damier décrivant la salle.
*@param id L'id des cellules.
*@return celluleTrouver Retourne les cellules du damier. 
**/ 
    public static Cellule rechercheCellule(Damier damier, int id) {

        int i;
        Cellule celluleTrouver=new Cellule();
        for (i = 0; i < damier.cellules.length; i++) {
            if (id == damier.cellules[i].id) {
                celluleTrouver = damier.cellules[i];
                break;
            }
        }
        return celluleTrouver;
    }
    
/**
*Fonction qui calcule le nombre de déplacement
*horizontale vers la sortie.
*@param cellule La cellule étudiée.
*@param sortie1 Cellule de sortie numéro 1.
*@param sortie2 Cellule de sortie numéro 2.
*@return nbCout Nombre de cout pour arriver à la sortie
**/ 
    public static int nombreDeCoupDeplacementHorizontale(Cellule cellule, Position sortie1, Position sortie2) {

        int nbCout;
        if (cellule.p.x < sortie1.x) { // on est a gauche
            nbCout = sortie1.x - cellule.p.x;
            nbCout += cellule.p.y - sortie1.y;
        } else { // on est a droite
            nbCout = cellule.p.x - sortie2.x;
            nbCout += cellule.p.y - sortie2.y;
        }
        return nbCout;
    }
    
/**
*Fonction qui calcule le nombre de déplacement
*verticale vers la sortie.
*@param cellule La cellule étudiée.
*@param sortie1 Cellule de sortie numéro 1.
*@param sortie2 Cellule de sortie numéro 2.
*@return nbCout Nombre de cout pour arriver à la sortie
**/ 
    public static int nombreDeCoupDeplacementVerticale(Cellule cellule, Position sortie1, Position sortie2) {

        int nbCout = cellule.p.y - sortie1.y;
        if (cellule.p.x < sortie1.x) { // on est a gauche
            nbCout += sortie1.x - cellule.p.x;
        } else { // on est a droite
            nbCout += cellule.p.y - sortie2.y;
        }
        return nbCout;
    }
    
/**
*Fonction qui calcule le nombre de déplacement
*giagonale vers la sortie.
*@param cellule La cellule étudiée.
*@param sortie1 Cellule de sortie numéro 1.
*@param sortie2 Cellule de sortie numéro 2.
*@return nbCout Nombre de cout pour arriver à la sortie
**/ 
    public static int nombreDeCoupDeplacementDiagonale(Cellule cellule, Position sortie1, Position sortie2) {

        boolean stop = false;
        int nbCout = 0;
        int tmpx = 0;
        int tmpy = 0;
	Position courant;


        while (!stop) {
            if (courant.x < sortie1.x) { // on est a gauche
                tmpx = courant.x + 1;
                nbCout++;
            } else { // a droite
                tmpx = courant.x - 1;
                nbCout++;
            }
            tmpy = courant.y - 1;

            courant.x = tmpx;
            courant.y = tmpy;

            if (tmpx == sortie1.x || tmpx == sortie2.x) {
                stop = true;
            }
        }

        nbCout += tmpy - sortie1.y;

        return nbCout;
    }
    
/**
*Fonction qui calcule quel est le meilleur cout 
*pour atteindre la sortie. 
*@param cellule La cellule étudiée.
*@param sortie1 Cellule de sortie numéro 1.
*@param sortie2 Cellule de sortie numéro 2.
*@return nbCout Nombre de cout pour arriver à la sortie
**/ 
    public static int meilleurCout(Cellule cellule, Position sortie1, Position sortie2) {

        int nbCout;
        int tmp;
        nbCout = nombreDeCoupDeplacementDiagonale(cellule, sortie1, sortie2);
        tmp = nombreDeCoupDeplacementVerticale(cellule, sortie1, sortie2);
        if (tmp < nbCout) {
            nbCout = tmp;
        }
        tmp = nombreDeCoupDeplacementHorizontale(cellule, sortie1, sortie2);
        if (tmp < nbCout) {
            nbCout = tmp;
        }
        return nbCout;
    }
    
/**
*Fonction qui initialise le damier. 
*@param N La longeur de la salle.
*@param M La largeur de la salle.
*@return damier Le damier décrivant la salle.
**/ 
    public static Damier initialisation(int N, int M) {
        Damier damier = new Damier();
        Cellule[] cellules = new Cellule[N * M];
        int tmpX=0;
        int tmpY=0;

        int i;
        for (i = 0; i < cellules.length; i++) { //parcourt liste de cellule
            Cellule cellule = new Cellule(); //creation cellule
            cellule.id = i + 1; //mise a jour de l'id
            if (tmpX <= N) { //si on est pas arriver au mur de droite
                tmpY += 1; //incrementation normal

            } else { //sinon on revient au mur de gauche et on change de ligne
                tmpX = 1;
                tmpY += 1;
            }
	    cellule.p.x = tmpX; //mise a jour des positions
            cellule.p.y = tmpY;
            cellule.nbOccupant = (int) Math.random() * MAXPERSONNE;
            damier.nbPersonnes += cellule.nbOccupant ;
            cellule.personnes = new Personne[MAXPERSONNE];
            int j;

            for (j = 0; j < MAXPERSONNE; j++) { //creation personne
                Personne personne = new Personne();
                personne.c = cellule;
                personne.sortie = false;
                cellule.personnes[j] = personne;
            }
            cellule.adjacentSortie = false;
            cellules[i] = cellule;

        }
        damier.cellules = cellules;


        return damier;
    }
    
/**
*Fonction qui fait la simulation de l'évacuation
*@param sortie1 Cellule de sortie numéro 1.
*@param sortie2 Cellule de sortie numéro 2.
*@param damier Le damier décrivant la salle.
*@param personne La personne a déplacer.
*@param c Cellule étudié dans le damier.
**/ 
    public static void Deplacement(Personne personne,Damier damier,Position sortie1, Position sortie2,Cellule c) {
        int i;
        int[] celladj;
        Cellule meillCell;
        for (i = 1; i < damier.cellules.length; i++) {
            if (c.p == sortie1 || c.p == sortie2) {
                personne.sortie = true;
                c.nbOccupant-=1;
                damier.nbPersonnes-=1;
            } else if (c.p != sortie1 || c.p != sortie2) {
                personne.sortie = false;
                celladj = recupererCelluleAdjacente(c);
                meillCell = recupererMeilleurChoixCellule(celladj, damier, sortie1, sortie2);
                if (meillCell.id != -1) {
                    c.nbOccupant-=1;
                    meillCell.nbOccupant+=1;
                }
            }
        }
    }
    
    /**
*Fonction qui fait l'affichage
*@param sortie1 Cellule de sortie numéro 1.
*@param sortie2 Cellule de sortie numéro 2.
*@param damier Le damier décrivant la salle.
**/ 
    public static void affichage(Damier damier,Position sortie1,Position sortie2,Cellule c)
    {
        int i = 638;
        int j = 640 * damier.M / damier.N - 2;
        EcranGraphique.clear();
        EcranGraphique.setColor(255, 0, 0);
        EcranGraphique.drawText(20, 20, 3, "Tx: %d, Ty: %d", new Object[] { Integer.valueOf(damier.N), Integer.valueOf(damier.M) });
        EcranGraphique.drawText(250, 20, 3, "Occupants: %d", new Object[] { Integer.valueOf(damier.nbPersonnes) });
        EcranGraphique.drawText(500, 20, 3, "Temps: %d", new Object[] { Integer.valueOf(9) });
        EcranGraphique.setColor(0, 0, 0);
        EcranGraphique.drawRect(10, 30, 640, 640 * damier.M / damier.N);
        EcranGraphique.setColor(255, 255, 0);
        //int k = (int)(11 + i * paramSalle.pP / paramSalle.tx + 0.5);
        //int m = (int)(11 + i * (paramSalle.pP + paramSalle.lP) / paramSalle.tx + 0.5);
        //EcranGraphique.drawLine(k, 30, m, 30);
        EcranGraphique.setColor(200, 0, 0);
        for (int n = 0; n < damier.nbPersonnes; n++) {
            int i1 = (int)(11.0 + i * c.personnes[n].c.p.x / damier.N + 0.5);
            int i2 = (int)(31.0 + j * c.personnes[n].c.p.y / damier.M + 0.5);
            EcranGraphique.drawPixel(i1, i2);
        }EcranGraphique.flush();
    }

    public static void main(String[] args) {

        int N=300;
        int M=300;
        Position sortie1 = new Position();
        Position sortie2 = new Position();
        Damier damier = initialisation(N, M);
        int x1 = N / 2;
        int x2 = N / 2 + 1;
        damier.cellules[x1].adjacentSortie = true;
        damier.cellules[x2].adjacentSortie = true;
        sortie1.x = x1;
        sortie2.x = x2;
        sortie1.y = 0;
        sortie2.y = 0;
	damier.nbPersonnes=1000;
        Ecran.afficher("Saisir la taille de la salle en x :");
        N=Clavier.saisirInt();
        Ecran.afficher("Saisir la taille de la salle en y : ");
        M=Clavier.saisirInt();
        Ecran.afficher("Saisir le nombre d'occupants : ");
        damier.nbPersonnes=Clavier.saisirInt();
	affichage(damier,sortie1,sortie2,Cellule);
	Deplacement(Personne,damier,sortie1,sortie2,Cellule);
	
    }
}
A voir également:

2 réponses

luckydu43 Messages postés 3992 Date d'inscription vendredi 9 janvier 2015 Statut Membre Dernière intervention 2 janvier 2025 983
Modifié par luckydu43 le 12/05/2015 à 21:43
Bonsoir !
C'est du beau travail. Les variables sont claires et notées en camelCase, présence de commentaires explicites et tout et tout !

Il y a plusieurs problèmes :
- initialiser la Position courant ainsi :
public static int nombreDeCoupDeplacementDiagonale(Cellule cellule, Position sortie1, Position sortie2) {

        boolean stop = false;
        int nbCout = 0;
        int tmpx = 0;
        int tmpy = 0;
 Position courant = new Position();

- Les classes EcranGraphique, Ecran, Clavier ne sont pas présentes
- Ces deux méthodes demandent des objets en paramètre, il y a pourtant une classe dans les deux appels de méthode ;-)
affichage(damier,sortie1,sortie2,Cellule);
 Deplacement(Personne,damier,sortie1,sortie2,Cellule);
 


Si le code est incomplet, il n'est pas possible pour moi d'y dénicher les imperfections ;-)

En te souhaitant bonne continuation en Java !
Les 3 plus grands mensonges du dev : 1. La doc ? On la fera plus tard... 2. Le programme a été testé et ne comporte aucun bug... 3. Les spécifications techniques arrivent...
0
mystiikk70 Messages postés 2 Date d'inscription mardi 12 mai 2015 Statut Membre Dernière intervention 12 mai 2015
12 mai 2015 à 21:56
Bonsoir, merci de votre réponse! J'ai donc rajouté l'initialisation de la position courant comme vous l'avez conseillez :)
Ensuite, les classes EcranGraphique, Ecran et Clavier sont dans mon répertoire de programmation donc pas de soucis la dessus !

"- Ces deux méthodes demandent des objets en paramètre, il y a pourtant une classe dans les deux appels de méthode ;-)" Je ne comprends pas bien ^^'
Et selon vous, que manquerais-il dans le programme ? :/
0
luckydu43 Messages postés 3992 Date d'inscription vendredi 9 janvier 2015 Statut Membre Dernière intervention 2 janvier 2025 983
12 mai 2015 à 22:21
Dans les 2 appels de méthodes, à la fin, vous appelez Cellule. Or, Cellule est la classe. Non l'objet.
Il vous vous spécifier dans les deux méthodes une cellule courante, objet Cellule.
Cette cellule courante devra bouger au fil de l'exécution, pour pouvoir déplacer les personnes de la cellule. Il faut donc une méthode à appeler qui modifie les paramètres de la cellule courante au fil de l'exécution. Une fois ses paramètres modifiés, vous pouvez la mettre dans l'appel de méthode affichage et déplacement.
Il manque donc une méthode deplacementCelluleCourante prenant en paramètre une Cellule (celluleCourante) et retournant une Cellule (celluleCourante) et un objet celluleCourante, instance de Cellule.

La méthode ressemblera à cela :
public static Cellule deplacementCelluleCourante (Cellule celluleCourante) {
    ...
    return celluleCourante;
}

Une fois ces deux objets créés (si l'on considère qu'une méthode est un objet, mais bref), il suffira de remplacer les dernières lignes par celles-ci :

affichage(damier,sortie1,sortie2,celluleCourante);
 Deplacement(Personne,damier,sortie1,sortie2,celluleCourante);


En espérant avoir été compréhensible ;-)

Bonne soirée !
0