The code more or less reflects the things seen in class, but I don’t understand your choice to give the same reward is in case of victory is in case of defeat of the player, in fact, I don’t understand how you can tell which move is right for player x and which is right for player O. It would be helpful to see a table of results with the winning percentages, another improvement could be the implementation of symmetry to avoid equivalent states and in such a way as to have a smaller dictionary size. However all in all I think that a good job has been done, and anyway I see that you have devoted time and work.
The code more or less reflects the things seen in class, but I don’t understand your choice to give the same reward is in case of victory is in case of defeat of the player, in fact, I don’t understand how you can tell which move is right for player x and which is right for player O. It would be helpful to see a table of results with the winning percentages, another improvement could be the implementation of symmetry to avoid equivalent states and in such a way as to have a smaller dictionary size. However all in all I think that a good job has been done, and anyway I see that you have devoted time and work.