Java 进阶P-5.1+P-5.2
城堡游戏
一、城堡游戏介绍:
1.这个程序的任务是通过玩家的输入的方向(纯文字)在虚构的城堡内移动(以纯文字作为移动后的返回结果)。
2.这个程序接受help、bye、go south、go north、go west、go east六种命令,要求命令单独一行输入并在结束时敲回车,另外如果接受go xxx的不合规信息会输出不存在这样的房间。
3.help提供帮助信息,bye结束游戏,go后面空一格加south、north、west、east表示在虚构的城堡中移动。
4.有五个地点,分别是:小酒吧,大厅,书房,卧室,次卧。
5.地图:
二、类的设计
首先我们要有三个类,第一个是Game类,用来表示游戏本身和执行各种游戏命令,第二个是Room类,用来表示游戏中的所有房间。可见整个城堡游戏只由这两个类构成,具体怎么运行就要先构造这两个大类。
1.Game类
Game类是整个游戏运行的核心,具有构造房间,开始游戏,执行命令三个功能。
2.Room类
城堡游戏中是由很多个小房间构成的,分别是小酒吧,大堂,书房,卧室,次卧这五个地点。每个房间只有一种属性,即description(房间名)。
三、具体实现
1.类的创建
首先我们要创造一个Game类,用来作为游戏的主体。我们知道Game类有三个功能,构造房间,开始游戏,执行命令。那么在
实现:
package jinjie_01; import java.util.Scanner; public class Game { private Room currentRoom; public Game() { createRooms(); } private void createRooms(){ Room pub,lobby,study,bedroom,bedroom1; //创造房间 pub = new Room("小酒馆"); lobby = new Room("大厅"); study = new Room("书房"); bedroom = new Room("卧室"); bedroom1 = new Room("次卧"); //设置出口 pub.setExits(null,null,null,lobby); lobby.setExits(null,study,pub,bedroom1); study.setExits(lobby,null,null,bedroom); bedroom.setExits(null,null,study,null); bedroom1.setExits(null,null,lobby,null); currentRoom = pub; } public void printWelcome(){ System.out.println("***********************************"); System.out.println("欢迎来到城堡游戏!"); System.out.println("这是一个超级无聊的小游戏。"); System.out.println("如果需要帮助,请输入help。"); System.out.println("那么我们开始游戏吧!"); System.out.println("***********************************"); System.out.println("现在你在"+currentRoom); } private void printHelp() { System.out.println("迷路了吗?你可以做的命令有:go | bye | help"); System.out.println("如:\tgo east"); } private void goRoom(String direction) { Room nextRoom = null; if (direction.equals("north")) { nextRoom = currentRoom.northExit; } if (direction.equals("east")) { nextRoom = currentRoom.eastExit; } if (direction.equals("south")) { nextRoom = currentRoom.southExit; } if (direction.equals("west")) { nextRoom = currentRoom.westExit; } if(nextRoom == null){ System.out.println("那里没有门!"); } else{ currentRoom = nextRoom; System.out.println("你在"+ currentRoom); System.out.println("出口有:"); if(currentRoom.northExit != null) System.out.println("north"); if(currentRoom.eastExit != null) System.out.println("east"); if(currentRoom.southExit != null) System.out.println("south"); if(currentRoom.westExit != null) System.out.println("west"); } } public static void main(String[] args) { Scanner in = new Scanner(System.in); Game game = new Game(); game.printWelcome(); while (true) { String line = in.nextLine(); String[] words = line.split(" "); if (words[0].equals("help")) { game.printHelp(); } else if ( words[0].equals("go")) { game.goRoom(words[1]); } else if ( words[0].equals("bye")){ break; } } System.out.println("***********************************"); System.out.println("游戏到此结束!"); System.out.println("欢迎下次光临!"); System.out.println("谢谢!"); System.out.println("***********************************"); } }
消除代码复制
首先,会发现下面这段代码在Game类中出现了两次,无疑这会使代码看起来并不优雅,重要的是:在程序中存在相似甚至相同的代码块,是非常低级的代码质量问题。
System.out.println("现在你在" + currentRoom);
System.out.print("出口有:");
if(currentRoom.northExit != null)
System.out.print("north ");
if(currentRoom.eastExit != null)
System.out.print("east ");
if(currentRoom.southExit != null)
System.out.print("south ");
if(currentRoom.westExit != null)
System.out.print("west ");
代码复制存在的问题是,如果需要修改一个副本,那么就必须同时修改所有其他的副本,否则就 存在不一致的问题。这增加了维护程序员的工作量,而且存在造成错误的潜在危险。很可能发 生的一种情况是,维护程序员看到一个副本被修改好了,就以为所有要修改的地方都已经改好 了。因为没有任何明显迹象可以表明另外还有一份一样的副本代码存在,所以很可能会遗漏还 没被修改的地方。
我们从消除代码复制开始。消除代码复制的两个基本手段,就是函数和父类。
这里用函数来解决城堡游戏中重复代码的问题:
public void showPrompt() {
System.out.println("现在你在" + currentRoom);
System.out.print("出口有:");
if(currentRoom.northExit != null)
System.out.print("north ");
if(currentRoom.eastExit != null)
System.out.print("east ");
if(currentRoom.southExit != null)
System.out.print("south ");
if(currentRoom.westExit != null)
System.out.print("west ");
}
删除重复的代码,在重复的地方调用showPrompt() 函数即可。