Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import java.applet.*;
- import java.awt.*;
- import java.util.*;
- /* WATOR predator-prey simulation based on A.K. Dewdney "Sharks and fish
- wage an ecological war on the toroidal planet Wa-Tor" (Scientific
- American, December 1984). Source code recovered from my 1996 compiled
- applet with help from JDK 1.2 disassembler. This version compiled
- with JDK 1.1.7A and exactly matches original's disassembler output.
- Placed in the public domain. This product is supplied "as is."
- Lawrence Leinweber, Cleveland, Ohio, U.S.A. 1999. */
- public class wator extends Applet implements Runnable {
- Label lb_size;
- Label lb_nshark;
- Label lb_nfish;
- Label lb_sbreed;
- Label lb_fbreed;
- Label lb_starve;
- Scrollbar sb_size;
- Scrollbar sb_nshark;
- Scrollbar sb_nfish;
- Scrollbar sb_sbreed;
- Scrollbar sb_fbreed;
- Scrollbar sb_starve;
- Button bn_go;
- Button bn_stop;
- Button bn_remix;
- Panel pn_tp;
- Panel pn_sc;
- Panel pn_bn;
- panelmap pn_mp;
- panelgrf pn_gf;
- int ni;
- int nj;
- int nshark;
- int nfish;
- boolean goflag;
- boolean remixflag;
- boolean brkflag;
- Object mutex;
- private Thread thread;
- public void start()
- {
- synchronized (mutex) {
- if (thread != null) return;
- thread = new Thread(this);
- thread.setPriority(Thread.MIN_PRIORITY);
- thread.start();
- }
- }
- public void stop()
- {
- synchronized (mutex) {
- if (thread != null && thread.isAlive()) thread.stop();
- thread = null;
- }
- }
- public void run()
- {
- int i, j, s, f;
- while (remixflag || pn_mp.paintflag || brkflag || goflag) {
- if (remixflag) {
- synchronized (mutex)
- { i = ni; j = nj; s = nshark; f = nfish; }
- if (fish.nshark != s || fish.nfish != f)
- fish.make(s, f);
- pn_mp.remix(i, j);
- pn_mp.paintflag = true;
- pn_gf.brk();
- remixflag = false;
- }
- if (pn_mp.paintflag)
- { pn_mp.paintflag = false; pn_mp.dopaint(); }
- if (brkflag)
- { brkflag = false; pn_gf.brk(); }
- if (goflag) {
- pn_mp.gen();
- pn_gf.gen(ni * nj, fish.nshark, fish.nfish);
- synchronized (mutex) {
- if (!remixflag) {
- setnshark(fish.nshark);
- setnfish(fish.nfish);
- }
- }
- }
- }
- thread = null;
- }
- public boolean handleEvent(Event e)
- {
- if (e.target instanceof Button)
- switch (e.id) {
- case e.ACTION_EVENT:
- if (e.target == bn_go) goflag = true;
- if (e.target == bn_stop) goflag = false;
- if (e.target == bn_remix) remixflag = true;
- if (goflag || remixflag) start();
- return (true);
- }
- else if (e.target instanceof Scrollbar)
- switch (e.id) {
- case e.SCROLL_ABSOLUTE:
- case e.SCROLL_LINE_UP:
- case e.SCROLL_LINE_DOWN:
- case e.SCROLL_PAGE_UP:
- case e.SCROLL_PAGE_DOWN:
- synchronized (mutex) {
- if (e.target == sb_size)
- remixflag = setsize(sb_size.getValue());
- if (e.target == sb_nshark)
- remixflag = setnshark(sb_nshark.getValue());
- if (e.target == sb_nfish)
- remixflag = setnfish(sb_nfish.getValue());
- if (e.target == sb_sbreed)
- brkflag = setsbreed(sb_sbreed.getValue());
- if (e.target == sb_fbreed)
- brkflag = setfbreed(sb_fbreed.getValue());
- if (e.target == sb_starve)
- brkflag = setstarve(sb_starve.getValue());
- }
- if (remixflag) start();
- return (true);
- }
- return (super.handleEvent(e));
- }
- public void init()
- {
- super.init();
- pn_mp = new panelmap();
- pn_mp.that = this;
- setLayout(new GridLayout(2, 1, 10, 10));
- pn_tp = new Panel();
- pn_tp.setLayout(new BorderLayout(3, 0));
- add(pn_tp);
- pn_tp.setBackground(Color.white);
- pn_sc = new Panel();
- pn_sc.setLayout(new GridLayout(14, 1, 3, 3));
- pn_tp.add("East", pn_sc);
- pn_sc.add(lb_size = new Label());
- lb_size.setForeground(pn_mp.getColor(Color.blue));
- pn_sc.add(sb_size = new Scrollbar(0));
- pn_sc.add(lb_nshark = new Label());
- lb_nshark.setForeground(pn_mp.getColor(Color.red));
- pn_sc.add(sb_nshark = new Scrollbar(0));
- pn_sc.add(lb_nfish = new Label());
- lb_nfish.setForeground(pn_mp.getColor(Color.green));
- pn_sc.add(sb_nfish = new Scrollbar(0));
- pn_sc.add(lb_sbreed = new Label());
- lb_sbreed.setForeground(pn_mp.getColor(Color.red));
- pn_sc.add(sb_sbreed = new Scrollbar(0));
- pn_sc.add(lb_fbreed = new Label());
- lb_fbreed.setForeground(pn_mp.getColor(Color.green));
- pn_sc.add(sb_fbreed = new Scrollbar(0));
- pn_sc.add(lb_starve = new Label());
- lb_starve.setForeground(pn_mp.getColor(Color.red));
- pn_sc.add(sb_starve = new Scrollbar(0));
- pn_sc.add(new Label());
- pn_bn = new Panel();
- pn_bn.setLayout(new GridLayout(1, 3, 3, 0));
- pn_sc.add(pn_bn);
- pn_bn.add(bn_go = new Button("Go"));
- pn_bn.add(bn_stop = new Button("Stop"));
- pn_bn.add(bn_remix = new Button("Remix"));
- pn_tp.add("Center", pn_mp);
- pn_gf = new panelgrf();
- add(pn_gf);
- validate();
- pn_gf.init(pn_mp.getColor(Color.red), pn_mp.getColor(Color.green),
- pn_mp.getColor(Color.blue));
- nshark = nfish = 0;
- setsize(1);
- while (ni * nj < 1000) setsize(Math.min(ni, nj) + 1);
- setnshark(1);
- setnfish(ni * nj - 1);
- setsbreed(10);
- setfbreed(3);
- setstarve(3);
- fish.seedrnd();
- remixflag = true;
- goflag = true;
- mutex = new Object();
- start();
- }
- private boolean setsize(int n)
- {
- int x, y;
- x = pn_mp.size().width - 2;
- y = pn_mp.size().height - 2;
- if (n < 1) n = 1;
- if (x < y) { nj = n; ni = n * y / x; }
- else { ni = n; nj = n * x / y; }
- sb_size.setValues(n, Math.min(x, y) / 10, 1, Math.min(x, y));
- lb_size.setText("Size " + Integer.toString(ni * nj) +
- " [1-" + Integer.toString(x * y) + "]");
- if (nfish + nshark > ni * nj) {
- setnfish(ni * nj * nfish / (nfish + nshark));
- setnshark(ni * nj - nfish);
- }
- return (true);
- }
- private boolean setnshark(int n)
- {
- sb_nshark.setValues(n, ni * nj / 10, 0, ni * nj);
- lb_nshark.setText("Sharks " + Integer.toString(n) +
- " [0-" + Integer.toString(ni * nj) + "]");
- nshark = n;
- if (nfish + nshark > ni * nj) setnfish(ni * nj - nshark);
- return (true);
- }
- private boolean setnfish(int n)
- {
- sb_nfish.setValues(n, ni * nj / 10, 0, ni * nj);
- lb_nfish.setText("Fish " + Integer.toString(n) +
- " [0-" + Integer.toString(ni * nj) + "]");
- nfish = n;
- if (nshark + nfish > ni * nj) setnshark(ni * nj - nfish);
- return (true);
- }
- private boolean setsbreed(int n)
- {
- sb_sbreed.setValues(n, 10, 1, 100);
- lb_sbreed.setText("Shark Breed " + Integer.toString(n) + " [1-100]");
- fish.sbreed = n;
- return (true);
- }
- private boolean setfbreed(int n)
- {
- sb_fbreed.setValues(n, 10, 1, 100);
- lb_fbreed.setText("Fish Breed " + Integer.toString(n) + " [1-100]");
- fish.fbreed = n;
- return (true);
- }
- private boolean setstarve(int n)
- {
- sb_starve.setValues(n, 10, 1, 100);
- lb_starve.setText("Shark Starve " + Integer.toString(n) + " [1-100]");
- fish.sstarve = n;
- return (true);
- }
- } /* end of class */
- class panelmap extends Panel {
- Color cl_rd;
- Color cl_gn;
- Color cl_bl;
- fish map[][];
- int x[];
- int y[];
- int dx[];
- int dy[];
- public int ni;
- public int nj;
- public boolean paintflag;
- Applet that;
- public Color getColor(Color c)
- {
- if (c == Color.red) return (cl_rd);
- if (c == Color.green) return (cl_gn);
- return (cl_bl);
- }
- public panelmap()
- {
- cl_rd = new Color(128, 0, 0);
- cl_gn = new Color(0, 64, 0);
- cl_bl = new Color(128, 128, 255);
- setBackground(cl_bl);
- }
- public void remix(int newi, int newj)
- {
- fish f;
- int i, j, k;
- ni = newi;
- nj = newj;
- x = new int[nj];
- y = new int[ni];
- dx = new int[nj];
- dy = new int[ni];
- k = size().width - 2;
- for (i = 0; i < nj; i++)
- dx[i] = ((k * i + k) / nj + 1) - (x[i] = (k * i) / nj + 1);
- k = size().height - 2;
- for (i = 0; i < ni; i++)
- dy[i] = ((k * i + k) / ni + 1) - (y[i] = (k * i) / ni + 1);
- map = new fish[ni][nj];
- for (f = fish.first(); f != null; f = f.next()) {
- do {
- i = fish.nrnd(ni);
- j = fish.nrnd(nj);
- } while (map[i][j] != null);
- map[f.i = i][f.j = j] = f;
- }
- }
- public void gen()
- {
- fish f, p;
- int r, i, j, en, pn;
- int[] ei, ej, pi, pj;
- Graphics g12;
- g12 = getGraphics();
- ei = new int[9];
- ej = new int[9];
- pi = new int[9];
- pj = new int[9];
- for (f = fish.first(); f != null; f = f.next()) {
- en = pn = 0;
- i = f.i; j = f.j;
- if (--i < 0) i += ni;
- if ((p = map[i][j]) == null) { ei[en] = i; ej[en] = j; en++; }
- else if (p.starve < 0) { pi[pn] = i; pj[pn] = j; pn++; }
- i = f.i; j = f.j;
- if (--j < 0) j += nj;
- if ((p = map[i][j]) == null) { ei[en] = i; ej[en] = j; en++; }
- else if (p.starve < 0) { pi[pn] = i; pj[pn] = j; pn++; }
- i = f.i; j = f.j;
- if (++i >= ni) i -= ni;
- if ((p = map[i][j]) == null) { ei[en] = i; ej[en] = j; en++; }
- else if (p.starve < 0) { pi[pn] = i; pj[pn] = j; pn++; }
- i = f.i; j = f.j;
- if (++j >= nj) j -= nj;
- if ((p = map[i][j]) == null) { ei[en] = i; ej[en] = j; en++; }
- else if (p.starve < 0) { pi[pn] = i; pj[pn] = j; pn++; }
- if (f.starve > 0 && pn > 0) { /* eat */
- r = fish.nrnd(pn);
- i = pi[r]; j = pj[r];
- map[i][j].starve = 0;
- map[i][j] = null;
- fish.nfish--;
- f.starve = fish.sstarve;
- }
- else if (f.starve > 0 && --f.starve == 0) { /* starve */
- fish.nshark--;
- map[f.i][f.j] = null;
- if (!paintflag) {
- g12.setColor(cl_bl);
- g12.fillRect(x[f.j], y[f.i], dx[f.j], dy[f.i]);
- }
- continue;
- }
- else if (en > 0) { /* move */
- r = fish.nrnd(en);
- i = ei[r]; j = ej[r];
- }
- else { /* surrounded */
- if (f.breed > 1) f.breed--;
- continue;
- }
- if (--f.breed == 0) { /* breed */
- p = new fish(f.starve < 0);
- map[p.i = f.i][p.j = f.j] = p;
- if (f.starve < 0) fish.nfish++; else fish.nshark++;
- f.breed = f.starve < 0? fish.fbreed: fish.sbreed;
- }
- else { /* move from */
- map[f.i][f.j] = null;
- if (!paintflag) {
- g12.setColor(cl_bl);
- g12.fillRect(x[f.j], y[f.i], dx[f.j], dy[f.i]);
- }
- }
- map[f.i = i][f.j = j] = f; /* move to */
- if (!paintflag) {
- g12.setColor(f.starve < 0? cl_gn: cl_rd);
- g12.fillRect(x[f.j], y[f.i], dx[f.j], dy[f.i]);
- }
- }
- }
- public void paint(Graphics g)
- {
- paintflag = true;
- that.start();
- }
- public void dopaint()
- {
- fish f;
- Image i;
- Graphics g;
- i = createImage(size().width, size().height);
- g = i.getGraphics();
- g.setColor(cl_bl);
- g.fillRect(0, 0, size().width, size().height);
- g.setColor(Color.black);
- g.drawRect(0, 0, size().width - 1, size().height - 1);
- for (f = fish.first(); f != null; f = f.next()) {
- g.setColor(f.starve < 0? cl_gn: cl_rd);
- g.fillRect(x[f.j], y[f.i], dx[f.j], dy[f.i]);
- }
- getGraphics().drawImage(i, 0, 0, this);
- }
- } /* end of class */
- class panelgrf extends Panel {
- int x;
- int y;
- int pos;
- Color cr;
- Color cg;
- Color cb;
- boolean cont;
- int stab[];
- int ftab[];
- Color ctab[];
- public void init(Color r, Color g, Color b)
- {
- int i;
- cr = r;
- cg = g;
- cb = b;
- setBackground(cb);
- x = size().width - 2;
- y = size().height - 2;
- stab = new int[x];
- ftab = new int[x];
- ctab = new Color[x];
- for (i = 0; i < x; i++) {
- stab[i] = ftab[i] = -1;
- ctab[i] = cb;
- }
- ctab[0] = Color.black;
- }
- public void brk()
- {
- Graphics g;
- int i;
- if (!cont) return;
- cont = false;
- synchronized (g = getGraphics()) {
- if ((i = pos + 1) >= x) i = 0;
- ctab[i] = Color.black;
- stab[i] = ftab[i] = -1;
- drawgen(g, i);
- ctab[pos] = Color.white;
- stab[i] = ftab[i] = -1;
- drawgen(g, pos);
- pos = i;
- }
- }
- public void gen(int n, int s, int f)
- {
- Graphics g;
- int i;
- cont = true;
- synchronized (g = getGraphics()) {
- if ((i = pos + 1) >= x) i = 0;
- ctab[i] = Color.black;
- stab[i] = ftab[i] = -1;
- drawgen(g, i);
- stab[pos] = (n - s) * (y - 1) / n + 1;
- ftab[pos] = (n - f) * (y - 1) / n + 1;
- ctab[pos] = cb;
- drawgen(g, pos);
- pos = i;
- }
- }
- public void paint(Graphics g)
- {
- int i;
- synchronized (g) {
- g.setColor(Color.black);
- g.drawRect(0, 0, size().width - 1, size().height - 1);
- for (i = 0; i < x; i++) drawgen(g, i);
- }
- }
- public void drawgen(Graphics g, int i)
- {
- int i0, n0, n;
- g.setColor(ctab[i]);
- g.drawLine(i + 1, 1, i + 1, y);
- i0 = i == 0? x - 1: i - 1;
- if ((n = stab[i]) != -1) {
- n0 = stab[i0];
- if (n0 == -1) n0 = n;
- if (n0 < n) n0++;
- if (n0 > n) n0--;
- g.setColor(cr);
- g.drawLine(i + 1, n0, i + 1, n);
- }
- if ((n = ftab[i]) != -1) {
- n0 = ftab[i0];
- if (n0 == -1) n0 = n;
- if (n0 < n) n0++;
- if (n0 > n) n0--;
- g.setColor(cg);
- g.drawLine(i + 1, n0, i + 1, n);
- }
- }
- } /* end of class */
- class fish extends Object {
- public int i;
- public int j;
- public int breed;
- public int starve;
- private fish f_next;
- private static fish fish_hed;
- static int nshark;
- static int nfish;
- static int sbreed;
- static int fbreed;
- static int sstarve;
- private static int rnd;
- public fish(boolean isfish)
- {
- f_next = fish_hed;
- fish_hed = this;
- i = isfish? fbreed: sbreed;
- breed = nrnd(isfish? fbreed: sbreed) + nrnd(isfish? fbreed: sbreed) + 1;
- starve = isfish? -1: nrnd(sstarve) + nrnd(sstarve) + 1;
- }
- public static fish first()
- {
- while (fish_hed != null && fish_hed.starve == 0)
- fish_hed = fish_hed.f_next;
- return (fish_hed);
- }
- public fish next()
- {
- while (f_next != null && f_next.starve == 0)
- f_next = f_next.f_next;
- return (f_next);
- }
- public static void make(int newnshark, int newnfish)
- {
- int i, j;
- fish f;
- while ((f = fish_hed) != null) {
- fish_hed = f.f_next;
- f.f_next = null;
- }
- nshark = newnshark;
- nfish = newnfish;
- for (i = 0, j = (nfish - nshark) / 2; i < nshark + nfish; i++) {
- if (j > 0) j -= nshark;
- else j += nfish;
- new fish(j > 0);
- }
- }
- public static void seedrnd()
- {
- rnd = new Random().nextInt() >> 16 & 077777;
- }
- public static int nrnd(int n)
- {
- if (n <= 1) return (0);
- return (((rnd = rnd * 1103515245 + 12345) >> 16 & 077777) * n >> 15);
- }
- } /* end of class */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement