/**********************************/ /*              */ /*  ライフゲーム   */ /*              */ /*  1997/10/19 宍戸 輝光  */ /*              */ /**********************************/ import java.awt.*; import java.util.Random; public class life extends java.applet.Applet implements Runnable { Image screen; Graphics g_screen; Choice ruleSelect,wait; Font f; Panel pn1,pn2,pn3,pn4; Label generation,creatures,rule_text,wait_text,m_x,m_y; Button bt1,bt2,bt3,bt4,bt5,bt6,bt7; Thread runner=null; boolean cell[][]=new boolean [64][64]; boolean pre_cell[][]=new boolean [64][64]; boolean pre_screen[][]=new boolean [64][64]; boolean cell_save[][]=new boolean [64][64]; boolean pre_able,autoRun,screen_done,runSus,repaint_done,save; int ge,cren,rule=2,wait_time=0,i,j,i2,j2,mx=65,my,ge_save; public void start(){ pre_able=false; autoRun=false; screen_done=true; save=false; screen=createImage(321,321); /*部品作成*/ g_screen=screen.getGraphics(); ruleSelect=new Choice(); wait=new Choice(); pn1=new Panel(); pn2=new Panel(); pn3=new Panel(); pn4=new Panel(); generation=new Label(); creatures=new Label(); rule_text=new Label(); wait_text=new Label(); m_x=new Label(); m_y=new Label(); generation.setBackground(Color.green); creatures.setBackground(Color.green); rule_text.setBackground(Color.green); wait_text.setBackground(Color.green); m_x.setBackground(Color.green); m_y.setBackground(Color.green); bt1=new Button(); bt2=new Button(); bt3=new Button(); bt4=new Button(); bt5=new Button(); bt6=new Button(); bt7=new Button(); resize(480,420); setBackground(Color.green); /*アプレットの背景を緑にする*/ ruleSelect.setBackground(Color.white);/*選択メニューの背景を白にする*/ f=new Font("TimesRoman",Font.PLAIN,12); /*ラベル・選択メニューFont*/ ruleSelect.setFont(f); generation.setFont(f); creatures.setFont(f); rule_text.setFont(f); wait_text.setFont(f); m_x.setFont(f); m_y.setFont(f); ruleSelect.addItem("2-3"); /*ラベル・選択メニューのテキスト定義*/ ruleSelect.addItem("3-4"); ruleSelect.select("2-3"); wait.addItem("0"); wait.addItem("10"); wait.addItem("250"); wait.addItem("500"); wait.addItem("750"); wait.addItem("1000"); wait.addItem("2000"); generation.setText("generation: "); creatures.setText("creatures: "); rule_text.setText("rule"); wait_text.setText("wait(ms)"); f=new Font("TimesRoman",Font.BOLD,16); /*ボタンのフォント*/ bt1.setFont(f); bt2.setFont(f); bt3.setFont(f); bt4.setFont(f); bt5.setFont(f); bt6.setFont(f); bt7.setFont(f); bt1.setLabel("Next"); bt2.setLabel("Previous"); bt3.setLabel("Auto run"); bt4.setLabel("Stop"); bt5.setLabel("Memorize"); bt6.setLabel("Clear"); bt7.setLabel("Recall"); this.setLayout((LayoutManager)null); add(pn1); add(pn2); add(pn3); add(pn4); add(m_x); add(m_y); pn1.reshape(0,8,480,32); pn2.reshape(32,384,480,32); pn3.reshape(360,64,100,48); pn4.reshape(360,128,100,48); m_x.reshape(352,192,96,32); m_y.reshape(352,232,96,32); pn1.setLayout(new FlowLayout(FlowLayout.LEFT,8,4)); pn2.setLayout(new FlowLayout(FlowLayout.LEFT,8,4)); pn3.setLayout(new FlowLayout(FlowLayout.CENTER,8,4)); pn4.setLayout(new FlowLayout(FlowLayout.CENTER,8,4)); pn1.add(generation); pn1.add(creatures); pn1.add(rule_text); pn1.add(ruleSelect); pn1.add(wait_text); pn1.add(wait); pn2.add(bt1); pn2.add(bt2); pn2.add(bt3); pn2.add(bt4); pn2.add(bt5); pn3.add(bt6); pn4.add(bt7); screenInit(); screenDraw(); bt7.enable(false); repaint(); if (runner==null) { runner=new Thread(this); /*スレッド生成*/ runner.start(); runner.suspend(); } } public void stop() { /*終了時にスレッド破棄*/ if (runner!=null) { runner.stop(); runner=null; } } public boolean mouseDown(Event evt,int x,int y){ /*マウスクリック*/ int xx,yy; if (x<=16 ||x>=336 ||y<=48 ||y>=368 ||(autoRun && !runSus)) return false; /*セルの外か自動更新中ならリターン*/ xx=(int)((x-16)/5); yy=(int)((y-48)/5); if (cell[xx][yy]) cell[xx][yy]=false; /*カーソルの位置に生物があれば除く*/ else if (!cell[xx][yy]) cell[xx][yy]=true; /*生物がいなければ置く*/ screenDraw(); repaint(); return true; } public boolean mouseMove(Event evt,int x,int y){ /*マウスカーソル移動*/ if (x<=16 ||x>=336 ||y<=48 ||y>=368) /*セルの外か*/ mx=65; else { mx=(int)((x-16)/5); my=(int)((y-48)/5); } if (mx<65) { /*マウスカーソルの座標を表示用ラベルに設定*/ m_x.setText("X : "+mx); m_y.setText("Y : "+my); } else { m_x.setText("X :"); m_y.setText("Y :"); } if (!autoRun || runSus) repaint(); return true; } public void screenInit() { /*セルを初期化*/ g_screen.setColor(Color.blue); g_screen.fillRect(0,0,321,321); g_screen.setColor(Color.white); for (i=0;i<65;i++) { g_screen.drawLine(i*5,0,i*5,320); g_screen.drawLine(0,i*5,320,i*5); } for (i=0;i<64;i++) for (j=0;j<64;j++) { cell[j][i]=false; pre_cell[j][i]=false; pre_screen[j][i]=false; } ge=0; cren=0; pre_able=false; runSus=false; bt2.enable(false); bt4.enable(false); } public void screenDraw() { /*スクリーン書き換え*/ cren=0; /* 生物数カウンタ初期化 */ screen_done=false; for (i=0;i<64;i++) /* 個々のセルに生物を描いていく */ for (j=0;j<64;j++) { if (cell[j][i]!=pre_screen[j][i]){ /* 変化あり */ if (cell[j][i]) g_screen.setColor(Color.cyan); else g_screen.setColor(Color.blue); g_screen.fillRect(1+j*5,1+i*5,4,4); } pre_screen[j][i]=cell[j][i]; if (cell[j][i]) /* 生物がいれば生物カウンタ+1*/ cren++; } screen_done=true; /*スクリーン書き換え済み*/ } public boolean action(Event evt,Object what) { if (evt.target==bt1) { /*世代更新ボタン*/ next_generation(); screenDraw(); repaint(); return true; } if (evt.target==bt2) { /*逆戻りボタン*/ for (i=0;i<64;i++) for (j=0;j<64;j++) cell[j][i]=pre_cell[j][i]; ge--; pre_able=false; bt2.enable(false); screenDraw(); repaint(); return true; } if (evt.target==bt3) { /*自動更新ボタン*/ autoRun=true; bt4.enable(true); bt1.enable(false); bt2.enable(false); bt3.enable(false); bt5.enable(false); bt6.enable(false); bt7.enable(false); ruleSelect.enable(false); runner.resume(); return true; } if (evt.target==bt4) { /*自動更新中止ボタン*/ autoRun=false; bt1.enable(true); bt3.enable(true); bt5.enable(true); bt6.enable(true); if (save) bt7.enable(true); bt4.enable(false); ruleSelect.enable(true); repaint(); } if (evt.target==bt5) { /*メモリーセーブボタン*/ for (i=0;i<64;i++) for (j=0;j<64;j++) cell_save[j][i]=cell[j][i]; ge_save=ge; screenDraw(); bt7.enable(true); save=true; repaint(); } if (evt.target==bt6) { /*クリアボタン*/ screenInit(); repaint(); } if (evt.target==bt7) { /*メモリーロードボタン*/ screenInit(); for (i=0;i<64;i++) for (j=0;j<64;j++) cell[j][i]=cell_save[j][i]; ge=ge_save; screenDraw(); repaint(); } if (evt.target==ruleSelect) { /*ルール選択*/ if (ruleSelect.getSelectedItem()=="2-3") rule=2; else if (ruleSelect.getSelectedItem()=="3-4") rule=3; } if (evt.target==wait) { /*ウエイト選択*/ wait_time=Integer.valueOf(wait.getSelectedItem()).intValue(); return true; } return false; } public void run() { /*スレッド本体*/ while (runner!=null) { if (autoRun && repaint_done) { next_generation(); screenDraw(); repaint_done=false; repaint(); if (wait_time>0) { /*ウエイト*/ try { Thread.sleep(wait_time); } catch (InterruptedException e) {} } } else if (!autoRun) { if (runner!=null) runner.suspend(); } } } public void next_generation() { /*世代更新*/ int celln; for (i=0;i<64;i++) for (j=0;j<64;j++) pre_cell[j][i]=cell[j][i]; for (i=0;i<64;i++) for (j=0;j<64;j++) { celln=0; for (i2=i-1;i20 && i2<64 && j2>0 && j2<64) if (pre_cell[j2][i2]) celln++; if (pre_cell[j][i]) celln--; if (rule==2) { /*2ー3ルール*/ if (celln==2) cell[j][i]=pre_cell[j][i]; else if (celln==3) cell[j][i]=true; else cell[j][i]=false; } else if (rule==3) { /*3ー4ルール*/ if (celln==3 || celln==4) cell[j][i]=true; else cell[j][i]=false; } } ge++; pre_able=true; if (!autoRun) bt2.enable(true); } public void paint(Graphics g){ if (screen_done) { /*スクリーン書き換え済みなら画面更新*/ generation.setText("generation:"+ge+" "); creatures.setText("creatures:"+cren+" "); g.drawImage(screen,16,48,this); /*盤面イメージ表示*/ } repaint_done=true; } public void update(Graphics g){ paint(g); } }