-3

I'm having trouble figuring out how to deal with an Inventory for my text based java game. I just finished Data Structures and Algorithms, so I figured this would be a good project for my resume.

Currently, I create the inventory in the constructor of the player class. I would like to instantiate the inventory with 3 potion items, from the item class. I try to do that in the player constructor, but I can't figure out why its not working.

My question is, how should I go about instantiating every character with 3 potions in his/her inventory?


Player class:

package projectmoria;


import java.util.ArrayList;
import java.util.List;


public class Player {

    private final String name;
    private final String description;
    private final int maxHitPoints;
    private int hitPoints;
    private final int minDamage;
    private final int maxDamage;
    private final int defense;
    private double critChance;
    private int currX;
    private int currY;
    private Room currRoom;
    private List<Item> inventory;

    public Player(String name, String description, int maxHitPoints,
            int minDamage, int maxDamage, int defense, double critChance) {
        this.name = name;
        this.description = description;
        this.maxHitPoints = maxHitPoints;
        this.hitPoints = maxHitPoints;
        this.minDamage = minDamage;
        this.maxDamage = maxDamage;
        this.defense = defense;
        this.critChance = critChance;
        this.currX = 14;
        this.currY = 14;
        inventory = new ArrayList<>();
        inventory.add(Item.addPotion(3, this.player)); //This is the line I need help with
    }

    public int attack() {
        return ProjectMoria.RAND.nextInt(maxDamage - minDamage + 1);
    }

    public int defend(Monster monster) {
        int incomingAttack = monster.attack();
        int random = ProjectMoria.RAND.nextInt(99) + 1;
        if (random <= monster.getCritChance()) {
            incomingAttack = incomingAttack * 2;
            IO.monsterCrit(); //TODO - move to different spot
        }
        IO.playerHitPointsMessage(incomingAttack, monster);
        hitPoints = (hitPoints * defense > incomingAttack)
                ? hitPoints - incomingAttack : 0;
        return hitPoints;
    }

    public void heal(Item potion){
        this.hitPoints =+ 20;
        inventory.remove(potion);
        IO.heal(this.hitPoints);
    }

    public static Player newWarrior() {
        return new Player("Warrior", "A tough, well-rounded fighter with"
                + " a balanced skillset.", 100, 20, 30, 3, 10);
    }

    public static Player newDuelist() {
        return new Player("Duelist", "A quick, nimble duelist with an"
                + " aptitude for landing critical attacks.", 8000, 10, 50, 2, 
                18);
    }

     public String getDescription() {
        return description;
    }

    public int getHitPoints() {
        return hitPoints;
    }

    public boolean isAlive() {
        return hitPoints > 0;
    }

    public String getName() {
        return name;
    }

    public int getMaxHitPoints() {
        return maxHitPoints;
    }

    public int getMinDamage() {
        return minDamage;
    }

    public int getMaxDamage() {
        return maxDamage;
    }

    public int getDefense() {
        return defense;
    }

    public double getCritChance() {
        return critChance;
    }

    public int getCurrX() {
        return currX;
    }

    public int getCurrY() {
        return currY;
    }

    public List<Item> getInventory() {
        return inventory;
    }


    public Room getCurrRoom() {
        return currRoom;
    }

    public void setCurrRoom(Room room) {
        currRoom = room;
    }

    public void setCurrX(int currX) {
        this.currX = currX;
    }

    public void setCurrY(int currY) {
        this.currY = currY;
    }
}

Item class:

package projectmoria;


public class Item {

    private final String name;
    private final String type;
    private final String description;

    public Item(String name, String type, String description){
        this.name = name;
        this.type = type;
        this.description = description;
    }

    public void use(Player player, Item item){
        if(item.type.equals("Potion")){
            player.heal(item);
        }
    }

    public void addPotion(int numOfPotions, Player player){
        for(int i = 0; i < numOfPotions; i ++){
            player.getInventory().add(potion());
        }
    }

    public Item potion(){
        return new Item ("Potion", "Potion", " a small vial filled with a "
                + "translucent red liquid");
    }
}
JKolb
  • 23
  • 6
  • 4
    Does this question hold the StackOverflow record for most code in a single post? – frozen Jul 25 '17 at 19:56
  • Please go through the How-To-Ask sections of the [help] to see how this site works and to get suggestions on how to improve this question. Doing this will probably help you to get better answers. – Hovercraft Full Of Eels Jul 25 '17 at 19:58
  • 1
    The only relevant code that needs to be included in this post is the Player constructor. – frozen Jul 25 '17 at 19:59
  • 1
    Also please check out: [How much research effort is expected of Stack Overflow users?](https://meta.stackoverflow.com/questions/261592/how-much-research-effort-is-expected-of-stack-overflow-users). In brief, it's a lot, a heck of a lot. – Hovercraft Full Of Eels Jul 25 '17 at 19:59
  • 1
    @frozen is right. Indeed, you need only to show the classes that you are manipulating and that causes a trouble. `Player` and `Item` are enough. – davidxxx Jul 25 '17 at 20:12
  • I included the rest of the code, in the hopes that someone might also review the rest of the program thus far. Point taken. – JKolb Jul 25 '17 at 20:43
  • 1
    @JKolb Unfortunately, it is not the place for general code review. Look at this site rather : https://codereview.stackexchange.com/ – davidxxx Jul 25 '17 at 20:52

2 Answers2

1

Actually in Player constructor :

inventory = new ArrayList<>();
inventory.add(Item.addPotion(3, this.player)); 

you are invoking :

public void addPotion(int numOfPotions, Player player){

This is an instance method.
You can invoke instance methods only on an instance.

Your addPotion() method looks like to be a factory method to create potion Items :

public void addPotion(int numOfPotions, Player player){
    for(int i = 0; i < numOfPotions; i ++){
        player.getInventory().add(potion());
    }
}

public Item potion(){
    return new Item ("Potion", "Potion", " a small vial filled with a "
            + "translucent red liquid");
}

So, you should do static addPotion() and potion() and it should solve your problem.
Besides, as potion() is only invoked by addPotion(), you can reduce it level access by making it private.

davidxxx
  • 125,838
  • 23
  • 214
  • 215
  • Thank you, that makes sense. I have a follow up question for you: How do I refer to the instance of the current player in my player constructor? "this.player" is not working correctly. – JKolb Jul 25 '17 at 20:48
  • You are welcome :) To pass the current instance, pass just `this`; `this.player` would refer to an instance field named `player` in the Player class. – davidxxx Jul 25 '17 at 20:54
0

You have to change the addPotion(...) method as a static method, if you want to call that method as Item.addPotion(...)

I would strongly suggest to make your Item class as an Enum Enum java doc and add these enums into your player's inventory. These are tons of design considerations you should be thinking about. If you go with the enum design. You will force Items to be locked down to only a few types of Items and players share this item.

However if the Item is strongly coupled with your player, for example you want the Item to decrement every time a player uses the portion. Then simply make the method addPotion static.

public static void addPotion(...)

Dhawan Gayash
  • 463
  • 1
  • 4
  • 17