[Codewar训练]Conway's Game of Life - Unlimited Edition(康威生命游戏)

问题:

段位:4

说明:

就是经典的康威生命游戏,输入会提供一个二维数组,然后根据提供的generations,计算出多少代的生命样子,并且需要把多余的(就是整行整列为0),外围的空间去掉,只剩下概括住细胞存在的二维数组返回。

康威生命游戏规则:

1、Any live cell with fewer than two live neighbours dies, as if caused by underpopulation.
2、Any live cell with more than three live neighbours dies, as if by overcrowding.
3、Any live cell with two or three live neighbours lives on to the next generation.
4、Any dead cell with exactly three live neighbours becomes a live cell.

1、一个细胞周围8个格子,少于2个活细胞(数值为1)就死去(变成0)
2、一个细胞周围8个格子,多于3个活细胞就死去
3、一个细胞周围8个格子,活细胞数量是 2 或 3 就能够存活到下一代
4、一个细胞周围8个格子,活细胞数量刚好 3 个,而且这个细胞是死的(0)就活过来了(1)

输入输出案例:

输入:
int a ={{1,1,1,0,0,0,1,0},      int generations = 1
        {1,0,0,0,0,0,0,1},
        {0,1,0,0,0,1,1,1}}


输出:
0,1,0,0,0,0,0,0,
1,1,0,0,0,0,0,0,
1,0,1,0,0,1,0,1,
0,0,0,0,0,0,1,1,
0,0,0,0,0,0,1,0,

我的代码:

整体比较复杂,就是需要注意扩展你的地图(细胞的二维数组);检查你的细胞周围活细胞数量;根据活细胞数量判断细胞是死是活;最后是剪切掉多余空间;

整体代码还没有优化,我的话也没借鉴其他的,毕竟代码量较大,大家思维就不太一样。

/**
 * 生命细胞
 */
public class ConwayLife {

    public static void main(String[] args) {

        int[][] test = {
                {1,1,1,0,0,0,1,0},
                {1,0,0,0,0,0,0,1},
                {0,1,0,0,0,1,1,1}};
        int[][] cells = ConwayLife.getGeneration(test, 1);

        for(int i = 0;i < cells.length;i ++) {
            for(int j = 0;j < cells[0].length;j ++) {
                System.out.print(cells[i][j] + ",");
            }
            System.out.println();
        }
    }

    // empty_live 空的生命盒标记
    private static int[][] temp_e;
    // save_live 记录下一代生命标记
    private static int[][] temp_s;
    // expend_flag 扩展标记,用于扩展数组
    private static boolean eF;

    public static int[][] getGeneration(int[][] cells, int generations) {
        // 因为codewar创建一个类就不断测试问题,所以每次进来都把开关弄成true
        eF = true;
        temp_s = cells;

        for(int g = generations;g -- > 0;) {
            // 1-判断是否扩展,扩展之后把旧数组temp_s内容赋值到temp_e,然后更换temp_s指向
            if(eF) {
                expends(temp_s);
                for(int x = temp_s.length;x -- > 0;) {
                    for(int y = temp_s[0].length;y -- > 0;) {
                        temp_e[x + 1][y + 1] = temp_s[x][y];
                    }
                }
                temp_s = temp_e;
                temp_e = new int[temp_s.length][temp_s[0].length];
            }

            // 2-进行遍历处理细胞生死情况
            for(int x = temp_s.length;x -- > 0;) {
                for(int y = temp_s[0].length;y -- > 0;) {
                    // 统计一个细胞周围活细胞
                    int count = checkLife(temp_s, x, y);

                    // 检查是死是活,true就是活过来了
                    if(chekcLive(temp_s[x][y], count)) {
                        // 如果是边界死细胞活过来了,就打开扩展标记
                        if(x == 0 
                        || y == 0 
                        || x == temp_s.length - 1 
                        || y == temp_s[0].length - 1) 
                            eF = true;
                        temp_e[x][y] = 1;
                    }
                    else temp_e[x][y] = 0;
                }
            }

            // 3-进行 temp_s 和 temp_e 指向互换
            int[][] temp_m = temp_s;
            temp_s = temp_e;
            temp_e = temp_m;
        }

        // 4-处理掉多余空间
        temp_s = cutOff(temp_s);

        return temp_s;
    }


    // 纯粹为了测量剩下的生命边界
    public static int[][] cutOff(int[][] temp_s) {
        int xtop = 0;
        int xdow = 0;
        int ytop = 0;
        int ydow = 0;
        
        // x顶部
        A:for(int i = 0;i < temp_s.length;i ++) {
            for(int j = 0;j < temp_s[0].length;j ++ ) {
                if(temp_s[i][j] != 0) {
                    xtop = i;
                    break A;
                }
            }
        }

        // y顶部
        A:for(int j = 0;j < temp_s[0].length;j ++ ) {
            for(int i = 0;i < temp_s.length;i ++) {
                if(temp_s[i][j] != 0) {
                    ytop = j;
                    break A;
                }
            }
        }

        // y底部
        A:for(int j = temp_s[0].length;j -- > 0;) {
            for(int i = temp_s.length;i -- > 0;) {
                if(temp_s[i][j] != 0) {
                    ydow = j;
                    break A;
                }
            }
        }

        // x底部
        A:for(int i = temp_s.length;i -- > 0;) {
            for(int j = temp_s[0].length;j -- > 0;) {
                if(temp_s[i][j] != 0) {
                    xdow = i;
                    break A;
                }
            }
        }

        // 测量好生命范围之后,创建新的数组赋值内容返回
        temp_e = new int[xdow - xtop + 1][ydow - ytop + 1];
        for(int i = xtop;i <= xdow;i ++) {
            for (int j = ytop;j <= ydow;j ++) {
                temp_e[i - xtop][j - ytop] = temp_s[i][j];
            }
        }
        temp_s = temp_e;
        return temp_s;
    }

    // 进行扩展,外面扩展一层
    public static void expends(int[][] temp_s) {
        temp_e = new int[temp_s.length + 2][temp_s[0].length + 2];
        eF = false;
    }

    // 检查生命现象
    public static boolean chekcLive(int val, int count) {
        if(count > 3 || count < 2) return false;
        else if(count == 3 && val == 0) return true;
        else if(count < 4 && count > 1 && val != 0) return true;
        else return false;
    }

    // 统计活细胞
    public static int checkLife(int[][] temp, int x, int y) {
        int count = 0;
        int x1 = x - 1;
        int x2 = x + 1;
        int y1 = y - 1;
        int y2 = y + 1;

        if(x1 >= 0) {
            count += temp[x1][y];
            if(y1 >= 0) {
                count += temp[x1][y1];
            }
            if(y2 < temp[0].length) {
                count += temp[x1][y2];
            }
        }
        if(x2 < temp.length) {
            count += temp[x2][y];
            if(y1 >= 0) {
                count += temp[x2][y1];
            }
            if(y2 < temp[0].length) {
                count += temp[x2][y2];
            }
        }

        if(y1 >= 0) {
            count += temp[x][y1];
        }
        if(y2 < temp[0].length) {
            count += temp[x][y2];
        }

        return count;
    }
}

你可能感兴趣的:(Java)