-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.

1 Answers1

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.

Simon B
  • 9,772