// == IFT6802 - TP2 == // // Carte.java: Garde trace de l'environnement du Robot // ---------- // V1.0 - J. Vaucher (fev.2004) // // - Carte est extensible et s'aggrandit au besoin en X comme en Y // - Contiend les methodes pour choisir la prochaine direction // // Utilise 2 tableaux: "b" pour les details de la carte // - "v" pour la 'valeur' de chaque case, // // - Algorithme de deplacement: // // Etat 0: a la creation, on nous donne une direction initiale (dir1), // une diagonale qui dit quel coin on cherche a atteindre. // Etat 1: On poursuit dans la direction donnee jusqu'a ce qu'on // ne puisse plus avancer dans la direction visee. Alors // on passe a l'etat 2; // Etat 2: On suit le mur qui nous a arrete en gardant la gauche au mur // jusqu'a ce qu'on trouve notre point d'impact sur le mur. // - Si on peut quitter le mur pour aller dans la direction "dir1" // on le quitte et on retourne a l'etat 1. // - Sinon, en trouvant le point initial, on sait qu'on a fait // le tour de la piece et on en connait les dimensions. On // passe a l'etat 3. // Etat 3: une fois les dimensions X-Y etablies, on sait aussi ou on // se trouve. Si un 'partenaire' nous a informe de la taille du jeu, // on pourra quitter l'etat 2 plus tot: des que la taille de la zone // explorees est egale a la taille du jeu. On se deplace selon // les valeurs du vecteur "v". On incremente les cases ou le robot // est passe (et ses voisins) et le robot se deplace vers les cases s // avec basse valeurs. --> technique qui assure qu'on visite // eventuellement toutes les cases - sans garder trace d'ou se trouve // poussieres. // - Une fois dans l'etat 3, on collabore avec les autres robots. Le // chef calcule les zones pour chaque robots et on modifie le vecteur "V" // pour ecarter le robots des autres zones. import java.util.Random ; public class Carte { static Random rnd = new Random(); char b [] [] ; float v [] [] ; int x, y, dir; int minX, minY, maxX, maxY; int dimX = -5, dimY = -5; boolean posConnu = false; public Carte(int xdim, int ydim) { // System.out.println("-------->> " + xdim + "x" + ydim ); b = new char [xdim][ydim]; v = new float [xdim][ydim]; for (int i = 0; imaxX) maxX=x; else if (xmaxY) maxY=y; else if (y>>>>>>>>> State 3 >>>>>>>>> " + dir + " " + oldDir); dimX = maxX-minX+1; dimY = maxY-minY+1; changeCarte(dimX+2,dimY+2,-minX+1,-minY+1); posConnu = true; dump(); } // Prochaine direction en suivant le mur for (int i=-2; i<7; i++) if( voisin(dir+i) !='*') { dir = (dir+8+i)%8; break; // return dir ; } if (inDir(x,y,closeX,closeY, dir1) > 0) // on est a un point plus proche de { // de la direction choisie "dir1" closeX = x; closeY = y; } if (dir != dir1 && voisin(dir1) != '*' // ON quitte le mur pour se rapprocher && inDir(x,y,closeX,closeY, dir1)>=0) // du coin prefere { dir = dir1; state=1; } break; case 3: return pickMove(); } // Traitement generique des collisions char c = voisin(dir); if (c != ' ' && c != '.' ) { if ( bumps > 0) System.out.println(" ==>" + c + "/" + bumps); if ( bumps > 3) { for (int i=-1; i<7; i++) if( voisin(dir+i) ==' ') { dir = (dir+8+i)%8; break; } } } return dir; } // Choix dans l'etat "3" selon le contenu du tableau "V" synchronized int pickMove() { float valX = 100; int i = dir; for (int j=0; j<8; j++) { int d2 = (i+j) % 8 ; int x2 = newX( x, d2); int y2 = newY( y, d2); char c = b[x2][y2]; float val = v[x2][y2]; if ( c!= '.' ) { v[x2][y2] = val = val+0.3F; } if (c == '*') val = 100; if (c == '.') { val = -5; //addDirt(x2,y2,1); } if ( val < valX ) { dir=d2; valX = val; } } return dir; } // ========================================================================= // Methodes de mise a jour de "V" selon les messages recus // ========================================================================= synchronized void addDirt(int x, int y ) { anneau(x,y,0,-2F,0) ; anneau(x,y,1,-1F,0) ; anneau(x,y,2,-0.5F,0) ; } synchronized void allera(int x, int y, int n) { int radius = (int) Math.round( Math.sqrt(1.0* dimX*dimY/n)); int dx = 1; float val = 1F; v[x][y] /= 2; while ( anneau(x,y,dx,val,1) ) { dx++; val = (dx=0 && i< v.length && j>=0 && j=0 && y >=0 && x < b.length && y < b[0].length) v[x][y]+=dv; } // ================ Utilitaires "geometriques" ====================== static int newX ( int x, int dir ) { switch (dir) { case 0: case 6: case 7: return x-1; case 2: case 3: case 4: return x+1; } return x; } static int newY ( int y, int dir ) { switch (dir) { case 0: case 1: case 2: return y-1; case 4: case 5: case 6: return y+1; } return y; } char voisin( int dir ) { int x2=x, y2=y; dir = (dir+8)%8; switch (dir) { case 0: x2=x-1; y2=y-1; break; case 1: x2=x ; y2=y-1; break; case 2: x2=x+1; y2=y-1; break; case 3: x2=x+1; y2=y; break; case 4: x2=x+1; y2=y+1; break; case 5: x2=x ; y2=y+1; break; case 6: x2=x-1; y2=y+1; break; case 7: x2=x-1; y2=y ; break; } return b[x2][y2]; } static int inDir(int x2, int y2, int x1, int y1, int dir) { int dx = x2-x1; int dy = y1-y2; switch (dir) { case 0: return dy-dx; case 1: return dy; case 2: return dx+dy; case 3: return dx; case 4: return dx-dy; case 5: return -dy; case 6: return -dx-dy; case 7: return -dx; } return 0; } // ---------- Impression des TABLEAUX ---------------------- synchronized void dump() { int xdim = b.length; int ydim = b[0].length; // System.out.println("x="+x + ", y=" + y); for (int i = 0; i9 ) return " "+i; else return " " + i; } }