// // ライフゲームエディタJava版第2回 // // 2000/ 6/20 宍戸 輝光 // import java.awt.*; import java.awt.event.*; class CLdat2 { // データクラス private byte lifes[][],blifes[][]; // セル配列 private int width,height; // 大きさ保存用変数 private int rules[]={-1,-1,0,1,-1,-1,-1,-1,-1}; CLdat2(int w,int h) { // コンストラクタ width=w; height=h; // 指定された大きさでセル配列確保 lifes=new byte[width][height]; blifes=new byte[width][height]; } public int getWidth() { return width; } public int getHeight() { return height; } public byte getLife(int x,int y) { return lifes[x][y]; } public void setLife(int x,int y,byte val) { lifes[x][y]=val; } public void setRules(int rul[]) { rules=rul; } public int[] getRules() { return rules; } public void next() { // 1ステップ進める int i,j,k,l,n,x,y; for (i=0;i<height;i++) // 処理前のセル配列を保存 for (j=0;j<width;j++) blifes[j][i]=lifes[j][i]; for (i=0;i<height;i++) // 注目セルを中心とする3×3セルの生物数計算 for (j=0;j<width;j++) { n=0; // 生物数カウンタクリア for (k=-1;k<2;k++) // 周辺の生物数合計 for (l=-1;l<2;l++) { if (j+l==-1) x=width-1; else if (j+l==width) x=0; else x=j+l; if (i+k==-1) y=height-1; else if (i+k==width) y=0; else y=i+k; n+=blifes[x][y]; } n-=blifes[j][i]; // 注目セル自身の分を引く if (rules[n]==-1) // ルールで生死判定 lifes[j][i]=0; else if (rules[n]==1) lifes[j][i]=1; } } } class CLdisp2 extends Canvas implements MouseListener { // 表示パネルクラス private CLdat2 ldat; private Image img; private Graphics g_img; private int vr=5; private int lwid,lhei; CLdisp2(CLdat2 dat) { ldat=dat; // 描画対象のデータクラスを保存 // データクラスの大きさ保存 lwid=ldat.getWidth(); lhei=ldat.getHeight(); setSize(lwid*vr+2,lhei*vr+2); setBackground(Color.white); addMouseListener(this); } private void drawDat() { // 現在の状況を描画 Color cl; for (int i=0;i<lhei;i++) for (int j=0;j<lwid;j++) { // 生物の有無で色を設定 if (ldat.getLife(j,i)==0) cl=Color.black; else cl=Color.green; g_img.setColor(cl); // 設定した色で(j,i)を塗りつぶす g_img.fillRect(j*vr+1,i*vr+1,vr-1,vr-1); } } public void paint(Graphics g) { if (img==null) { // 最初の描画時にイメージ作成 img=createImage(lwid*vr,lhei*vr); g_img=img.getGraphics(); g_img.setColor(Color.blue); g_img.fillRect(0,0,lwid*vr,lhei*vr); } drawDat(); // 現在の状況をイメージに描画 g.drawImage(img,1,1,this); } public void update(Graphics g) { // ちらつき防止のためオーバーライド paint(g); } public void mousePressed(MouseEvent e) {} public void mouseClicked(MouseEvent e) { // マウスクリック int x=(int)((e.getX()-1)/vr); int y=(int)((e.getY()-1)/vr); if (ldat.getLife(x,y)==0) ldat.setLife(x,y,(byte)1); else ldat.setLife(x,y,(byte)0); repaint(); } public void mouseReleased(MouseEvent e) {} public void mouseEntered(MouseEvent e) {} public void mouseExited(MouseEvent e) {} } class CRule2 extends Panel { // ルール設定パネル Checkbox rchk[][]; CheckboxGroup rchkb[]; Label lb[]; CRule2() { int i,j; rchk=new Checkbox[3][9]; rchkb=new CheckboxGroup[9]; String str[]=new String[3]; str[0]="O"; str[1]="X"; str[2]="-"; lb=new Label[9]; setBackground(new Color(160,192,192)); setLayout(new GridLayout(9,4,1,2)); for (i=0;i<9;i++) { // チェックボックス作成 lb[i]=new Label(String.valueOf(i),Label.CENTER); add(lb[i]); rchkb[i]=new CheckboxGroup(); for (j=0;j<3;j++) { rchk[j][i]=new Checkbox(str[j],false,rchkb[i]); add(rchk[j][i]); } } } public void getRules(int rules[]) { for (int i=0;i<9;i++) if (rchk[0][i].getState()) rules[i]=1; else if (rchk[1][i].getState()) rules[i]=-1; else rules[i]=0; } public void setRules(int rules[]) { for (int i=0;i<9;i++) if (rules[i]==1) rchk[0][i].setState(true); else if (rules[i]==-1) rchk[1][i].setState(true); else rchk[2][i].setState(true); } } class CLife2 extends Frame implements ActionListener { CLdat2 ldat; Panel pl; Button bt,btNext; CLdisp2 disp; CRule2 rl; CLife2() { setLayout(new BorderLayout()); ldat=new CLdat2(64,64); disp=new CLdisp2(ldat); rl=new CRule2(); bt=new Button("Close"); // ボタン生成 bt.addActionListener(this); // ボタンのイベントリスナ設定 btNext=new Button("Next"); btNext.addActionListener(this); pl=new Panel(); // 部品配置用パネル生成 pl.setBackground(new Color(160,144,192)); pl.add(bt); // パネルにボタン配置 pl.add(btNext); rl.setRules(ldat.getRules()); add(disp,"Center"); add(pl,"South"); // パネルをフレーム上に配置 add(rl,"East"); } public static void main(String args[]) { CLife2 app=new CLife2(); // アプリケーション生成 app.pack(); app.show(); app.repaint(); } public void actionPerformed(ActionEvent e) { if (e.getSource()==bt) { // ボタンクリックイベント dispose(); // アプリケーションフレーム破棄 System.exit(0); // 終了 } if (e.getSource()==btNext) { rl.getRules(ldat.getRules()); ldat.next(); disp.repaint(); } } }