// HotelServer2.java: environnement pour le TP2 du cours ift6802 // // Jean Vaucher (Janv. 2004) // version 1.1 - 9 fev. 2004 // // Modifications: // Correction de l'ordre a , dans le Broadcast de // la position du chien ( signalle par Bellavance, 9 fev. ) import java.io.*; import java.net.*; import java.util.*; import java.awt.* ; import javax.swing.JFrame ; import javax.swing.DefaultListModel ; public class HotelServer2 { static int idCnt = 1; static boolean finished = false; static Random rnd = new Random(); static int id = rnd.nextInt(100); static float delais = 1 ; float time = 0; static int multiPort = 7777; static InetAddress multiAdr ; static MulticastSocket multiSocket ; static JFrame gui; DatagramSocket socket ; InetAddress localAdr ; int port ; InetAddress clientAdr ; int clientPort ; static Map agents = new HashMap(); // Vector score = new Vector(); DefaultListModel score = new DefaultListModel(); Vector props = new Vector(); int LIM = 16 ; Board board ; Chien fido; public static void main(String[] args) throws IOException { if (args.length>0) try { int pt = Integer.parseInt(args[0]); if (pt != 0) multiPort = pt; if (args.length > 1) delais = Float.parseFloat( args[1] ); } catch (Exception e) {} new HotelServer2().init(); } void init() throws IOException { multiAdr = InetAddress.getByName("230.0.0.1"); multiSocket = new MulticastSocket( multiPort ); multiSocket.joinGroup( multiAdr ); localAdr = InetAddress.getLocalHost(); socket = new DatagramSocket(); port = socket.getLocalPort(); board = new Board( LIM, this ); fido = new Chien( board ); for (int i=0; i<4; i++) new Dirt( board ) ; board.print(); gui = new HotelFrame( this, LIM ); new Slave1().start(); new Slave2().start(); new Slave3().start(); new HuiRobot(multiPort).init(); } // --------------------------------------------------------------------- // Slave 1: handles LOGINS // --------------------------------------------------------------------- class Slave1 extends Thread { public void run() { DatagramPacket packet; System.out.println("Hotel Server starting"); while (true) { try { byte[] buf = new byte[256]; packet = new DatagramPacket(buf, buf.length); multiSocket.receive(packet); String received = new String(packet.getData(),0,packet.getLength()); // System.out.println("Receiving: " + received); StringTokenizer st = new StringTokenizer( received, "," ); String rep = st.nextToken(); handleMsg( rep, st ); } catch (IOException e) { System.out.println("Problem: " + e ); } } } } void handleMsg( String type, StringTokenizer st ) { if ( type.equals("allo") ) { int agentID = idCnt++ ; try { InetAddress clientAdr = InetAddress.getByName(st.nextToken()); int clientPort = Integer.parseInt(st.nextToken()); Agent a = new Agent( board, agentID, clientAdr, clientPort); synchronized (agents) { agents.put( a.key, a ); } score.addElement( a ); broadcast("new,999,0,"+agentID); new Dirt (board ); } catch (Exception e) { System.out.println("Problem: " + e ); } } } void send( String s, Agent a) { try { socket.send( new DatagramPacket( s.getBytes(), s.length(), a.adr, a.port)); } catch (IOException e) { System.out.println("Problem: " + e ); } } void broadcast( String s) { try { socket.send( new DatagramPacket( s.getBytes(), s.length(), multiAdr, multiPort)); } catch (IOException e) { System.out.println("Problem: " + e ); } } // --------------------------------------------------------------------- // Slave 2 which updates the display and send status to all agents // --------------------------------------------------------------------- class Slave2 extends Thread { int t2 = 0; public void run() { DatagramPacket packet; Agent a = null; Agent vict; sleep(4.0); System.out.println("SIMULATION starting"); while (! finished ) { time += delais; vict = null; for (Iterator it=agents . values().iterator(); it.hasNext(); ) { a = (Agent) it.next(); // System.out.println(a); if ( ! a.move()) send( "bang," + a.key + ",0", a); if ( a.cnt++ > 3) vict = a; } if (vict != null) { agents.remove( vict.key ); props.remove(vict); System.out.println("Agent_"+vict.key+ " est mort!"); board.board[vict.x][vict.y] = ' '; } fido.move(); if ( time > t2 ) { board.print(); t2 = (int) (time + 2 ); } if (rnd.nextFloat()<0.4) broadcast("pos,999,0,#,"+fido.x+","+fido.y); for (Iterator it=agents . values().iterator(); it.hasNext(); ) { a = (Agent) it.next(); String env = "env," + a.key + ",0," + board.neighbours( a.x, a.y ); send( env, a ); } board.wipe(); gui.repaint(); try { Thread.sleep( (long) (delais*1000) ); } catch( Exception e ) {} } } void sleep ( double secs ) { try { Thread.sleep( (long) secs*1000 ); } catch( Exception e ) {} } } // --------------------------------------------------------------------- // Slave 3: handles incoming datagrams and updates the Agent directions // --------------------------------------------------------------------- class Slave3 extends Thread { public void run() { DatagramPacket packet; while (! finished ) try { byte[] buf = new byte[256]; packet = new DatagramPacket(buf, buf.length); socket.receive(packet); String received = new String(packet.getData(),0,packet.getLength()); // System.out.println("Receiving: " + received); // System.out.println("From: " + packet.getAddress() // + ":" + packet.getPort()); StringTokenizer st = new StringTokenizer( received, "," ); String rep = st.nextToken(); String dest = st.nextToken(); String orig = st.nextToken(); int dir = Integer.parseInt(st.nextToken()); Agent a = (Agent) agents.get( orig ); if (a != null) { a.dir = dir; a.cnt = 0; } } catch (IOException e) { System.out.println("Problem: " + e ); } } } } //================================================================ // b o a r d //================================================================ class Board { char [] [] board ; int LIM; int DELTA = 28 ; HotelServer2 HS; Vector props ; Random rnd = new Random(); public Board( int lim, HotelServer2 hs ) { LIM = lim; HS = hs ; props = hs.props ; board = new char [LIM+2] [LIM+2] ; initBoard(); } void initBoard() { for (int i=0; i 4) m = new MurV(this); else m = new MurH(this); props.add(m); } void wipe() { for (int i=1; i '0' ) { increment( x1,y1,10); for (int i = x1-1; i<=x1+1; i++) for (int j = y1-1; j<=y1+1; j++) increment(i,j, 4); for (int i = x1-1; i<=x1+1; i++) increment(i,y1, 1); for (int j = y1-1; j<=y1+1; j++) increment(x1,j, 1); } } int bestdir = dir; int bestX = newX(x,dir), bestY = newY(y,dir); int lowscore = scoreboard [bestX][bestY]; if (lowscore == 0 ) ; else if (rnd.nextFloat()<0.5) { dir = (dir+7)%8; for (int dd = 0 ; dd<=8; dd++) { int d = (dir+dd)%9; int x2 = newX(x,d); int y2 = newY(y,d); if ( scoreboard[x2][y2] < lowscore ) { bestX = x2; bestY = y2; lowscore = scoreboard[x2][y2]; bestdir = d; } } } else { dir = (dir+1) %8; for (int dd = 8 ; dd>=0; dd--) { int d = (dir+dd)%9; int x2 = newX(x,d); int y2 = newY(y,d); if ( scoreboard[x2][y2] < lowscore ) { bestX = x2; bestY = y2; lowscore = scoreboard[x2][y2]; bestdir = d; } } } // System.out.println("bestDir:" + bestdir); // jeu[x][y] = oldC; x = bestX; y = bestY; dir = bestdir; oldC = jeu[x][y]; // jeu[x][y] = C; return true; } void increment( int x, int y, int n) { if ( x<1 || x>LIM) return; if ( y<1 || y>LIM) return; scoreboard[x][y] += n; } 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; } 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; } public void paint(Component canvas, Graphics g) { Image myImage = Toolkit.getDefaultToolkit().getImage("smiley.gif"); g.drawImage(myImage, coord(x), coord(y), canvas); display.board [x][y] = C; } } abstract class Mur extends Piece { int n ; int x,y, x2, y2 ; public Mur( Board b) { super( b ); n = b.LIM / 3; C = '*'; dimension(); } abstract void dimension(); public void paint(Component canvas, Graphics g ) { int gx1, gx2, gy1, gy2; gx1 = coord( x ); gx2 = coord( x2+1); gy1 = coord( y ); gy2 = coord( y2+1); g.setColor(Color.darkGray); g.fillRect( gx1, gy1, gx2-gx1, gy2-gy1) ; for ( int xx=x; xx<=x2 ; xx++) for ( int yy=y; yy<=y2 ; yy++) display.board [xx][yy] = C; } public String toString(){ return "Mur: x=" + x + ", y=" + y + ", x2=" + x2 + ", y2=" + y2 ; } } class MurH extends Mur { public MurH( Board b) { super( b ); } void dimension() { x = 1+rnd.nextInt(2*display.LIM/3); y = y2 = 2+rnd.nextInt(display.LIM-2); x2 = Math.min( x+n, display.LIM); for ( int xx=x; xx<=x2 ; xx++) display.board [xx][y] = '*'; } } class MurV extends Mur { public MurV( Board b) { super( b ); } void dimension() { x = x2 = 2+rnd.nextInt(display.LIM-2); y = 1+rnd.nextInt(2*display.LIM/3); y2 = Math.min( y+n, display.LIM); for ( int yy=y; yy<=y2 ; yy++) display.board [x][yy] = '*'; } }