Вы не можете одновременно беспокоиться о производительности и коде для удовольствия:)
Подумайте о том, чтобы вместо битборта было "nibbleboard" (или, по крайней мере, байтборд), где каждый клочок представляет один тип фигуры.Каждый кусочек также является индексом в таблице одноэлементных объектов, которые работают с этим типом фрагмента.
class Empty : public Piece {};
class Rook : public Piece {};
...
const int wrook = 1;
...
const int bpawn = 12;
Piece* Operator[13] = {new Empty(), new Rook(), ..., new Pawn()};
byte table[64] = {
wrook, wbishop, wknight, wking, wqueen, wknight, wbishop, wrook,
wpawn, wpawn, wpawn, wpawn, wpawn, wpawn, wpawn, wpawn,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
bpawn, bpawn, bpawn, bpawn, bpawn, bpawn, bpawn, bpawn,
brook, bbishop, bknight, bking, bqueen, bknight, bbishop, brook};
// Given some position and some operation DoSomething we would have this:
Operator[table[position]]->DoSomething(table, position, <other parameters>);
// Possible return value of DoSomething might be new table