# app.py import uvicorn from fastapi import FastAPI, Query, HTTPException from fastapi.responses import PlainTextResponse import numpy as np import logging import time # Import our logic from game_logic import parse_board_hex, is_game_over from ai import find_best_move, get_dynamic_depth, SEARCH_DEPTH # Import base depth logging.basicConfig(level=logging.INFO) log = logging.getLogger(__name__) app = FastAPI() # Define the actual depth to use for this instance # SET TO 6 IF YOU REALLY WANT, BUT BEWARE TIMEOUTS! # Use dynamic depth instead: # API_SEARCH_DEPTH = 6 @app.get("/move", response_class=PlainTextResponse) async def get_ai_move(board: str = Query(..., min_length=16, max_length=16, regex="^[0-9a-fA-F]{16}$")): """ Receives a 16-char hex board string, returns the best move 'u','d','l','r' or 'g'. """ log.info(f"Received board: {board}") start_time = time.time() try: board_array = parse_board_hex(board.upper()) if is_game_over(board_array): log.info("Game Over detected.") return "g" # Use dynamic depth or fixed depth depth_to_use = get_dynamic_depth(board_array) # depth_to_use = API_SEARCH_DEPTH # Or use fixed log.info(f"Calculating move with depth {depth_to_use}...") move = find_best_move(board_array, depth=depth_to_use) duration = time.time() - start_time log.info(f"Replying with move: '{move}' in {duration:.4f}s") return move except ValueError as ve: log.error(f"Invalid board string: {board} - {ve}") raise HTTPException(status_code=400, detail="Invalid board string format.") except Exception as e: log.error(f"Internal error processing board {board}: {e}", exc_info=True) # Return a default or 'g' on error to not block the client too much # raise HTTPException(status_code=500, detail=str(e)) return "g" # return game over on server error # --- For HuggingFace Spaces --- # HF Spaces looks for an app running on 0.0.0.0:7860 if __name__ == "__main__": log.info(f"Starting 2048 AI API with BASE_DEPTH={SEARCH_DEPTH}...") # For local testing: http://127.0.0.1:7860/move?board=0000000000100010 # For HF Spaces: host must be 0.0.0.0, port must be 7860 uvicorn.run(app, host="0.0.0.0", port=7860)