pmariglia / showdown

A Pokemon Showdown Battle Bot written in Python
GNU General Public License v3.0
254 stars 176 forks source link

Abstract bot class to allow extension with other decision methods #17

Closed alexayalamcs closed 4 years ago

alexayalamcs commented 4 years ago

Currently, decision and state processing logic are tightly coupled. I suggest we rework this logic to allow a superclass to be defined which handles all decision logic.

This superclass should not handle modifying or determining what's allowed in our current state. Ideally, it's only given information and constraints on our current state. Each turn, the superclass will be asked to make a decision based on whatever criteria.

This extension will allow this project to be used with other methods of selecting the best move. In particular, I'm interested in extending this project using Reinforcement Learning but this is difficult without some rework of the current code. I will be willing to work on this rework myself, but I need information on the classes I should touch as well as the structure that is preferred for this project. I want to make sure this feature is implemented in a way where it's aligned with the project's goal.

pmariglia commented 4 years ago

First off, thanks for your interest! I love it when more people become interested in writing Pokemon bots.

I'm totally not against some refactoring to allow this to be possible - better separating the battle parsing from the decision logic is on a to-do list of mine.

Right now I think you can kind of do what you want by writing your own find_best_move function. The input is a Battle object with everything that is known with certainty about the state of the battle.

Furthermore, the two decision making methods in this project are find_best_move_safest and find_best_move_nash. The input to these two are a list of battles, which are meant to represent all likely battles based on usage statistics.

With that being said I do agree that we can better define these boundaries. Let's talk about how we can do this. I'm mostly interested in what you think the ideal input to this class/function would be. Would you want a Battle object with only the known information, or would you like the framework to find all likely battles?

alexayalamcs commented 4 years ago

This idea mostly takes inspiration from the OpenAI gym project. Note that OpenAI gym is specific to creating environments for reinforcement learning, so not all aspects will apply to this project.

I'll call this proposed class "Bot" for now. At its core, it will have functions that interact with the Battle object to get any necessary information on the current state. These functions may be whatever that assists in developing a bot. There will be a few functions that are expected to be overridden, say get_move, get_switch, and get_action. get_action would be if a move or switch should be performed.

Any decision logic should be in its own class and extend this new Bot class. It will be expected to override the methods functions and implement its own decision logic.

So for the two listed decision methods, each one will be made into its own class using Bot as a superclass. We would also need to rework the configuration logic to load the specific class instead. The rest of the code should assume it's working with a Bot class.

The result would allow for any new bot developers to easily add their bot to this project. They would need to create a new class, extend Bot, and implement their decision logic; then it's ready to go. How would you feel about this?

pmariglia commented 4 years ago

Yeah I think we're on the same page. Since there seems to be some interest I'll be more motivated to actually do this.

it will have functions that interact with the Battle object to get any necessary information on the current state

I've had a few ideas about what these functions might look like but I'd love some input as well - what would you find useful?

Ill see about doing some refactoring and getting a first version of this framework.

alexayalamcs commented 4 years ago

These are a few I can think of immediately.

The child bot class could directly retrieve this information from the appropriate classes. However, I feel it'll be more helpful if the superclass handles wrapping these general methods. Also, I am available and happy to work on these changes! I want to get more work done on my bot. It'll be easier for me to work collaboratively on a framework since working with the Showdown server is tricky.

pmariglia commented 4 years ago

~See PR #18.~

~Just a first version with much more to do.~

Closed because there is a problem. Will update.

pmariglia commented 4 years ago

Sorry about the back and forth.

See PR #19

I will be merging this tomorrow unless I find out the performance has been affected. This should act as a starting point and we can work together to improve it from there.

alexayalamcs commented 4 years ago

Thank you! I have not had the time to look into the changes or try them out. I will report back when I've had a chance to play with it.

I think it's fair to close this issue for now. I'll make a new issue or pull request if I think of something useful that could be added.