0

I'm working on a text based adventure game in Java, and I'm trying to figure out a way to check what weapon the player has and set their damage output appropriately.

Here is what I have set up so far:

Item object:

Item (String name, String type, String description, String location)

("Assault Rifle", "rifle", "A rifle that goes pew pew.", "armory")

Player inventory:

HashMap<String, Item> inventory = new HashMap<String, Item>()

Right now, I can use an if statement to grab the name of the object, and set the damage modifiers for it:

if (player.getInventory().containsKey("Assault Rifle")) {
        player.setMaxAttackDmg(55);
        player.setWeaponModifier(2);
    }

What I want to be able to do is match on the item type, and not the name. I'm assuming I need a loop of some kind to iterate through the player's inventory, but I don't know how I match the HashMap value since it is an object of type Item. So it would have something like:

for (item in inventory) {
    if (item.getType().equals("rifle")) {
        player.setMaxAttackDmg(55);
        player.setWeaponModifier(2);
    }

Is there way to do that, or a better way for me to do this?

1
  • 2
    You should instead do proper OOP and create a Weapon and Item class and then have stuff like attackDmg as property of such classes. Then the player can just have a List<Item> and a Weapon and get his attack power from there with simple getter methods. Commented Nov 27, 2020 at 22:07

3 Answers 3

2

You can iterate through the values of the map to retrieve the items and then apply your test:

public Item find(String type) {
    for(final Item item : inventory.values()) {
        if(item.type().equals(type)) {
            return item;
        }
    }
    return null; // or throw an exception
}

It's certainly not the most OO approach ;) but it does what you want.

You might want to look at the other accessors of the map class such as keySet and entrySet for other ways to 'view' the inventory.

Once you have something working you might also want to investigate Java8 streams which support this sort of functionality in a much more elegant and readable way.

Sign up to request clarification or add additional context in comments.

Comments

1

You already know how to do it using loop, your approach works.

A better way to retrieve this value from a Map is to use a stream and filter out for the first occurrence, and then perform an action if the player has this on his inventory.

For example:

inventory.values()
    .stream()
    .filter(item -> item.type().equals(type))
    .findFirst()
    .ifPresent(item -> /*your action*/);

Additionally, I'd recommend you refactor your code in a more object-oriented way, for example based on the snippet you provide you could create a sub-class of Item called Weapon and have a method in Person to equip your weapon and increase your stats, e.g:

  private void equipWeapon(Weapon weapon){
    player.setMaxAttackDmg(weapon.getAttackDamage());
    player.setWeaponModifier(weapon.getModifier());
  }

3 Comments

Thanks, I'll have to look into streams as I haven't come across that yet. I struggle a bit with object-oriented thinking. I will definitely take your advice and implement weapon as a sub class. The kicker for this project is that items need to be read from a text file, so I'll have to create another file with the weapon data and import it.
If you don't want to mess up with streams yet, you'd need to change your for each loop to refer to the map's values, for example: for(item in inventory.values()){...}
I ended up making a Weapon class, and made equipWeapon() and dropWeapon() methods to change that stats. Thank you so much for your help! Now I need to work on my fight() method as I'm sure it's not very object-oriented...
1

I’d make a Weapon Enum with properties like maxAttackDmg. Then you can simply get the properties on the enum without knowing what instance it is. If weapons need to have complex behavior, and are more than just data classes, then those should be regular classes, not enum.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.