miron / NeonCore

Terminal based Cyberpunk Tabletop RPG with Nostr as database and openAI API compatible commands
3 stars 1 forks source link

skill_check_command_module #43

Open miron opened 1 year ago

miron commented 1 year ago

The Command design pattern could be a good fit for this scenario. The idea behind the Command pattern is to encapsulate a request or an operation in an object, which can be passed around and executed later. In this case, the SkillCheckCommand class would encapsulate the logic for a skill check and expose a single method, such as "execute()" or "check()", that can be called to perform the check.

The class could have an attribute called "check_name" which would indicate which type of check it is, such as "perception_check", "stealth_check" etc.. and an attribute called "check_value" that would hold the value of the check, that is the number the player has to beat.

You can also have different implementations of the execute method for different type of check.

class SkillCheckCommand:
    def __init__(self, check_name, check_value):
        self.check_name = check_name
        self.check_value = check_value

    def execute(self, player_value):
        if self.check_name == "perception_check":
            #perception check logic
            pass
        elif self.check_name == "stealth_check":
            #stealth check logic
            pass
        #other check logic

You can then create instances of this class for each check you want to perform in your game, and execute them as needed.

You could have the ActionManager class import the SkillCheckCommand module, and then use the classes within that module to handle the perception_check and stealth_check commands. The SkillCheckCommand module could contain classes like PerceptionCheckCommand and StealthCheckCommand, which would be subclasses of a base SkillCheckCommand class.

One way to organize this would be to have the SkillCheckCommand module define the base class and the individual subclasses, and then have the ActionManager import the module and use the subclasses to handle the commands. The subclasses would contain the specific logic for each type of check and can be called based on the command entered by the player.

Another approach could be to have the ActionManager class import the SkillCheckCommand module, and then use the module's functions to handle the different type of checks, rather than using classes. This way you can avoid the overhead of instantiating objects for each check and just call the function directly.

miron commented 1 year ago

It looks like the SkillCheck class has some functionality that is specific to performing a skill check (e.g. perform_check method) and some functionality that is specific to handling an NPC encounter (e.g. handle_npc_encounter method).

To turn this into a SkillCheckCommand module, I would recommend breaking up the SkillCheck class into two separate classes, one for handling the skill check itself (e.g. PerceptionCheckCommand, StealthCheckCommand) and one for handling the NPC encounter (e.g. NPCEncounterCommand).

The PerceptionCheckCommand and StealthCheckCommand classes should inherit from the cmd.Cmd class and include the perform_check method which takes care of rolling the dice and determining success or failure.

The NPCEncounterCommand class should inherit from cmd.Cmd and include the handle_npc_encounter method which prompts the player to use luck points, performs the skill check and spend the luck points.

You can also remove the raise StopIteration and break statement in the handle_npc_encounter method, as it doesn't make sense to raise an exception and exit the loop when you want to continue the game.

It's also important to note that it will be beneficial to refactor the code to use class variables or properties, instead of accessing self.character.lucky_pool or self.character.stats["luck"] directly.

Lastly, in your ActionManager class, you can add new commands for each of the PerceptionCheckCommand and StealthCheckCommand classes and call their respective methods.