Загрузка данных


from fastapi import FastAPI, Request, WebSocket, WebSocketDisconnect
from fastapi.responses import HTMLResponse
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates

import random
import uvicorn

app = FastAPI()

app.mount("/static", StaticFiles(directory="static"), name="static")

templates = Jinja2Templates(directory="templates")

players = []
connections = {}
roles = {}

game_started = False
current_turn = 0

WORDS = [
"Airport",
"School",
"Hospital",
"Bank",
"Hotel"
]

current_location = ""
spy_player = ""

@app.get("/", response_class=HTMLResponse)
async def index(request: Request):

```
return templates.TemplateResponse(
    request=request,
    name="index.html"
)
```

@app.get("/room", response_class=HTMLResponse)
async def room(request: Request, nickname: str):

```
return templates.TemplateResponse(
    request=request,
    name="room.html",
    context={
        "nickname": nickname
    }
)
```

async def broadcast(message):

```
for connection in connections.values():
    await connection.send_text(message)
```

@app.websocket("/ws/{nickname}")
async def websocket_endpoint(websocket: WebSocket, nickname: str):

```
global current_turn

await websocket.accept()

connections[nickname] = websocket

if nickname not in players:
    players.append(nickname)

await broadcast(f"SYSTEM: {nickname} joined the game")

try:

    while True:

        data = await websocket.receive_text()

        if players[current_turn] != nickname:
            await websocket.send_text(
                "SYSTEM: Not your turn"
            )
            continue

        if nickname == spy_player:

            if data.lower() == current_location.lower():

                await broadcast(
                    f"SYSTEM: Spy guessed the location ({current_location})"
                )

                await broadcast(
                    f"SYSTEM: SPY WON"
                )

                continue

        next_player = players[(current_turn + 1) % len(players)]

        await broadcast(
            f"{nickname} asks question to {next_player}: {data}"
        )

        current_turn = (current_turn + 1) % len(players)

        await broadcast(
            f"SYSTEM: Current turn -> {players[current_turn]}"
        )

except WebSocketDisconnect:

    if nickname in players:
        players.remove(nickname)

    if nickname in connections:
        del connections[nickname]

    await broadcast(f"SYSTEM: {nickname} left")
```

@app.get("/start")
async def start_game():

```
global game_started
global current_location
global spy_player
global current_turn

if len(players) < 2:
    return {
        "error": "Need at least 2 players"
    }

if game_started:
    return {
        "error": "Game already started"
    }

game_started = True

current_turn = 0

spy_player = random.choice(players)

current_location = random.choice(WORDS)

for player in players:

    if player == spy_player:
        roles[player] = "SPY"
    else:
        roles[player] = current_location

for player in players:

    websocket = connections[player]

    if player == spy_player:
        await websocket.send_text(
            "ROLE: SPY"
        )
    else:
        await websocket.send_text(
            f"ROLE: {current_location}"
        )

await broadcast(
    f"SYSTEM: Game started"
)

await broadcast(
    f"SYSTEM: First turn -> {players[current_turn]}"
)

return {
    "status": "started"
}
```

if **name** == "**main**":

```
uvicorn.run(
    app,
    host="0.0.0.0",
    port=8000
)
```