/**
 * This is a demo of factory object design pattern. This pattern allows you
 * to abstract away the common logic for some framework.
 * In this case the framework is MazeGame2. The common logic is in the constructor
 * of MazeGame2. By using factory object pattern, we are able to create MazeGame2
 * with different rooms without reimplementing the connection logic.
 * The 'connection logic' is really simple here (just one connect) but one can
 * imagine a much more complex case with many more connections.
 * 
 * The concept of MazeGame is take from Wikipedia:
 * 		https://en.wikipedia.org/wiki/Factory_method_pattern
 * The code is original.
 * 
 * @author Jason Qiu
 */
public class MazeGame2 {
	
	private RoomFactory factory;
	
	/*
	 * Constructs a MazeGame where it utilizes a room factory
	 * to create rooms and build connections between them
	 * 
	 * @param factory a factory which creates rooms
	 * @effects Create a MazeGame where there are two rooms
	 * made by the room factory and connects them
	 */
    public MazeGame2(RoomFactory factory) {
    	this.factory = factory;
        Room room1 = factory.make();
        Room room2 = factory.make();
        room1.connect(room2);
    }

    /*
     * @effects Build two different MazeGames using different room factories
     */
	public static void main(String[] args) {
		MazeGame2 g = new MazeGame2(new OrdinaryRoomFactory());
		MazeGame2 g2 = new MazeGame2(new MagicRoomFactory());
	}

}

/*
 * For factory object
 */
interface RoomFactory {
	/*
	 * @return the room to make
	 */
	public Room make();
}

class OrdinaryRoomFactory implements RoomFactory {
	public Room make() {
		return new OrdinaryRoom();
	}
}

class MagicRoomFactory implements RoomFactory {
	public Room make() {
		return new MagicRoom();
	}
}