/* * Islet ICP'98 demonstation * Redistribution permitted under the terms of GNU General Public License version 2 * "ftp://prep.ai.mit.edu/pub/gnu/GPL" * Author: Jan Kratochvil (no flames for this piece of crap, please) */ import java.applet.*; import java.awt.*; import java.awt.event.*; import java.awt.image.*; import java.util.*; public class Islet extends Applet { Applet app=this; private interface ImageLoader { public Image load(String name); } static private class CmdLoader implements ImageLoader { Toolkit kit; public CmdLoader(Toolkit _kit) { kit=_kit; } public Image load(String name) { return(kit.getImage(name)); } } private class AppLoader implements ImageLoader { public Image load(String name) { return(app.getImage(app.getCodeBase(),name)); } } private class AppListener extends MouseAdapter implements MouseListener { public void mouseClicked(MouseEvent e) { new IsletThread(false,new AppLoader()); } } public void paint(Graphics g) { super.paint(g); g.setColor(new Color(100,255,100)); g.fill3DRect(0,0,getSize().width-1,getSize().height-1,true); g.setColor(Color.black); g.setFont(new Font("Courier",Font.BOLD,getSize().height*8/10)); g.drawString("Open demo window",getSize().height*2/10,getSize().height*8/10); } public void update(Graphics g) { paint(g); } //Leave background garbaged public void init() { addMouseListener(new AppListener()); } public String getAppletInfo() { return( "Islet by Jan Kratochvil in 1998. Created for purposes of ICP'98 competition.\n"+ "Redistribution permitted under GNU General Public License (AKA GPL) version 2 (exactly) found on ftp://prep.ai.mit.edu/pub/gnu/GPL." ); } static public void main(String[] args) { new IsletThread(true,new CmdLoader(Toolkit.getDefaultToolkit())); } static private class IntBugCheck extends Thread { Thread t; public IntBugCheck(Thread _t) { t=_t; setDaemon(true); start(); } public void run() { try { sleep(30); } catch (InterruptedException e) {} t.interrupt(); } } //! Indentation violation: static private class IsletThread extends Thread { boolean doexit; Frame fview,fcontrol; Imager img; View view; ScrollPane viewpane; FieldWater water; boolean prepared=false; Point mousefld=new Point(-1,-1); boolean mousefldok=false; byte tool; ToolBox tools[]; ImageLoader imageloader; TimerQ timerq=new TimerQ(); static final int deltax[]={0,1,0,-1},deltay[]={-1,0,1,0}; boolean running=false; ERandom rnd=new ERandom(); int fldcnt[]; Vector fld=new Vector(); //synchronized inside View! final long buggywait=200; private Vector getfld(int y) { return((Vector)fld.elementAt(y)); } private Field getfld(Point pt) { return((Field)(getfld(pt.y).elementAt(pt.x))); } private Field getfld(int x,int y) { return(getfld(new Point(x,y))); } private void setfld(int y,Vector v) { fld.setElementAt(v,y); } private void setfld(Point pt,Field f) { getfld(pt.y).setElementAt(f,pt.x); } private void setfld(int x,int y,Field f) { setfld(new Point(x,y),f); } private class ERandom extends Random { public int nextUInt() { return(Math.abs(nextInt())); } } private class Timer { public long when; public Field trig; public Timer(long ms,Field _trig) { when=System.currentTimeMillis()+ms; trig=_trig; timerq.add(this); } } private class TimerQ { Vector q=new Vector(); synchronized public void add(Timer tm) { int i; for (i=0;i=tm.when) break; q.insertElementAt(tm,i); interrupt(); } public void runday() { new Timer(1000,null); } synchronized public long getMin() { while (!q.isEmpty()) { Timer t=(Timer)q.firstElement(); if (t.when>System.currentTimeMillis()) break; Field f=t.trig; q.removeElementAt(0); if (f!=null) { view.kickRobotAss(f); continue; } runday(); if (daytime.val+1(rnd.nextUInt()%100))==side.wh) { //we won weight+=r.weight; break; } r.weight+=weight; r.orient=(byte)(orient^2); r.paint(); spawn(r); dispose(); return; } setfld(npt,this); f.dispose(); spawn(this); pt=npt; this.paint(); } } private class FieldRobotX extends FieldRobot { public FieldRobotX(Point _pt) { super(_pt,false); setup(img.ROBOTX); } public FieldRobotX(int x,int y) { this(new Point(x,y)); } } private class FieldRobotY extends FieldRobot { public FieldRobotY(Point _pt) { super(_pt,true ); setup(img.ROBOTY); } public FieldRobotY(int x,int y) { this(new Point(x,y)); } } public IsletThread(boolean _doexit,ImageLoader _imageloader) { doexit=_doexit; imageloader=_imageloader; start(); } private class View extends Panel implements MouseListener,MouseMotionListener,AdjustmentListener { synchronized public void paint(Graphics g) { if (!prepared) return; Rectangle r=g.getClipBounds(); Point pt; view.validateFld(pt=new Point(r.x/img.sizex,r.y/img.sizey)); int x=pt.x,y=pt.y; view.validateFld(pt=new Point((r.x+r.width -1)/img.sizex,(r.y+r.height-1)/img.sizey)); int xm=pt.x,ym=pt.y; for (;y<=ym;y++) { Vector v=getfld(y); for (int xw=x;xw<=xm;xw++) { Field f=(Field)v.elementAt(xw); img.draw(g,f.getImgValue(),f.cellPt(),(xw==mousefld.x && y==mousefld.y?Color.black:null),this); } } } public void update(Graphics g) { paint(g); } //Leave background garbaged synchronized public void kickRobotAss(Field f) { f.moveYourAss(); } public boolean validateFld(Point pt) { boolean v=true; if (pt.x>=sizex.val) { pt.x=sizex.val-1; v=false; } if (pt.y>=sizey.val) { pt.y=sizey.val-1; v=false; } if (pt.x<0) { pt.x=0; v=false; } if (pt.y<0) { pt.y=0; v=false; } return(v); } synchronized public Point getAnyFld(byte tp) { if (fldcnt[tp]<=0) return(null); int skip=rnd.nextUInt()%fldcnt[tp],x=0,y=0; while (skip>=0 && y=sizex.val) { x=0; y++; } } if (skip>0) return(null); //Shouldn't happen! return(new Point(x,y)); } synchronized public void mousePressed (MouseEvent e) { mouseMoved(e); if (!mousefldok) return; Field f=getfld(mousefld),fnew; if (f.getValue()==tool) return; setfld(mousefld,(fnew=water.create(mousefld,tool))); f.dispose(); fnew.paint(); } synchronized public void paintAt(Point pt) { if (mousefldok) getfld(mousefld).paint(); } synchronized public void fldupdate(Point pt) { if (pt.equals(mousefld)) return; paintAt(mousefld); mousefld=pt; mousefldok=view.validateFld(new Point(mousefld)); paintAt(mousefld); } public void mouseClicked (MouseEvent e) {} public void mouseEntered (MouseEvent e) {} public void mouseReleased(MouseEvent e) {} public void mouseExited (MouseEvent e) { fldupdate(new Point(-1,-1)); } public void mouseDragged (MouseEvent e) { mousePressed(e); } public void mouseMoved (MouseEvent e) { fldupdate(water.whichCell(e.getPoint())); } public Dimension getPreferredSize() { Point pt=water.cellPt(sizex.val,sizey.val); return(new Dimension(pt.x,pt.y)); } public Dimension getMinimumSize() { return(getPreferredSize()); } synchronized public void adjustmentValueChanged(AdjustmentEvent e) { int x,y,xval,xnewval,yval,ynewval; if (sizex==null || sizey==null) return; xval=sizex.val; xnewval=sizex.newval; yval=sizey.val; ynewval=sizey.newval; if (xval>xnewval) sizex.val=xnewval; if (yval>ynewval) sizey.val=ynewval; if (xval>xnewval) for (y=0;yynewval) { for (y=ynewval;y0) setValue(val-1); } public void inc() { if (valfldcnt[tp]) if (view.putFieldToField(tp,img.LAND)) break; silent=false; setCount(fldcnt[tp]); } } private class Side extends Controller implements AdjustmentListener { ScrollBarVal speed; boolean wh; public Panel control; public String toString() { return(wh?"Y":"X"); } public Side(boolean _wh,int _speed) { setup((_wh?img.ROBOTY:img.ROBOTX),"Count"); wh=_wh; control=new Panel(); control.setBackground(Color.gray); control.setLayout(new GridLayout(0,1)); control.add(new Label(toString()+" control:")); control.add(cnt.panel); control.add((speed=new ScrollBarVal("Speed",_speed,1,100,null)).panel); } } private class FoodCnt extends Controller implements AdjustmentListener { public FoodCnt() { setup(img.FOOD,"Food count"); } } Side sidex,sidey; ScrollBarVal sizex,sizey,lenx,leny,fightday,fightnight,daytime,foodwght; boolean pertp; ItemListener dayboxdog; Checkbox daybox; FoodCnt foodcnt; private class DayLengther implements AdjustmentListener,ItemListener { boolean b; public DayLengther(boolean _b) { b=_b; } public void adjustmentValueChanged(AdjustmentEvent e) { if (b==pertp && daytime!=null) daytime.setMax((b?leny:lenx).newval-1); } public void itemStateChanged(ItemEvent e) { if (pertp==!daybox.getState()) return; pertp=!pertp; daytime.prelab.setText(pertp?"Night time:":"Day time:"); daytime.setMax((pertp?leny:lenx).newval-1); daytime.setValue(0); if (!pertp) view.addTimers(img.ROBOTX); } } public void run() { img=new Imager(imageloader); Frame fr; fr=fview=new Frame("Islet Island View"); fr.addWindowListener(new WindowClose()); //viewpane=new ScrollPane(ScrollPane.SCROLLBARS_ALWAYS); //viewpane.add(view=new View()); //fr.add(viewpane); fr.add(view=new View()); view.addMouseListener(view); view.addMouseMotionListener(view); fr=fcontrol=new Frame("Islet Control Panel"); fview.setLocation(300,10); fcontrol.setLocation(10,10); fcontrol.setSize(280,660); fr.addWindowListener(new WindowClose()); fr.setLayout(new FlowLayout()); { Panel p=new Panel(); p.setBackground(Color.gray); p.setLayout(new GridLayout(0,1)); p.add((sizex=new ScrollBarVal("Isle width" ,0,0,100,view)).panel); p.add((sizey=new ScrollBarVal("Isle height",0,0,100,view)).panel); fr.add(p); } { Panel p=new Panel(); p.setBackground(Color.gray); p.add(new Label("Tools:")); for (byte i=0;iY",20,0,100,null)).panel); p.add((fightnight=new ScrollBarVal("XY",80,0,100,null)).panel); fr.add(p); } { Panel p=new Panel(); p.setBackground(Color.gray); p.setLayout(new GridLayout(0,1)); p.add((foodwght=new ScrollBarVal("Food weight",50,0,200,null)).panel); foodwght.setSuffix("%"); p.add((foodcnt=new FoodCnt()).cnt.panel); fr.add(p); } fr.add((sidex=new Side(false,15)).control); fr.add((sidey=new Side(true ,10)).control); { Panel p=new Panel(); p.setBackground(Color.gray); { Button b=new Button("Start"); b.addActionListener(new ButtonStartStop(b)); p.add(b); } { Button b=new Button("Quit"); b.addActionListener(new ButtonQuit()); p.add(b); } fr.add(p); } sizex.setValue(20); sizey.setValue(20); sizex.bar.setMinimum(1); sizey.bar.setMinimum(1); prepared=true; view.repaint(); fview.show(); fcontrol.show(); new IntBugCheck(this); boolean buggy=true; try { sleep(100); } catch (InterruptedException e) { buggy=false; } System.out.println(toString()+" - check for Netscape Communicator 4.05 Preview Release 1 (AWT 1.1.5) interrupt() bug: " +(buggy?"FOUND, workarounding it.":"none, OK")); for (;;) { try { long l=timerq.getMin(); if (l>buggywait && buggy) l=buggywait; sleep(l); } catch (InterruptedException e) {} } } }//IsletThread }//Islet