Closed hgducharme closed 3 months ago
The goal here is so that later on if we want to change the implementation of board representation, move generation, search, or evaluation, all we have to do is subclass the interface and swap it out. It would make swapping out new implementations immensely easy. However, there is an argument to be made that we know the implementation we want at compile time, so are interfaces necessary? I feel like they serve more of a purpose if you don't know the needed implementation at runtime, but maybe it's ok to implement this pattern for swapping out at compile time
An argument for implementing these interfaces: it will make testing easier and we'll be able to swap out fakes, mocks, and stubs. We'll be able to do more unit testing and not have all of our tests be integration tests
https://stackoverflow.com/questions/482745/namespaces-for-enum-types-best-practices
Consider enforcing enum names
MoveGenerator
design considerations: should a MoveGenerator
class actually have PawnMoveGenerator
, KnightMoveGenerator
, ..., etc. member variables to this? In enterprise code I would say yes. This is good dependency injection, single responsibility principle, etc. Are we gonna need it? Idk. Maybe do that later, if we feel like it'll help.
Something like this seems like good encapsulation and design:
main() {
MoveGeneration.init()
MoveEvaluation.init()
}
MoveGeneration.init() {
attack_tables::init()
}
I have already coded to the Bitboard
implementation so heavily that there's no going back. In enterprise code it would've maybe been good to have a BoardRepresentation
class that hides how the board is actually being represented, but it's all good, no worries. I have kept move generation as it's own thing and will be doing the same for move evaluation
Some interfaces that can be implemented: