2

我决定创建一个帐户来提出一个我自己似乎无法弄清楚的问题,或者通过一些谷歌搜索,希望我没有忽略它。

本质上,我正在尝试用 Java 制作一个文本冒险游戏,并且在理解我应该如何将对象概念中的所有内容联系起来时遇到了一些麻烦。我已经成功地使用 XML stax 并将文件发送到程序,并使用属性和其他东西,使用户可以输入与选项关联的整数,并查看选项是否需要“项目”或给他们一个物品。然而,我没有对此采取 OOP。

我希望我的新程序能够让人们接受一串用户输入,而不仅仅是一个整数,并根据数组列表(如果存在)对其进行检查。这更接近于大多数人可能熟悉的经典 MUD。

我想以模块化的方式设计它,所以我可以慢慢地添加想法,并增加更多的复杂性,所以我也不想要“它工作得很好,所以让它不管它”的方法。

目前我只是想要接近这个的东西:

一个 Room 对象,它有:ID、Description 和可交互的 Choice 对象(这个我不确定)

如果是这样,房间对象可能需要一个选择对象。

我已经考虑过了,尝试了一些代码,又重新考虑了一遍,每一次,我总是比我觉得我应该做的更多的硬编码,并且制作了比我觉得必要的更多的变量,这让我觉得我我错过了一些在我的想法中至关重要的东西。

我还希望通过输入文件创建这些房间,而不是在代码中生成(所以基本上代码是任何类型的故事阅读器/工匠,而不是一个)

我也一直在尝试这个太久,我的解决方案变得越来越糟,但下面是我最近尝试的一个粗略的想法:

一个 GameManager 类,它接受 userInput 并在传递它之前对其进行一些检查。我没有传递任何数据,因为我不确定该方法。我也不习惯正则表达式,所以其中一些也可能是错误的,如果是,也许指出来,但这不是我的重点

import java.util.Scanner;

public class GameManager {

private static final String EXIT_PHRASE = "exit";
public static void main(String[] args) {

    Scanner userInput = new Scanner(System.in);
        String userStringVal = "";
        while(!userStringVal.equals(EXIT_PHRASE)){
            userStringVal= userInput.nextLine();
            if(checkKeywords(userStringVal)){
                System.out.println("matches keyword");
            }
            else System.out.println("didnt match a keyword");
        }
    userInput.close();
}

public static boolean checkKeywords(String string){
    boolean isKeyword = false;
    string.toLowerCase();
    if(string.matches("travel.*") || string.matches("search.*")){
        System.out.println("passed first check");
        String substring = string.substring(6);
        if(matchDirection(substring)){
        isKeyword = true;   
        }
    }

    return isKeyword;
}

public static boolean matchDirection(String string){
    boolean hasDirection = false;
if(string.matches(".*\\bnorth|south|east|west|northeast|northwest|southeast|       southwest|up|down")){
        hasDirection = true;
}
    return hasDirection;
}
}

我这样认为的 Room 对象:

import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;

public class Room {

private String roomDescription = "";
private int roomID=0;
private int northExit=0;
private int southExit=0;
private int eastExit=0;
private int westExit=0;
private int northeastExit=0;
private int northwestExit=0;
private int southeastExit=0;
private int southwestExit=0;
private int upExit=0;
private int downExit=0;
private String[] interactables = new String[10];
private Options options = new Options();

public Room(XMLStreamReader reader) throws XMLStreamException{
    setAttValues(reader);
    setRoomDescription(reader);
    setUpOptions();
}

public void setinteractables(XMLStreamReader reader){
    int count = reader.getAttributeCount();

    for(int i = 0; i < count; i++){
        interactables[i] = reader.getAttributeValue(i);
    }
}

public void setAttValues(XMLStreamReader reader){
    int count = reader.getAttributeCount();
    for(int i = 0; i < count; i++){
        String att = reader.getAttributeLocalName(i);
        if(att !=""){
        switch(att){
        case "North": northExit=Integer.parseInt(att);

        case "South": southExit=Integer.parseInt(att);

        case "East": eastExit=Integer.parseInt(att);

        case "West": westExit=Integer.parseInt(att);

        case "NorthEast": northeastExit=Integer.parseInt(att);

        case "NorthWest": northwestExit=Integer.parseInt(att);

        case "SouthEast": southeastExit=Integer.parseInt(att);

        case "SouthWest": southwestExit=Integer.parseInt(att);

        case "Up": upExit=Integer.parseInt(att);

        case "Down": downExit=Integer.parseInt(att);

        case "ID": roomID=Integer.parseInt(att);
        }
        }
    }
}

public void setRoomDescription(XMLStreamReader reader) throws XMLStreamException{
    roomDescription = reader.getElementText();
}

public void setUpOptions(){
options.setCardinalPointers(northExit, southExit, eastExit, westExit);
options.setIntercardinalPointers(northeastExit, northwestExit, southeastExit, southwestExit);
options.setElevationPointers(upExit, downExit);
}
}

我能做些什么来确保我不必用这么多变量说明这么多方向?

这是我想到的 Option 类的一个快速而粗略的想法,但我没有完成决定我已经在错误的方向上走得太远了

