Я хотел бы проверить, соответствует ли мой пользовательский ввод имени объекта в ArrayList, и если да, удалить его,

Я создаю текстовую игру, в которой пользователь может подбирать и бросать предметы, которые он находит в комнате. У меня возникли трудности с тем, чтобы заставить пользователя удалять предметы из своего инвентаря ArrayList.

Это то, что у меня есть для метода удаления элемента:

public boolean dropItem(Command command) {
    if(!command.hasSecondWord()) { // if user only types 'drop' we don't know what to drop...
        System.out.println("Drop what?");
        return false;
    }
    else {
        String commandInput = command.getSecondWord(); // turn item in command into string
        String itemString;
        for(Item item : pc.getInventory()) { // for every item in player inventory
            itemString = item.getName(); // set itemString to name of item
            if(itemString.equals(commandInput)){ // check if item matches user input
                if(pc.getInventory().contains(item)) {// check inventory contains the item
                    int i = pc.getInventory().indexOf(item); // get index of item
                    pc.removeFromInventory(i); // remove item from inventory
                    pc.getCurrentRoom().addToItems(item); // drop item into room
                    System.out.println(itemString + " dropped.");
                    return true;
                }
                else {
                    System.out.println(commandInput + " is not in your inventory.");
                    return false;                   
                }
            }
            else {
                System.out.println(commandInput + " is not in your inventory.");
                return false;
            }
        }
        return false;
    }
}

Код для методов, вызываемых в приведенном выше коде:

public String getSecondWord(String string) {
    String x = string;
    String secondWord = x.split(" ")[1];
    return secondWord;
}

public void addToInventory(Item item) {
    inventory.add(item);
}

public void removeFromInventory(int i) {
    inventory.remove(i);
}

public ArrayList<Item> getInventory(){
    return inventory;
}
public Room getCurrentRoom() {
    return currentRoom;
}
public Item getItem() {
    return item;
}

public void emptyItem() {
    this.item = null;
}
public void addToItems(Item item) {
    items.add(item);
}

Поэтому, если мой пользователь берет напиток, а затем ноутбук и хочет бросить ноутбук, он говорит, что у него нет ноутбука. Они могут только бросить пить. как только напиток уронили, они могут уронить ноутбук.


person Chelsea Houston    schedule 20.03.2021    source источник
comment
В общем, я думаю, что ваш пример кода немного длинный, чтобы получить помощь. Я предлагаю удалить как можно больше кода из вашего кода, но так, чтобы проблема все еще проявлялась, а затем обновить вопрос. (Кстати, это иногда само по себе выявляет проблему!)   -  person gub    schedule 20.03.2021
comment
У меня нет проблем с длиной сдвига вашего кода, но это не минимально воспроизводимый пример. Он должен быть воспроизводимым, чтобы я мог скопировать его в свою IDE, скомпилировать и отладить для вас. Мы ожидаем, что вы приложите не меньше усилий для создания своего вопроса, чем вы ожидаете от добровольцев, которые могут вам ответить.   -  person NomadMaker    schedule 20.03.2021


Ответы (1)


Вы возвращаетесь слишком рано после проверки первого пункта. Кроме того, есть некоторые избыточные проверки, если в инвентаре есть предмет, а затем вызывается indexOf для того же предмета.

Таким образом, код следует исправить и упростить следующим образом:

public boolean dropItem(Command command) {
    if(!command.hasSecondWord()) { // if user only types 'drop' we don't know what to drop...
        System.out.println("Drop what?");
        return false;
    }

    String commandInput = command.getSecondWord(); // turn item in command into string
    ArrayList<Item> inventory = pc.getInventory();
    for (int i = 0, n = inventory.size(); i < n; i++) {
        Item item = inventory.get(i);
        if (commandInput.equals(item.getName())) {
            pc.getCurrentRoom().addToItems(item);
            pc.removeFromInventory(i);
            System.out.println(item.getName() + " dropped.");
            return true;
        }
    }
    System.out.println(commandInput + " is not in your inventory.");
    return false;
}

Существующий код можно дополнительно рефакторить с помощью Stream API и Optional:

public boolean dropItem(Command command) {
    if(!command.hasSecondWord()) { // if user only types 'drop' we don't know what to drop...
        System.out.println("Drop what?");
        return false;
    }

    String commandInput = command.getSecondWord(); // turn item in command into string
    ArrayList<Item> inventory = pc.getInventory();
    
    Optional<Item> found = inventory.stream()
        .filter(item -> commandInput.equals(item.getName()))
        .findFirst();
    found.ifPresentOrElse(item -> {
        pc.getCurrentRoom().addToItems(item);
        inventory.remove(item);
        System.out.println(item.getName() + " dropped.");
    }, () -> System.out.println(commandInput + " is not in your inventory."));
    return found.isPresent();
}
person Alex Rudenko    schedule 20.03.2021