真夜中の色彩

真夜中の雰囲気が好きなプログラマのブログ

ライフゲーム

会社ではJavaのお勉強中です。
本を読むだけじゃ身に付きそうにもないので、ライフゲームを作ってみました。
とはいっても、アニメーションするとかじゃなくて、単に世代毎に表示するだけだけど。

import java.io.*;

public class Lifegame {
	Cells m_cells;
	PrintWriter writer;

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Lifegame lifegame = new Lifegame();
		lifegame.gameStart(200);
	}
	
	Lifegame(){
		m_cells = new Cells();
		m_cells.readFile();		
		try {
			writer = new PrintWriter(new BufferedWriter(new
FileWriter("lifelog.txt")));
		}catch(IOException e){
			System.out.println(e);
		}						
	}

	/**
	 * 世代の移り変わりを計算して、結果を出力する
	 * @param ageMax
	 */
	void gameStart(int ageMax){
		int age = 0;
		while(age < ageMax){
			System.out.println(m_cells.toString());
			writer.println(m_cells.toString());
			
			m_cells.nextAge();	
			age++;			
		}		
	}
}

class Cells {
	/** セルの縦 */
	final int HIGHT = 20;
	/** セルの横 */
	final int WIDTH = 40;
	/** 死滅状態 */
	final int DEAD = 0;
	/** 生存状態 */
	final int ALIVE = 1;
	/** 全セル */
	int cell[][] = new int[HIGHT][WIDTH];

	Cells(){
		for(int j=0; j<HIGHT; j++){
			for(int i=0; i<WIDTH; i++){
				cell[j][i] = DEAD;
			}
		}
	}
	
	/**
	 * 初期状態をファイル読み込みする。
	 * ファイル名は固定。
	 */
	public void readFile(){
		try{
			BufferedReader reader = new BufferedReader(new FileReader("life.txt"));
			String line;
			int j=0;
			while ( (line = reader.readLine()) != null) {
				if(j>=HIGHT){
					break;
				}
				for (int i = 0; i < line.length() && i < WIDTH; i++) {
					char tmpchar = line.charAt(i);
					if (tmpchar == '.') {
						cell[j][i] = DEAD;						
					} else {
						cell[j][i] = ALIVE;
					}
				}				
				j++;
			}			
		} catch(FileNotFoundException e) {
			System.out.println(e);						
		} catch(IOException e) {
			System.out.println(e);			
		}		
	}
	
	/**
	 * 次世代の状態の計算を行う。
	 *
	 */
	public void nextAge(){
		int copyCell[][] = new int[HIGHT][WIDTH];
		int count=0;
		
		for(int j=0; j<HIGHT; j++){
			for(int i=0; i<WIDTH; i++){
				count = 0;
				// 境界のあたりを考慮しつつ、生存数をカウント。
				for(int k=j-1; k<=j+1; k++){
					if(k<0 || k>(HIGHT-1)){
						continue;
					}						
					for(int l=i-1; l<=i+1; l++){
						if(l<0 || l>(WIDTH-1)){
							continue;		
						}
						if(k==j && l==i){
							continue;
						}
						if(cell[k][l] == ALIVE){
							count++;					
						}
					}				
				}
				// カウント結果を元に、次世代の状態を決定。
				if(count==3){
					copyCell[j][i]=ALIVE;						
				} else if(count==2 && cell[j][i]==ALIVE){
					copyCell[j][i]=ALIVE;
				} else {
					copyCell[j][i]=DEAD;
				}				
			}
		}
		cell = copyCell;
	}
	
	/**
	 * セルの全状態を出力
	 */
	public String toString(){
		StringBuffer sbuf = new StringBuffer();
		for(int j=0; j<HIGHT; j++){
			for(int i=0; i<WIDTH; i++){
				if(cell[j][i] == 0){
					sbuf.append("□");					
				} else {
					sbuf.append("■");
				}
			}
			sbuf.append("\n");
		}
		return sbuf.toString();		
	}
}

う〜む。
ソースを書けても、いかにうまく、美しく書くかが難しいですね。
通りすがったお暇な方がいらっしゃいましたら、何かアドバイスよろしくお願いします('ω')