(命令行)推箱子

之前一直心心念想做小游戏,这次终于花了一个下午写了一个推箱子,本来想做有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();

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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,386评论 6 479
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,939评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,851评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,953评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,971评论 5 369
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,784评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,126评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,765评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,148评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,744评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,858评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,479评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,080评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,053评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,278评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,245评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,590评论 2 343

推荐阅读更多精彩内容