{"spec_id":"chessboard-pieces","library":"altair","language":"python","code":"\"\"\" anyplot.ai\nchessboard-pieces: Chess Board with Pieces for Position Diagrams\nLibrary: altair 6.1.0 | Python 3.13.13\nQuality: 92/100 | Updated: 2026-05-17\n\"\"\"\n\nimport os\nimport sys\n\n\n# Handle import conflict when script is named altair.py\nscript_dir = os.path.dirname(os.path.abspath(__file__))\nsys.path = [p for p in sys.path if os.path.abspath(p) != script_dir and p not in (\"\", \".\")]\n\nimport altair as chart_module\nimport pandas as pd\n\n\n# Theme tokens\nTHEME = os.getenv(\"ANYPLOT_THEME\", \"light\")\nPAGE_BG = \"#FAF8F1\" if THEME == \"light\" else \"#1A1A17\"\nINK = \"#1A1A17\" if THEME == \"light\" else \"#F0EFE8\"\nINK_SOFT = \"#4A4A44\" if THEME == \"light\" else \"#B8B7B0\"\n\n# Chess board squares (standard colors, theme-independent)\nLIGHT_SQUARE = \"#F0D9B5\"\nDARK_SQUARE = \"#B58863\"\nBOARD_BORDER = INK_SOFT\n\n# Unicode chess pieces mapping\nPIECE_SYMBOLS = {\n    \"K\": \"♔\",\n    \"Q\": \"♕\",\n    \"R\": \"♖\",\n    \"B\": \"♗\",\n    \"N\": \"♘\",\n    \"P\": \"♙\",  # White\n    \"k\": \"♚\",\n    \"q\": \"♛\",\n    \"r\": \"♜\",\n    \"b\": \"♝\",\n    \"n\": \"♞\",\n    \"p\": \"♟\",  # Black\n}\n\n# Scholar's Mate position: Famous tactical pattern\npieces = {\n    # White pieces\n    \"a1\": \"R\",\n    \"b1\": \"N\",\n    \"c1\": \"B\",\n    \"d1\": \"Q\",\n    \"e1\": \"K\",\n    \"f1\": \"B\",\n    \"h1\": \"R\",\n    \"a2\": \"P\",\n    \"b2\": \"P\",\n    \"c2\": \"P\",\n    \"d2\": \"P\",\n    \"f2\": \"P\",\n    \"g2\": \"P\",\n    \"h2\": \"P\",\n    \"e4\": \"P\",\n    \"c4\": \"B\",\n    \"h5\": \"Q\",\n    # Black pieces\n    \"a8\": \"r\",\n    \"b8\": \"n\",\n    \"c8\": \"b\",\n    \"d8\": \"q\",\n    \"f8\": \"b\",\n    \"g8\": \"n\",\n    \"h8\": \"r\",\n    \"a7\": \"p\",\n    \"b7\": \"p\",\n    \"c7\": \"p\",\n    \"d7\": \"p\",\n    \"f7\": \"p\",\n    \"g7\": \"p\",\n    \"h7\": \"p\",\n    \"e5\": \"p\",\n    \"f6\": \"n\",\n    \"e7\": \"k\",  # King exposed for checkmate threat\n}\n\n# Create board squares data\nfiles = \"abcdefgh\"\nboard_data = []\nfor col_idx, file in enumerate(files):\n    for row in range(1, 9):\n        square = f\"{file}{row}\"\n        is_light = (col_idx + row) % 2 == 1\n        color = LIGHT_SQUARE if is_light else DARK_SQUARE\n        board_data.append({\"file\": file, \"rank\": str(row), \"color\": color, \"square\": square})\n\nboard_df = pd.DataFrame(board_data)\n\n# Create pieces data - separate white and black for styling\nwhite_pieces_data = []\nblack_pieces_data = []\n\nfor square, piece in pieces.items():\n    file = square[0]\n    rank = square[1]\n    symbol = PIECE_SYMBOLS[piece]\n    is_white = piece.isupper()\n    piece_data = {\"file\": file, \"rank\": rank, \"symbol\": symbol, \"piece\": piece}\n    if is_white:\n        white_pieces_data.append(piece_data)\n    else:\n        black_pieces_data.append(piece_data)\n\nwhite_pieces_df = pd.DataFrame(white_pieces_data)\nblack_pieces_df = pd.DataFrame(black_pieces_data)\n\n# Define ordering for file and rank\nfile_order = list(\"abcdefgh\")\nrank_order = list(\"87654321\")  # Top to bottom in standard chess view\n\n# Create board squares layer\nboard = (\n    chart_module.Chart(board_df)\n    .mark_rect(stroke=BOARD_BORDER, strokeWidth=2)\n    .encode(\n        x=chart_module.X(\n            \"file:N\",\n            sort=file_order,\n            axis=chart_module.Axis(\n                title=None,\n                labelFontSize=28,\n                labelFontWeight=\"bold\",\n                labelColor=INK,\n                orient=\"bottom\",\n                ticks=False,\n                domain=False,\n                labelPadding=12,\n            ),\n        ),\n        y=chart_module.Y(\n            \"rank:N\",\n            sort=rank_order,\n            axis=chart_module.Axis(\n                title=None,\n                labelFontSize=28,\n                labelFontWeight=\"bold\",\n                labelColor=INK,\n                orient=\"left\",\n                ticks=False,\n                domain=False,\n                labelPadding=12,\n            ),\n        ),\n        color=chart_module.Color(\"color:N\", scale=None, legend=None),\n    )\n)\n\n# White pieces with dark outline for visibility\nwhite_pieces = (\n    chart_module.Chart(white_pieces_df)\n    .mark_text(fontSize=70, fontWeight=\"bold\", stroke=\"#2c2c2c\", strokeWidth=1.5)\n    .encode(\n        x=chart_module.X(\"file:N\", sort=file_order),\n        y=chart_module.Y(\"rank:N\", sort=rank_order),\n        text=\"symbol:N\",\n        color=chart_module.value(\"#FAFAFA\"),\n    )\n)\n\n# Black pieces (solid black, clearly visible)\nblack_pieces = (\n    chart_module.Chart(black_pieces_df)\n    .mark_text(fontSize=70, fontWeight=\"bold\")\n    .encode(\n        x=chart_module.X(\"file:N\", sort=file_order),\n        y=chart_module.Y(\"rank:N\", sort=rank_order),\n        text=\"symbol:N\",\n        color=chart_module.value(\"#1a1a1a\"),\n    )\n)\n\n# Combine layers\nchart = (\n    chart_module.layer(board, white_pieces, black_pieces)\n    .properties(\n        width=1000,\n        height=1000,\n        background=PAGE_BG,\n        title=chart_module.Title(\n            \"Scholar's Mate Setup · chessboard-pieces · altair · anyplot.ai\",\n            fontSize=32,\n            anchor=\"middle\",\n            color=INK,\n            offset=20,\n        ),\n    )\n    .configure_view(strokeWidth=4, stroke=BOARD_BORDER, fill=PAGE_BG)\n)\n\n# Save as PNG and HTML (square format: 3600x3600 at scale 3.6)\npng_path = os.path.join(script_dir, f\"plot-{THEME}.png\")\nhtml_path = os.path.join(script_dir, f\"plot-{THEME}.html\")\nchart.save(png_path, scale_factor=3.6)\nchart.save(html_path)\n"}