• PuyoPuyo DFS算法练习


    PuyoPuyo DFS算法练习

    题目和解析有空再整理。

    package puyopuyo;
    
    /**
     * @Author jinjun99
     * @Date Created in 2021/11/21 11:18
     * @Description
     * @Since version-1.0
     */
    public class Block {
    
        /**
         * 状态
         */
        int event = 0;
        /**
         * 方向
         */
        int dir = 0;
    
        /**
         * 列号
         */
        int col = 0;
        /**
         * 颜色
         */
        int[] val;
    
        public Block(int[] val) {
            this.val = val;
        }
    }
    
    
    package puyopuyo;
    
    /**
     * @Author jinjun99
     * @Date Created in 2021/11/21 13:00
     * @Description
     * @Since version-1.0
     */
    public class Point {
        int x = 0;
        int y = 0;
    
        public Point(int x, int y) {
            this.x = x;
            this.y = y;
        }
    
        public Point() {
        }
    }
    
    
    package puyopuyo;
    
    import java.util.Arrays;
    import java.util.Stack;
    
    /**
     * @Author jinjun99
     * @Date Created in 2021/11/21 17:36
     * @Description
     * @Since version-1.0
     */
    public class Demo02 {
        /**
         * 宽度
         */
        private static int width = 4;
        /**
         * 高度
         */
        private static int height = 6;
        /**
         * 地图
         */
        private static int[][] map = new int[height][width];
        /**
         * 标记图
         */
        private static int[][] mark = new int[height][width];
        /**
         * 列的高度,y坐标
         */
        private static int[] tail = new int[width];
        private static int[] dirX = {1,0,-1,0};
        private static int[] dirY = {0,1,0,-1};
        /**
         * 当前块
         */
        private static Block block;
        /**
         * 地图初始化
         */
        private static void inti(int w){
            width = w;
            map = new int[height][width];
        }
        /**
         * 旋转一个角度
         * @param angle
         */
        private static void rotate(int angle){
            block.dir=(block.dir+angle)%4;
            //右边界
            if (block.dir==0&&block.col==width-1){
                block.col=width-2;
            }
            if (block.dir==2&&block.col==0){
                block.col=1;
            }
        }
        /**
         * 移动一段距离
         * @param distance
         */
        private static void move(int distance){
            block.col+=distance;
            //中间区域不用考虑
            if (block.col>=1 && block.col<=width-2){
                return;
            }
            //右方向看右边界
            if (block.dir==0 && block.col>=width-1){
                block.col=width-2;
                return;
            }
            //左方向看左边界
            if (block.dir==2 && block.col<=0){
                block.col=1;
                return;
            }
            //其他方向右越界(dis过大)
            if (block.col > width-1){
                block.col = width-1;
            }
            //其他方向左越界(dis过大)
            if (block.col < 0){
                block.col = 0;
            }
        }
        private static void hinder(int count,int life){
           // block.event = 2;
            int h = height-1;
            for (int i = 0; i < count; i++) {
                map[h-tail[i]][i] = -1*life;
                tail[i]++;
            }
        }
        /**
         * 更新当前块下落后的地图,记录列高度
         * @return
         */
        private static int land(){
            //1.将一个圆叠在另一个圆上,不留空隙。
            Point p1 = new Point();
            Point p2 = new Point();
            int h = height-1;
            if (block.event==0){
                switch (block.dir){
                    case 0:
                    {
                        p1.x = block.col;
                        p1.y = h-tail[block.col];
                        map[p1.y][p1.x] = block.val[0];
                        p2.x = block.col+1;
                        p2.y = h-tail[block.col];
                        map[p2.y][p2.x] = block.val[1];
                        tail[block.col]++;
                        tail[block.col+1]++;
                        break;
                    }
                    case 1:
                    {
                        p1.x = block.col;
                        p1.y = h-(tail[block.col]+1);
                        map[p1.y][p1.x] = block.val[0];
                        p2.x = block.col;
                        p2.y = h-tail[block.col];
                        map[p2.y][p2.x] = block.val[1];
                        tail[block.col]+=2;
                        break;
                    }
                    case 2:
                    {
                        p1.x = block.col;
                        p1.y = h-tail[block.col];
                        map[p1.y][p1.x] = block.val[0];
                        p2.x = block.col-1;
                        p2.y = h-tail[block.col-1];
                        map[p2.y][p2.x] = block.val[1];
                        tail[block.col]++;
                        tail[block.col-1]++;
                        break;
                    }
                    case 3:
                    {
                        p1.x = block.col;
                        p1.y = h-tail[block.col];
                        map[p1.y][p1.x] = block.val[0];
                        p2.x = block.col;
                        p2.y = h-(tail[block.col]+1);
                        map[p2.y][p2.x] = block.val[1];
                        tail[block.col]+=2;
                        break;
                    }
                    default:
                        break;
                }
                solution(p1,p2);
            }
            int j=0;
            for (int i = 0; i < width; i++) {
                j= Math.max(tail[i], j);
            }
            return j;
        }
        private static Point[] drop = new Point[width*height];
    
        /**
         * 块下落后的消除
         * @param p1
         * @param p2
         */
        private static void solution(Point p1,Point p2){
            int dropNum = 2;
            drop[0] = p1;
            drop[1] = p2;
    
            while (dropNum!=0){
                for (int i = 0; i < dropNum; i++) {
                    //一组两个颜色相同
                    if (mark[drop[i].y][drop[i].x] == 1){
                        continue;
                    }
                    dfs(drop[i].x,drop[i].y);
                    clear();
                }
                markHinder();
                dropNum = updateMap();
            }
        }
        private static Stack<Point> elimP = new Stack<>();
        private static int[][] mark2 = new int[height][width];
    
        /**
         * 搜索4个同色相连块,放入搜索队列
         * @param x
         * @param y
         */
        private static void dfs(int x,int y){
            mark2[y][x] = 1;
            elimP.push(new Point(x,y));
            for (int i = 0; i < 4; i++) {
                int a = x+dirX[i];
                int b = y+dirY[i];
                if (a>=0&&a<width&&b>=0&&b<height&&map[b][a]==map[y][x]&&mark2[b][a]==0){
                    dfs(a,b);
                }
            }
        }
    
        /**
         * 根据搜索结果清理同色块
         */
        private static void clear(){
            int s = elimP.size();
            if (s>=4){
                for (int i = 0; i < s; i++) {
                    Point p = elimP.pop();
                    map[p.y][p.x]=0;
                    mark[p.y][p.x]=1;
                    tail[p.x]--;
                }
            }
            elimP.removeAllElements();
    
        }
        /**
         * 消除同色块后,更新阻碍块寿命和位置,顺便消除标记
         */
        private static void markHinder(){
            int h = height-1;
            for (int i = 0; i < width; i++) {
                for (int j = 0; j <= tail[i]; j++) {
                    if (map[h-j][i]<0){
                        if (check(h-j,i)==1){
                            map[h-j][i] += 1;
                            if (map[h-j][i]==0){
                                tail[i]--;
                            }
                        }
                    }
                }
            }
            mark2 = new int[height][width];
            mark = new int[height][width];
        }
    
        /**
         * 同色块消除后,把空中的块放下来,顺便放入搜索队列
         * @return 空中块的数量
         */
        private static int updateMap(){
            int c = 0;
            int s = 0;
            int sum = 0;
            int h = height-1;
            for (int i = 0; i < width; i++) {
                for (int j = 0; j < tail[i]; j++) {
                    int l = h-j;
                    if (map[l][i]==0){
                        if (j>=tail[i]){
                            break;
                        }
                        //j=1,c=3
                        while (map[l-c][i]==0&&j+c<tail[i]){
                            c++;
                        }
                        if (j+c+1==tail[i]){
                            tail[i]=j;
                            break;
                        }
                        if (map[l-c][i]>0) {
                            map[l][i] = map[l - c][i];
                            map[l - c][i] = 0;
                            drop[s].x = i;
                            drop[s++].y = l;
                            sum++;
                        }
                        if (map[l-c][i]<0) {
                            map[l][i] = map[l - c][i];
                            map[l - c][i] = 0;
                        }
                    }
                }
            }
            return sum;
    
        }
    
        /**
         * 查看阻碍块四周是否有爆裂的同色块
         * @param y
         * @param x
         * @return
         */
        private static int check(int y,int x){
            for (int i = 0; i < 4; i++) {
                int a = y+dirY[i];
                int b = x+dirX[i];
                if (a>=0&&b>=0&&a<height&&b<width&&mark[a][b]==1){
                    return 1;
                }
            }
            return 0;
        }
    
        public static void main(String[] args) {
            int sum = 0;
            block = new Block(new int[]{1,1});
            rotate(0);
            move(1);
            sum = land();
            hinder(2,2);
            hinder(4,1);
            block = new Block(new int[]{2,2});
            rotate(0);
            move(2);
            sum = land();
            block = new Block(new int[]{1,1});
            rotate(1);
            move(2);
            sum = land();
            block = new Block(new int[]{2,2});
            rotate(1);
            move(3);
            sum = land();
    
            for (int i = 0; i < height; i++) {
                for (int j = 0; j < width; j++) {
                    if (map[i][j]<0){
                        System.out.print(map[i][j]);
                    }else {
                        System.out.print(" "+map[i][j]);
                    }
                    if (j==width-1){
                        System.out.println();
                    }
                }
            }
            System.out.println("最高列长度是:"+sum);
        }
    }
    
    

    负数代表阻碍块生命值,正数代表颜色,0为空

    打印一下过程:

     0 0 0 0
     0 0 0 0
     0 0 0 0
     0 0 0 0
     0 0 0 0
     0 1 1 0
    最高列长度是:1
    
     0 0 0 0
     0 0 0 0
     0 0 0 0
     0-1 2 0
    -1-2-1 2
    -2 1 1-1
    最高列长度是:3
    
     0 0 0 0
     0 0 1 0
     0 0 1 0
     0-1 2 0
    -1-2-1 2
    -2 1 1-1
    最高列长度是:5
    
     0 0 0 0
     0 0 0 0
     0 0 0 0
     0 0 0 0
    -1 0 0 0
    -1-1 0 0
    最高列长度是:2
    
  • 相关阅读:
    logging日志模块
    mysql数据库--explain(查询表是否走索引)各个字段含义
    函数的命名空间、作用域、闭包函数
    模块
    Hibernate Stack Overflow
    PostgreSQL ----- No relations found.
    spring杂记
    JUnit test case 执行顺序
    转换成maven时报错
    参考网页
  • 原文地址:https://www.cnblogs.com/jinjun99/p/15597658.html
Copyright © 2020-2023  润新知