📄 edgeofchaosca.java
字号:
package edgeofchoas;/* This code is, for the moment, totally uncommented. Sorry. David Eck Department of Mathematics and Computer Science Hobart and William Smith Colleges Geneva, NY 14456 E-mail: eck@hws.edu WWW: http://math.hws.edu/eck June 18, 1996 NOTE: YOU CAN DO ANYTHING YOU WANT WITH THIS CODE, EXCEPT COPYRIGHT IT, PATENT IT, OR OTHERWISE TRY TO CLAIM CREDIT FOR IT.*/import java.awt.*;import java.util.Random;public class EdgeOfChaosCA extends java.applet.Applet implements Runnable { boolean isStandalone = false; Choice statesChoice, neighborsChoice, isotropyChoice, speedChoice; Random rand; CACanvas CA; Label info; TextField txtNumber; String infoString; Scrollbar scroll; int sleepTime; int scrollMax; Thread runner; Color[] color; int states,neighbors,ruleCt,lambdaCt; int[] rules; int[] lambdaRule; int[] lambdaState; int[] isoMate; int isoStates; int isoNeighbors; int isoCt; boolean anisotropic; int actionNeeded = 0; final static int actionNew = 1, actionRandom = 2, actionRandomClump = 3, actionReset = 4, actionScroll = 5, actionClear = 6, actionStartup = 7, actionStop = 8, actionOneDotStart = 9; public EdgeOfChaosCA(){ init(); } public void init() { rand = new Random(); Panel mainPanel = new Panel(); mainPanel.setLayout(new BorderLayout(10,10)); Panel controlPanel = new Panel(); controlPanel.setLayout(new GridLayout(11,1,3,3)); statesChoice = new Choice(); statesChoice.addItem("2 States"); statesChoice.addItem("3 States"); statesChoice.addItem("4 States"); statesChoice.addItem("5 States"); statesChoice.addItem("6 States"); statesChoice.addItem("7 States"); statesChoice.addItem("8 States"); statesChoice.addItem("9 States"); statesChoice.addItem("10 States"); statesChoice.select(2); neighborsChoice = new Choice(); neighborsChoice.addItem("3 Neighbors"); neighborsChoice.addItem("5 Neighbors"); neighborsChoice.addItem("7 Neighbors"); neighborsChoice.addItem("9 Neighbors"); neighborsChoice.select(1); isotropyChoice = new Choice(); isotropyChoice.addItem("Isotropic"); isotropyChoice.addItem("Anisotropic"); isotropyChoice.select(0); speedChoice = new Choice(); speedChoice.addItem("Fastest"); speedChoice.addItem("Fast"); speedChoice.addItem("Moderate"); speedChoice.addItem("Slow"); speedChoice.addItem("Slower"); speedChoice.select(1); sleepTime = 10; infoString = "4 States, 5 Neighbors, Isotropic; 544 Rules; Lambda = "; info = new Label(infoString + "0.333 "); info.setFont(new Font("TimesRoman", Font.BOLD, 12)); mainPanel.add("North",info); CA = new CACanvas(); Color[] color = new Color[10]; color[0] = Color.white; color[1] = Color.black; color[2] = Color.red; color[3] = Color.blue; color[4] = Color.yellow; color[5] = Color.cyan; color[6] = Color.magenta; color[7] = Color.green; color[8] = Color.gray; color[9] = Color.orange; CA.properties(5,4,null,color,false); mainPanel.add("Center",CA); scroll = new Scrollbar(Scrollbar.VERTICAL,185,15,0,543); scrollMax = 543; mainPanel.add("East",scroll); controlPanel.add(new Button("New")); controlPanel.add(statesChoice); controlPanel.add(neighborsChoice); controlPanel.add(isotropyChoice); controlPanel.add(speedChoice); controlPanel.add(new Button("Restart")); controlPanel.add(new Button("Clear")); controlPanel.add(new Button("Random Start")); controlPanel.add(new Button("Random Clump")); controlPanel.add(new Button("One Dot Start")); txtNumber = new TextField(); controlPanel.add(txtNumber); setLayout(new BorderLayout(10,10)); add("East", controlPanel); add("Center", mainPanel); } synchronized void setAction(int act) { actionNeeded = act; } synchronized int checkAction() { int temp = actionNeeded; actionNeeded = 0; return temp; } public void start() { if (runner == null) { runner = new Thread(this); setAction(actionStartup); runner.start(); } } public void stop() { if (runner != null) { setAction(actionStop); runner.stop(); runner = null; } } public Insets insets() { return new Insets(3,3,3,3); } public void run() { boolean running = true; while (running) { int act = checkAction(); switch (act) { case 0: CA.next(); break; case actionStartup: try { Thread.sleep(500); } // delay start 1/2 second catch (InterruptedException e) { } doNew(0); break; case actionStop: running = false; break; case actionClear: CA.clear(); break; case actionReset: CA.reset(); break; case actionRandom: doRandom(); break; case actionRandomClump: doRandomClump(); break; case actionOneDotStart: CA.set(null); break; case actionNew: doNew(1); break; case actionScroll: do { try { Thread.sleep(250); } catch (InterruptedException e) { } } while (checkAction() == actionScroll); if (scroll.getValue() != lambdaCt) { newLambda(); CA.reset(); } break; } if (sleepTime > 0) { try { Thread.sleep(sleepTime); } catch (InterruptedException e) { } } //else //Thread.yield(); } } void doNew(int type) { states = statesChoice.getSelectedIndex() + 2; neighbors = neighborsChoice.getSelectedIndex()*2 + 3; anisotropic = (isotropyChoice.getSelectedItem().equals("Anisotropic")); int oldruleCt=0; if(type==1){ oldruleCt=ruleCt; } ruleCt = 1; for (int i = 1; i <= neighbors; i++) ruleCt = ruleCt*states; rules = new int[ruleCt]; if (anisotropic) { lambdaRule = new int[ruleCt]; lambdaState = new int[ruleCt]; makeRules(); } else { if (isoStates != states || isoNeighbors != neighbors) computeisoMate(); lambdaRule = new int[isoCt]; lambdaState = new int[isoCt]; makeIsoRules(); ruleCt = isoCt; } scrollMax = ruleCt-1; infoString = "" + states + " States, " + neighbors + " Neighbors, " + isotropyChoice.getSelectedItem() + "; " + ruleCt + " Rules; Lambda = "; int scrollValue; if(type==0){ scrollValue = (int)((double)ruleCt / 3.0 + 0.5); }else{ int tmp=scroll.getValue(); scrollValue=(int)((double)(ruleCt*tmp)/(double)(oldruleCt)); } if(type==1)scrollValue=scroll.getValue(); int scrollInc; double tmp1 = (double)(ruleCt) / 25.0; scrollInc=(int)(tmp1); if(scrollInc==0)scrollInc=1; scroll.setValues(scrollValue,scrollInc,0,scrollMax); info.setText(infoString + ((double)scrollValue / (double)scrollMax)); CA.properties(states,neighbors,rules,color,false); newLambda(); //得到新规则的编码 String txt=""; for(int i=0;i<ruleCt;i++){ txt+=rules[i]; } txtNumber.setText(txt); doRandom(); } void makeRules() { rules[0] = 0; lambdaState[0] = 0; lambdaRule[0] = 0; for (int i=1; i < ruleCt; i++) { rules[i] = 0; lambdaRule[i] = i; lambdaState[i] = 1 + (int)(rand.nextDouble()*(states-1)); if (lambdaState[i] >= states) lambdaState[i] = states; } for (int i = ruleCt-1; i>1; i--) { int r = 1 + (int)(rand.nextDouble()*i); if (r > i) r = i; int temp = lambdaRule[i]; lambdaRule[i] = lambdaRule[r]; lambdaRule[r] = temp; } lambdaCt = 0; } void makeIsoRules() { boolean[] used = new boolean[ruleCt]; for (int i=0; i<ruleCt; i++) { used[i] = false; rules[i] = 0; } lambdaState[0] = 0; lambdaRule[0] = 0; int k=1; for (int i=1; i<ruleCt; i++) { if (!used[i]) { lambdaRule[k] = i; used[isoMate[i]] = true; k++; } } for (int i = isoCt-1; i>1; i--) { int r = 1 + (int)(rand.nextDouble()*i); if (r > i) r = i; int temp = lambdaRule[i]; lambdaRule[i] = lambdaRule[r]; lambdaRule[r] = temp; } for (int i=1; i<isoCt; i++) { lambdaState[i] = 1 + (int)(rand.nextDouble()*(states-1)); if (lambdaState[i] >= states) lambdaState[i] = states; } lambdaCt = 0; } void newLambda() { int newLambdaCt = scroll.getValue(); if (anisotropic) { if (newLambdaCt > lambdaCt) { for (int i=lambdaCt+1; i<=newLambdaCt; i++) CA.setRule(lambdaRule[i],lambdaState[i]); } else if (newLambdaCt < lambdaCt) { for (int i=lambdaCt; i>newLambdaCt; i--) CA.setRule(lambdaRule[i],0); } } else { if (newLambdaCt > lambdaCt) { for (int i=lambdaCt+1; i<=newLambdaCt; i++) { CA.setRule(lambdaRule[i],lambdaState[i]); CA.setRule(isoMate[lambdaRule[i]],lambdaState[i]); } } else if (newLambdaCt < lambdaCt) { for (int i=lambdaCt; i>newLambdaCt; i--) { CA.setRule(lambdaRule[i],0); CA.setRule(isoMate[lambdaRule[i]],0); } } } lambdaCt = newLambdaCt; } void computeisoMate() { if (isoMate == null || isoMate.length < ruleCt) isoMate = new int[ruleCt]; isoMate[0] = 0; for (int i=1; i<ruleCt; i++) isoMate[i] = -1; int[] num = new int[9]; for (int i=0; i<=8; i++) num[i] = 0; isoCt = 1; int y=0; do { int j=0; while (j < neighbors && ++num[j] >= states) { num[j] = 0; j++; } y++; if (isoMate[y] == -1) { int x = num[0]; for (int k = 1; k<neighbors; k++) x = states*x + num[k]; isoMate[x] = y; isoMate[y] = x; isoCt++; } } while (y < ruleCt-1); isoStates = states; isoNeighbors = neighbors; } void doRandom() { CA.set(null); int width = CA.getSize().width; for (int i=0; i<width; i++) { int c = (int)(rand.nextDouble() * states); if (c >= states) c = 0; CA.setCell(i,c); } CA.setStart(); } void doRandomClump() { CA.set(null); int width = CA.getSize().width; for (int i=0; i<width; i++) CA.setCell(i,0); int left = (width / 2) - (width / 10); int right = (width / 2) + (width / 10); for (int i=left; i<=right; i++) { int c = (int)(rand.nextDouble() * states); if (c >= states) c = 0; CA.setCell(i,c); } CA.setStart(); } void doSpeed(int speed) { switch (speed) { case 0: sleepTime = 0; break; case 1: sleepTime = 15; break; case 2: sleepTime = 50; break; case 3: sleepTime = 200; break; case 4: sleepTime = 500; break; } } void checkNeighbors() { int n = neighborsChoice.getSelectedIndex(); int s = statesChoice.getSelectedIndex(); int max = 0; switch (s) { case 0: max = 3; break; case 1: max = 3; break; case 2: max = 2; break; case 3: max = 1; break; case 4: max = 1; break; case 5: max = 1; break; default: max = 0; break; } if (n > max) neighborsChoice.select(max); } public boolean action(Event evt, Object arg) { if (evt.target instanceof Button) { if (arg.equals("New")) setAction(actionNew); else if (arg.equals("Restart")) setAction(actionReset); else if (arg.equals("Random Start")) setAction(actionRandom); else if (arg.equals("Random Clump")) setAction(actionRandomClump); else if (arg.equals("Clear")) setAction(actionClear); else if (arg.equals("One Dot Start")) setAction(actionOneDotStart); } else if (evt.target == speedChoice) doSpeed(speedChoice.getSelectedIndex()); else if (evt.target == neighborsChoice || evt.target == statesChoice) checkNeighbors(); return true; } public boolean handleEvent(Event evt) { if (evt.id == Event.SCROLL_ABSOLUTE || evt.id == Event. SCROLL_LINE_DOWN || evt.id == Event. SCROLL_LINE_UP || evt.id == Event. SCROLL_PAGE_DOWN || evt.id == Event. SCROLL_PAGE_UP) { int val = scroll.getValue(); if (val == scrollMax) info.setText(infoString + "1.00"); else { int x = (int)(((double)val / (double)scrollMax) * 1000.0); if (x>=100) info.setText(infoString + "0." + x); else if (x>=10) info.setText(infoString + "0.0" + x); else info.setText(infoString + "0.00" + x); } setAction(actionScroll); return true; } else return super.handleEvent(evt); }} // class EdgeCA
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -