🐐
This commit is contained in:
@@ -14,11 +14,10 @@ from game import (
|
||||
)
|
||||
from models import Card as CardModel, Deck as DeckModel, DeckCard as DeckCardModel, User as UserModel
|
||||
from card import compute_deck_type
|
||||
from ai import AI_USER_ID, run_ai_turn, get_random_personality, choose_cards
|
||||
|
||||
logger = logging.getLogger("app")
|
||||
|
||||
AI_USER_ID = "ai"
|
||||
|
||||
## Storage
|
||||
|
||||
active_games: dict[str, GameState] = {}
|
||||
@@ -376,15 +375,22 @@ def create_solo_game(
|
||||
player_cards: list,
|
||||
ai_cards: list,
|
||||
deck_id: str,
|
||||
difficulty: int = 5,
|
||||
) -> str:
|
||||
ai_personality = get_random_personality()
|
||||
ai_deck = choose_cards(ai_cards, difficulty, ai_personality)
|
||||
|
||||
player_deck_type = compute_deck_type(player_cards) or "Balanced"
|
||||
ai_deck_type = compute_deck_type(ai_cards) or "Balanced"
|
||||
ai_deck_type = compute_deck_type(ai_deck) or "Balanced"
|
||||
|
||||
state = create_game(
|
||||
user_id, username, player_deck_type, player_cards,
|
||||
AI_USER_ID, "Computer", ai_deck_type, ai_cards,
|
||||
AI_USER_ID, "Computer", ai_deck_type, ai_deck,
|
||||
)
|
||||
|
||||
state.ai_difficulty = difficulty
|
||||
state.ai_personality = ai_personality.value
|
||||
|
||||
active_games[state.game_id] = state
|
||||
connections[state.game_id] = {}
|
||||
active_deck_ids[user_id] = deck_id
|
||||
@@ -422,86 +428,3 @@ def calculate_combat_animation_time(events: list[CombatEvent]) -> float:
|
||||
total += ANIMATION_DELAYS["post_combat_buffer"]
|
||||
return total
|
||||
|
||||
async def run_ai_turn(game_id: str):
|
||||
state = active_games.get(game_id)
|
||||
if not state or state.result:
|
||||
return
|
||||
if state.active_player_id != AI_USER_ID:
|
||||
return
|
||||
|
||||
human_id = state.opponent_id(AI_USER_ID)
|
||||
waited = 0
|
||||
while not connections[game_id].get(human_id) and waited < 10:
|
||||
await asyncio.sleep(0.5)
|
||||
waited += 0.5
|
||||
|
||||
await asyncio.sleep(calculate_combat_animation_time(state.last_combat_events))
|
||||
|
||||
player = state.players[AI_USER_ID]
|
||||
|
||||
|
||||
ws = connections[game_id].get(human_id)
|
||||
async def send_state(state: GameState):
|
||||
if ws:
|
||||
try:
|
||||
await ws.send_json({
|
||||
"type": "state",
|
||||
"state": serialize_state(state, human_id),
|
||||
})
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
most_expensive_in_hand = max((c.cost for c in player.hand), default=0)
|
||||
if player.energy < most_expensive_in_hand:
|
||||
for slot in range(BOARD_SIZE):
|
||||
slot_card = player.board[slot]
|
||||
if slot_card is not None and player.energy + slot_card.cost <= most_expensive_in_hand:
|
||||
if ws:
|
||||
try:
|
||||
await ws.send_json({
|
||||
"type": "sacrifice_animation",
|
||||
"instance_id": slot_card.instance_id,
|
||||
})
|
||||
except Exception:
|
||||
pass
|
||||
await asyncio.sleep(0.65)
|
||||
action_sacrifice(state, slot)
|
||||
await send_state(state)
|
||||
await asyncio.sleep(0.35)
|
||||
|
||||
play_order = list(range(BOARD_SIZE))
|
||||
random.shuffle(play_order)
|
||||
for slot in play_order:
|
||||
if player.board[slot] is not None:
|
||||
continue
|
||||
affordable = [i for i, c in enumerate(player.hand) if c.cost <= player.energy]
|
||||
if not affordable:
|
||||
break
|
||||
best = max(affordable, key=lambda i: player.hand[i].cost)
|
||||
action_play_card(state, best, slot)
|
||||
await send_state(state)
|
||||
await asyncio.sleep(0.5)
|
||||
|
||||
action_end_turn(state)
|
||||
await send_state(state)
|
||||
|
||||
if state.result:
|
||||
from database import SessionLocal
|
||||
db = SessionLocal()
|
||||
try:
|
||||
record_game_result(state, db)
|
||||
if ws:
|
||||
await ws.send_json({
|
||||
"type": "state",
|
||||
"state": serialize_state(state, human_id),
|
||||
})
|
||||
finally:
|
||||
db.close()
|
||||
active_deck_ids.pop(human_id, None)
|
||||
active_deck_ids.pop(AI_USER_ID, None)
|
||||
active_games.pop(game_id, None)
|
||||
connections.pop(game_id, None)
|
||||
return
|
||||
|
||||
if state.active_player_id == AI_USER_ID:
|
||||
asyncio.create_task(run_ai_turn(game_id))
|
||||
|
||||
Reference in New Issue
Block a user