-2
\$\begingroup\$

I'm trying to develop a text-based game. Here is the concept-demo version.

class Arena {
    public static void battle(Hero h1, Hero h2){
        h1.setHp(h1.getHp()-h2.getPhysical_attack());
        h1.info();
    }

    public static void main(String[] args) {
        System.out.println("Entering Arena ...");
        Hero mike = new Hero();
        mike.setUname("mike");
        mike.info();
        Hero tom = new Hero();
        tom.setUname("tom");
        tom.info();
        battle(mike, tom);
    }
}

class Hero{
    private String uname;
    private int hp;
    private int physical_attack;
    Hero(){
        hp = 620;
        physical_attack = 66;
    }
    public String getUname() {
        return uname;
    }

    public void setUname(String uname) {
        this.uname = uname;
    }

    public int getHp() {
        return hp;
    }

    public void setHp(int hp) {
        this.hp = hp;
    }

    public int getPhysical_attack() {
        return physical_attack;
    }

    public void setPhysical_attack(int physical_attack) {
        this.physical_attack = physical_attack;
    }
    void info() {
        System.out.println("HP of "+uname+"'s hero = "+hp);
    }
}

Is it common to use static void method to handle objects that way?

\$\endgroup\$
2
  • 4
    \$\begingroup\$ This feels like it might be a bit early for a review. static can be ok, however there's questions I'd consider... are you going to support multiple Arena, with different Hero's fighting? How come Mike never hits Tom back? Does it make sense to have a Hero that doesn't have a name, or should this be a constructor parameter? Are you going to support equipment (to reduce damage / inflict more damage)? Get/Set pairings setup a race condition does that matter? Should Hero have a take damage method instead? etc... \$\endgroup\$
    – forsvarir
    Commented Apr 21, 2021 at 15:39
  • 1
    \$\begingroup\$ The current question title, which states your concerns about the code, is too general to be useful here. Please edit to the site standard, which is for the title to simply state the task accomplished by the code. Please see How to get the best value out of Code Review: Asking Questions for guidance on writing good question titles. \$\endgroup\$ Commented Apr 21, 2021 at 20:40

2 Answers 2

1
\$\begingroup\$

Few suggestions

  1. Arena.battle can be changed to instance method rather than a static method. This will help in conducting matches in different arenas.
  2. Use constructor to set the uname, initial hp and initial physical_attack
  3. Its better to use camel case for variable names instead of underscore(_)
  4. Constructors can be overloaded to mandate uname and suitable default values for hp and physicalAttack.
  5. toString() can be overloaded instead of info()
  6. hashCode and equals can be overridden to ensure that same player is not matched against himself

Regarding the usage of static method to schedule games

  1. It's always better to have a separate scheduler class to schedule games.
  2. This will help in unit testing using dependency injection
  3. also, it will be easier to mock non-static methods than static methods in unit test
\$\endgroup\$
4
  • \$\begingroup\$ Thank you. Does "Use constructor to set the uname" refer to the constructor of class Arena or class Hero? \$\endgroup\$
    – JJJohn
    Commented Apr 22, 2021 at 12:12
  • 1
    \$\begingroup\$ @JJJohn, The constructor suggestion was primarily for Hero class. Irrespective of this, if we have a mandatory parameter and if the value will be mostly available, then its better to pass it as constructor to enable easier understanding. Also, if the instance variable was never needed to be updated after construction, its better to mark the variable as final and use constructor parameter only. \$\endgroup\$
    – Horse
    Commented Apr 23, 2021 at 3:54
  • \$\begingroup\$ Thank you so much. Would you please give some examples for different arenas? For example, player1 vs. player2 at arena1 while player3 vs. player4 at arena2, so arena1 and arena2 are 2 instance of the class Arena, is my understanding correct? \$\endgroup\$
    – JJJohn
    Commented Apr 25, 2021 at 22:25
  • 1
    \$\begingroup\$ True. Your understanding is correct. Few more next steps, 1. an identifier for each arena 2. whether same player can play in different arenas at the same time? This requires some kind an event/game organizing strategy. It's better to separate responsibilities for game matching from Arena/Hero classes and evolve them as independent pluggable strategies. Adding reasonable unit tests will help in long run. \$\endgroup\$
    – Horse
    Commented Apr 26, 2021 at 23:59
0
\$\begingroup\$

Since the Arena class has no state, and what state it needs is passed in as arguments, it seems reasonable to me for the methods to be static. This is a common pattern for utility-like classes. To make it more explicit you can add the keyword final to the class to indicate that no-one should create an instance of this class (there would be no point).

However the way you're accessing that method is not very standard. If you want it to be static you should really be accessing it like so:

Arena.battle(mike, tom);

If, as others have suggested, you want Arena to be a class from which instance objects are created, rather than a utility class, then I'd suggest giving it some state. Your battle method already takes two Hero instances. An alternative approach would be to set the Hero instances on your Arena object and then call battle like so:

class Arena {

    private Hero h1;
    private Hero h2;

    public void battle() {
        h1.setHp(h1.getHp()-h2.getPhysical_attack());
        h1.info();
    }

    public static void main(String[] args) {
        System.out.println("Entering Arena ...");

        Hero mike = new Hero();
        mike.setUname("mike");
        mike.info();

        Hero tom = new Hero();
        tom.setUname("tom");
        tom.info();

        Arena arena = new Arena();
        arena.hero1 = mike;
        arena.hero2 = tom;
        arena.battle();
    }
}

That way you can call other methods on the Arena in the future and not have to remember which Heros you passed to it. For example, a method that prints the result of the battle, or an average result of multiple battles over time.

\$\endgroup\$
1
  • 2
    \$\begingroup\$ The battle method should no longer be static since it works with instance properties h1 and h2... \$\endgroup\$
    – slepic
    Commented Apr 22, 2021 at 4:26

Not the answer you're looking for? Browse other questions tagged or ask your own question.