import java.awt.*; import java.awt.event.*; import java.applet.*; import java.util.*; import java.awt.image.*; public class RandomWalk extends Applet implements Runnable, ActionListener{ public String getAppletInfo() {return "RandomWalk, written by Diego Moriarty Jun98";} public String[][] getParameterInfo(){ String info[][]={ {"defaultSeparation","integer","Separation from node to node when loaded"}}; return info; } Frame f=new Frame("RandomWalk"); Applet theApplet=this; Panel P=new Panel(); int separation=2,sx=0,sy=0; Node m[], trace[]; CyclerCanvas cyclerCanvas; Thread cyclerThread; Button moreB,lessB,dockB,improveB,cycleB; Label separationL=new Label(""); Image traceImage; final static int shades=127; Node middle; public static void main(String[] args){ RandomWalk R=new RandomWalk(); R.createP(); R.f.add("Center",R.P); R.f.setVisible(true); } public void init(){ try{separation=Integer.parseInt(getParameter("separation"));} catch(NumberFormatException e){} createP(); setLayout(new BorderLayout()); add("Center",P); } public void createP(){ Dimension screen = Toolkit.getDefaultToolkit().getScreenSize(); f.setSize(400,250); f.setLocation((screen.width-400)/2, (screen.height-250)/2); P.setLayout(new BorderLayout()); cyclerCanvas=new CyclerCanvas(); cyclerCanvas.addComponentListener(new ComponentAdapter(){ public void componentResized(ComponentEvent e){ createMap(); } }); cyclerCanvas.setBackground(Color.blue); cyclerCanvas.addMouseListener(new MouseAdapter(){ public void mouseClicked(MouseEvent e){ if(cyclerThread!=null){cyclerThread.stop();cyclerThread=null;} walk(e.getY()/separation*sx+e.getX()/separation); cycleB.setEnabled(true); } }); cyclerCanvas.addMouseMotionListener(new MouseMotionAdapter(){ public void mouseDragged(MouseEvent e){ if(cyclerThread!=null){ cyclerThread.stop();cyclerThread=null; cycleB.setEnabled(true); cyclerCanvas.setImage(traceImage); trace(middle); } int x=e.getX(),y=e.getY(); if(x<0||y<0||x>sx*separation||y>sy*separation) return; Node newTrace=m[e.getY()/separation*sx+e.getX()/separation]; if(trace[newTrace.distance]==newTrace&&trace[newTrace.distance+1]==null) return; trace(newTrace); } }); P.add("Center",cyclerCanvas); Panel p=new Panel(); p.setLayout(new GridBagLayout()); GridBagConstraints c=new GridBagConstraints(); c.weightx=1;c.fill=c.HORIZONTAL; c.gridwidth=2; p.add(dockB=new Button("Float"),c); dockB.addActionListener(this); p.add(new Label("Separation:"),c); c.gridwidth=1; p.add(lessB=new Button("<"),c); lessB.addActionListener(this); separationL.setText(Integer.toString(separation)); p.add(separationL,c); p.add(moreB=new Button(">"),c); moreB.addActionListener(this); c.gridwidth=2; p.add(improveB=new Button("Improve"),c); improveB.addActionListener(this); c.gridwidth=c.REMAINDER; p.add(cycleB=new Button("Cycle"),c); cycleB.addActionListener(this); P.add("South",p); } public void createMap(){ if(cyclerThread!=null){cyclerThread.stop();cyclerThread=null;} int width=cyclerCanvas.getSize().width,height=cyclerCanvas.getSize().height; traceImage=P.createImage(width,height); sx=(width-1)/separation+1; sy=height/separation; m=new Node[sy*sx]; trace=new Node[m.length]; middle=m[sy/2*sx+sx/2]; Vector to=new Vector(); for(int i=0;i0) to.addElement(m[i-1]); if(i/sx0) to.addElement(m[i-sx]); m[i].to=new Node[to.size()]; m[i].haveit=new boolean[to.size()]; for(int j=0;j1){ separation-=1; separationL.setText(Integer.toString(separation)); createMap(); } }else if(source==moreB){ if(separation<40){ separation+=1; separationL.setText(Integer.toString(separation)); createMap(); } }else if(source==dockB){ if(dockB.getLabel()=="Dock"){ f.setVisible(false); f.removeAll(); dockB.setLabel("Float"); theApplet.add("Center",P); validateTree(); }else{ theApplet.removeAll(); dockB.setLabel("Dock"); f.add("Center",P); f.setVisible(true); } }else if(source==improveB){ if(cyclerThread!=null){ cyclerThread.stop();cyclerThread=null; cycleB.setEnabled(true); cyclerCanvas.setImage(traceImage); trace(middle); } //send a packet that tries to improve on the current path //on arrival at a node the packet will be usually sent downstream //Once every ten (or so) a risk will be taken by sending it through an alternative node //The resulting cost info is sent down (the entrepeneur node can then adjust its tables) calcDistances(m); for(int i=0;i0;){ pixel=pixels[i]; if((pixel=pixels[i])!=0xffffffff ) rpixels[i]=0xff000000 |pixel+plusBlue&0x000000ff |pixel+plusGreen&0x0000ff00 |pixel+plusRed&0x00ff0000; else rpixels[i]=0xff0000ff; } frame[f]=P.createImage(new MemoryImageSource( cyclerImage.getWidth(null),cyclerImage.getHeight(null) ,ColorModel.getRGBdefault(),rpixels ,0,cyclerImage.getWidth(null))); try{ //System.out.println(""+f+" "+shades+" "+Runtime.getRuntime().freeMemory()+" "+Runtime.getRuntime().totalMemory()); // synchronized(this){wait(1000);} cyclerCanvas.setImage(frame[f]); }catch(OutOfMemoryError oome){System.out.println("ouch!"); // }catch(InterruptedException ie){ } } int f=0; Graphics cg=cyclerCanvas.getGraphics(); while(true){ cyclerCanvas.img=frame[f]; try{ //System.out.println(""+f+" "+shades+" "+Runtime.getRuntime().freeMemory()+" "+Runtime.getRuntime().totalMemory()); // synchronized(this){wait(2);} if(cg!=null) cg.drawImage(cyclerCanvas.img,0,0,null); }catch(OutOfMemoryError oome){System.out.println("gee!"); // }catch(InterruptedException ie){System.out.println("interrupted"); } f=(f+1)%frame.length; cyclerThread.yield(); } } public void walk(int p){ for(int i=0;i0;) if(I.to[c]==previous) { I.haveit[c]=true; break; } if(I.gotit&&previous!=I.next){ //annoying neighbour t=previous; // return packet previous=I; I=t; }else{ if(I.gotit){ //returned previous=I.from; //make it look like a query }else{ //new query g.drawLine(previous.x,previous.y,I.x,I.y); og.drawLine(previous.x,previous.y,I.x,I.y); if(I.next!=null) break; // found an old path I.gotit=true;I.from=previous; } free=0; for(c=0;c=0&&(t=trace[i])!=from;i--,from=from.next){ if(t!=null){ g.setColor(Color.lightGray); g.drawLine(t.x,t.y,t.next.x,t.next.y); g.setColor(Color.black); } g.drawLine(from.x,from.y,from.next.x,from.next.y); trace[i]=from; } g.dispose(); } } class CyclerCanvas extends Canvas{ public Image img; public void update(Graphics g){paint(g);} public void setImage(Image img){ this.img=img; Graphics g=getGraphics(); if(g!=null){ g.drawImage(img,0,0,null); g.dispose(); } } public void paint(Graphics g){ if(img!=null) g.drawImage(img,0,0,this); } } class Node{ int distance; //not of benefit to the node boolean gotit; Node from; int x,y; Node next, to[]; boolean haveit[]; // it could be optimized out for this model // it represents the local knowledge of a node concerning a packet: as far as I know neighbor X have/had it Node(int x, int y){this.x=x;this.y=y;} }