diff --git a/backend/__init__.py b/backend/__init__.py index 1c730cc..6dfda89 100644 --- a/backend/__init__.py +++ b/backend/__init__.py @@ -4,8 +4,8 @@ from typing import List import eventlet import socketio -from game import Game -from players import Player +from bang.game import Game +from bang.players import Player sio = socketio.Server(cors_allowed_origins="*") app = socketio.WSGIApp(sio, static_files={ @@ -69,6 +69,11 @@ def private(sid): g.set_private() advertise_lobbies() +@sio.event +def toggle_expansion(sid, expansion_name): + g = sio.get_session(sid).game + g.toggle_expansion(expansion_name) + @sio.event def join_room(sid, room): room_name = room['name'] diff --git a/backend/cards.py b/backend/bang/cards.py similarity index 96% rename from backend/cards.py rename to backend/bang/cards.py index bbed56d..a5c1084 100644 --- a/backend/cards.py +++ b/backend/bang/cards.py @@ -1,7 +1,7 @@ from typing import List, Set, Dict, Tuple, Optional from abc import ABC, abstractmethod from enum import IntEnum -import roles as r +import bang.roles as r class Suit(IntEnum): DIAMONDS = 0 # ♦ @@ -57,7 +57,7 @@ class Card(ABC): for i in range(len(player.equipment)): print('tipo',type(self)) if type(player.equipment[i]) == type(self): - player.game.deck.scrap(self.equipment[i]) + player.game.deck.scrap(player.equipment[i]) player.equipment[i] = self break else: @@ -162,7 +162,7 @@ class Bang(Card): if player.has_played_bang and not any([isinstance(c, Volcanic) for c in player.equipment]) and against != None: return False elif against != None: - import characters as chars + import bang.characters as chars super().play_card(player, against=against) player.has_played_bang = not isinstance( player.character, chars.WillyTheKid) @@ -199,7 +199,7 @@ class CatBalou(Card): def play_card(self, player, against): if against != None and (len(player.game.get_player_named(against).hand) + len(player.game.get_player_named(against).equipment)) > 0: super().play_card(player, against=against) - from players import PendingAction + from bang.players import PendingAction player.pending_action = PendingAction.CHOOSE player.choose_action = 'discard' player.target_p = against @@ -281,7 +281,7 @@ class Mancato(Card): self.desc = "Usa questa carta per annullare un bang" def play_card(self, player, against): - import characters as chars + import bang.characters as chars if (not player.has_played_bang and against != None and isinstance(player.character, chars.CalamityJanet)): player.sio.emit('chat_message', room=player.game.name, data=f'{player.name} ha giocato {self.name} come un BANG! contro {against}.') @@ -301,7 +301,7 @@ class Panico(Card): def play_card(self, player, against): if against != None and (len(player.game.get_player_named(against).hand) + len(player.game.get_player_named(against).equipment)) > 0: super().play_card(player, against=against) - from players import PendingAction + from bang.players import PendingAction player.pending_action = PendingAction.CHOOSE player.choose_action = 'steal' player.target_p = against @@ -339,8 +339,9 @@ class WellsFargo(Card): return True -def get_starting_deck() -> List[Card]: - return [ +def get_starting_deck(expansions:List[str]) -> List[Card]: + from bang.expansions import DodgeCity + base_cards = [ Barile(Suit.SPADES, 'Q'), Barile(Suit.SPADES, 'K'), Dinamite(Suit.HEARTS, 2), @@ -422,3 +423,7 @@ def get_starting_deck() -> List[Card]: Saloon(Suit.HEARTS, 5), WellsFargo(Suit.HEARTS, 3), ] + if 'dodge_city' in expansions: + base_cards.extend(DodgeCity.get_cards()) + return base_cards + diff --git a/backend/characters.py b/backend/bang/characters.py similarity index 100% rename from backend/characters.py rename to backend/bang/characters.py diff --git a/backend/deck.py b/backend/bang/deck.py similarity index 93% rename from backend/deck.py rename to backend/bang/deck.py index 202fbe0..015a841 100644 --- a/backend/deck.py +++ b/backend/bang/deck.py @@ -1,11 +1,11 @@ from typing import List, Set, Dict, Tuple, Optional import random -import cards as cs +import bang.cards as cs class Deck: def __init__(self, game): super().__init__() - self.cards: List[cs.Card] = cs.get_starting_deck() + self.cards: List[cs.Card] = cs.get_starting_deck(game.expansions) self.game = game random.shuffle(self.cards) self.scrap_pile: List[cs.Card] = [] diff --git a/backend/bang/expansions/__init__.py b/backend/bang/expansions/__init__.py new file mode 100644 index 0000000..aebf978 --- /dev/null +++ b/backend/bang/expansions/__init__.py @@ -0,0 +1,5 @@ + +from bang.expansions.dodge_city import cards +class DodgeCity(): + def get_cards(): + return cards.get_starting_deck() \ No newline at end of file diff --git a/backend/bang/expansions/dodge_city/cards.py b/backend/bang/expansions/dodge_city/cards.py new file mode 100644 index 0000000..aecabbe --- /dev/null +++ b/backend/bang/expansions/dodge_city/cards.py @@ -0,0 +1,36 @@ +from bang.cards import * + +class Riparo(Mustang): + def __init__(self, suit, number): + super().__init__(suit, number) + self.name = 'Riparo' + self.icon = '⛰' + +class Binocolo(Mirino): + def __init__(self, suit, number): + super().__init__(suit, number) + self.name = 'Binocolo' + self.icon = '🔍' + +class Pugno(Card): + def __init__(self, suit, number): + super().__init__(suit, 'Pugno!', number, range=1) + self.icon = '👊' + self.desc = "Spara a un giocatore a distanta 1" + self.need_target = True + + def play_card(self, player, against): + if against != None: + import bang.characters as chars + super().play_card(player, against=against) + player.game.attack(player, against) + return True + return False + +def get_starting_deck() -> List[Card]: + return [ + #TODO: aggiungere anche le carte normalmente presenti https://bang.dvgiochi.com/cardslist.php?id=3 + Riparo(Suit.DIAMONDS, 'K'), + Binocolo(Suit.DIAMONDS, 10), + Pugno(Suit.SPADES, 10), + ] diff --git a/backend/game.py b/backend/bang/game.py similarity index 92% rename from backend/game.py rename to backend/bang/game.py index 961e608..75c3ddc 100644 --- a/backend/game.py +++ b/backend/bang/game.py @@ -2,10 +2,10 @@ from typing import List, Set, Dict, Tuple, Optional import random import socketio -import players -import characters -from deck import Deck -import roles +import bang.players as players +import bang.characters as characters +from bang.deck import Deck +import bang.roles as roles class Game: def __init__(self, name, sio:socketio): @@ -20,6 +20,25 @@ class Game: self.waiting_for = 0 self.initial_players = 0 self.password = '' + self.expansions = [] + + def notify_room(self): + self.sio.emit('room', room=self.name, data={ + 'name': self.name, + 'started': self.started, + 'players': [{'name':p.name, 'ready': False} for p in self.players], + 'password': self.password, + 'expansions': self.expansions, + }) + + def toggle_expansion(self, expansion_name): + if not self.started: + print('toggling', expansion_name) + if expansion_name in self.expansions: + self.expansions.remove(expansion_name) + else: + self.expansions.append(expansion_name) + self.notify_room() def add_player(self, player: players.Player): if player in self.players or len(self.players) >= 7: @@ -27,7 +46,7 @@ class Game: player.join_game(self) self.players.append(player) print(f'Added player {player.name} to game') - self.sio.emit('room', room=self.name, data={'name': self.name, 'started': self.started, 'players': [p.name for p in self.players], 'password': self.password}) + self.notify_room() self.sio.emit('chat_message', room=self.name, data=f'{player.name} è entrato nella lobby.') def set_private(self): @@ -36,10 +55,11 @@ class Game: print(self.name, 'is now private pwd', self.password) else: self.password = '' - self.sio.emit('room', room=self.name, data={'name': self.name, 'started': self.started, 'players': [p.name for p in self.players], 'password': self.password}) + self.notify_room() def notify_character_selection(self): self.readyCount += 1 + self.notify_room() if self.readyCount == len(self.players): self.distribute_roles() @@ -212,7 +232,7 @@ class Game: if self.started and index <= self.turn: self.turn -= 1 self.players.pop(index) - self.sio.emit('room', room=self.name, data={'name': self.name, 'started': self.started, 'players': [p.name for p in self.players]}) + self.notify_room() self.sio.emit('chat_message', room=self.name, data=f'{player.name} è morto.') if self.started: self.sio.emit('chat_message', room=self.name, data=f'{player.name} era {player.role.name}!') diff --git a/backend/players.py b/backend/bang/players.py similarity index 99% rename from backend/players.py rename to backend/bang/players.py index 0c5fe0f..d4ab136 100644 --- a/backend/players.py +++ b/backend/bang/players.py @@ -2,10 +2,10 @@ from enum import IntEnum import json from random import randrange import socketio -import deck -import roles as r -import cards as cs -import characters as chars +import bang.deck as deck +import bang.roles as r +import bang.cards as cs +import bang.characters as chars class PendingAction(IntEnum): PICK = 0 @@ -17,9 +17,9 @@ class PendingAction(IntEnum): class Player: - import game as g def __init__(self, name, sid, sio): + import bang.game as g super().__init__() self.name = name self.sid = sid diff --git a/backend/roles.py b/backend/bang/roles.py similarity index 100% rename from backend/roles.py rename to backend/bang/roles.py diff --git a/frontend/src/components/Lobby.vue b/frontend/src/components/Lobby.vue index fa2a236..073c40e 100644 --- a/frontend/src/components/Lobby.vue +++ b/frontend/src/components/Lobby.vue @@ -27,6 +27,10 @@ +