生命游戲其實是一個零玩家游戲,它包括一個二維矩形世界,這個世界中的每個方格居住著一個活著的或死了的細胞。一個細胞在下一個時刻生死取決于相鄰八個方格中活著的或死了的細胞的數量。如果相鄰方格活著的細胞數量過多,這個細胞會因為資源匱乏而在下一個時刻死去;相反,如果周圍活細胞過少,這個細胞會因太孤單而死去。
具體規則如下:
1)如果一個細胞周圍有3個細胞為生(一個細胞周圍共有8個細胞),則該細胞為生(即該細胞若原先為死,則轉為生,若原先為生,則保持不變) 。
2) 如果一個細胞周圍有2個細胞為生,則該細胞的生死狀態保持不變;
3) 在其它情況下,該細胞為死(即該細胞若原先為生,則轉為死,若原先為死,則保持不變)
在程序中,使用0代表死,1代表生。
串行模式
public class lifegame {public static List<String> readTxt(String fileName){List<String> list=new ArrayList<>();try { // 防止文件建立或讀取失敗,用catch捕捉錯誤并打印,也可以throw/* 讀入TXT文件 */File filename = new File(fileName); // 要讀取以上路徑的input。txt文件InputStreamReader reader = new InputStreamReader(new FileInputStream(filename)); // 建立一個輸入流對象readerBufferedReader br = new BufferedReader(reader); // 建立一個對象,它把文件內容轉成計算機能讀懂的語言String line = "";line = br.readLine();while (line != null) {list.add(line);line = br.readLine();}} catch (Exception e) {e.printStackTrace();}return list;}public static void writeTxt(String content){try { // 防止文件建立或讀取失敗,用catch捕捉錯誤并打印,也可以throw/* 讀入TXT文件 */File writename = new File("output.txt"); // 相對路徑,如果沒有則要建立一個新的output。txt文件writename.createNewFile(); // 創建新文件BufferedWriter out = new BufferedWriter(new FileWriter(writename));out.write(content); // \r\n即為換行out.flush(); // 把緩存區內容壓入文件out.close(); // 最后記得關閉文件} catch (Exception e) {e.printStackTrace();}}public boolean[][] world;public int len;int times;public lifegame(List<String> list) {int n=Integer.parseInt(list.get(0));world=new boolean[n][n];this.len=n;this.times=Integer.parseInt(list.get(1));System.out.println(len);for(int i=2;i<list.size();i++){String[] temp=list.get(i).split(",");int x=Integer.parseInt(temp[0]),y=Integer.parseInt(temp[1]);world[x][y]=true;}System.out.println(list.get(0)+times);}public void print(){for(int i=0;i<len;i++){for(int j=0;j<len;j++)if(world[i][j])System.out.print(1);else System.out.print(0);System.out.println();}System.out.println();}private int[][] dir=new int[][]{{0,1},{0,-1},{1,0},{-1,0},{1,1},{-1,-1},{-1,1},{1,-1}};public void change(){int[][] count=new int[len][len];for(int i=0;i<len;i++)for(int j=0;j<len;j++)count[i][j]=count(i,j);for(int i=0;i<len;i++)for(int j=0;j<len;j++)if(count[i][j]==3){world[i][j]=true;}else if(count[i][j]!=2)world[i][j]=false;}public int count(int x,int y){int ret=0;for(int[] c:dir){int nextX=c[0]+x,nextY=c[1]+y;if(nextX>=0&&nextX<len&&nextY>=0&&nextY<len){ret+=world[nextX][nextY]?1:0;}}return ret;}public static void main(String[] args){lifegame on=new lifegame(readTxt("input.txt"));for(int i=0;i<on.times;i++){on.change();}StringBuilder stringBuilder=new StringBuilder();for(int i=0;i<on.len;i++)for(int j=0;j<on.len;j++){if(on.world[i][j]){stringBuilder.append(i).append(',').append(j).append("\r\n");}}writeTxt(stringBuilder.toString());}
}
并行模式
public class lifegame2 {public static List<String> readTxt(String fileName){List<String> list=new ArrayList<>();try { // 防止文件建立或讀取失敗,用catch捕捉錯誤并打印,也可以throw/* 讀入TXT文件 */File filename = new File(fileName); // 要讀取以上路徑的input。txt文件InputStreamReader reader = new InputStreamReader(new FileInputStream(filename)); // 建立一個輸入流對象readerBufferedReader br = new BufferedReader(reader); // 建立一個對象,它把文件內容轉成計算機能讀懂的語言String line = "";line = br.readLine();while (line != null) {list.add(line);line = br.readLine();}} catch (Exception e) {e.printStackTrace();}return list;}public static void writeTxt(String content){try { // 防止文件建立或讀取失敗,用catch捕捉錯誤并打印,也可以throw/* 讀入TXT文件 */File writename = new File("output.txt"); // 相對路徑,如果沒有則要建立一個新的output。txt文件writename.createNewFile(); // 創建新文件BufferedWriter out = new BufferedWriter(new FileWriter(writename));out.write(content); // \r\n即為換行out.flush(); // 把緩存區內容壓入文件out.close(); // 最后記得關閉文件} catch (Exception e) {e.printStackTrace();}}int[][] count;private boolean[][] world;int len;public int times;public int getTimes() {return times;}public lifegame2(List<String> list) {int n=Integer.parseInt(list.get(0));world=new boolean[n][n];count=new int[n][n];this.len=n;this.times=Integer.parseInt(list.get(1));System.out.println(len);for(int i=2;i<list.size();i++){String[] temp=list.get(i).split(",");int x=Integer.parseInt(temp[0]),y=Integer.parseInt(temp[1]);world[x][y]=true;}System.out.println(list.get(0)+times);}public void print(){for(int i=0;i<len;i++){for(int j=0;j<len;j++)if(world[i][j])System.out.print(1);else System.out.print(0);System.out.println();}System.out.println();}public String excute(int c){ExecutorService executorService= Executors.newFixedThreadPool(c);for(int j=0;j<times;j++){CountDownLatch countDownLatch=new CountDownLatch(c);Thread[] threads = new Thread[10];for(int i=0;i<len;i+=len/c){excuteThread cur=new excuteThread(count,i,i+len/c-1,world,countDownLatch);executorService.execute(cur);}try {countDownLatch.await();} catch (InterruptedException e) {e.printStackTrace();}for(int i=0;i<len;i++)for(int k=0;k<len;k++)if(count[i][k]==3){world[i][k]=true;}else if(count[i][k]!=2)world[i][k]=false;System.out.printf("第%d輪結束\n",j);}executorService.shutdown();while (!executorService.isTerminated()){}StringBuilder stringBuilder=new StringBuilder();for(int i=0;i<len;i++)for(int j=0;j<len;j++){if(world[i][j]){stringBuilder.append(i).append(',').append(j).append("\r\n");}}return stringBuilder.toString();}public static void main(String[] args){lifegame2 on=new lifegame2(readTxt("input.txt"));long s=System.currentTimeMillis();String t=on.excute(4);System.out.println(((double) (System.currentTimeMillis()-s))/1000);writeTxt(t);}
}
public class excuteThread implements Runnable{int[][] count;int l,r,len;boolean[][] world;CountDownLatch countDownLatch;public excuteThread(int [][] count,int l,int r,boolean[][] world,CountDownLatch countDownLatch) {len=count.length;this.count=count;this.l=l;this.r=r;this.countDownLatch=countDownLatch;this.world=world;}@Overridepublic void run() {System.out.println("線程"+l*4/len+"開始");for(int i=0;i<len;i++)for(int j=l;j<=r;j++)count[i][j]=count(i,j);System.out.println("線程"+l*4/len+"結束");countDownLatch.countDown();}private int[][] dir=new int[][]{{0,1},{0,-1},{1,0},{-1,0},{1,1},{-1,-1},{-1,1},{1,-1}};public int count(int x,int y){int ret=0;for(int[] c:dir){int nextX=c[0]+x,nextY=c[1]+y;if(nextX>=0&&nextX<len&&nextY>=0&&nextY<len){ret+=world[nextX][nextY]?1:0;}}return ret;}
}