First of all, nice that you added a graph that shows your solution converging to the optimal, and also a nice idea to add the statistics about pure_random, gabrielle and donato strategies. However they are a bit confusing. Does donato having 43.6% mean that it won or lost 43.6% of the time? I'm guessing that higher percentage number means worse win ratio or something, but the figure is a bit confusing. Some labels would make the graphs a bit more readable.
Although the idea that the weights are probabilities of choosing between those four strategies is a bit of a "lazy" definition of weights, and that it doesn't really prove anything interesting, it does show that the weights converge to the optimal solution after enough iterations.
Not quite sure how the select_strategy() works and why you chose to do it like that, but it seems like it works, so I am not gonna ask any questions there :) Although it should be said that you probably could have used some libraries like numpy to make the select_strategy() and normalize() functions redundant. I know that there exists such methods.
The eval() function could be half the size if you just wrote the if and elif-statements a bit smarter, like instead of writing for example (if strategy == 0) just add all the strategies to a list and use the strategy number as the index to get each strategy from the list in correct order.
First of all, nice that you added a graph that shows your solution converging to the optimal, and also a nice idea to add the statistics about pure_random, gabrielle and donato strategies. However they are a bit confusing. Does donato having 43.6% mean that it won or lost 43.6% of the time? I'm guessing that higher percentage number means worse win ratio or something, but the figure is a bit confusing. Some labels would make the graphs a bit more readable.
Although the idea that the weights are probabilities of choosing between those four strategies is a bit of a "lazy" definition of weights, and that it doesn't really prove anything interesting, it does show that the weights converge to the optimal solution after enough iterations.
Not quite sure how the select_strategy() works and why you chose to do it like that, but it seems like it works, so I am not gonna ask any questions there :) Although it should be said that you probably could have used some libraries like numpy to make the select_strategy() and normalize() functions redundant. I know that there exists such methods.
The eval() function could be half the size if you just wrote the if and elif-statements a bit smarter, like instead of writing for example (if strategy == 0) just add all the strategies to a list and use the strategy number as the index to get each strategy from the list in correct order.
Just my two cents.