2

自分ではわからない質問をしたり、グーグルで調べたりしても、見落としていないことを願って、アカウントを作成することにしました。

基本的に、私は Java でテキスト アドベンチャー ゲームを作成しようとしていますが、オブジェクトのアイデアですべてをどのように関連付けるべきかを理解するのに少し苦労しています。XML スタックスを使用してファイルをプログラムに送信し、属性などを使用して、ユーザーがオプションに関連付けられた整数を入力できるようにし、オプションが「項目」を必要とするかどうかを確認することに成功しました。アイテム。ただし、これには OOP を使用しませんでした。

整数だけではなく、ユーザー入力の文字列を取り込んで、配列リストが存在する場合は配列リストと照合できる新しいプログラムが必要です。これは、ほとんどの人がよく知っているクラシックな MUD に近いものです。

モジュラー方式で設計したいので、ゆっくりとアイデアを追加したり、複雑さを増したりできます。そのため、「うまく機能するので放っておきましょう」というアプローチも必要ありません。

現在、私は単にこれに近いものが欲しいです:

ID、説明、および対話可能な Choice オブジェクト (これはよくわかりません) を持つ Room オブジェクト。出口と対話可能なオブジェクトの両方で、各部屋の可能な選択肢を保持するオブジェクトを作成することを考えました。

その場合、ルーム オブジェクトには Choice オブジェクトが必要な場合があります。

よく考えて、いくつかのコードを試して、もう一度考え直しましたが、毎回、必要以上にハードコーディングを終わらせ続け、必要だと思うよりも多くの変数を作り続けています。私の考えには決定的な何かが欠けています。

また、これらの部屋は、コードで生成されるのではなく、入力されたファイルを介して作成されることを望んでいます (基本的に、コードは、1 つではなく、任意のタイプのストーリー リーダー/クラフターです)。

私もこれをあまりにも長く試みており、私の解決策は悪化していますが、以下は大まかなアイデアに対する私の最近の試みです:

userInput を受け取り、それを渡す前にそれをチェックする GameManager クラス。アプローチがわからないため、データを渡していません。また、私は正規表現に慣れていないので、その一部も間違っている可能性があります。もしそうなら、それを指摘するかもしれませんが、それは私の焦点では​​ありません

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);
}
}

非常に多くの変数で非常に多くの方向を述べる必要がないようにするにはどうすればよいですか?

これは私が考えたオプションクラスの簡単で大まかなアイデアですが、私はすでに間違った方向に行きすぎていると判断しきれませんでした

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 は私が使用していたもの) から情報を取得する) を作成するための良い方法は何でしょうか。ユーザーは、自由に入力できるこれらのキーワードに基づいて対話し、配列の保持キーワードのインデックス値に限定されません。

ユーザーが「北への旅」のようなものを入力して、最初にキーワードを入力したかどうかを確認します。この場合は旅行で、次に方向です。次に、他のどこかで旅行が記載されているかどうかを確認し、可能性のある北出口で北を確認します部屋にある場合とない場合があります。次に、check のような別のキーワードの場合、簡単にするために、まったく同じ方向を持ちますが、別の文字列をチェックします。

次に、部屋「northExit」が存在する場合は、別の部屋 ID へのポインターを使用して、何らかの方法でオプションを取得します。しかし、この思考プロセスは、次の部屋に行くためにアイテムを必要とする将来の可能性について考えるときに問題を引き起こします. また、これらのオプションを保存/取得する場所がいくつかの問題を引き起こしています。

4

1 に答える 1

0

ご紹介したいものは2つあります。最初に、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型の詳細については、こちらを参照してください。

2 番目に紹介したいのは、 として知られるデータ構造Mapです。マップは辞書とも呼ばれ、マップがどのように機能するかを理解するのに役立ちます。Map は 1 つのオブジェクトを取り、それを別のオブジェクトにマップします。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 に答える