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() 函数即可。
Java 进阶P-5.1+P-5.2的更多相关文章
- Java 进阶 hello world! - 中级程序员之路
Java 进阶 hello world! - 中级程序员之路 Java是一种跨平台的语言,号称:"一次编写,到处运行",在世界编程语言排行榜中稳居第二名(TIOBE index). ...
- Java进阶(五)Java I/O模型从BIO到NIO和Reactor模式
原创文章,同步发自作者个人博客,http://www.jasongj.com/java/nio_reactor/ Java I/O模型 同步 vs. 异步 同步I/O 每个请求必须逐个地被处理,一个请 ...
- Java线程间通信方式剖析——Java进阶(四)
原创文章,同步发自作者个人博客,转载请在文章开头处以超链接注明出处 http://www.jasongj.com/java/thread_communication/ CountDownLatch C ...
- Java进阶(三)多线程开发关键技术
原创文章,同步发自作者个人博客,转载请务必以超链接形式在文章开头处注明出处http://www.jasongj.com/java/multi_thread/. sleep和wait到底什么区别 其实这 ...
- 当我们说线程安全时,到底在说什么——Java进阶系列(二)
原创文章,同步发自作者个人博客,转载请以超链接形式在文章开头处注明出处http://www.jasongj.com/java/thread_safe/ 多线程编程中的三个核心概念 原子性 这一点,跟数 ...
- Java进阶03 IO基础
链接地址:http://www.cnblogs.com/vamei/archive/2013/04/11/3000905.html 作者:Vamei 出处:http://www.cnblogs.com ...
- Java进阶01 String类
链接地址:http://www.cnblogs.com/vamei/archive/2013/04/08/3000914.html 作者:Vamei 出处:http://www.cnblogs.com ...
- 从ConcurrentHashMap的演进看Java多线程核心技术 Java进阶(六)
本文分析了HashMap的实现原理,以及resize可能引起死循环和Fast-fail等线程不安全行为.同时结合源码从数据结构,寻址方式,同步方式,计算size等角度分析了JDK 1.7和JDK 1. ...
- Java进阶(七)正确理解Thread Local的原理与适用场景
原创文章,始自发作者个人博客,转载请务必将下面这段话置于文章开头处(保留超链接). 本文转发自技术世界,原文链接 http://www.jasongj.com/java/threadlocal/ Th ...
- Java进阶(四十七)Socket通信
Java进阶(四十七)Socket通信 今天讲解一个 Hello Word 级别的 Java Socket 通信的例子.具体通讯过程如下: 先启动Server端,进入一个死循环以便一直监听某端口是 ...
随机推荐
- scrapy传递 item时的 数据不匹配 和一些注意事项
item 在传递数据时需要拷贝内存地址 yield scrapy.Request( url=title_url, callback=self.parse_detail, # 用深拷贝的方式 复制子对象 ...
- .NET 7 AOT 的使用以及 .NET 与 Go 互相调用
目录 背景 C# 部分 环境要求 创建一个控制台项目 体验 AOT 编译 C# 调用库函数 减少体积 C# 导出函数 C# 调用 C# 生成的 AOT Golang 部分 安装 GCC Golang ...
- 表单的子元素可不在form标签内
表单是网页用于向服务器发送数据的元素.其用法类似下面: <form method="POST" action="/login"> <input ...
- perl匹配特殊写法
my $name='4'; #找匹配4 for($name) { if(/^4$/) { print "success\n"; } else { print "faile ...
- Perl语言中一些内置变量等,$x、qw、cmp、eq、ne等
转载 Perl语言中一些内置变量等,$x.qw.cmp.eq.ne等 字母 符号 释义 eq = = equal(等于) ne != not equal(不等于) cmp 比较 qq " ...
- Jenkins发版通知企业微信机器人
1)开始通知 在Jenkins发版过程的第一步添加下面内容,调用下面脚本实现机器人发版通知(注意脚本路径和传参) ${BUILD_USER}是Jenkins内置变量,执行发布的用户名,需要安装插件-B ...
- MVC开发单元测试小工具 —— 搜寻还没写单元测试的方法
方法比较笨,有更好的建议可以提. 写这个工具呢,因为要写单元测试,保证代码质量,方便修改维护.一切为了自己方便.当然这个算是个人开发的项目 1.MVC中控制器建立个基类(这个光明正大的抄袭的),控制往 ...
- extern "C"的使用
在使用C++开发程序时,有时使用到别人开发的第三方库,而这第三库是使用C开发的.直接使用会报错如下: cpp error LNK2019: 无法解析的外部符号 "int __cdecl su ...
- float16与float32转换
// based on https://gist.github.com/martin-kallman/5049614 // float32 // Martin Kallman // // Fast h ...
- 论文复现|Panoptic Deeplab(全景分割PyTorch)
摘要:这是发表于CVPR 2020的一篇论文的复现模型. 本文分享自华为云社区<Panoptic Deeplab(全景分割PyTorch)>,作者:HWCloudAI . 这是发表于CVP ...