I would not use the 3D world at all. This is just to make it look nice. I suggest follow the MVC (model-view controller) pattern where the model is in Python.
Model
E.g. the board as 2d-array (list of lists) of fields. Each field knows what figure is on it (or if it is empty).
Any operation will be performed on that board (moving figures, removing figures etc.). The chess rules will be applied on that operations.
View
The view is what the user sees. So this is the 3D world. With all the meshes and materials. Whenever the model changes ... the view (3D world) will be updated. You can add eye-candy animations wherever you want. It has no impact on the model as it is not important to the chess game itself.
Important is that the model notifies the view when something changed. So the 3D objects know they need to do something.
Example A: the King moved from A1 to B2 (model change). You notify the view that there was a change.
The King sees: "I'm relocated to B2" -> so he jumps, crouches, flies .... to the location associated with B2.
Example B the King moved from A1 to B2 and tower (at B2) gets removed.
The King sees: "I'm relocated to B2 hitting the tower" -> so he fights .... to the location associated with B2.
The Tower sees: "I'm need to disappear" -> hie fights with the King and disappears with an explosion.
I hope you get the idea. (If not imagine your display is a 8x8 block of ascii characters). The model should still be able to do chess.
Controller
How does the model know what operation to perform? Here you need the controller (not to confuse with the BGE logic brick controller). The controller notifies the model about any input from the view (or somewhere else).
Example A
When the user clicks on the king the controller tells the model the user selected the king. The model calculates what fields are available for moving the king (the model knows the rules!). Then it notifies the view that there is an update (selection changed, clickable fields changed). The view shows a nice representation (e.g highlight the King, let the available fields glow).
When the user clicks on a available field (B2), the controller tells the model that this field was selected. The model moves the King to B2 ... see example A of section view.
Example B
When the user clicks on the king the controller tells the model the user selected the king. The model calculates what fields are available for moving the king (the model knows the rules!). Then it notifies the view that there is an update (selection changed, clickable fields changed). The view shows a nice representation (e.g highlight the King, let the available fields glow). As B2 is occupied by the tower, the tower gets an highlight too.
When the user clicks on the tower/field (B2), the controller tells the model that this field was selected. The model validates if that was a valid move removes the tower and moves the King to B2 ... see example B of section view.
Conclusion:
The MVC pattern, let you isolate the core game logic (chess rules, board data, chess operations) from pure visual aspects and user input.
The model should be independent -> the model should not know about the view or the controller. It should just know there is a view and how to tell that it should update (e.g. communication via messages).
Keep in mind the model could use any view and controller such as text output and calculated turns (from a chess engine/AI) in any combination. There can be even several of them at the same time.
The model defines an interface for communication to the view and from/to the controller.
I do not think that there is a sufficient way to implement a chess model without Python in the BGE.