Move generator optimisation

The legality check was over complicated to make it more optimal but as
it turns out, it was actually slower then the plain brute force
implementation. Now we simply make the move (without calculating Zobrist
etc.) and run inCheck.

Also optimised the attack functions by short circuiting computation on
the different piece types.