为什么有这篇文章
面向对象设计思想是现代程序设计的重要基础,目前我在MOOC上学习翁凯老师的java进阶,主要就是进行面向对象的入门学习。
在课程中,第五节讲述了了面向对象简单实际应用,主要例子是城堡游戏,将其降提供的原始低耦合,使用类的继承提高程序的拓展性。
编程的学习中,实际的练习十分重要,以前总是看视频进行学习,觉得十分简单,但实际操作时依然困难重重。
所以我就这个 城堡游戏 的课后讨论中提出的 随机进入房间 进行了实现,并将结果做一个备份。
MOOC地址
面向对象程序设计——Java语言
实践来源是其课后讨论中的
如何实现任意门?
如果想要实现任意门,即在某个房间,想要从某个出口出去,结果每次会走到不同的房间去。
如果要实现这样的任意门,整个程序的架构应该是怎样的?
如果任意门只是在这个房间的所有的门之间轮转,应该怎样实现?
如果任意门能在整个城堡的所有的门之间轮转,应该怎样实现?
来自课件“如何实现任意门?”
代码部分
话不多说直接放代码,代码均添加了详细的以下文件均在一个名为castle的package中。
- 首先是Game.java
package castle;
/*
* 20181014 by Dreamer
*/
import java.util.HashMap;
import java.util.Scanner;
public class Game {
private Room currentRoom;// 当前房间
// 操作String与对应handler的HashMap
// Room名字String与对应Room的HashMap
private HashMap<String, Handler> handlers = new HashMap<String, Handler>();
private HashMap<String, Room> rooms = new HashMap<String, Room>();
// 初始化
public Game() {
createRooms();
currentRoom = rooms.get("outside"); // 从城堡门外开始
handlers.put("go", new HandlerGo(this));
handlers.put("bye", new HandlerBye(this));
handlers.put("help", new HandlerHelp(this));
handlers.put("random", new HandlerGoRandom(this));
handlers.put("randomRoom", new HandlerRandomRoom(this));
}
// 制造及设置Room的HashMap
private void createRooms() {
// 制造Room
rooms.put("outside", new Room("城堡外"));
rooms.put("lobby", new Room("大堂"));
rooms.put("pub", new Room("小酒吧"));
rooms.put("study", new Room("书房"));
rooms.put("bedroom", new Room("卧室"));
rooms.put("heiwu", new Room("小黑屋"));
// 初始化Room的出口
addRoom("outside", "south", "lobby");
addRoom("outside", "east", "study");
addRoom("outside", "west", "pub");
addRoom("lobby", "north", "outside");
addRoom("pub", "east", "outside");
addRoom("study", "west", "outside");
addRoom("study", "south", "bedroom");
addRoom("bedroom", "north", "study");
addRoom("bedroom", "up", "heiwu");
addRoom("heiwu", "down", "bedroom");
}
// 设置Room出口的方法
private void addRoom(String room, String direction, String nextRoom) {
rooms.get(room).setExit(direction, rooms.get(nextRoom));
}
// 欢迎
private void printWelcome() {
System.out.println();
System.out.println("欢迎来到城堡!");
System.out.println("这是一个超级无聊的游戏。");
System.out.println("如果需要帮助,请输入 'help' 。");
System.out.println();
System.out.println("现在你在" + currentRoom);
System.out.print("出口有:");
System.out.println(currentRoom.getExitDesc());
}
// 返回Room的数量
public int getSize() {
int size = 0;
size = rooms.size();
return size;
}
// 接受Room的名字String
// 返回对应的Room
public Room getRoom(String roomKey) {
return rooms.get(roomKey);
}
// 返回当前所在的Room
public Room getRoomNow() {
return currentRoom;
}
// 返回所有Room名字的String[]
public String[] getMapKey() {
String[] mapKeyList = rooms.keySet().toArray(new String[getSize()]);
return mapKeyList;
}
// 接受方向String
// 返回对应的Room
public void goRoom(String direction) {
Room nextRoom = null;
nextRoom = currentRoom.goRoom(direction);
if (nextRoom == null) {
System.out.println("那里没有门!");
} else {
currentRoom = nextRoom;
System.out.println("你在" + currentRoom);
System.out.print("出口有:");
System.out.println(currentRoom.getExitDesc());
}
}
// 接受一个Room
// 将此Room设为当前Room
public void resetRoom(Room room) {
currentRoom = room;
System.out.println("你在" + currentRoom);
System.out.print("出口有:");
System.out.println(currentRoom.getExitDesc());
}
// 运行游戏
public void play() {
Scanner in = new Scanner(System.in);
while (true) {
String line = in.nextLine();// 读取输入
String[] words = line.split(" ");// 以“ ”为分隔转为String[]
Handler handler = handlers.get(words[0]);// 第0个string是操作
String value = words[0];// 默认value设为第0个string
// 如果有不止一个输入,则将value设为第1个string作为参数
if (words.length > 1) {
value = words[1];
}
// 如果有这个操作的话就把参数传入做handler.doCmd(value)
if (handler != null) {
handler.doCmd(value);
if (handler.isBye()) {
break;
}
}
}
in.close();
}
public static void main(String[] args) {
Game game = new Game();
game.printWelcome();
game.play();
System.out.println("感谢您的光临。再见!");
}
}
- Room.java
package castle;
/*
* 20181014 by Dreamer
*/
import java.util.HashMap;
public class Room {
private String description;// 房间描述
// 出口String及对应Room的HashMap
private HashMap<String, Room> room = new HashMap<String, Room>();
// 初始化,给房间描述
public Room(String getdescription) {
description = getdescription;
}
// 设置Room的出口String及对应的Room
public void setExit(String direction, Room nextroom) {
room.put(direction, nextroom);
}
// 返回将出口String加空格
public String getExitDesc() {
StringBuffer sb = new StringBuffer();
for (String a : room.keySet()) {
sb.append(a + " ");
}
return sb.toString();
}
// 返回出口string的HashMap大小
public int getSize() {
int size = 0;
size = room.size();
return size;
}
// 返回出口String的list
public String[] getMapKey() {
String[] mapKeyList = room.keySet().toArray(new String[getSize()]);
return mapKeyList;
}
// 返回对应String的Room
public Room goRoom(String direction) {
return room.get(direction);
}
// 重构toString()
@Override
public String toString() {
return description;
}
}
- HandlerBye.java
package castle;
/*
* 20181014 by Dreamer
* 1退出
*/
public class HandlerBye extends Handler {
public HandlerBye(Game game) {
super(game);
}
// 返回isBye的true
public boolean isBye() {
return true;
}
}
- HandlerGo.java
package castle;
/*
* 20181014 by Dreamer
* 1去一个指定的room
*/
public class HandlerGo extends Handler {
public HandlerGo(Game game) {
super(game);
}
// 接收string去所指的room
public void doCmd(String word) {
game.goRoom(word);
}
}
- HandlerGoRandom.java
package castle;
/*
* 20181014 by Dreamer
* 1随机到一个紧邻当前room的room
*/
public class HandlerGoRandom extends Handler {
public HandlerGoRandom(Game game) {
super(game);
}
public void doCmd(String word) {
Room room = game.getRoom(word);
if (room == null) {
room = game.getRoomNow();
}
int num = room.getSize();
int rand = (int) (Math.random() * num);
String[] keyMap = room.getMapKey();
word = keyMap[rand];
game.goRoom(word);
}
}
- HandlerHelp.java
package castle;
/*
* 20181014 by Dreamer
* 1退出
*/
public class HandlerHelp extends Handler {
public HandlerHelp(Game game) {
super(game);
}
public void doCmd(String word) {
System.out.println("迷路了吗?你可以做的命令有:go bye help");
System.out.println("如:\tgo east");
}
}
- HandlerRandomRoom.java
package castle;
/*
* 20181014 by Dreamer
* 1退出
*/
public class HandlerRandomRoom extends Handler {
public HandlerRandomRoom(Game game) {
super(game);
}
public void doCmd(String word) {
String room = game.getRoomNow().toString();// 得到当前Room的描述赋给room
do {
int num = game.getSize();// 得到game的Room数量
int rand = (int) (Math.random() * num);// 在数量内随机一个数
String[] keyMap = game.getMapKey();// 得到game里所有房间的String[]
word = keyMap[rand];// 用随机数rand取一个room
game.resetRoom(game.getRoom(word));
;// 把取来的room设为当前room
} while (room.equals(game.getRoom(word).toString()));// 如果随机完了的room和随机前一样,就重来
}
}