Runs on angular@4.3.x
A plugin oriented chess component.
The module is actually a shell with plugins.
The shell provides contracts and some building block for the plugins.
The logic behind a plugin system is that there are different types of chess games.
Also, there are already multiple chess implementation's out there, a plugin can wrap an implementation and save a lot of work.
This approach enables endless game variants.
It can be games with different rules (engines), or games with different UI (3D, native, different pieces, etc...)
A UI plugin is a sort of a Renderer
which means a native implementation is also quite easy.
There are 3 types of plugins
Engine plugins provides the logic, an engine might also implement AI (optional)
Currently there are 2 engine plugins:
The Chessjs
engine is a wrapper around the Chess.js library.
The description in the Chess.js Github repository says:
A Javascript chess library for chess move generation/validation, piece placement/movement, and check/checkmate/draw detection
This means the the Chessjs
plugin does not support AI, thus only human vs human matches are allowed.
The Chessjs-AI
engine extends (inherits) the Chessjs
engine and adds AI on top of it using stockfish.js.
stockfish.js is a Javascript port of the powerful open-source *Stockfish engine.
Stockfish is probably the strongest AI chess engine in Javascript, this comes with a cost - a very big payload size.
stockfish.js use the postMessage API since it is intended to run in a web worker.
It is very hard manage async operation's that way and keep a reasonable flow without crazy state management.
To achieve a nice flow I had to wrap it, I ended up building a Promise API
wrapper around stockfish.js
Using the wrapper makes development super easy as state outside the wrapper is not an issue, the wrapper takes care of it all.
I will probably post this wrapper as a different library, you can find it in src/packages/es6-stockfish
Thinking Angular, it might sound weird why a Promise API and not Observables? after all postMessage is a classic stream of messages rather then a single event. There are 2 reasons: (1) Observables not in ES6, this is a big constraint. (2) While stockfish sends a stream of message, they are always in response to a request. Since a request has a unique response and there are no multiple requests of the same type in the same time - a Promise API is more suitable here.
UI plugins use logic plugins to display the board and allow users to interact with the board. Currently there is 1 UI plugin:
OnPush
strategy with all of the components for maximum performance.A controller has 2 responsibilities:
Currently controllers are not really plugins, they are intended as such.