tictactoe / app.py
Paweł Łaba
zmiana dodanie opcji zapisu
ecea336
raw
history blame
4.3 kB
from fastapi import FastAPI, HTTPException, Request
from fastapi.responses import HTMLResponse
from fastapi.staticfiles import StaticFiles
from starlette.routing import Mount
import numpy as np
from tensorflow import keras
import hashlib
import json
import os
class TicTacToeAI:
def __init__(self, model_path="model/model.keras"):
self.model_path = model_path
self.model = None
self.load_model()
def load_model(self):
"""Wczytuje model z pliku"""
if os.path.exists(self.model_path):
self.model = keras.models.load_model(self.model_path)
return True
return False
def get_move(self, board):
"""Zwraca najlepszy ruch dla danego stanu planszy"""
if self.model is None:
raise ValueError("Model nie został wczytany")
board_array = np.array(board)
predictions = self.model.predict(board_array.reshape(1, -1), verbose=0)[0]
valid_moves = np.where(board_array == 0)[0]
if len(valid_moves) == 0:
raise ValueError("Brak dostępnych ruchów")
valid_predictions = [(i, pred) for i, pred in enumerate(predictions) if i in valid_moves]
return int(max(valid_predictions, key=lambda x: x[1])[0])
# Inicjalizacja AI
ai = TicTacToeAI()
# Ustawienie prefiksu aplikacji
app = FastAPI(root_path="/spaces/labapawel/tictactoe")
@app.on_event("startup")
async def print_routes():
"""Wyświetla wszystkie zarejestrowane trasy"""
for route in app.routes:
if hasattr(route, "methods"): # Jeśli trasa obsługuje metody HTTP
print(f"Path: {route.path}, Name: {route.name}, Methods: {route.methods}")
elif isinstance(route, Mount): # Jeśli to katalog statyczny
print(f"Mounted Path: {route.path}, Name: {route.name}, App: {route.app}")
else: # Inny typ trasy
print(f"Other Route Path: {route.path}, Name: {route.name}")
# Montowanie katalogu publicznego
app.mount("/static", StaticFiles(directory="public"), name="static")
@app.get("/", response_class=HTMLResponse)
async def read_root():
try:
with open("public/index.html", "r") as file:
return HTMLResponse(content=file.read(), status_code=200)
except FileNotFoundError:
return HTMLResponse(content="Plik index.html nie został znaleziony", status_code=404)
@app.get("/status")
async def get_status():
print("Endpoint /status został wywołany.")
return {
"status": "success",
"model_loaded": True, # lub odpowiedni warunek
"model_path": "model/model.keras"
}
@app.post("/savegame")
async def save_game(request: Request):
try:
data = await request.json()
final_board = data.get("final_board")
sequence = data.get("sequence")
if not final_board or not sequence:
raise HTTPException(status_code=400, detail="Missing required data")
game_hash = hash(str(final_board) + str(sequence))
game_data = {
"final_board": final_board,
"sequence": sequence,
"hash": game_hash
}
try:
with open("public/games_data.json", "r") as f:
existing_data = json.load(f)
except (FileNotFoundError, json.JSONDecodeError):
existing_data = []
existing_data.append(game_data)
with open("public/games_data.json", "w") as f:
json.dump(existing_data, f)
return {"status": "success", "hash": game_data["hash"]}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@app.post("/move")
async def get_move(request: Request):
"""
Endpoint do wykonania ruchu AI
"""
try:
data = await request.json() # Pobierz dane JSON z żądania
board = data.get("board")
if not board:
raise HTTPException(status_code=400, detail="Brak planszy w żądaniu")
if len(board) != 9 or not all(x in [0, 1, -1] for x in board):
raise HTTPException(status_code=400, detail="Nieprawidłowe dane planszy")
move = ai.get_move(board)
return {"status": "success", "move": move}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))