Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Chess input representation v2.8 #125

Merged
merged 3 commits into from
May 30, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
@project: CrazyAra
@author: queensgambit
Input representation for chess v2.1.
Input representation for chess v2.8.
This presentation avoids potential overfitting and bias, e.g. no color information, no move counter, no progress counter
and adds features which are hard for the CNN to extract, e.g. material info, number legal moves, checkerboard,
opposite color bishops.
Expand All @@ -25,11 +25,12 @@
CHANNEL_IS_960 = 19
CHANNEL_PIECE_MASK = 20
CHANNEL_CHECKERBOARD = 22
CHANNEL_MATERIAL = 23
CHANNEL_MATERIAL_DIFF = 23
CHANNEL_OPP_BISHOPS = 28
CHANNEL_CHECKERS = 29
CHANNEL_CHECK_MOVES = 30
CHANNEL_MOBILITY = 32
CHANNEL_MATERIAL_COUNT = 33


def board_to_planes(board: chess.Board, normalize=True, last_moves=None):
Expand Down Expand Up @@ -84,13 +85,14 @@ def board_to_planes(board: chess.Board, normalize=True, last_moves=None):
Checkers | 1 | Indicates all pieces giving check |
Checking Moves | 2 | Indicates all checking moves (from sq, to sq) |
Mobility | 1 | Indicates the number of legal moves
P1 Material Count | 5 | (pieces are ordered: PAWN, KNIGHT, BISHOP, ROOK, QUEEN), normalized with 8 |
---
13 planes
18 planes
The total number of planes is calculated as follows:
# --------------
13 + 4 + 2 + 1 + 13
Total: 33 planes
13 + 4 + 2 + 1 + 18
Total: 38 planes
:param board: Board handle (Python-chess object)
:param normalize: True if the inputs shall be normalized to the range [0.-1.]
Expand Down Expand Up @@ -193,10 +195,10 @@ def board_to_planes(board: chess.Board, normalize=True, last_moves=None):
# Channel: 23 - 27
# Relative material difference (negative if less pieces than opponent and positive if more)
# iterate over all pieces except the king
assert(channel == CHANNEL_MATERIAL)
assert(channel == CHANNEL_MATERIAL_DIFF)
for piece_type in chess.PIECE_TYPES[:-1]:
matt_diff = len(board.pieces(piece_type, me)) - len(board.pieces(piece_type, you))
planes[channel, :, :] = matt_diff / NORMALIZE_PIECE_NUMBER if normalize else matt_diff
material_count = len(board.pieces(piece_type, me)) - len(board.pieces(piece_type, you))
planes[channel, :, :] = material_count / NORMALIZE_PIECE_NUMBER if normalize else material_count
channel += 1

# Channel: 28
Expand Down Expand Up @@ -236,6 +238,14 @@ def board_to_planes(board: chess.Board, normalize=True, last_moves=None):
planes[channel, :, :] = len(my_legal_moves) / NORMALIZE_MOBILITY if normalize else len(my_legal_moves)
channel += 1

# Channel: 33
# Material
assert(channel == CHANNEL_MATERIAL_COUNT)
for piece_type in chess.PIECE_TYPES[:-1]:
material_count = len(board.pieces(piece_type, me))
planes[channel, :, :] = material_count / NORMALIZE_PIECE_NUMBER if normalize else material_count
channel += 1

assert channel == NB_CHANNELS_TOTAL
return planes

