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() 函数即可。