public class Options {

private int northPointer = 0;
private int southPointer= 0;
private int eastPointer = 0;
private int westPointer = 0;
private int northeastPointer= 0;
private int northwestPointer = 0;
private int southeastPointer = 0;
private int southwestPointer = 0;
private int upPointer = 0;
private int downPointer = 0;
private String northInteractable = "";
private String southInteractable = "";
private String eastInteractable = "";
private String westInteractable = "";
private String northeastInteractable ="";
private String northwestInteractable = "";
private String southeastInteractable = "";
private String southwestInteractable = "";
private String upInteractable = "";
private String downInteractable = "";

public Options(){
}

public void setCardinalPointers(int north, int south, int east, int west){
    northPointer = north;
    southPointer = south;
    eastPointer = east;
    westPointer = west;
}
public void setIntercardinalPointers(int northeast, int northwest, int       southeast, int southwest){
    northeastPointer = northeast;
    northwestPointer=northwest;
    southeastPointer=southeast;
    southwestPointer=southwest;
}

public void setElevationPointers(int up, int down){
    upPointer = up;
    downPointer = down;
}



public String whatToReturn(String string){
    String importantPart = "";

    if(string.matches("travel.*")){
        String substring = string.substring(6);

    }

    else {
        importantPart = "Interactable";
        String substring = string.substring(6);
        if (substring.matches("\\bnorth\\b")) {
            if(northInteractable!=0){

            }
        }

        else if (substring.matches("\\bsouth\\b"))

        else if (substring.matches("\\beast\\b"))

        else if (substring.matches("\\bwest\\b"))

        else if (substring.contains("northeast"))

        else if (substring.contains("northwest"))

        else if (substring.contains("southeast"))

        else if (substring.contains("southwest"))

        else if (substring.contains("up"))

        else if (substring.contains("down"))
    }
    return importantPart;

}
}

直到我输入这个之后我才看到冒险标签,所以我会开始仔细阅读那里,但仍然会发布这个,所以如果有一个很好的答案,我很抱歉,我还没有找到它。

回顾一下:将几个对象关联起来以创建一个房间对象(从文件中获取信息(XML 是我习惯使用的))的好方法是什么,该对象具有出口、描述和交互。用户与这些基于可自由输入的关键字进行交互,不限于数组持有关键字的索引值。

我在想,当用户输入诸如“向北旅行”之类的内容时,首先检查他们是否输入了关键字,在这种情况下是旅行,然后是方向。然后在其他地方检查它是否说明了旅行,用可能的northExit检查房间可能有也可能没有。然后,如果它的另一个关键字,比如检查,为了简单起见,也有完全相同的方向,但检查不同的字符串。

然后,如果房间“northExit”存在,以某种方式获得一个选项,带有指向另一个房间ID的指针。虽然这个思考过程让我在考虑未来需要物品才能到达下一个房间的可能性时产生了一些问题。此外,在哪里存储/获取这些选项也会造成一些困难。

4

1 回答 1

0

我想向您介绍两件事。第一个,在enum. 您可以将其视为一种特殊的类,其中所有可能的选项都在类定义中枚举。这非常适合您的情况,例如方向。枚举可以很简单,您只需列出在其他类中使用的所有可能选项:

public enum Direction {
    NORTH, NORTH_EAST, EAST, SOUTH_EAST, SOUTH, SOUTH_WEST, WEST, NOTH_WEST;
}

如果您希望它们具有自己的方法和属性,它们可能会更复杂一些:

public enum Direction {
    NORTH(true), NORTH_EAST(false), EAST(true), SOUTH_EAST(false), SOUTH(true), SOUTH_WEST(false), WEST(true), NOTH_WEST(false);

    private final boolean isCardinal;

    private Direction(boolean isCardinal){
        this.isCardinal = isCardinal;
    }

    public boolean isCardinal(){
        return isCardinal;
    }

    public static Collection<Direction> getCardinalDirections(){
        return Arrays.asList(Direction.values()).stream().filter(Direction::isCardinal).collect(Collectors.toList());
    }

    public static Collection<Direction> getIncardinalDirections(){
        return Arrays.asList(Direction.values()).stream().filter(x -> !x.isCardinal()).collect(Collectors.toList());
    }
}

请在此处阅读有关 Javaenum类型的更多信息。

我想向您介绍的第二件事是称为Map. 地图也被称为字典,这通常可以帮助理解它们是如何工作的。Map 将获取一个对象并将其映射到另一个对象,例如 Dictionary 如何将单词映射到其定义,或者电话簿如何将一个人的姓名映射到他们的电话号码。我们可以Room通过使用Map. 我不会重现您的所有代码,因为我现在专注于您的Room存在:

public class Room {

    private Map<Direction, Room> exits;

    public Room(){
        this.exits = new HashMap<>();
    }

    public void setExit(Direction direction, Room room){
        this.exits.put(direction, room);
    }

    public Room getExit(Direction direction){
        return this.exits.get(direction);
    }
}

请在此处阅读有关 JavaMap接口的更多信息。

当然,您将需要调整从 XML 等读取的方法。但是,现在,您的Room类应该大大简化了。

我希望这能为您指明一个有用的方向。

于 2017-01-01T23:41:05.437 回答