Expand Down Expand Up @@ -329,10 +339,14 @@ def normalize_input_planes(planes):
:param planes: Input planes representation
:return: The normalized planes
"""
channel = CHANNEL_MATERIAL
channel = CHANNEL_MATERIAL_DIFF
for _ in chess.PIECE_TYPES[:-1]:
planes[channel, :, :] /= NORMALIZE_PIECE_NUMBER
channel += 1
planes[CHANNEL_MOBILITY, :, :] /= NORMALIZE_MOBILITY
channel = CHANNEL_MATERIAL_COUNT
for _ in chess.PIECE_TYPES[:-1]:
planes[channel, :, :] /= NORMALIZE_PIECE_NUMBER
channel += 1

return planes
2 changes: 1 addition & 1 deletion DeepCrazyhouse/src/domain/variants/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@
if VERSION == 1:
NB_CHANNELS_POS = 15
else: # VERSION == 2
NB_CHANNELS_POS = 12 + 1 + 13 # 12 pieces + 1 en-passant and 13 auxiliary
NB_CHANNELS_POS = 12 + 1 + 18 # 13 # 12 pieces + 1 en-passant and 13 auxiliary
if VERSION == 1:
NB_CHANNELS_CONST = 7
else: # VERSION == 2
Expand Down
129 changes: 129 additions & 0 deletions DeepCrazyhouse/src/preprocessing/get_plane_statistics.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Get Plane Statistics (Unit-Test Preparation)\n",
"\n",
"* file: get_plane_statistics.ipynb\n",
"* brief: Allows investigating the board planes and their statistics. These can later be used e.g. for unit-tests.\n",
"\n",
"* author: QueensGambit\n",
"* contact: johannes.czech@cs.tu-darmstadt.de\n",
"* versions:\n",
" * 2021-05-30 initial version"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"%load_ext autoreload\n",
"%autoreload 2\n",
"%reload_ext autoreload"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import sys, os\n",
"sys.path.insert(0,'../../../')\n",
"import os\n",
"import sys\n",
"import chess\n",
"import logging\n",
"from DeepCrazyhouse.src.preprocessing.pgn_to_planes_converter import PGN2PlanesConverter\n",
"from DeepCrazyhouse.src.runtime.color_logger import enable_color_logging\n",
"from DeepCrazyhouse.src.domain.variants.input_representation import board_to_planes, get_planes_statistics\n",
"enable_color_logging()\n",
"logging.getLogger().setLevel(logging.WARNING)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"b = chess.Board(\"r3k1nr/pbp4p/p2p2pb/4P3/3P4/N2q1n2/PPP2PPP/5K1R w kq - 0 14\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"get_planes_statistics(b, True, [])"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"b = chess.Board()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"b.push_uci(\"e2e4\")\n",
"b.push_uci(\"c7c5\")\n",
"b.push_uci(\"d2d3\")\n",
"b.push_uci(\"a7a6\")\n",
"b.push_uci(\"e4e5\")\n",
"b.push_uci(\"d7d5\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"b"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"get_planes_statistics(b, False, [chess.Move.from_uci(\"d7d5\")])"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.6"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
5 changes: 3 additions & 2 deletions engine/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@ if (MODE_CHESS)
project(ClassicAra CXX)
add_definitions(-DMODE_CHESS)
add_definitions(-DMCTS_TB_SUPPORT)
add_definitions(-DVERSION=1)
# add_definitions(-DVERSION=2)
# add_definitions(-DVERSION=1)
add_definitions(-DVERSION=2)
add_definitions(-DSUB_VERSION=8)
endif()

if (MODE_LICHESS)
Expand Down
43 changes: 34 additions & 9 deletions engine/src/environments/chess_related/inputrepresentation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -375,18 +375,31 @@ inline void set_mobility(PlaneData& p, const vector<Action>& legalMoves)
p.set_plane_to_value<true>(p.normalize ? legalMoves.size() / StateConstants::NORMALIZE_MOBILITY() : legalMoves.size());
}

inline void set_opposite_bishops(PlaneData& p) {
inline void set_opposite_bishops(PlaneData& p)
{
if (p.pos->opposite_bishops()) {
p.set_plane_to_one<false>();
}
++p.currentChannel;
}

inline void set_material_count(PlaneData& p)
{
float relativeCount = p.pos->count<PAWN>(p.me());
p.set_plane_to_value<true>(p.normalize ? relativeCount / StateConstants::NORMALIZE_PIECE_NUMBER() : relativeCount);
relativeCount = p.pos->count<KNIGHT>(p.me());
p.set_plane_to_value<true>(p.normalize ? relativeCount / StateConstants::NORMALIZE_PIECE_NUMBER() : relativeCount);
relativeCount = p.pos->count<BISHOP>(p.me());
p.set_plane_to_value<true>(p.normalize ? relativeCount / StateConstants::NORMALIZE_PIECE_NUMBER() : relativeCount);
relativeCount = p.pos->count<ROOK>(p.me());
p.set_plane_to_value<true>(p.normalize ? relativeCount / StateConstants::NORMALIZE_PIECE_NUMBER() : relativeCount);
relativeCount = p.pos->count<QUEEN>(p.me());
p.set_plane_to_value<true>(p.normalize ? relativeCount / StateConstants::NORMALIZE_PIECE_NUMBER() : relativeCount);
}

#ifdef MODE_CHESS
void board_to_planes_v_2_7(const Board *pos, bool normalize, float *inputPlanes, const vector<Action>& legalMoves)
inline void board_to_planes_v_2_7(PlaneData& planeData, const vector<Action>& legalMoves)
{
// Fill in the piece positions
PlaneData planeData(pos, inputPlanes, normalize);
set_plane_pieces(planeData);
set_plane_ep_square(planeData);
assert(planeData.currentChannel == StateConstants::NB_CHANNELS_POS());
Expand All @@ -403,20 +416,32 @@ void board_to_planes_v_2_7(const Board *pos, bool normalize, float *inputPlanes,
set_checkers(planeData);
set_check_moves(planeData, legalMoves);
set_mobility(planeData, legalMoves);
assert(planeData.currentChannel == StateConstants::NB_CHANNELS_TOTAL());
}

inline void board_to_planes_v_2_8(PlaneData& planeData, const vector<Action>& legalMoves)
{
board_to_planes_v_2_7(planeData, legalMoves);
set_material_count(planeData);
}

#endif

void board_to_planes(const Board *pos, size_t boardRepetition, bool normalize, float *inputPlanes, const vector<Action>& legalMoves)
{
#if VERSION == 2
board_to_planes_v_2_7(pos, normalize, inputPlanes, legalMoves);
return;
#endif
// Fill in the piece positions
// Iterate over both color starting with WHITE
PlaneData planeData(pos, inputPlanes, normalize);

#if VERSION == 2
#if SUB_VERSION == 7
board_to_planes_v_2_7(planeData, legalMoves);
#elif SUB_VERSION == 8
board_to_planes_v_2_8(planeData, legalMoves);
#endif
assert(planeData.currentChannel == StateConstants::NB_CHANNELS_TOTAL());
return;
#endif

// (I) Set the pieces for both players
set_plane_pieces(planeData);

Expand Down
Loading