-1

I asked similar question earlier this morning, and for whatever reason, I'm not getting a complete answer to my question. I'll ask it a different way.

I was attempting to understand Eric Lippert's blog series Wizard and Warriors and see the difficulties that can happen when you try to use the type system to encode the rules of a game.

Suppose I have a Weapon class and a Character class.

public abstract class Weapon 
{
    private String name;
    private int damage;

    public abstract void attack(Character character)
} 


 public abstract class Character
 {
     public final boolean tryCarry(Weapon weapon)
     {
         // code to try and add weapon to player inventory. 
     }
 }

In my linked question I asked about using an enum or a collection of enums that are attributes that describe a Weapon, so for example, a Sword might have LongBlade and Destructable as attributes, and the Character object can query that collection to determine if the Weapon can be added to the player inventory, provided it meets certain requirements.

So an implementation might look like this:

public final boolean tryCarry(Weapon weapon)
{
   if !(weapon.containsAttribute(GameObjectAttribute.LongBlade))
   {
       // add weapon to inventory
   } 
}

As the answers suggest, it complicates the problem.

The blog suggests the use of a Rule class. My linked question suggests a tryCarry(Weapon weapon) method.

Maybe I don't fully understand the blog series (and if I don't, can someone provide more detail?) but I can't see it any other way.

The way I understand it is, you have to communicate either with the Rule or Player class to determine what Weapon you have, and if it can be added. How would you do this? To me anyway, a value, if it's a string or enum must be stored somewhere to indicate exactly what weapon you're trying to add.

  • I'm not sure what the actual question is, or what problem you're trying to solve? At a guess though, maybe you need to look into an ECS, and have a "Carry" system. – Steve Smith Oct 2 '18 at 9:22
  • @SteveSmith - My question has been clearly stated, you have to communicate either with the Rule or Player class to determine what Weapon you have, and if it can be added. How would you do this? – user315575 Oct 2 '18 at 13:03
1

Follow the "tell, don't ask" principle.

If you want a character to pick up a weapon, call tryCarry to tell them to pick it up. If they can't, they will report that back.

Every (object of every) class should know what it is capable of doing, and should have methods to do that. So if you want it to do something, just tell it. If sometimes it can't do that, make sure you design the method with a status response.

If there are rules to check, then each character should know what rules apply to them. So checking the rule should be part of the tryCarry method. Any rules would be initialised in the constructor.

You tell the character what to pick up by passing it a reference to the object you want picked up. Don't invent other strings or enums as that just complicates things.

  • Can you provide a code sample? The problem I'm having is Weapon is an abstract class. The Rule needs to know the Weapon I'm trying to carry, how can I tell it, I'm attempting to carry a Sword? – user315575 Oct 2 '18 at 13:05
  • @BasementJoe why can't your weapon class include information about the type of the weapon? – Zavior Oct 2 '18 at 13:56
  • @Zavior - I had an enum in the Weapon class indicating what weapon it was, but I was told it's bad practice and violates DRY. See for yourself: softwareengineering.stackexchange.com/questions/373390/… – user315575 Oct 2 '18 at 14:41
  • @Zavior - The Rule class needs to know what Weapon I'm carrying, but it's abstracted away, how then can I enforce the rule? I need someway to communicate that I'm attempting to carry a Sword. – user315575 Oct 2 '18 at 14:43
  • @BasementJoe Ultimately, you cannot pick up a Weapon, as there can never be an object that is a Weapon (it's an abstract class). You can pick up a Sword object, and the Sword should know that it's a Sword. Java supports reflection. So if the Character is actually a Wizard, and the Weapon is actually a Sword, then you can pass both into the "can I pick it up" rule, and the rule can use reflection to see if that's possible. If you really hate reflection, some kind of toString implemented on every class would do instead. – Simon B Oct 2 '18 at 16:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy