import java.awt.*; import java.applet.*; public class LifeGame extends Applet implements Runnable { final int lifefieldwidth = 100; // ライフ配列の幅 final int lifefieldheight = 100; // ライフ配列の高さ final int lifewidth = 5; // ライフ1個の表示サイズ幅 final int lifeheight = 5; // ライフ1個の表示サイズ高さ final byte NOTHING = 0x00; // なにもない空間 final byte STONE = 0x02; // 石(ライフフィールドを囲っている) final byte LIFE_A = 0x01; // ライフA final byte LIFE_B = 0x03; // ライフB(未使用) final Color NOTHING_COLOR = Color.black;// なにもない空間の表示色 final Color STONE_COLOR = Color.gray; // 石の表示色 final Color LIFE_A_COLOR = Color.green; // ライフAの表示色 final Color LIFE_B_COLOR = Color.yellow;// ライフBの表示色 byte lifefield[][]; // ライフフィールド配列 byte tool; // 編集アイテム int generation; // 現在のライフフィールドの世代 boolean autonext; // オートネクストonのときはtrue boolean threadisrunning; // スレッド実行中はtrue Thread nextgenerationthread; // GUI部品 Button nextbutton; Button autobutton; Button refreshbutton; Button toolbutton; Button clearbutton; Label generationlabel; public void init() { // 変数初期化 initVar(); // UI作成 nextbutton = new Button("next"); autobutton = new Button("auto"); refreshbutton = new Button("refresh"); toolbutton = new Button("current tool:"); clearbutton = new Button("all clear"); setTool(tool); generationlabel = new Label(Integer.toString(generation), Label.LEFT); this.add(nextbutton); this.add(autobutton); this.add(clearbutton); this.add(toolbutton); this.add(generationlabel); this.add(refreshbutton); } public void run() { threadisrunning = true; System.out.println("Thread in"); do{ Graphics g = this.getGraphics(); byte nextlifefield[][] = new byte[lifefieldwidth][lifefieldheight]; for(int i = 0; i < lifefieldwidth; i++) for(int j = 0; j < lifefieldheight; j++) { // ライフフィールドの縁は石 if((i == 0) || (j == 0) || (i == lifefieldwidth-1) || (j == lifefieldheight-1)) nextlifefield[i][j] = STONE; else { int lifecount = 0; // 周囲8マスのライフの存在ををチェックする if(lifefield[i-1][j-1] == LIFE_A) lifecount++; if(lifefield[i-1][j] == LIFE_A) lifecount++; if(lifefield[i-1][j+1] == LIFE_A) lifecount++; if(lifefield[i][j-1] == LIFE_A) lifecount++; if(lifefield[i][j+1] == LIFE_A) lifecount++; if(lifefield[i+1][j-1] == LIFE_A) lifecount++; if(lifefield[i+1][j] == LIFE_A) lifecount++; if(lifefield[i+1][j+1] == LIFE_A) lifecount++; // 石は石 // ライフが4以上のとき過密により死滅 // ライフが1以下のとき過疎により死滅 // ライフが3のとき誕生 // それ以外は変化なし if(lifefield[i][j] == STONE) nextlifefield[i][j] = STONE; else { if(lifecount >= 4) nextlifefield[i][j] = NOTHING; else if(lifecount <= 1) nextlifefield[i][j] = NOTHING; else if(lifecount == 3) nextlifefield[i][j] = LIFE_A; else nextlifefield[i][j] = lifefield[i][j]; } } // 次世代パターン描画 if(nextlifefield[i][j] != lifefield[i][j]) dottingLife(g, nextlifefield[i][j], i, j); /* debug System.out.println("lifecount:" + lifecount + " current:" + lifefield[i][j] + " next:" + nextlifefield[i][j]); */ } generation++; lifefield = nextlifefield; generationlabel.setText(Integer.toString(generation)); try{ Thread.sleep(100); }catch(InterruptedException e){}; }while(autonext); System.out.println("Thread out"); threadisrunning = false; } public boolean action(Event evt, Object obj) { if(evt.target == nextbutton) { autonext = false; // 現在のスレッドの終了を待つ while(threadisrunning); nextgenerationthread = new Thread(this); nextgenerationthread.start(); } else if(evt.target == autobutton) { if(autonext) { autonext = false; // スレッド終了を待つ while(threadisrunning); autobutton.setLabel("auto"); } else { // 現在のスレッドの終了を待つ while(threadisrunning); autonext = true; nextgenerationthread = new Thread(this); nextgenerationthread.start(); autobutton.setLabel("stop"); } } else if(evt.target == refreshbutton) repaint(); else if(evt.target == toolbutton) { switch(tool) { case LIFE_A: setTool(NOTHING); break; case LIFE_B: System.out.println("Error in tool"); case NOTHING: setTool(STONE); break; case STONE: setTool(LIFE_A); break; default: System.out.println("Error in tool"); } } else if(evt.target == clearbutton) { // スレッド強制停止 if(nextgenerationthread != null) nextgenerationthread.stop(); threadisrunning = false; // 変数初期化 initVar(); // 表示 setTool(tool); generationlabel.setText(Integer.toString(generation)); autobutton.setLabel("auto"); repaint(); } return true; } public boolean mouseDown(Event e, int x, int y) { dropLife(x, y); return true; } public boolean mouseDrag(Event e, int x, int y) { dropLife(x, y); return true; } public void paint(Graphics g) { drawLifeField(g); } public void stop() { System.out.println("applet stop"); if(nextgenerationthread != null) nextgenerationthread.stop(); } private final void initVar() { generation = 0; autonext = false; threadisrunning = false; tool = LIFE_A; lifefield = new byte[lifefieldwidth][lifefieldheight]; for(int i=0; i 0) && (py > 0) && (px < lifefieldwidth-1) && (py < lifefieldheight-1)) { Graphics g = this.getGraphics(); lifefield[px][py] = tool; dottingLife(g, tool, px, py); } } } }