import java.awt.*; import java.awt.event.*; import java.util.*; import EDU.neu.ccs.demeter.*; class Worm implements Runnable, Cloneable { private static int counter = 0; private int id; private static Random rand = new Random(); private Point next; // Top left corner of worm segment private Color color = new Color(Math.abs(rand.nextInt()) % 156, Math.abs(rand.nextInt()) % 156, Math.abs(rand.nextInt()) % 156); private Point[] coords; // "head" at [0] private double direction; // radians private int last_turn; private int speed = 50; // pause private Worms field; Worm(Worms w) { field = w; id = counter++; next = new Point(); next.x = Math.abs(rand.nextInt()) % (WIDTH-WORM_THICKNESS) + LEFT; next.y = Math.abs(rand.nextInt()) % (HEIGHT-WORM_THICKNESS) + TOP; coords = new Point[WORM_LENGTH]; for(int i=0;i 90 && (rand.nextInt()>0)) --speed; else speed += rand.nextInt()%5; } } private void newDirection() { try { enter_meth$newDirection(); int delta = rand.nextInt()%3; if(delta > 1) delta = 1; else if(delta < -1) delta = -1; delta += last_turn; if(delta < -2) delta = -2; else if(delta > 2) delta = 2; direction = (direction + delta*Math.PI/8) % (Math.PI*2); int new_x = (int)(next.x + Math.cos(direction)*WORM_STEP); int new_y = (int)(next.y - Math.sin(direction)*WORM_STEP); if(new_x < LEFT) { if(new_y < TOP) direction = Math.PI/4*7; else if(new_y > BOTTOM - WORM_THICKNESS) direction = Math.PI/4; else direction = 0; } else if(new_x > RIGHT - WORM_THICKNESS) { if(new_y < TOP) direction = Math.PI/4*5; else if(new_y > BOTTOM - WORM_THICKNESS) direction = Math.PI/4*3; else direction = Math.PI; } else if(new_y < TOP) { direction = Math.PI/2*3; } else if(new_y > BOTTOM - WORM_THICKNESS) { direction = Math.PI/2; } next.x = new_x; next.y = new_y; } finally { nexts[id]=next; for(int i=0;i<3;i++) if(i!=id) for(int j=0;j0;i--) coords[i].setLocation(coords[i-1]); coords[0].setLocation(next); } finally { for(int i=0;i<3;i++) if(blocked[i]) { blocked[i]=false; for(int j=0;j<3;j++) if(j!=i) for(int k=0;k=0;i--) { g.setColor(color); g.fillOval(coords[i].x, coords[i].y, WORM_THICKNESS, WORM_THICKNESS); } int head_x = coords[0].x + WORM_THICKNESS/2; int head_y = coords[0].y + WORM_THICKNESS/2; int left_x = (int)(head_x - WORM_THICKNESS/5*Math.sin(direction)); int left_y = (int)(head_y - WORM_THICKNESS/5*Math.cos(direction)); int right_x = (int)(head_x + WORM_THICKNESS/5*Math.sin(direction)); int right_y = (int)(head_y + WORM_THICKNESS/5*Math.cos(direction)); g.setColor(Color.white); g.drawLine(left_x, left_y, left_x, left_y); g.drawLine(right_x, right_y, right_x, right_y); } static Point[][] locations = new Point[3][]; static Point[] nexts = new Point[3]; static boolean[] blocked = new boolean[3]; private static Object cool$synch = new Object() ; public static Cool$Lock meth$newDirectionlock = new Cool$Lock(false, new XVector()) ; private synchronized void enter_meth$newDirection() { while( !(meth$newDirectionlock.isEnterable()) ) { try { synchronized(cool$synch) { cool$synch.wait(); } } catch(InterruptedException e) {} } } public static Cool$Lock meth$steplock = new Cool$Lock(true, new XVector().append(meth$newDirectionlock)) ; private synchronized void enter_meth$step() { while( !(!blocked[id] && meth$steplock.isEnterable()) ) { try { synchronized(cool$synch) { cool$synch.wait(); } } catch(InterruptedException e) {} } } public static Cool$Lock meth$runlock = new Cool$Lock(false, null); private synchronized void enter_meth$run() { while( !(meth$runlock.isEnterable()) ) { try { synchronized(cool$synch) { cool$synch.wait(); } } catch(InterruptedException e) {} } locations[id]=coords; } }