Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions backend/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
GAME_UPDATE = "game:update" # Sends updated game state
GAME_SUBMIT_KEYWORD = "game:submit_keyword" # Team lead submits keyword and count
GAME_SUBMIT_GUESS = "game:submit_guess" # Team members submit their card guesses
GAME_SELECT_CARD = "game:select_card" # Team member selects/deselects a card
GAME_CARD_SELECTION_UPDATE = "game:card_selection_update" # Broadcast card selection changes
GAME_ERROR = "game:error" # Game-related errors

# Game card types
Expand Down
62 changes: 60 additions & 2 deletions backend/sockets/game.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
GAME_UPDATE,
GAME_SUBMIT_KEYWORD,
GAME_SUBMIT_GUESS,
GAME_SELECT_CARD,
GAME_CARD_SELECTION_UPDATE,
FIELD_IS_TEAM_LEAD,
FIELD_TEAM,
)
Expand All @@ -17,7 +19,8 @@
get_sanitized_game_state,
submit_keyword,
submit_guess,
end_turn
end_turn,
handle_card_selection
)


Expand Down Expand Up @@ -226,4 +229,59 @@ def handle_end_turn(data):
end_turn(game_state)

# Send updated game state to all players
send_game_update(lobby_id, game_state, lobby['participants'])
send_game_update(lobby_id, game_state, lobby['participants'])

@socketio.on(GAME_SELECT_CARD)
def handle_select_card(data):
"""Handle team member selecting/deselecting a card"""
lobby_id = data.get('lobby_id')
user_id = data.get('user_id')
card_id = data.get('card_id')
is_selected = data.get('is_selected', True)

if not lobby_id or not user_id or card_id is None:
emit(GAME_ERROR, {"message": "Invalid card selection data"})
return

# Get the game state
game_state = get_game(lobby_id)
if not game_state:
emit(GAME_ERROR, {"message": "Game not found"})
return

# Get the lobby data
lobbies = get_lobbies()
if lobby_id not in lobbies:
emit(GAME_ERROR, {"message": "Lobby not found"})
return

lobby = lobbies[lobby_id]

# Verify the user is on the active team but is not a team lead
user_participant = next((p for p in lobby['participants'] if p['id'] == user_id), None)
if not user_participant:
emit(GAME_ERROR, {"message": "User not found in lobby"})
return

user_team = user_participant.get(FIELD_TEAM)
is_team_lead = user_participant.get(FIELD_IS_TEAM_LEAD, False)

if user_team != game_state['active_team'] or is_team_lead:
emit(GAME_ERROR, {"message": "Only team members on the active team can select cards"})
return

# Handle the card selection
success = handle_card_selection(game_state, user_id, card_id, is_selected)

if not success:
emit(GAME_ERROR, {"message": "Invalid card selection"})
return

# Broadcast the card selection update to all players in the lobby
emit(GAME_CARD_SELECTION_UPDATE, {
"selected_cards": game_state.get("selected_cards", {}),
"user_id": user_id,
"card_id": card_id,
"is_selected": is_selected,
"user_name": user_participant.get('display_name', 'Unknown')
}, room=lobby_id)
36 changes: 34 additions & 2 deletions backend/utils/game.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ def create_game(lobby_id):
"active_keyword": None,
"board": board,
"game_over": False,
"winner": None
"winner": None,
"selected_cards": {} # Tracks real-time card selections: {user_id: [card_ids]}
}

active_games[lobby_id] = game_state
Expand Down Expand Up @@ -159,7 +160,8 @@ def get_sanitized_game_state(game_state, user_id, participants):
"active_keyword": game_state["active_keyword"],
"game_over": game_state["game_over"],
"winner": game_state["winner"],
"board": sanitized_board
"board": sanitized_board,
"selected_cards": game_state.get("selected_cards", {})
}

return sanitized
Expand Down Expand Up @@ -290,4 +292,34 @@ def end_turn(game_state):
if game_state["active_team"] == TEAM1:
game_state["round_number"] += 1

return True


def handle_card_selection(game_state, user_id, card_id, is_selected):
"""Handle a team member selecting or deselecting a card"""
if not game_state or game_state.get("game_over", False):
return False

if game_state["game_phase"] != "team_guessing":
return False

# Initialize selected_cards if it doesn't exist
if "selected_cards" not in game_state:
game_state["selected_cards"] = {}

# Initialize user's selections if they don't exist
if user_id not in game_state["selected_cards"]:
game_state["selected_cards"][user_id] = []

user_selections = game_state["selected_cards"][user_id]

if is_selected:
# Add card to user's selections if not already selected
if card_id not in user_selections:
user_selections.append(card_id)
else:
# Remove card from user's selections
if card_id in user_selections:
user_selections.remove(card_id)

return True
Loading