shortdeck1.3:ui and fix
This commit is contained in:
@@ -1,12 +1,35 @@
|
||||
import sys
|
||||
import os
|
||||
from pathlib import Path
|
||||
project_root = Path(__file__).resolve().parent.parent
|
||||
if str(project_root) not in sys.path:
|
||||
sys.path.insert(0, str(project_root))
|
||||
|
||||
from fastapi import FastAPI, HTTPException
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
from pydantic import BaseModel
|
||||
from typing import List, Optional, Dict, Any
|
||||
|
||||
from .persistence import append_game_history
|
||||
from .arena_adapter import ArenaGame
|
||||
from shortdeck_server.persistence import append_game_history
|
||||
from shortdeck_server.arena_adapter import ArenaGame
|
||||
|
||||
app = FastAPI(title="ShortDeck Poker Server", version="1.0.0")
|
||||
|
||||
app.add_middleware(
|
||||
CORSMiddleware,
|
||||
allow_origins=["*"],
|
||||
allow_credentials=True,
|
||||
allow_methods=["*"],
|
||||
allow_headers=["*"],
|
||||
)
|
||||
|
||||
app = FastAPI(title="shortdeck-server")
|
||||
GAME = ArenaGame()
|
||||
|
||||
client_path = project_root / "client"
|
||||
if client_path.exists():
|
||||
app.mount("/client", StaticFiles(directory=str(client_path)), name="client")
|
||||
|
||||
class JoinRequest(BaseModel):
|
||||
name: str
|
||||
|
||||
@@ -19,16 +42,67 @@ class JoinResponse(BaseModel):
|
||||
class ActionRequest(BaseModel):
|
||||
player_id: int
|
||||
action: str # "fold", "call", "raise", "check", "bet"
|
||||
amount: int | None = None
|
||||
amount: Optional[int] = None
|
||||
|
||||
class ApiResponse(BaseModel):
|
||||
success: bool = True
|
||||
message: Optional[str] = None
|
||||
data: Optional[Dict[str, Any]] = None
|
||||
error: Optional[str] = None
|
||||
|
||||
class GameInfo(BaseModel):
|
||||
game_id: str
|
||||
players: List[str]
|
||||
dealer_index: int
|
||||
current_turn: int
|
||||
stage: str
|
||||
total_pot: int
|
||||
side_pots: List[Dict[str, Any]]
|
||||
player_cards: List[str]
|
||||
board_cards: List[str]
|
||||
stacks: List[int]
|
||||
player_states: List[str]
|
||||
current_pot: List[int]
|
||||
actions: Dict[str, Any]
|
||||
|
||||
class HandStrength(BaseModel):
|
||||
hand_type: str
|
||||
description: str
|
||||
strength: float
|
||||
cards: List[str]
|
||||
|
||||
class Game1v1Response(BaseModel):
|
||||
success: bool
|
||||
message: str
|
||||
human_player_id: Optional[int] = None
|
||||
ai_player_id: Optional[int] = None
|
||||
game_id: Optional[str] = None
|
||||
|
||||
|
||||
@app.post("/reset_game")
|
||||
def reset_game():
|
||||
global GAME
|
||||
try:
|
||||
GAME = ArenaGame()
|
||||
return {"success": True, "message": "游戏已重置"}
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=str(e)) from e
|
||||
|
||||
@app.post("/join", response_model=JoinResponse)
|
||||
def join(req: JoinRequest):
|
||||
try:
|
||||
print(f"收到加入请求: {req.name}")
|
||||
player_id = GAME.join_game(req.name)
|
||||
print(f"玩家 {req.name} 成功加入,ID: {player_id}")
|
||||
return JoinResponse(player_id=player_id, name=req.name)
|
||||
except ValueError as e:
|
||||
print(f"加入游戏失败 - ValueError: {e}")
|
||||
raise HTTPException(status_code=400, detail=str(e)) from e
|
||||
return JoinResponse(player_id=player_id, name=req.name)
|
||||
except Exception as e:
|
||||
print(f"加入游戏失败 - Exception: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
raise HTTPException(status_code=500, detail=str(e)) from e
|
||||
|
||||
|
||||
@app.get("/get_game_state")
|
||||
@@ -40,11 +114,78 @@ def get_game_state(player_id):
|
||||
return state
|
||||
|
||||
|
||||
@app.post("/apply_action")
|
||||
@app.post("/apply_action", response_model=Dict[str, Any])
|
||||
def apply_action(req: ActionRequest):
|
||||
try:
|
||||
GAME.apply_action(req.player_id, req.action, req.amount)
|
||||
result = GAME.apply_action(req.player_id, req.action, req.amount)
|
||||
append_game_history(GAME.game_id, {"history": GAME.history})
|
||||
return result
|
||||
except ValueError as e:
|
||||
raise HTTPException(status_code=400, detail=str(e)) from e
|
||||
return {"ok": True}
|
||||
|
||||
@app.get("/valid_actions/{player_id}")
|
||||
def get_valid_actions(player_id: int):
|
||||
try:
|
||||
actions = GAME.get_valid_actions(player_id)
|
||||
return {"valid_actions": actions}
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=str(e)) from e
|
||||
|
||||
@app.get("/hand_strength/{player_id}")
|
||||
def get_hand_strength(player_id: int):
|
||||
try:
|
||||
strength = GAME.get_hand_strength(player_id)
|
||||
return strength
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=str(e)) from e
|
||||
|
||||
|
||||
@app.get("/winners")
|
||||
def get_winners():
|
||||
try:
|
||||
winners = GAME.get_winners()
|
||||
return winners
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=str(e)) from e
|
||||
|
||||
@app.post("/reset")
|
||||
def reset_game(request: dict = None):
|
||||
try:
|
||||
global GAME
|
||||
keep_chips = False
|
||||
|
||||
if request and isinstance(request, dict):
|
||||
keep_chips = request.get("keep_chips", False)
|
||||
|
||||
if keep_chips and GAME and len(GAME.agents) >= 2:
|
||||
GAME.reset_hand_keep_chips()
|
||||
message = "游戏重置,筹码保持"
|
||||
else:
|
||||
GAME = ArenaGame()
|
||||
message = "游戏完全重置"
|
||||
return {"ok": True, "message": message}
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=str(e)) from e
|
||||
|
||||
@app.get("/hand_complete")
|
||||
def check_hand_complete():
|
||||
try:
|
||||
is_complete = GAME.check_hand_complete()
|
||||
return {"hand_complete": is_complete}
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=str(e)) from e
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import uvicorn
|
||||
|
||||
print(" Starting ShortDeck Poker Server...")
|
||||
print(" Server will run on http://localhost:8001")
|
||||
print(" API docs available at http://localhost:8001/docs")
|
||||
|
||||
uvicorn.run(
|
||||
app,
|
||||
host="127.0.0.1",
|
||||
port=8001,
|
||||
reload=False
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user