城堡游戏

一、城堡游戏介绍:
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() 函数即可。

Java 进阶P-5.1+P-5.2的更多相关文章

  1. Java 进阶 hello world! - 中级程序员之路

    Java 进阶 hello world! - 中级程序员之路 Java是一种跨平台的语言,号称:"一次编写,到处运行",在世界编程语言排行榜中稳居第二名(TIOBE index). ...

  2. Java进阶(五)Java I/O模型从BIO到NIO和Reactor模式

    原创文章,同步发自作者个人博客,http://www.jasongj.com/java/nio_reactor/ Java I/O模型 同步 vs. 异步 同步I/O 每个请求必须逐个地被处理,一个请 ...

  3. Java线程间通信方式剖析——Java进阶(四)

    原创文章,同步发自作者个人博客,转载请在文章开头处以超链接注明出处 http://www.jasongj.com/java/thread_communication/ CountDownLatch C ...

  4. Java进阶(三)多线程开发关键技术

    原创文章,同步发自作者个人博客,转载请务必以超链接形式在文章开头处注明出处http://www.jasongj.com/java/multi_thread/. sleep和wait到底什么区别 其实这 ...

  5. 当我们说线程安全时,到底在说什么——Java进阶系列(二)

    原创文章,同步发自作者个人博客,转载请以超链接形式在文章开头处注明出处http://www.jasongj.com/java/thread_safe/ 多线程编程中的三个核心概念 原子性 这一点,跟数 ...

  6. Java进阶03 IO基础

    链接地址:http://www.cnblogs.com/vamei/archive/2013/04/11/3000905.html 作者:Vamei 出处:http://www.cnblogs.com ...

  7. Java进阶01 String类

    链接地址:http://www.cnblogs.com/vamei/archive/2013/04/08/3000914.html 作者:Vamei 出处:http://www.cnblogs.com ...

  8. 从ConcurrentHashMap的演进看Java多线程核心技术 Java进阶(六)

    本文分析了HashMap的实现原理,以及resize可能引起死循环和Fast-fail等线程不安全行为.同时结合源码从数据结构,寻址方式,同步方式,计算size等角度分析了JDK 1.7和JDK 1. ...

  9. Java进阶(七)正确理解Thread Local的原理与适用场景

    原创文章,始自发作者个人博客,转载请务必将下面这段话置于文章开头处(保留超链接). 本文转发自技术世界,原文链接 http://www.jasongj.com/java/threadlocal/ Th ...

  10. Java进阶(四十七)Socket通信

    Java进阶(四十七)Socket通信   今天讲解一个 Hello Word 级别的 Java Socket 通信的例子.具体通讯过程如下: 先启动Server端,进入一个死循环以便一直监听某端口是 ...

随机推荐

  1. MAUI 初体验 联合 WinForm 让家里废弃的手机当做电脑副品用起来

    软件效果图 软件架构草图 效果解释:运行 winform 端后 使用 ctrl+c 先复制任何词语,然后ctrl+空格 就可以将翻译结果显示在 安卓,IOS,windows 甚至 mac 任意客户端 ...

  2. python中的字符串学习

    # 1.字符串的下标(索引) # 取字符串中的子串 print('1.字符串的下标(索引)') str1 = 'PYTHON' print(str1[0]) print(str1[-4]) # 2.字 ...

  3. 部署grafana+telegraf+influxdb 及 配置 jmeter后端监听

    搞性能测试,可以搭建Grafana+Telegraf+InfluxDB 监控平台,监控服务器资源使用率.jmeter性能测试结果等. telegraf: 是一个用 Go 编写的代理程序,可收集系统和服 ...

  4. 12、求Sn = a + aa + aaa + aaaa + ....其中a为一个数字,一共有n项。a和n由用户键盘输入。

    /* 求Sn = a + aa + aaa + aaaa + ....其中a为一个数字,一共有n项.a和n由用户键盘输入. */ #include <stdio.h> #include & ...

  5. day18-web工程路径

    web工程路径 配置tomcat运行快捷键 tomcat启动的默认快捷键时shift+f10,可以自定义配置:file-setting-keymap-搜索run,找到右边写有shift+f10的选项, ...

  6. bugku 计算器

    打开就一个输入框和验证,尝试后发现输入框限制了位数,这还不简单,F12直接修改表单长度试试 成功得到flag

  7. Go 每日一库之 go-carbon,优雅的golang日期时间处理库

    Carbon 是一个轻量级.语义化.对开发者友好的 golang 时间处理库,支持链式调用. Carbon 已被 awesome-go 收录, 如果您觉得不错,请给个 star 吧. github.c ...

  8. Day34:BigDecimal的使用

    BigDecimal 在基本数据类型中对于浮点数的计算时会出现精度丢失的情况,这个时候我们采用BigDecimal类来解决精度丢失的问题. public class Test{ public stat ...

  9. 如何用 30s 给面试官讲清楚跳表

    查找 假设有如下这样一个有序链表: 想要查找 24.43.59,按照顺序遍历,分别需要比较的次数为 2.4.6 目前查找的时间复杂度是 O(N),如何提高查找效率? 很容易想到二分查找,将查找的时间复 ...

  10. Nmap安装

    Nmap(Network Mapper,网络映射器)是一款开放源代码的网络探测和安全审核工具.它被设计用来快速扫描大型网络,包括主机探测与发现.开放的端口情况.操作系统与应用服务指纹识别.WAF识别及 ...