{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.14","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":86524,"databundleVersionId":9818394,"sourceType":"competition"},{"sourceId":167505,"sourceType":"modelInstanceVersion","modelInstanceId":142488,"modelId":154485}],"dockerImageVersionId":30786,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# **Active Graph Theory: A Revolutionary Approach to Contextual AI**\n\n### **Overview**\nThis notebook is an exploration of **Active Graph Theory (AGT)** and its application in solving complex, context-driven problems. While framed within the context of a chess AI challenge, the principles demonstrated here have far-reaching implications across data science, artificial intelligence, and beyond.\n\n\n\n**Active Graph Theory (AGT)** represents a shift from brute-force and static data analysis to **dynamic, contextual reasoning.** By leveraging principles like **Dynamic Relationship Expansion (DRE)** and **Active Cube Theory**, this framework enables a system to:\n- Dynamically infer relationships without pretraining on massive datasets.\n- Contextualize data in real-time, adapting to evolving environments.\n- Solve problems efficiently by mimicking natural decision-making processes.\n\nThis isn’t just about playing chess—it’s about **redefining how data interacts with logic and inference** in ways that mirror the adaptability of human thought.\n\n---\n\n### **A Unique Process**\nThis notebook may not follow the traditional structure you might expect from a polished machine learning project. Instead, it reflects my **iterative, first-principles approach**:\n- I solve problems by building frameworks from the ground up, not by starting with existing models or theories.\n- My process naturally intersects with broader principles like Einstein’s **Theory of Relativity**, graph theory, and logical structures, but these are **outcomes, not starting points.**\n\nWhile the code and structure may appear unconventional at times, it is a direct representation of my thought process—fueled by experimentation, iteration, and an unrelenting curiosity.\n\n---\n\n### **Why This Matters**\nWhat you’ll see here is not just a chess bot; it’s a demonstration of a universal framework:\n- **Dynamic Contextual Inference**: The bot prioritizes moves based on relationships and real-time game dynamics rather than brute-force simulations.\n- **Transferable Ideas**: The principles applied here can be extended to fields like fraud detection, real-time decision systems, and even physics simulations.\n- **Efficiency at Scale**: AGT does not rely on GPU-intensive training but instead uses structured logic to infer outcomes dynamically.\n\nThe chess bot is simply the beginning—a demonstration of what happens when data, relationships, and context converge in meaningful ways.\n\n---\n\n### **Acknowledgments**\nThis work represents countless hours of iteration, experimentation, and collaboration. While the ideas here are my own, I want to acknowledge the modern tools that have facilitated this journey, including **ChatGPT**, which has acted as a collaborator, bouncing ideas and helping refine this framework.\n\nThis notebook is a testament to what can be achieved when curiosity meets persistence. I hope you enjoy exploring this work as much as I’ve enjoyed creating it.\n\n---\n\n### **A Note on Structure**\nThis notebook might feel unconventional. It wasn’t designed to impress with perfect organization but to showcase the raw process of discovery and problem-solving. Every section reflects my iterative journey—an honest look at how breakthroughs are made.\n\n---\n\n### **Let’s Begin**\nWhat follows is an application of **Active Graph Theory** in the context of a chess AI. Beneath the moves, algorithms, and code is a deeper story of how data can be understood, structured, and leveraged to create systems that think dynamically. Let’s dive in.","metadata":{}},{"cell_type":"code","source":"from IPython.display import HTML\n\n# List of YouTube video URLs\nvideo_urls = [\n \"https://www.youtube.com/embed/YwxHNlEc2hU\", # First video\n \"https://www.youtube.com/embed/_dqUJch3PF8\", # Second video\n \"https://www.youtube.com/embed/noUThX4Tnnk\", # Third video\n \"https://www.youtube.com/embed/AI90-uL5Hf4\" # Fourth video\n]\n\n# Initialize an empty string to hold the HTML\nhtml_content = '
'\n\n# Loop through each video URL and create an iframe for each\nfor url in video_urls:\n html_content += f'
'\n\n# Close the div tag\nhtml_content += '
'\n\n# Display the HTML content\nHTML(html_content)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-22T22:39:01.525720Z","iopub.execute_input":"2024-11-22T22:39:01.526094Z","iopub.status.idle":"2024-11-22T22:39:01.534187Z","shell.execute_reply.started":"2024-11-22T22:39:01.526060Z","shell.execute_reply":"2024-11-22T22:39:01.533143Z"}},"outputs":[{"execution_count":3,"output_type":"execute_result","data":{"text/plain":"","text/html":"




"},"metadata":{}}],"execution_count":3},{"cell_type":"markdown","source":"# FIDE & Google Efficient Chess AI Challenge\n\nWelcome! This notebook will familiarize you with using competition's environment, creating an agent, and submitting your first chess bot!","metadata":{}},{"cell_type":"code","source":"# first let's make sure you have internet enabled\nimport requests\nrequests.get('http://www.google.com',timeout=10).ok","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-21T20:33:27.729299Z","iopub.execute_input":"2024-11-21T20:33:27.729570Z","iopub.status.idle":"2024-11-21T20:33:27.779742Z","shell.execute_reply.started":"2024-11-21T20:33:27.729544Z","shell.execute_reply":"2024-11-21T20:33:27.778778Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"#### If you don't have internet access (it doesn't say \"True\" above)\n1. make sure your account is Phone Verified in [account settings](https://www.kaggle.com/settings)\n2. make sure internet is turned on in Settings -> Turn on internet","metadata":{}},{"cell_type":"code","source":"%%capture\n# ensure we are on the latest version of kaggle-environments\n!pip install --upgrade kaggle-environments","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-21T20:33:27.782738Z","iopub.execute_input":"2024-11-21T20:33:27.783079Z","iopub.status.idle":"2024-11-21T20:33:37.419883Z","shell.execute_reply.started":"2024-11-21T20:33:27.783046Z","shell.execute_reply":"2024-11-21T20:33:37.418502Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Now let's set up the chess environment!\nfrom kaggle_environments import make\nenv = make(\"chess\", debug=True)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-21T20:33:37.421549Z","iopub.execute_input":"2024-11-21T20:33:37.421889Z","iopub.status.idle":"2024-11-21T20:33:37.467042Z","shell.execute_reply.started":"2024-11-21T20:33:37.421857Z","shell.execute_reply":"2024-11-21T20:33:37.465975Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# this should run a game in the environment between two random bots\n# NOTE: each game starts from a randomly selected opening\nresult = env.run([\"random\", \"random\"])\nenv.render(mode=\"ipython\", width=1000, height=1000) ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-21T20:33:37.468833Z","iopub.execute_input":"2024-11-21T20:33:37.469223Z","iopub.status.idle":"2024-11-21T20:33:44.761251Z","shell.execute_reply.started":"2024-11-21T20:33:37.469190Z","shell.execute_reply":"2024-11-21T20:33:44.760235Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### Creating your first agent\nNow let's create your first agent! The environment has the [Chessnut](https://github.com/cgearhart/Chessnut) pip package installed and we'll use that to parse the board state and generate moves.","metadata":{}},{"cell_type":"code","source":"%%writefile main.py\nfrom Chessnut import Game\nimport random\n\n# Piece values for material evaluation\nPIECE_VALUES = {\n \"p\": 1, \"n\": 3, \"b\": 3, \"r\": 5, \"q\": 9, \"k\": 0,\n \"P\": -1, \"N\": -3, \"B\": -3, \"R\": -5, \"Q\": -9, \"K\": 0\n}\n\nCENTER_SQUARES = {\"d4\", \"d5\", \"e4\", \"e5\"}\n\ndef debug(message):\n \"\"\"\n Utility function for debugging.\n \"\"\"\n print(f\"DEBUG: {message}\")\n\ndef prioritize_moves(game, moves):\n \"\"\"\n Prioritize moves based on first principles.\n \"\"\"\n prioritized_moves = []\n\n for move in moves:\n piece = game.board.get_piece(Game.xy2i(move[:2]))\n target_square = move[2:4]\n target_piece = game.board.get_piece(Game.xy2i(target_square))\n\n # Checkmate moves (highest priority)\n g = Game(game.get_fen())\n g.apply_move(move)\n if g.status == Game.CHECKMATE:\n debug(f\"Checkmate move found: {move}\")\n return [move]\n\n # Captures (next priority)\n if target_piece != ' ':\n debug(f\"Capture move: {move}, Captures: {target_piece}\")\n prioritized_moves.append((move, 3 + PIECE_VALUES.get(target_piece.lower(), 0)))\n\n # Central control (medium priority)\n elif target_square in CENTER_SQUARES:\n debug(f\"Central control move: {move}\")\n prioritized_moves.append((move, 2))\n\n # Development of knights and bishops (early-game priority)\n elif piece.lower() in {'n', 'b'}:\n debug(f\"Development move: {move}\")\n prioritized_moves.append((move, 1))\n\n # Default: Other moves (low priority)\n else:\n prioritized_moves.append((move, 0))\n\n # Sort moves by priority (descending)\n prioritized_moves.sort(key=lambda x: x[1], reverse=True)\n return [move for move, _ in prioritized_moves]\n\ndef chess_bot(obs):\n \"\"\"\n Simple chess bot using first principles logic.\n \"\"\"\n game = Game(obs.board)\n moves = list(game.get_moves())\n\n if not moves:\n return None # No legal moves available\n\n # Prioritize moves based on first principles\n prioritized_moves = prioritize_moves(game, moves)\n\n # Pick the best move (highest priority)\n best_move = prioritized_moves[0] if prioritized_moves else random.choice(moves)\n debug(f\"Best move selected: {best_move}\")\n return best_move\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-21T20:33:44.762362Z","iopub.execute_input":"2024-11-21T20:33:44.762654Z","iopub.status.idle":"2024-11-21T20:33:44.769860Z","shell.execute_reply.started":"2024-11-21T20:33:44.762626Z","shell.execute_reply":"2024-11-21T20:33:44.768782Z"},"jupyter":{"source_hidden":true}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"%%writefile main.py\nfrom Chessnut import Game\nimport random\n\n# Piece values for material evaluation\nPIECE_VALUES = {\n \"p\": 1, \"n\": 3, \"b\": 3, \"r\": 5, \"q\": 9, \"k\": 0,\n \"P\": -1, \"N\": -3, \"B\": -3, \"R\": -5, \"Q\": -9, \"K\": 0\n}\n\nCENTER_SQUARES = {\"d4\", \"d5\", \"e4\", \"e5\"}\nOPEN_FILE_BONUS = 1 # Bonus for controlling open files\nKING_SAFETY_BONUS = 2 # Bonus for moves protecting the king\nPAWN_PROMOTION_BONUS = 10 # Bonus for promoting pawns\n\n# Dynamic weights for different phases of the game\nDYNAMIC_WEIGHTS = {\n \"early_game\": {\"center_control\": 2, \"development\": 3, \"captures\": 1},\n \"mid_game\": {\"center_control\": 1, \"development\": 2, \"captures\": 3},\n \"end_game\": {\"center_control\": 1, \"development\": 1, \"captures\": 5, \"king_safety\": 3},\n}\n\ndef get_game_phase(game):\n \"\"\"\n Determine the phase of the game based on material and move count.\n \"\"\"\n material_count = sum(abs(PIECE_VALUES[piece.lower()]) for piece in game.board.get_board().values() if piece != \" \")\n if material_count > 20:\n return \"early_game\"\n elif material_count > 10:\n return \"mid_game\"\n else:\n return \"end_game\"\n\ndef debug(message):\n \"\"\"\n Utility function for debugging.\n \"\"\"\n print(f\"DEBUG: {message}\")\n\ndef prioritize_moves(game, moves):\n \"\"\"\n Prioritize moves based on first principles and dynamic adjustments.\n \"\"\"\n prioritized_moves = []\n game_phase = get_game_phase(game)\n weights = DYNAMIC_WEIGHTS[game_phase]\n\n for move in moves:\n piece = game.board.get_piece(Game.xy2i(move[:2]))\n target_square = move[2:4]\n target_piece = game.board.get_piece(Game.xy2i(target_square))\n\n score = 0\n\n # Checkmate moves (highest priority)\n g = Game(game.get_fen())\n g.apply_move(move)\n if g.status == Game.CHECKMATE:\n debug(f\"Checkmate move found: {move}\")\n return [move]\n\n # Captures (weighted by phase)\n if target_piece != ' ':\n score += weights[\"captures\"] + PIECE_VALUES.get(target_piece.lower(), 0)\n\n # Central control\n if target_square in CENTER_SQUARES:\n score += weights[\"center_control\"]\n\n # Development of knights and bishops (early-game priority)\n if piece.lower() in {'n', 'b'}:\n score += weights[\"development\"]\n\n # King safety (endgame focus)\n if game_phase == \"end_game\" and (piece.lower() == 'k' or target_square in {\"g1\", \"g8\", \"c1\", \"c8\"}):\n score += KING_SAFETY_BONUS\n\n # Pawn promotion (endgame priority)\n if piece.lower() == 'p' and target_square[1] in {\"1\", \"8\"}: # Promotion rank\n score += PAWN_PROMOTION_BONUS\n\n # Default scoring for all moves\n prioritized_moves.append((move, score))\n\n # Sort moves by priority (descending)\n prioritized_moves.sort(key=lambda x: x[1], reverse=True)\n return [move for move, _ in prioritized_moves]\n\ndef predict_opponent_move(game, moves):\n \"\"\"\n Predict the opponent's best response to our moves by simulating each.\n \"\"\"\n opponent_scores = []\n for move in moves:\n g = Game(game.get_fen())\n g.apply_move(move)\n opponent_moves = list(g.get_moves())\n if opponent_moves:\n opponent_scores.append(min(prioritize_moves(g, opponent_moves), key=lambda x: PIECE_VALUES.get(g.board.get_piece(Game.xy2i(x[2:4])).lower(), 0)))\n return opponent_scores\n\ndef chess_bot(obs):\n \"\"\"\n Chess bot using dynamic evaluation and predictions.\n \"\"\"\n game = Game(obs.board)\n moves = list(game.get_moves())\n\n if not moves:\n return None # No legal moves available\n\n # Prioritize moves\n prioritized_moves = prioritize_moves(game, moves)\n\n # Predict opponent moves and adjust based on anticipated threats\n if len(prioritized_moves) > 1:\n predicted_responses = predict_opponent_move(game, prioritized_moves[:5]) # Analyze top 5 moves\n for i, move in enumerate(prioritized_moves[:5]):\n if predicted_responses[i]: # Adjust priority to avoid moves leading to losses\n prioritized_moves[i] = (move, prioritized_moves[i][1] - PIECE_VALUES.get(game.board.get_piece(Game.xy2i(predicted_responses[i][2:4])).lower(), 0))\n\n # Sort moves after considering predictions\n prioritized_moves.sort(key=lambda x: x[1], reverse=True)\n\n # Pick the best move\n best_move = prioritized_moves[0][0] if prioritized_moves else random.choice(moves)\n debug(f\"Best move selected: {best_move}\")\n return best_move\n\n## v2\n\nfrom Chessnut import Game\nimport random\n\n# Piece values for material evaluation\nPIECE_VALUES = {\n \"p\": 1, \"n\": 3, \"b\": 3, \"r\": 5, \"q\": 9, \"k\": 0,\n \"P\": -1, \"N\": -3, \"B\": -3, \"R\": -5, \"Q\": -9, \"K\": 0\n}\n\nCENTER_SQUARES = {\"d4\", \"d5\", \"e4\", \"e5\"}\n\ndef debug(message):\n \"\"\"Utility function for debugging.\"\"\"\n print(f\"DEBUG: {message}\")\n\ndef get_game_phase(game):\n \"\"\"\n Determine the game phase based on material count.\n Early game: High material.\n Mid game: Medium material.\n End game: Low material.\n \"\"\"\n fen = game.get_fen() # Retrieve FEN string\n board_state = fen.split()[0] # The first part of FEN represents the board\n material_count = 0\n\n for char in board_state:\n if char.isalpha(): # If it's a piece\n material_count += abs(PIECE_VALUES[char.lower()])\n\n if material_count > 30:\n return \"early\"\n elif 15 < material_count <= 30:\n return \"mid\"\n else:\n return \"end\"\n\ndef prioritize_moves(game, moves):\n \"\"\"Prioritize moves based on first principles and game phase.\"\"\"\n game_phase = get_game_phase(game) # Fix applied here\n prioritized_moves = []\n\n for move in moves:\n piece = game.board.get_piece(Game.xy2i(move[:2]))\n target_square = move[2:4]\n target_piece = game.board.get_piece(Game.xy2i(target_square))\n\n # Checkmate moves (highest priority)\n g = Game(game.get_fen())\n g.apply_move(move)\n if g.status == Game.CHECKMATE:\n debug(f\"Checkmate move found: {move}\")\n return [move]\n\n # Captures (next priority)\n if target_piece != ' ':\n debug(f\"Capture move: {move}, Captures: {target_piece}\")\n prioritized_moves.append((move, 3 + PIECE_VALUES.get(target_piece.lower(), 0)))\n\n # Central control (medium priority)\n elif target_square in CENTER_SQUARES:\n debug(f\"Central control move: {move}\")\n prioritized_moves.append((move, 2))\n\n # Development of knights and bishops (early-game priority)\n elif piece.lower() in {'n', 'b'}:\n debug(f\"Development move: {move}\")\n prioritized_moves.append((move, 1))\n\n # Default: Other moves (low priority)\n else:\n prioritized_moves.append((move, 0))\n\n # Sort moves by priority (descending)\n prioritized_moves.sort(key=lambda x: x[1], reverse=True)\n return [move for move, _ in prioritized_moves]\n\n\n\ndef prioritize_moves(game, moves):\n \"\"\"Prioritize moves based on first principles and game phase.\"\"\"\n game_phase = get_game_phase(game)\n prioritized_moves = []\n\n for move in moves:\n piece = game.board.get_piece(Game.xy2i(move[:2]))\n target_square = move[2:4]\n target_piece = game.board.get_piece(Game.xy2i(target_square))\n\n # Checkmate moves (highest priority)\n g = Game(game.get_fen())\n g.apply_move(move)\n if g.status == Game.CHECKMATE:\n debug(f\"Checkmate move found: {move}\")\n return [move]\n\n # Endgame: Aggressively target the king\n if game_phase == \"end\":\n if g.status == Game.CHECK:\n debug(f\"Check move in endgame: {move}\")\n prioritized_moves.append((move, 5)) # Prioritize checks\n elif target_piece == 'K': # Target the king\n debug(f\"King-targeting move: {move}\")\n prioritized_moves.append((move, 4))\n else:\n prioritized_moves.append((move, 0)) # Penalize irrelevant moves\n continue\n\n # Captures (high priority)\n if target_piece != ' ':\n debug(f\"Capture move: {move}, Captures: {target_piece}\")\n prioritized_moves.append((move, 3 + PIECE_VALUES.get(target_piece.lower(), 0)))\n\n # Central control (medium priority)\n elif target_square in CENTER_SQUARES:\n debug(f\"Central control move: {move}\")\n prioritized_moves.append((move, 2))\n\n # Development of knights and bishops (early-game priority)\n elif piece.lower() in {'n', 'b'}:\n debug(f\"Development move: {move}\")\n prioritized_moves.append((move, 1))\n\n # Default: Other moves (low priority)\n else:\n prioritized_moves.append((move, 0))\n\n # Sort moves by priority (descending)\n prioritized_moves.sort(key=lambda x: x[1], reverse=True)\n return [move for move, _ in prioritized_moves]\n\n# Encourage king centralization and safety in the endgame\nif game_phase == \"end\" and piece.lower() == 'k':\n if target_square in CENTER_SQUARES:\n debug(f\"King centralization move: {move}\")\n prioritized_moves.append((move, 2))\n else:\n prioritized_moves.append((move, 0)) # Avoid irrelevant king moves\n\n# Encourage pawn promotion in the endgame\nif piece.lower() == 'p':\n rank = int(target_square[1])\n if (rank == 8 and piece.islower()) or (rank == 1 and piece.isupper()):\n debug(f\"Pawn promotion move: {move}\")\n prioritized_moves.append((move, 10)) # High priority for promotion\n elif game_phase == \"end\" and abs(rank - int(move[1])) == 1:\n debug(f\"Pawn advancing move: {move}\")\n prioritized_moves.append((move, 2)) # Encourage pawn advancement\n\ndef chess_bot(obs):\n \"\"\"Simple chess bot using first principles logic.\"\"\"\n game = Game(obs.board)\n moves = list(game.get_moves())\n\n if not moves:\n return None # No legal moves available\n\n # Prioritize moves based on first principles\n prioritized_moves = prioritize_moves(game, moves)\n\n # Pick the best move (highest priority)\n best_move = prioritized_moves[0] if prioritized_moves else random.choice(moves)\n debug(f\"Best move selected: {best_move}\")\n return best_move","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-21T20:33:44.771445Z","iopub.execute_input":"2024-11-21T20:33:44.771965Z","iopub.status.idle":"2024-11-21T20:33:44.789010Z","shell.execute_reply.started":"2024-11-21T20:33:44.771909Z","shell.execute_reply":"2024-11-21T20:33:44.787912Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"%%writefile main.py\nfrom Chessnut import Game\nimport random\nimport logging\n\n# Configure Debugging and Logging\nDEBUG = True\nlogging.basicConfig(level=logging.DEBUG if DEBUG else logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')\n\ndef debug(message):\n \"\"\"Utility function for debugging.\"\"\"\n if DEBUG:\n logging.debug(message)\n\n# Constants\nPIECE_VALUES = {\n \"p\": 1, \"n\": 3, \"b\": 3, \"r\": 5, \"q\": 9, \"k\": 0,\n \"P\": -1, \"N\": -3, \"B\": -3, \"R\": -5, \"Q\": -9, \"K\": 0\n}\nCENTER_SQUARES = {\"d4\", \"d5\", \"e4\", \"e5\"}\n\ndef load_weights():\n \"\"\"Load weights for move prioritization.\"\"\"\n # Optional: Extend with dynamic learning\n return {\"central_control\": 3, \"captures\": 5, \"check\": 10, \"promotion\": 15}\n\nWEIGHTS = load_weights()\n\ndef parse_board_from_fen(fen):\n \"\"\"\n Parse the board from the FEN string into a dictionary representation.\n Returns a dictionary where keys are square names (e.g., \"a1\") and values are pieces (e.g., \"P\", \"r\").\n \"\"\"\n rows = fen.split()[0].split(\"/\")\n board = {}\n for rank_idx, row in enumerate(rows):\n file_idx = 0\n for char in row:\n if char.isdigit():\n file_idx += int(char) # Skip empty squares\n else:\n square = f\"{chr(file_idx + ord('a'))}{8 - rank_idx}\"\n board[square] = char\n file_idx += 1\n return board\n\ndef get_game_phase(game):\n \"\"\"\n Determine the game phase: opening, midgame, or endgame.\n Based on material count.\n \"\"\"\n fen = game.get_fen()\n board = parse_board_from_fen(fen)\n material_count = sum(abs(PIECE_VALUES[piece.lower()]) for piece in board.values() if piece != \" \")\n if material_count > 30:\n return \"opening\"\n elif 20 < material_count <= 30:\n return \"midgame\"\n else:\n return \"end\"\n\ndef prioritize_moves(game, moves):\n \"\"\"\n Prioritize moves based on first principles and game phase.\n \"\"\"\n game_phase = get_game_phase(game)\n prioritized_moves = []\n\n for move in moves:\n piece = game.board.get_piece(Game.xy2i(move[:2]))\n target_square = move[2:4]\n target_piece = game.board.get_piece(Game.xy2i(target_square))\n\n # Checkmate moves (highest priority)\n g = Game(game.get_fen())\n g.apply_move(move)\n if g.status == Game.CHECKMATE:\n debug(f\"Checkmate move found: {move}\")\n return [move]\n\n # Endgame: Aggressively target the king\n if game_phase == \"end\":\n if g.status == Game.CHECK:\n debug(f\"Check move in endgame: {move}\")\n prioritized_moves.append((move, WEIGHTS[\"check\"]))\n elif target_piece == 'K': # Target the king\n debug(f\"King-targeting move: {move}\")\n prioritized_moves.append((move, WEIGHTS[\"check\"]))\n continue\n\n # Captures (high priority)\n if target_piece != ' ':\n debug(f\"Capture move: {move}, Captures: {target_piece}\")\n prioritized_moves.append((move, WEIGHTS[\"captures\"] + PIECE_VALUES.get(target_piece.lower(), 0)))\n\n # Central control (medium priority)\n elif target_square in CENTER_SQUARES:\n debug(f\"Central control move: {move}\")\n prioritized_moves.append((move, WEIGHTS[\"central_control\"]))\n\n # Development of knights and bishops (early-game priority)\n elif piece.lower() in {'n', 'b'}:\n debug(f\"Development move: {move}\")\n prioritized_moves.append((move, 1))\n\n # Pawn promotion (endgame priority)\n elif piece.lower() == 'p':\n rank = int(target_square[1])\n if (rank == 8 and piece.islower()) or (rank == 1 and piece.isupper()):\n debug(f\"Pawn promotion move: {move}\")\n prioritized_moves.append((move, WEIGHTS[\"promotion\"]))\n\n # Default: Other moves (low priority)\n else:\n prioritized_moves.append((move, 0))\n\n # Sort moves by priority (descending)\n prioritized_moves.sort(key=lambda x: x[1], reverse=True)\n return [move for move, _ in prioritized_moves]\n\ndef chess_bot(obs):\n \"\"\"\n Enhanced chess bot using prioritized move evaluation.\n \"\"\"\n game = Game(obs.board)\n moves = list(game.get_moves())\n\n if not moves:\n return None # No legal moves available\n\n # Prioritize moves based on first principles\n prioritized_moves = prioritize_moves(game, moves)\n\n # Pick the best move (highest priority)\n best_move = prioritized_moves[0] if prioritized_moves else random.choice(moves)\n debug(f\"Best move selected: {best_move}\")\n return best_move\n\n# Testing the bot\nif __name__ == \"__main__\":\n from kaggle_environments import make\n\n env = make(\"chess\", debug=True)\n\n # Test bot against random agent\n result = env.run([\"main.py\", \"random\"])\n print(\"Agent exit status/reward/time left: \")\n for agent in result[-1]:\n print(\"\\t\", agent.status, \"/\", agent.reward, \"/\", agent.observation.remainingOverageTime)\n print(\"\\n\")\n # Render the game\n env.render(mode=\"ipython\", width=1000, height=1000)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-21T20:33:44.790417Z","iopub.execute_input":"2024-11-21T20:33:44.790767Z","iopub.status.idle":"2024-11-21T20:33:44.803728Z","shell.execute_reply.started":"2024-11-21T20:33:44.790737Z","shell.execute_reply":"2024-11-21T20:33:44.802716Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"%%writefile main.py\nfrom Chessnut import Game\nimport random\nimport logging\n\n# Configure Debugging and Logging\nDEBUG = True\nlogging.basicConfig(level=logging.DEBUG if DEBUG else logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')\n\ndef debug(message):\n \"\"\"Utility function for debugging.\"\"\"\n if DEBUG:\n logging.debug(message)\n\n# Constants\nPIECE_VALUES = {\n \"p\": 1, \"n\": 3, \"b\": 3, \"r\": 5, \"q\": 9, \"k\": 0,\n \"P\": -1, \"N\": -3, \"B\": -3, \"R\": -5, \"Q\": -9, \"K\": 0\n}\nCENTER_SQUARES = {\"d4\", \"d5\", \"e4\", \"e5\"}\nCORNER_SQUARES = {\"a1\", \"h1\", \"a8\", \"h8\"}\n\ndef king_seeks_cover(board, king_square, enemy_attacks, friendly_pieces):\n \"\"\"\n Guides the king toward safer squares.\n \"\"\"\n # Generate potential king moves\n possible_moves = []\n file, rank = king_square[0], int(king_square[1])\n\n for file_offset in [-1, 0, 1]:\n for rank_offset in [-1, 0, 1]:\n if file_offset == 0 and rank_offset == 0:\n continue # Skip current square\n target_file = chr(ord(file) + file_offset)\n target_rank = str(rank + rank_offset)\n target_square = f\"{target_file}{target_rank}\"\n if target_square in board: # Ensure valid square\n possible_moves.append(target_square)\n\n # Filter moves for safety\n safe_moves = [\n move for move in possible_moves\n if move not in enemy_attacks and move not in friendly_pieces\n ]\n\n # Prioritize moves near board edges or corners\n prioritized_moves = sorted(\n safe_moves,\n key=lambda sq: (\n sq in CORNER_SQUARES, # Prefer corners\n sq[0] in \"ah\" or sq[1] in \"18\" # Prefer edges\n ),\n reverse=True,\n )\n return prioritized_moves\n\n\ndef load_weights():\n \"\"\"Load weights for move prioritization.\"\"\"\n return {\"central_control\": 3, \"captures\": 5, \"check\": 10, \"promotion\": 15, \"cornering\": 10}\n\nWEIGHTS = load_weights()\n\ndef parse_board_from_fen(fen):\n \"\"\"Parse the board from the FEN string into a dictionary representation.\"\"\"\n rows = fen.split()[0].split(\"/\")\n board = {}\n for rank_idx, row in enumerate(rows):\n file_idx = 0\n for char in row:\n if char.isdigit():\n file_idx += int(char) # Skip empty squares\n else:\n square = f\"{chr(file_idx + ord('a'))}{8 - rank_idx}\"\n board[square] = char\n file_idx += 1\n return board\n\ndef get_opponent_king_position(board, player):\n \"\"\"Get the position of the opponent's king.\"\"\"\n king = \"k\" if player == \"w\" else \"K\"\n for square, piece in board.items():\n if piece == king:\n return square\n return None\n\ndef is_adjacent(square1, square2):\n \"\"\"Check if two squares are adjacent.\"\"\"\n file_diff = abs(ord(square1[0]) - ord(square2[0]))\n rank_diff = abs(int(square1[1]) - int(square2[1]))\n return max(file_diff, rank_diff) == 1\n\ndef get_game_phase(game):\n \"\"\"Determine the game phase: opening, midgame, or endgame.\"\"\"\n fen = game.get_fen()\n board = parse_board_from_fen(fen)\n material_count = sum(abs(PIECE_VALUES[piece.lower()]) for piece in board.values() if piece != \" \")\n if material_count > 20:\n return \"opening\"\n elif 10 < material_count <= 20:\n return \"midgame\"\n else:\n return \"end\"\n\ndef prioritize_moves(game, moves):\n \"\"\"Prioritize moves based on first principles and game phase.\"\"\"\n game_phase = get_game_phase(game)\n fen = game.get_fen()\n board = parse_board_from_fen(fen)\n player = \"w\" if fen.split()[1] == \"w\" else \"b\"\n opponent_king = get_opponent_king_position(board, player)\n prioritized_moves = []\n score = WEIGHTS[\"central_control\"]\n score += apply_decay(move) # Apply decay to move score\n prioritized_moves.append((move, score))\n\n\n for move in moves:\n piece = board.get(move[:2], \" \")\n target_square = move[2:4]\n target_piece = board.get(target_square, \" \")\n\n # Checkmate moves (highest priority)\n g = Game(game.get_fen())\n g.apply_move(move)\n if g.status == Game.CHECKMATE:\n debug(f\"Checkmate move found: {move}\")\n return [move]\n\n # Endgame: Corner the opponent king\n # Endgame: Corner the opponent king or defend friendly king\n # Endgame: Focus on restricting the opponent king\n if phase == \"endgame\" and opponent_king_pos:\n if is_adjacent(end_square, opponent_king_pos):\n debug(f\"Restricting king mobility: {move}\")\n score = 5 + apply_decay(move) # Boost for restricting king\n prioritized_moves.append((move, score))\n elif end_square in KING_ACTIVITY_SQUARES:\n debug(f\"Controlling key square near king: {move}\")\n score = 3 + apply_decay(move)\n prioritized_moves.append((move, score))\n\n # Seek cover for the friendly king\n cover_moves = king_seeks_cover(board, friendly_king, enemy_attacks, list(board.keys()))\n if cover_moves:\n for move in moves:\n if move[2:4] in cover_moves:\n debug(f\"King seeking cover: {move}\")\n prioritized_moves.append((move, WEIGHTS[\"check\"]))\n continue\n \n # Restrict opponent king\n if opponent_king:\n if is_adjacent(target_square, opponent_king):\n debug(f\"Restricting king's mobility: {move}\")\n prioritized_moves.append((move, WEIGHTS[\"check\"]))\n elif target_square in CORNER_SQUARES:\n debug(f\"Driving king to corner: {move}\")\n prioritized_moves.append((move, WEIGHTS[\"cornering\"]))\n continue\n\n # Captures (high priority)\n if target_piece != \" \":\n debug(f\"Capture move: {move}, Captures: {target_piece}\")\n prioritized_moves.append((move, WEIGHTS[\"captures\"] + PIECE_VALUES.get(target_piece.lower(), 0)))\n\n # Central control (medium priority)\n elif target_square in CENTER_SQUARES:\n debug(f\"Central control move: {move}\")\n prioritized_moves.append((move, WEIGHTS[\"central_control\"]))\n\n # Default: Other moves (low priority)\n else:\n prioritized_moves.append((move, 0))\n\n # Sort moves by priority (descending)\n prioritized_moves.sort(key=lambda x: x[1], reverse=True)\n return [move for move, _ in prioritized_moves]\n\n# Initialize decay counter (global or in bot state)\nMOVE_HISTORY = {}\n\ndef apply_decay(move):\n \"\"\"Apply a decay factor to repetitive moves.\"\"\"\n if move in MOVE_HISTORY:\n MOVE_HISTORY[move] += 1\n else:\n MOVE_HISTORY[move] = 1\n return max(0, 10 - MOVE_HISTORY[move]) # Reduce score based on repetition\n\n\ndef chess_bot(obs):\n \"\"\"Chess bot using advanced logic with decay and dynamic phases.\"\"\"\n fen = obs['board']\n game = Game(fen)\n moves = list(game.get_moves())\n\n if not moves:\n return None # No legal moves available\n\n # Convert FEN to board representation\n board = fen_to_board(game.get_fen())\n\n # Determine game phase\n white_pieces, black_pieces = count_pieces(board)\n game_phase = determine_game_phase(white_pieces, black_pieces)\n\n # Prioritize moves dynamically\n prioritized_moves = prioritize_moves(game, moves, game_phase, board)\n\n # Pick the best move\n best_move = prioritized_moves[0] if prioritized_moves else random.choice(moves)\n debug(f\"Best move selected: {best_move}\")\n return best_move\n\n\n# Testing the bot\nif __name__ == \"__main__\":\n from kaggle_environments import make\n\n env = make(\"chess\", debug=True)\n\n # Test bot against random agent\n result = env.run([\"main.py\", \"random\"])\n print(\"Agent exit status/reward/time left: \")\n for agent in result[-1]:\n print(\"\\t\", agent.status, \"/\", agent.reward, \"/\", agent.observation.remainingOverageTime)\n print(\"\\n\")\n # Render the game\n env.render(mode=\"ipython\", width=1000, height=1000)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-21T20:33:44.805201Z","iopub.execute_input":"2024-11-21T20:33:44.805526Z","iopub.status.idle":"2024-11-21T20:33:44.822995Z","shell.execute_reply.started":"2024-11-21T20:33:44.805490Z","shell.execute_reply":"2024-11-21T20:33:44.821843Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"%%writefile main.py\nfrom Chessnut import Game\nimport random\nimport logging\n\n# Configure Debugging and Logging\nDEBUG = True\nlogging.basicConfig(level=logging.DEBUG if DEBUG else logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')\n\ndef debug(message):\n \"\"\"Utility function for debugging.\"\"\"\n if DEBUG:\n logging.debug(message)\n\n# Constants\nPIECE_VALUES = {\n \"p\": 1, \"n\": 3, \"b\": 3, \"r\": 5, \"q\": 9, \"k\": 0,\n \"P\": -1, \"N\": -3, \"B\": -3, \"R\": -5, \"Q\": -9, \"K\": 0\n}\nCENTER_SQUARES = {\"d4\", \"d5\", \"e4\", \"e5\"}\nCORNER_SQUARES = {\"a1\", \"h1\", \"a8\", \"h8\"}\nKING_ACTIVITY_SQUARES = {\"c4\", \"c5\", \"d3\", \"d6\", \"e3\", \"e6\", \"f4\", \"f5\"}\n\n# Global decay tracking\nMOVE_HISTORY = {}\n\n# Define weights for move prioritization\nWEIGHTS = {\n \"central_control\": 3,\n \"captures\": 5,\n \"check\": 10,\n \"promotion\": 15,\n \"cornering\": 10\n}\n\ndef apply_decay(move):\n \"\"\"Apply a decay factor to repetitive moves.\"\"\"\n if move in MOVE_HISTORY:\n MOVE_HISTORY[move] += 1\n else:\n MOVE_HISTORY[move] = 1\n return max(0, 10 - MOVE_HISTORY[move]) # Reduce score for repetitive moves\n\ndef fen_to_board(fen):\n \"\"\"Convert FEN string to a board representation.\"\"\"\n rows = fen.split()[0].split(\"/\")\n board = {}\n for rank_idx, row in enumerate(rows):\n file_idx = 0\n for char in row:\n if char.isdigit():\n file_idx += int(char) # Empty squares\n else:\n square = f\"{chr(file_idx + ord('a'))}{8 - rank_idx}\"\n board[square] = char\n file_idx += 1\n return board\n\ndef get_opponent_king_position(board, player):\n \"\"\"Find the opponent king's position.\"\"\"\n king = \"k\" if player == \"w\" else \"K\"\n for square, piece in board.items():\n if piece == king:\n return square\n return None\n\ndef is_adjacent(square1, square2):\n \"\"\"Check if two squares are adjacent.\"\"\"\n file_diff = abs(ord(square1[0]) - ord(square2[0]))\n rank_diff = abs(int(square1[1]) - int(square2[1]))\n return max(file_diff, rank_diff) == 1\n\ndef king_seeks_cover(board, king_square, enemy_attacks, friendly_pieces):\n \"\"\"Direct the king to safer squares.\"\"\"\n possible_moves = []\n file, rank = king_square[0], int(king_square[1])\n for file_offset in [-1, 0, 1]:\n for rank_offset in [-1, 0, 1]:\n if file_offset == 0 and rank_offset == 0:\n continue\n target_file = chr(ord(file) + file_offset)\n target_rank = str(rank + rank_offset)\n target_square = f\"{target_file}{target_rank}\"\n if target_square in board:\n possible_moves.append(target_square)\n safe_moves = [\n move for move in possible_moves\n if move not in enemy_attacks and move not in friendly_pieces\n ]\n prioritized_moves = sorted(\n safe_moves,\n key=lambda sq: (\n sq in CORNER_SQUARES,\n sq[0] in \"ah\" or sq[1] in \"18\"\n ),\n reverse=True,\n )\n return prioritized_moves\n\ndef determine_game_phase(board):\n \"\"\"Determine game phase based on material count.\"\"\"\n material_count = sum(abs(PIECE_VALUES[piece.lower()]) for piece in board.values() if piece != \" \")\n if material_count > 20:\n return \"opening\"\n elif 10 < material_count <= 20:\n return \"midgame\"\n else:\n return \"endgame\"\n\ndef prioritize_moves(game, moves, phase, board):\n \"\"\"Prioritize moves dynamically based on game phase.\"\"\"\n prioritized_moves = []\n player = \"w\" if game.get_fen().split()[1] == \"w\" else \"b\"\n opponent_king = get_opponent_king_position(board, player)\n \n for move in moves:\n start_square = move[:2]\n end_square = move[2:4]\n piece = board.get(start_square, \" \")\n target_piece = board.get(end_square, \" \")\n\n # Checkmate moves\n g = Game(game.get_fen())\n g.apply_move(move)\n if g.status == Game.CHECKMATE:\n debug(f\"Checkmate move: {move}\")\n return [move]\n\n # Endgame: Restrict opponent king or defend friendly king\n if phase == \"endgame\" and opponent_king:\n if is_adjacent(end_square, opponent_king):\n debug(f\"Restricting opponent king: {move}\")\n score = 5 + apply_decay(move)\n prioritized_moves.append((move, score))\n elif end_square in KING_ACTIVITY_SQUARES:\n debug(f\"Targeting key square: {move}\")\n score = 3 + apply_decay(move)\n prioritized_moves.append((move, score))\n continue\n\n # Captures\n if target_piece != \" \":\n debug(f\"Capture: {move}, capturing {target_piece}\")\n score = WEIGHTS[\"captures\"] + PIECE_VALUES.get(target_piece.lower(), 0)\n prioritized_moves.append((move, score))\n continue\n\n # Central control\n if end_square in CENTER_SQUARES:\n debug(f\"Central control: {move}\")\n score = WEIGHTS[\"central_control\"]\n prioritized_moves.append((move, score))\n continue\n\n # Default moves\n score = apply_decay(move)\n prioritized_moves.append((move, score))\n\n prioritized_moves.sort(key=lambda x: x[1], reverse=True)\n return [move for move, _ in prioritized_moves]\n\ndef chess_bot(obs):\n \"\"\"Dynamic chess bot with prioritization.\"\"\"\n fen = obs['board']\n game = Game(fen)\n moves = list(game.get_moves())\n\n if not moves:\n return None\n\n board = fen_to_board(fen)\n phase = determine_game_phase(board)\n debug(f\"Game phase: {phase}\")\n\n prioritized_moves = prioritize_moves(game, moves, phase, board)\n best_move = prioritized_moves[0] if prioritized_moves else random.choice(moves)\n debug(f\"Best move: {best_move}\")\n return best_move\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-21T20:33:44.824720Z","iopub.execute_input":"2024-11-21T20:33:44.825317Z","iopub.status.idle":"2024-11-21T20:33:44.841435Z","shell.execute_reply.started":"2024-11-21T20:33:44.825271Z","shell.execute_reply":"2024-11-21T20:33:44.840294Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"%%writefile main.py\nfrom Chessnut import Game\nimport random\nimport logging\n\n# Configure Debugging and Logging\nDEBUG = True\nlogging.basicConfig(level=logging.DEBUG if DEBUG else logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')\n\ndef debug(message):\n \"\"\"Utility function for debugging.\"\"\"\n if DEBUG:\n logging.debug(message)\n\n# Constants\nPIECE_VALUES = {\n \"p\": 1, \"n\": 3, \"b\": 3, \"r\": 5, \"q\": 9, \"k\": 0,\n \"P\": -1, \"N\": -3, \"B\": -3, \"R\": -5, \"Q\": -9, \"K\": 0\n}\nCENTER_SQUARES = {\"d4\", \"d5\", \"e4\", \"e5\"}\nCORNER_SQUARES = {\"a1\", \"h1\", \"a8\", \"h8\"}\nKING_ACTIVITY_SQUARES = {\"c4\", \"c5\", \"d3\", \"d6\", \"e3\", \"e6\", \"f4\", \"f5\"}\n\n# Define weights for move prioritization\nWEIGHTS = {\n \"central_control\": 3,\n \"captures\": 5,\n \"check\": 10,\n \"aggression\": 7,\n \"cornering\": 12\n}\n\n# Move history to prevent repetitive moves\nMOVE_HISTORY = {}\n\ndef apply_decay(move):\n \"\"\"Apply a decay factor to repetitive moves.\"\"\"\n if move in MOVE_HISTORY:\n MOVE_HISTORY[move] += 1\n else:\n MOVE_HISTORY[move] = 1\n return max(0, 10 - MOVE_HISTORY[move]) # Penalize repetitive moves\n\ndef fen_to_board(fen):\n \"\"\"Convert FEN string to a board representation.\"\"\"\n rows = fen.split()[0].split(\"/\")\n board = {}\n for rank_idx, row in enumerate(rows):\n file_idx = 0\n for char in row:\n if char.isdigit():\n file_idx += int(char)\n else:\n square = f\"{chr(file_idx + ord('a'))}{8 - rank_idx}\"\n board[square] = char\n file_idx += 1\n return board\n\ndef get_opponent_king_position(board, player):\n \"\"\"Find the opponent king's position.\"\"\"\n king = \"k\" if player == \"w\" else \"K\"\n for square, piece in board.items():\n if piece == king:\n return square\n return None\n\ndef is_adjacent(square1, square2):\n \"\"\"Check if two squares are adjacent.\"\"\"\n file_diff = abs(ord(square1[0]) - ord(square2[0]))\n rank_diff = abs(int(square1[1]) - int(square2[1]))\n return max(file_diff, rank_diff) == 1\n\ndef king_seeks_cover(board, king_square, enemy_attacks, friendly_pieces):\n \"\"\"Direct the king to safer squares.\"\"\"\n possible_moves = []\n file, rank = king_square[0], int(king_square[1])\n for file_offset in [-1, 0, 1]:\n for rank_offset in [-1, 0, 1]:\n if file_offset == 0 and rank_offset == 0:\n continue\n target_file = chr(ord(file) + file_offset)\n target_rank = str(rank + rank_offset)\n target_square = f\"{target_file}{target_rank}\"\n if target_square in board:\n possible_moves.append(target_square)\n safe_moves = [\n move for move in possible_moves\n if move not in enemy_attacks and move not in friendly_pieces\n ]\n return safe_moves\n\ndef determine_game_phase(board):\n \"\"\"Determine game phase based on material count.\"\"\"\n material_count = sum(abs(PIECE_VALUES[piece.lower()]) for piece in board.values() if piece != \" \")\n if material_count > 25:\n return \"opening\"\n elif 10 < material_count <= 25:\n return \"midgame\"\n else:\n return \"endgame\"\n\ndef prioritize_moves(game, moves, phase, board):\n \"\"\"Prioritize moves dynamically based on game phase.\"\"\"\n prioritized_moves = []\n player = \"w\" if game.get_fen().split()[1] == \"w\" else \"b\"\n opponent_king = get_opponent_king_position(board, player)\n\n for move in moves:\n start_square = move[:2]\n end_square = move[2:4]\n piece = board.get(start_square, \" \")\n target_piece = board.get(end_square, \" \")\n\n # Checkmate moves\n g = Game(game.get_fen())\n g.apply_move(move)\n if g.status == Game.CHECKMATE:\n debug(f\"Checkmate move: {move}\")\n return [move]\n\n # Captures\n if target_piece != \" \":\n score = WEIGHTS[\"captures\"] + PIECE_VALUES.get(target_piece.lower(), 0)\n prioritized_moves.append((move, score))\n continue\n\n # Central control\n if end_square in CENTER_SQUARES:\n score = WEIGHTS[\"central_control\"]\n prioritized_moves.append((move, score))\n continue\n\n # Endgame strategies\n if phase == \"endgame\":\n if opponent_king and is_adjacent(end_square, opponent_king):\n score = WEIGHTS[\"check\"] + apply_decay(move)\n prioritized_moves.append((move, score))\n elif end_square in KING_ACTIVITY_SQUARES:\n score = WEIGHTS[\"aggression\"] + apply_decay(move)\n prioritized_moves.append((move, score))\n continue\n\n # Default moves\n score = apply_decay(move)\n prioritized_moves.append((move, score))\n\n prioritized_moves.sort(key=lambda x: x[1], reverse=True)\n return [move for move, _ in prioritized_moves]\n\ndef chess_bot(obs):\n \"\"\"Dynamic chess bot with prioritization.\"\"\"\n fen = obs['board']\n game = Game(fen)\n moves = list(game.get_moves())\n\n if not moves:\n return None\n\n board = fen_to_board(fen)\n phase = determine_game_phase(board)\n debug(f\"Game phase: {phase}\")\n\n prioritized_moves = prioritize_moves(game, moves, phase, board)\n best_move = prioritized_moves[0] if prioritized_moves else random.choice(moves)\n debug(f\"Best move: {best_move}\")\n return best_move\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-21T20:33:44.842978Z","iopub.execute_input":"2024-11-21T20:33:44.843318Z","iopub.status.idle":"2024-11-21T20:33:44.857239Z","shell.execute_reply.started":"2024-11-21T20:33:44.843278Z","shell.execute_reply":"2024-11-21T20:33:44.856074Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"%%writefile main.py\nfrom Chessnut import Game\nimport random\nimport logging\n\n# Configure Debugging and Logging\nDEBUG = True\nlogging.basicConfig(level=logging.DEBUG if DEBUG else logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')\n\ndef debug(message):\n \"\"\"Utility function for debugging.\"\"\"\n if DEBUG:\n logging.debug(message)\n\n# Constants\nPIECE_VALUES = {\n \"p\": 1, \"n\": 3, \"b\": 3, \"r\": 5, \"q\": 9, \"k\": 0,\n \"P\": -1, \"N\": -3, \"B\": -3, \"R\": -5, \"Q\": -9, \"K\": 0\n}\nCENTER_SQUARES = {\"d4\", \"d5\", \"e4\", \"e5\"}\nKING_ACTIVITY_SQUARES = {\"c4\", \"c5\", \"d3\", \"d6\", \"e3\", \"e6\", \"f4\", \"f5\"}\n\n# Move history to reduce repetitive moves\nMOVE_HISTORY = {}\n\n# Define weights for move prioritization\nWEIGHTS = {\n \"central_control\": 3,\n \"captures\": 8,\n \"checks\": 12,\n \"defense\": 7,\n \"aggression\": 10,\n \"coordination\": 15,\n}\n\ndef apply_decay(move):\n \"\"\"Apply a decay factor to repetitive moves.\"\"\"\n if move in MOVE_HISTORY:\n MOVE_HISTORY[move] += 1\n else:\n MOVE_HISTORY[move] = 1\n return max(0, 10 - MOVE_HISTORY[move]) # Penalize repetitive moves\n\ndef fen_to_board(fen):\n \"\"\"Convert FEN string to a board representation.\"\"\"\n rows = fen.split()[0].split(\"/\")\n board = {}\n for rank_idx, row in enumerate(rows):\n file_idx = 0\n for char in row:\n if char.isdigit():\n file_idx += int(char)\n else:\n square = f\"{chr(file_idx + ord('a'))}{8 - rank_idx}\"\n board[square] = char\n file_idx += 1\n return board\n\ndef evaluate_opponent_moves(game, moves):\n \"\"\"Evaluate opponent's responses to each move.\"\"\"\n opponent_moves = []\n for move in moves:\n g = Game(game.get_fen())\n g.apply_move(move)\n opponent_moves.extend(list(g.get_moves()))\n return set(opponent_moves)\n\n\n\ndef endgame_prioritization(board, moves, player):\n \"\"\"Refine moves to corner the opponent king in the endgame.\"\"\"\n prioritized_moves = []\n king_square = [sq for sq, piece in board.items() if piece.lower() == \"k\" and piece.isupper() != (player == \"w\")]\n\n for move in moves:\n end_square = move[2:4]\n\n # Target the opponent king directly\n if end_square in king_square:\n prioritized_moves.append((move, WEIGHTS[\"checks\"] + 20))\n continue\n\n # Moves that restrict the opponent king's movement\n g = Game(board)\n g.apply_move(move)\n new_king_moves = list(g.get_moves())\n restricted_squares = len(king_square) - len(new_king_moves)\n\n score = WEIGHTS[\"coordination\"] + restricted_squares\n prioritized_moves.append((move, score))\n\n # Sort by priority\n prioritized_moves.sort(key=lambda x: x[1], reverse=True)\n return [move for move, _ in prioritized_moves]\n \ndef prioritize_moves(game, moves, phase, board):\n \"\"\"Prioritize moves dynamically based on game phase and opponent evaluation.\"\"\"\n prioritized_moves = []\n player = \"w\" if game.get_fen().split()[1] == \"w\" else \"b\"\n\n for move in moves:\n start_square = move[:2]\n end_square = move[2:4]\n piece = board.get(start_square, \" \")\n target_piece = board.get(end_square, \" \")\n\n # Checkmate moves\n g = Game(game.get_fen())\n g.apply_move(move)\n if g.status == Game.CHECKMATE:\n debug(f\"Checkmate move: {move}\")\n return [move]\n\n # Captures\n if target_piece != \" \":\n score = WEIGHTS[\"captures\"] + PIECE_VALUES.get(target_piece.lower(), 0)\n prioritized_moves.append((move, score))\n continue\n\n # Central control\n if end_square in CENTER_SQUARES:\n score = WEIGHTS[\"central_control\"]\n prioritized_moves.append((move, score))\n continue\n\n # Checks and Threats\n g = Game(game.get_fen())\n g.apply_move(move)\n if g.status == Game.CHECK:\n score = WEIGHTS[\"checks\"]\n prioritized_moves.append((move, score))\n continue\n\n # Endgame: King Coordination\n if phase == \"endgame\":\n if piece.lower() in {\"q\", \"r\", \"b\"}: # Aggressive long-range pieces\n score = WEIGHTS[\"coordination\"] + apply_decay(move)\n endgame_prioritization.append((move, score))\n continue\n\n # Default moves with decay\n score = apply_decay(move)\n prioritized_moves.append((move, score))\n\n # Sort moves by priority\n prioritized_moves.sort(key=lambda x: x[1], reverse=True)\n return [move for move, _ in prioritized_moves]\n\ndef chess_bot(obs):\n \"\"\"Dynamic chess bot with prioritization and strategy.\"\"\"\n fen = obs['board']\n game = Game(fen)\n moves = list(game.get_moves())\n\n if not moves:\n return None\n\n board = fen_to_board(fen)\n phase = \"endgame\" if len(moves) < 20 else \"midgame\"\n debug(f\"Game phase: {phase}\")\n\n opponent_moves = evaluate_opponent_moves(game, moves)\n debug(f\"Evaluating opponent moves: {len(opponent_moves)} possibilities\")\n\n prioritized_moves = prioritize_moves(game, moves, phase, board)\n best_move = prioritized_moves[0] if prioritized_moves else random.choice(moves)\n debug(f\"Best move: {best_move}\")\n return best_move\n\n# Test the bot\nif __name__ == \"__main__\":\n from kaggle_environments import make\n\n env = make(\"chess\", debug=True)\n\n result = env.run([\"main.py\", \"random\"])\n print(\"Agent exit status/reward/time left: \")\n for agent in result[-1]:\n print(\"\\t\", agent.status, \"/\", agent.reward, \"/\", agent.observation.remainingOverageTime)\n env.render(mode=\"ipython\", width=1000, height=1000)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-21T20:33:45.495699Z","iopub.execute_input":"2024-11-21T20:33:45.496041Z","iopub.status.idle":"2024-11-21T20:33:45.504545Z","shell.execute_reply.started":"2024-11-21T20:33:45.496009Z","shell.execute_reply":"2024-11-21T20:33:45.503578Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### Testing your agent\n\nNow let's see how your agent does againt the random agent!","metadata":{}},{"cell_type":"code","source":"result = env.run([\"main.py\", \"random\"])\nprint(\"Agent exit status/reward/time left: \")\n# look at the generated replay.json and print out the agent info\nfor agent in result[-1]:\n print(\"\\t\", agent.status, \"/\", agent.reward, \"/\", agent.observation.remainingOverageTime)\nprint(\"\\n\")\n# render the game\nenv.render(mode=\"ipython\", width=1000, height=1000) ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-21T20:33:44.876302Z","iopub.execute_input":"2024-11-21T20:33:44.876623Z","iopub.status.idle":"2024-11-21T20:33:45.493878Z","shell.execute_reply.started":"2024-11-21T20:33:44.876587Z","shell.execute_reply":"2024-11-21T20:33:45.492871Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# To Submit:\n1. Download (or save) main.py\n2. Go to the [submissions page](https://www.kaggle.com/competitions/fide-google-efficiency-chess-ai-challenge/submissions) and click \"Submit Agent\"\n3. Upload main.py\n4. Press Submit!\n\nNow doubt you are already thinking of ways this bot could be improved! Go ahead and fork this notebook and get started! ♟️","metadata":{}},{"cell_type":"markdown","source":"# Submitting Multiple files \n### (or compressing your main.py)\n\nSet up your directory structure like this:\n```\nkaggle_submissions/\n main.py\n \n```\n\nYou can run `tar -czf submission.tar.gz -C kaggle_submissions .` and upload `submission.tar.gz`","metadata":{}}]}