翁恺老师的Java课程,讨论,任意门

城堡游戏的任意门。实现过程很简单,但是我想了一天,操作步骤就是扩展一个Handler类,在Game类里面加一个函数,在Handler里面调用。其实怎么加上去的不重要,重要的是,读懂函数与函数之间的关系,这个代码关系非常复杂,要看关系图才能看懂。这个关系图只能在纸上写,如果不想画关系图,另一个看懂代码的办法就是把每一行都写上注释。

三个主类:

game类:

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Scanner;

public class Game {
	
	//定义变量
    private Room currentRoom;//当前房间,默认为null
    private HashMap<String, Handler> handlers=new HashMap<String, Handler>();//用来储存命令的哈希表   
    ArrayList<Room> rooms = new ArrayList<Room>();//用ArrarList储存创建的进去的房间
    
    //构造函数
    public Game() 
    {
    	//向命令行里添加元素,key是命令,value是继承Handler的子类
    	handlers.put("go",new HandlerGo(this));
    	handlers.put("bye", new HandlerBye(this));
    	handlers.put("help", new HandlerHelp(this));
    	handlers.put("random", new HandlerRandom(this));//这里的this可以看做是Game的一个对象
        createRooms();//创建对象的时候构造房间
    }

    //制造房间函数
	private void createRooms()
    {
    	//写这个方便复制粘贴
    	String[] dir= {"north","east","south","west"};
            
        //	制造房间
    	Room outside, lobby, pub, study, bedroom;
        outside = new Room("城堡外");
        lobby = new Room("大堂");
        pub = new Room("小酒吧");
        study = new Room("书房");
        bedroom = new Room("卧室");
    
        //	初始化房间的出口
        outside.setExit(dir[1], lobby);
        outside.setExit(dir[2], study);
        outside.setExit(dir[3], pub);
        pub.setExit(dir[1], outside);
        lobby.setExit(dir[3], outside);
        study.setExit(dir[0], outside);
        study.setExit(dir[1], bedroom);
        bedroom.setExit(dir[3], study);
        
        //把创建的房间加入容器rooms
        rooms.add(lobby);
        rooms.add(study);
        rooms.add(pub);
        rooms.add(outside);
        rooms.add(bedroom);   
        
        //当前位置
        currentRoom=outside;
    }
	
	//任意门1,一个房间的四个门,每次进入到随机的门
	public void goRandom()
	{
		String[] dir= {"north","east","south","west"};//定义四个方向
		int a=(int)(Math.random()*4);//产生随机数0~3		
		Room nextRoom=currentRoom.getExit(dir[a]);//随机传入一个方向
		if (nextRoom == null) {
            System.out.println("那里没有门!");
        }
        else {
            currentRoom = nextRoom;
            showPrompt();
        }		
	}
	
	//任意门2,从outside出发,每次进入到一个随机房间
//	public void goRandom()
//	{
//		int a=(int) (Math.random()*5);//产生随机数0~4
//		currentRoom = rooms.get(a);//进入任意一个房间
//        showPrompt();
//	}

    private void printWelcome() {
        System.out.println();
        System.out.println("欢迎来到城堡!");
        System.out.println("这是一个超级无聊的游戏。");
        System.out.println("如果需要帮助,请输入 'help' 。");
        System.out.println();
        showPrompt();
    }

    // 进入房间
    protected void goRoom(String direction) 
    {
        Room nextRoom=currentRoom.getExit(direction);//获取输入的方向
        if (nextRoom == null) {
            System.out.println("那里没有门!");
        }
        else {
            currentRoom = nextRoom;
            showPrompt();
        }
    }
	
    //提示信息
    public void showPrompt()
    {
    	System.out.println("你在" + currentRoom);
        System.out.print("出口有: ");
        System.out.print(currentRoom.getExitDesc());
        System.out.println();
    }
    
    //运行主程序,最主要的程序,读懂这段代码对理解整个程序事半功倍
    public void play() {
    	Scanner in = new Scanner(System.in);
    	
    	while ( true ) {
    		String line = in.nextLine();
    		String[] words = line.split(" ");//以空格为间隔,返回字符数组
    		Handler handler=handlers.get(words[0]);//根据当前输入判断让handler管理哪个Handler对象
    		String value="";
    		if(words.length>1)//如果不只是一个单词,value等于输入的方向
    		{
    			value=words[1];
    		}
//    		else//增加的判断,为了适应任意门
//    		{
//    			value=words[0];
//    		}
    		if(handler!=null)
    		{
    			handler.doCmd(value);//根据管理的类,调用相应的函数
    			if(handler.isBye())//管理了HandlerBye的对象,调用isBye()函数
    			{
    				break;//跳出循环
    			}
    		}
    	}
    	in.close();
    }
	public static void main(String[] args) {
		
		Game game = new Game();
		game.printWelcome();
		game.play();//这里是程序运行的核心,出问题要在这里找       
        System.out.println("感谢您的光临。再见!");
        
	}

}

Room类

import java.util.HashMap;

public class Room {
    private String description;
    private HashMap<String, Room> exits=new HashMap<String, Room>();
    
    //构造函数,初始化房间位置描述
    public Room(String description) 
    {
        this.description = description;
    }

    //设置方向函数
    public void setExit(String dir,Room room) {
    	exits.put(dir, room);//利用函数向容器里面添加key(方向)和value(房间)
    }
    
    //获取当前房间的出口方向
    public String getExitDesc()
    {
    	StringBuffer sb=new StringBuffer();
    	for(String dir:exits.keySet())
    	{
    		sb.append(dir);//append方法,将后面的字符加入到该对象里面
    		sb.append(" ");
    	}
    	 
    	return sb.toString();
    }

    //传入一个方向,获取对应的房间
    public Room getExit(String direction)
    {
    	Room ret=null;
        ret=exits.get(direction);
        return ret;
    }
    
    //来自Object类的函数,输出对象的时候,输出该对象的返回值
    @Override
    public String toString()
    {
        return description;
    }
    
}

Handle类

//命令类
public class Handler {
	public Game game;
	public Handler(Game game)
	{
		this.game=game;//初始化的时候构造一个Game对象,传给子类,用于调用Game的函数
	}
	public void doCmd(String word)//让子类重写该方法
	{
		
	}
	public boolean isBye() {//HandlerBye的判断条件
		return false;
	}
}

四个子类:

//离开命令
public class HandlerBye extends Handler {
	
	public HandlerBye(Game game) {
		super(game);
		// TODO Auto-generated constructor stub
	}
	public boolean isBye()
	{
		return true;
	}
}

//进入房间命令
public class HandlerGo extends Handler {
	public HandlerGo(Game game) {
		super(game);
	}
	public void doCmd(String word) {
		game.goRoom(word);
	}

}
//帮助命令
public class HandlerHelp extends Handler {

	public HandlerHelp(Game game) {
		super(game);
		// TODO Auto-generated constructor stub
	}
	public void doCmd(String word)
	{
		System.out.println("迷路了吗?你可以做的命令有:go bye help random");
        System.out.println("如:\tgo east");
	}

}
//进入随机的房间,任意门命令
public class HandlerRandom extends Handler {

	public HandlerRandom(Game game) {
		super(game);
		// TODO Auto-generated constructor stub
	}

	@Override
	public void doCmd(String word) {
		// TODO Auto-generated method stub
		game.goRandom();
	}
}

代码看不懂,一定要多看几遍课程,第一次听得时候晕晕乎乎的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值