ctfhacker / bombly

70 stars 9 forks source link

API Discussion #12

Open ghost opened 8 years ago

ghost commented 8 years ago

I've been trying to think about how the API should be structured for when we make the package more object oriented. I have a general idea so far, but I wanted to open this issue to get some early feedback and discussion.

I like this general idea of how to interact with the bomb itself:

import bombly

bomb = bombly.Bomb()

bomb.batteries = 5
bomb.frk = True
bomb.car = True
bomb.parallel = True
bomb.last_digit = 0
bomb.vowel = True

properties = bomb.properties # returns a dictionary of all properties {'batteries': 5, 'frk': True, etc..})

bomb.add_strike()
bomb.remove_strike()

status = bomb.status()
bomb.reset()
bomb.exploded()
bomb.disarmed()

An issue I'm having though is when it comes to creating and solving the actual puzzle modules. The Bomb object needs to have a reference to each puzzle module that is added to it, so that when bomb.reset() is called, it can also reset or remove each puzzle module.

For example:

wires_one = bomb.add_module(Wires())
bomb.remove_module(wires_one)

The issue with this, is I'm unsure of when/how to give each puzzle the information it needs to be able to solve. With some modules like simple wires, it's easy to give the Wires() object all the information it needs to solve when you instantiate it: Wires(('red', 'red', 'white', 'yellow'))

However, some puzzles, like wire sequences, would need to have multiple steps because you would not be able to give all of the information it needs at the start.

Also most modules need access to some of the properties in bomb.properties to solve their puzzle, so I'm also trying to figure when those would be passed to the puzzle object.

I wanted to open this issue now, so that anyone who has an idea for a consistent and clean puzzle API could chime in.

dopeghoti commented 8 years ago

What makes the most immediate sense to me is for a Module to optionally have a list of Needs, which would be supplied by bomb.properties. I might suggest reworking to initialize e. g. bomb.properties['batteries'] to None (as opposed to using the sentinel value currently used).

Then, when a given module needs to know, for example, the number of batteries, it can check to see whether it's None - If it is, pass a message back saying "I need this information"; otherwise, use the information and proceed.

ghost commented 8 years ago

How would you suggest the package inform what is using it that it needs more information, an Exception?

dopeghoti commented 8 years ago

If you'll forgive the metaphor, we already are "priming" the bomb-bot with information generally before defusing (e. g. "batteries three") to set the details. All we need to do is have a common "Unable to defuse this module due to insufficient data" routine that identifies the unfulfilled Need. Supply the information, and try the module again or possibly resume where it left off if we make the routine more stateful.