美文网首页
(命令行)推箱子

(命令行)推箱子

作者: A黄橙橙 | 来源:发表于2018-08-23 11:45 被阅读0次

    之前一直心心念想做小游戏,这次终于花了一个下午写了一个推箱子,本来想做有GUI的,但是找了半个小时图之后就放弃了。
    其实推箱子思路很简单,逻辑也很清晰,主要是想看一下自己能不能用类的思想来实现,我也不知道自己这样写有哪些问题,还希望路过的大神指点一下。
    文末贴一个我遇到的问题及参考的博客

    package SokoMan;
    
    import java.util.Scanner;
    
    public class Main {
        /*
         * 使用手册:命令行推箱子小游戏
         * 
         * 符号含义:
         * .:空地
         * M:墙
         * O:箱子
         * Y:人(当前处于空地)
         * T:(Target)目的地
         * f:(find)箱子到达目的地
         * $:人站在目的地上面
         * 
         * 移动:
         * w-上
         * s-下
         * a-左
         * d-右
         * 
         * 操作说明:
         * 每次运行游戏就会弹出地图,每次移动会更新地图(输入上下左右后回车,每次只能有一个命令),当所有目标归位时显示“You Win”,同时游戏结束,程序退出
         * 
         * 测试说明:
         * 所有测试用数据都在最前面。
         * x,y代表初始时人的位置
         * tot代表目的地的总数
         * ROW和COL代表地图的行和列
         * 更改地图时注意同时更改以上数据即可。
         * 
         * 后编:
         * 以下代码中
         * x,y都代表当前的人物的位置
         * x_,y_都代表当前的人物在当前方向的下一个位置
         * newX,newY都代表当前的人物在当前方向的下下一个位置
         * 
         */
        
        /*
         * 0为空地
         * 1为墙
         * 2为箱子
         * 3为没有箱子的目的地
         * 4为有箱子的目的地
         * 5为人在空地
         * 6为人在目标
         */
        //如果判定出来是有目标的箱子,优先进入目标
        int x, y;
        int x_, y_;
        int newX, newY;
        static int num = 0;
        final static int tot = 3;
        static int ROW = 6;
        static int COL = 10;
        int[][] maze = {
                {1,1,1,1,1,1,1,1,1,1},
                {1,0,0,0,0,0,0,0,0,1},
                {1,5,2,3,0,2,3,0,0,1},
                {1,0,0,0,2,3,0,0,0,1},
                {1,0,0,0,0,0,0,0,0,1},
                {1,1,1,1,1,1,1,1,1,1},
        };
        Print print = new Print();
        Change change = new Change();
        
        //人的下一个位置是箱子,仅处理 箱子-(?) 的情况
        class Box{
            Wall wall = new Wall();
            public void Check(String dir){
                newX=change.changeX(dir,x_);
                newY=change.changeY(dir,y_);
                if(maze[newX][newY] == 1){ //箱子-墙
                    print.print(dir,false);
                }else if(maze[newX][newY] == 2){ //箱子-箱子
                    print.print(dir,false);
                }else if(maze[newX][newY] == 0){ //箱子-空地
                    print.print(dir,true);
                }else if(maze[newX][newY] == 3){ //箱子-没有箱子的目的地
                    //num++;
                    print.print(dir,true);
                }else if(maze[newX][newY] == 4){ //箱子-有箱子的目的地
                    print.print(dir,false);
                }
            }
        }
    
        //人的下一个位置是墙,仅处理 墙-(?) 的情况
        class Wall{
            
            public void Check(String dir){
                print.print(dir, false);
            }
        }
        
        //人的下一个位置是目标,仅处理 目标-(?) 的情况
        class Target{
            public void Check(String dir){
                if(maze[x_][y_] == 4){ //人-有箱子的目的地
                    newX = change.changeX(dir,x_);
                    newY = change.changeY(dir,y_);
                    if(maze[newX][newY] == 0){ //人-有箱子的目的地-空地
                        print.print(dir,true);
                    }else if(maze[newX][newY] == 1){ //人-有箱子的目的地-墙
                        print.print(dir, false);
                    }else if(maze[newX][newY] == 2){ //人-有箱子的目的地-箱子
                        print.print(dir, false);
                    }else if(maze[newX][newY] == 3){ //人-有箱子的目的地-没有箱子的目的地
                        print.print(dir, true);
                    }else if(maze[newX][newY] == 4){ //人-有箱子的目的地-有箱子的目的地
                        print.print(dir, false);
                    }
                }else if(maze[x_][y_] == 3){
                    print.print(dir, true);
                }
            }
        }
        
        //初始图片并且每次找到人在对应方向的下一个物品,调用该类处理
        //每次行走结束判断是否胜利
        class Person{
            Box box = new Box();
            Wall wall = new Wall();
            Target target = new Target();
            Person(){
                x = 2; y = 1;
                print.print("a", false);
            }
            public void run(){
                Scanner scan = new Scanner(System.in);
                while(scan.hasNext()){
                    String dir = scan.next();
                    System.out.println(dir);
                    if(dir.equals("a")==false && dir.equals("s")==false 
                            && dir.equals("d")==false && dir.equals("w")==false) continue;
                    x_=change.changeX(dir,x);
                    y_=change.changeY(dir,y);
                    if(maze[x_][y_] == 0){
                        print.print(dir, true);
                    }else if(maze[x_][y_] == 1){
                        print.print(dir, false);
                    }else if(maze[x_][y_] == 2){
                        box.Check(dir);
                    }else if(maze[x_][y_] == 3 || maze[x_][y_] == 4){
                        target.Check(dir);
                    }
                    if(num == tot){
                        System.out.println("You Win!");
                        break;
                    }
                }
            }
        }
        
        //更新图片并同时更新箱子到达目标的箱子数num
        class Print{
            public void print(String dir,boolean flag){
                //说明这是移动后的坐标
                if(flag == true){
                    if(maze[x][y] == 5 || maze[x][y] == 6){
                        if(maze[x][y] ==5) maze[x][y] = 0;
                        else maze[x][y] = 3;
                        if(maze[x_][y_] == 0){ //人-空地
                            x = x_; y = y_;
                            maze[x_][y_] = 5; 
                        }else if(maze[x_][y_] == 2){
                            if(maze[newX][newY] == 0){ //人-箱子-空地 
                                x = x_; y = y_;
                                maze[x_][y_] = 5;
                                maze[newX][newY] = 2;  
                            }else if(maze[newX][newY] == 3){ //人-箱子-没箱子的目的地
                                num++;
                                x = x_; y = y_;
                                maze[x_][y_] =5;
                                maze[newX][newY] = 4;
                            }
                        }else if(maze[x_][y_] == 3){ //人-没有箱子的目的地
                            x = x_; y = y_;
                            maze[x_][y_] = 6;
                        }else if(maze[x_][y_] == 4){ //人-有箱子的目的地
                            if(maze[newX][newY] == 0){ //人-有箱子的目的地-空地
                                num--;
                                x = x_; y = y_;
                                maze[x_][y_] = 6;
                                maze[newX][newY] = 2;
                            }else if(maze[newX][newY] == 3){ //人-有箱子的目的地-没有箱子的目的地
                                x = x_; y = y_;
                                maze[x_][y_] = 6;
                                maze[newX][newY] = 4;
                            }
                        }
                    }
                }
                
                for(int i=0;i<ROW;i++){
                    for(int j=0;j<COL;j++){
                        if(maze[i][j] == 0){
                            System.out.print(".");
                        }else if(maze[i][j] == 1){
                            System.out.print("M");
                        }else if(maze[i][j] == 2){
                            System.out.print("O");
                        }else if(maze[i][j] == 3){
                            System.out.print("T");
                        }else if(maze[i][j] == 4){
                            System.out.print("f");
                        }else if(maze[i][j] == 5){
                            System.out.print("Y");
                        }else if(maze[i][j] == 6){
                            System.out.print("$");
                        }
                    }
                    System.out.println();
                }
            }
        }
        
        //找到当前x,y的下一个位置
        class Change{
            public int changeX(String dir,int _x){
                if(dir.equals("w")){
                    _x--;
                }else if(dir.equals("s")){
                    _x++;
                }
                return _x;
            }
            public int changeY(String dir,int _y){
                if(dir.equals("a")){
                    _y--;
                }else if(dir.equals("d")){
                    _y++;
                }
                return _y;
            }
        }
        
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            /*
             * 注释掉的语句会报错,因为内部类是依赖于外部类的 如果要创建成员内部类的对象,前提是必须存在一个外部类对象
             */
            //Person person = new Person();
            Person person = new Main().new Person();
            person.run();
        }
    }
    
    

    Java内部类
    Java内部类一般包括四种:成员内部类,局部内部类,匿名内部类和静态内部类。
    上面代码就有成员内部类。1.成员内部类可以无条件访问外部类中的所有成员属性和成员方法(包括private成员和静态成员),但是当内部类和外部类有相同的成员变量或方法时,会发生隐藏现象,默认访问的是内部类成员(外部类.this.成员变量)。2.外部类访问成员内部类必须创建一个成员内部类的对象,再通过只想这个对象的引用来访问

    //方法一
    Main main_=new Main();
    Main.Person person2 = main_.new Person();
    
    //方法二
    Main.Person person1 = new Main().new Person();
    

    其他的内部类种类还没遇到过,没有很好的理解,先贴出海 子的博客。

    相关文章

      网友评论

          本文标题:(命令行)推箱子

          本文链接:https://www.haomeiwen.com/subject/fzupiftx.html