From 768415d2ed00a1ecfe231e33470c84f517e7cc02 Mon Sep 17 00:00:00 2001 From: Alberto Xamin Date: Sun, 15 Nov 2020 23:13:17 +0100 Subject: [PATCH] progress --- cards.py | 38 ++++++++++++-------- characters.py | 99 ++++++++++++++++++++++++++++++++++++++++++++------- deck.py | 18 +++++----- game.py | 21 ++++++++++- players.py | 65 +++++++++++++++++++++++++++++++-- roles.py | 12 +++---- 6 files changed, 205 insertions(+), 48 deletions(-) diff --git a/cards.py b/cards.py index a13f672..63cfe6b 100644 --- a/cards.py +++ b/cards.py @@ -1,12 +1,12 @@ from typing import List, Set, Dict, Tuple, Optional from abc import ABC, abstractmethod -from enum import Enum +from enum import IntEnum -class Suit(Enum): - DIAMONDS = 1 # ♦ - CLUBS = 2 # ♣ - HEARTS = 3 # ♥ - SPADES = 4 # ♠ +class Suit(IntEnum): + DIAMONDS = 0 # ♦ + CLUBS = 1 # ♣ + HEARTS = 2 # ♥ + SPADES = 3 # ♠ class Card(ABC): sym = { @@ -15,7 +15,7 @@ class Card(ABC): 'Q': 12, 'K': 13 } - def __init__(self, name: str, suit: Suit, number, is_equipment:bool=False, is_weapon:bool=False): + def __init__(self, suit: Suit, name: str, number, is_equipment:bool=False, is_weapon:bool=False, vis_mod:int=0, sight_mod:int=0, range:int=99): super().__init__() self.name = name self.suit = suit @@ -26,6 +26,14 @@ class Card(ABC): self.number = self.sym[number] self.is_equipment = is_equipment self.is_weapon = is_weapon + self.vis_mod = vis_mod + self.sight_mod = sight_mod + self.range = range + + def __str__(self): + char = ['♦️','♣️','♥️','♠️'][int(self.suit)] + return f'{self.name} {char}{self.number}' + return super().__str__() class Barile(Card): def __init__(self, suit, number): @@ -37,11 +45,11 @@ class Dinamite(Card): class Mirino(Card): def __init__(self, suit, number): - super().__init__(suit, 'Mirino', number, is_equipment=True) + super().__init__(suit, 'Mirino', number, is_equipment=True, sight_mod=1) class Mustang(Card): def __init__(self, suit, number): - super().__init__(suit, 'Mustang', number, is_equipment=True, is_weapon=True) + super().__init__(suit, 'Mustang', number, is_equipment=True, is_weapon=True, vis_mod=1) class Prigione(Card): def __init__(self, suit, number): @@ -49,23 +57,23 @@ class Prigione(Card): class Remington(Card): def __init__(self, suit, number): - super().__init__(suit, 'Remington', number, is_equipment=True, is_weapon=True) + super().__init__(suit, 'Remington', number, is_equipment=True, is_weapon=True, range=3) class RevCarabine(Card): def __init__(self, suit, number): - super().__init__(suit, 'Rev. Carabine', number, is_equipment=True, is_weapon=True) + super().__init__(suit, 'Rev. Carabine', number, is_equipment=True, is_weapon=True, range=4) class Schofield(Card): def __init__(self, suit, number): - super().__init__(suit, 'Schofield', number, is_equipment=True, is_weapon=True) + super().__init__(suit, 'Schofield', number, is_equipment=True, is_weapon=True, range=2) class Volcanic(Card): def __init__(self, suit, number): - super().__init__(suit, 'Volcanic', number, is_equipment=True, is_weapon=True) + super().__init__(suit, 'Volcanic', number, is_equipment=True, is_weapon=True, range=1) class Winchester(Card): def __init__(self, suit, number): - super().__init__(suit, 'Winchester', number, is_equipment=True, is_weapon=True) + super().__init__(suit, 'Winchester', number, is_equipment=True, is_weapon=True, range=5) class Bang(Card): def __init__(self, suit, number): @@ -105,7 +113,7 @@ class Mancato(Card): class Panico(Card): def __init__(self, suit, number): - super().__init__(suit, 'Panico!', number) + super().__init__(suit, 'Panico!', number, range=1) class Saloon(Card): def __init__(self, suit, number): diff --git a/characters.py b/characters.py index ecfe611..ba56150 100644 --- a/characters.py +++ b/characters.py @@ -8,21 +8,21 @@ class Character(ABC): self.sight_mod = 0 self.visibility_mod = 0 - @abstractmethod - def on_hurt(self, dmg: int): - pass + # @abstractmethod + # def on_hurt(self, dmg: int): + # pass - @abstractmethod - def on_pick(self, card): # tipo dinamite e prigione - pass + # @abstractmethod + # def on_pick(self, card): # tipo dinamite e prigione + # pass - @abstractmethod - def on_empty_hand(self): - pass + # @abstractmethod + # def on_empty_hand(self): + # pass - @abstractmethod - def on_empty_hand(self): - pass + # @abstractmethod + # def on_empty_hand(self): + # pass class BartCassidy(Character): def __init__(self): @@ -35,5 +35,78 @@ class BlackJack(Character): def __init__(self): super().__init__("Black Jack", max_lives=4) +class CalamityJanet(Character): + def __init__(self): + super().__init__("Calamity Janet", max_lives=4) + +class ElGringo(Character): + def __init__(self): + super().__init__("El Gringo", max_lives=3) + +class JesseJones(Character): + def __init__(self): + super().__init__("Jesse Jones", max_lives=4) + +class Jourdonnais(Character): + def __init__(self): + super().__init__("Jourdonnais", max_lives=4) + +class KitCarlson(Character): + def __init__(self): + super().__init__("Kit Carlson", max_lives=4) + +class LuckyDuke(Character): + def __init__(self): + super().__init__("Lucky Duke", max_lives=4) + +class PaulRegret(Character): + def __init__(self): + super().__init__("Paul Regret", max_lives=3) + +class PedroRamirez(Character): + def __init__(self): + super().__init__("Pedro Ramirez", max_lives=4) + +class RoseDoolan(Character): + def __init__(self): + super().__init__("Rose Doolan", max_lives=4) + +class SidKetchum(Character): + def __init__(self): + super().__init__("Sid Ketchum", max_lives=4) + +class SlabTheKiller(Character): + def __init__(self): + super().__init__("Slab The Killer", max_lives=4) + +class SuzyLafayette(Character): + def __init__(self): + super().__init__("Suzy Lafayette", max_lives=4) + +class VultureSam(Character): + def __init__(self): + super().__init__("Vulture Sam", max_lives=4) + +class WillyTheKid(Character): + def __init__(self): + super().__init__("Willy The Kid", max_lives=4) + def all_characters(): - return [BartCassidy(), BlackJack()] \ No newline at end of file + return [ + BartCassidy(), + BlackJack(), + CalamityJanet(), + ElGringo(), + JesseJones(), + Jourdonnais(), + KitCarlson(), + LuckyDuke(), + PaulRegret(), + PedroRamirez(), + RoseDoolan(), + SidKetchum(), + SlabTheKiller(), + SuzyLafayette(), + VultureSam(), + WillyTheKid(), + ] \ No newline at end of file diff --git a/deck.py b/deck.py index c2a3b1c..708fdd8 100644 --- a/deck.py +++ b/deck.py @@ -1,28 +1,30 @@ from typing import List, Set, Dict, Tuple, Optional import random -import cards +from cards import Card, get_starting_deck class Deck: def __init__(self): super().__init__() - self.cards: List[cards.Card] = random.shuffle(cards.get_starting_deck()) - self.scrap_pile: List[cards.Card] = [] + self.cards: List[Card] = get_starting_deck() + random.shuffle(self.cards) + self.scrap_pile: List[Card] = [] + print(f'Deck initialized with {len(self.cards)} cards') def peek(self, n_cards: int) -> list: return self.cards[:n_cards] - def peek_scrap_pile(self,) -> cards.Card: + def peek_scrap_pile(self,) -> Card: if len(self.scrap_pile) > 0: return self.scrap_pile[-1] else: return None - def pick_and_scrap(self) -> cards.Card: + def pick_and_scrap(self) -> Card: card = self.cards.pop(0) self.scrap_pile.append(card) return card - def draw(self) -> cards.Card: + def draw(self) -> Card: card = self.cards.pop(0) if len(self.cards) == 0: self.cards = self.scrap_pile[:-1].copy() @@ -30,11 +32,11 @@ class Deck: self.scrap_pile = self.scrap_pile[-1:] return card - def draw_from_scrap_pile(self) -> cards.Card: + def draw_from_scrap_pile(self) -> Card: if len(self.scrap_pile) > 0: return self.scrap_pile.pop(0) else: return self.draw() - def scrap(self, card: cards.Card): + def scrap(self, card: Card): self.scrap_pile.append(card) \ No newline at end of file diff --git a/game.py b/game.py index c1f54f1..d16d873 100644 --- a/game.py +++ b/game.py @@ -16,13 +16,15 @@ class Game: def add_player(self, player: players.Player): player.join_game(self) self.players.append(player) + print(f'Added player {player.id} to game') def choose_characters(self): - char_cards = random.sample(all_characters(), len(self.players)) + char_cards = random.sample(all_characters(), len(self.players)*2) for i in range(len(self.players)): self.players[i].set_available_character(char_cards[i*2:i*2+2]) def start_game(self): + print('GAME IS STARING') if self.started: return self.started = True @@ -43,6 +45,11 @@ class Game: self.players[i].hand.append(self.deck.draw()) self.play_turn() + def get_visible_players(self, player): + i = self.players.index(player) + sight = player.get_sight() + return [self.players[j] for j in range(len(self.players)) if i != j and min(abs(i-j)-1, abs(i-len(self.players)-j))+players[j].get_visibility() <= sight] + def play_turn(self): self.players[self.turn].play_turn() @@ -50,3 +57,15 @@ class Game: self.turn = (self.turn + 1) % len(self.players) self.play_turn() + +game = Game() +p1 = players.Player('p1') +game.add_player(p1) +p2 = players.Player('p2') +game.add_player(p2) +p3 = players.Player('p3') +game.add_player(p3) +game.start_game() +for p in game.players: + p.set_character(random.choice(p.available_characters)) +game.distribute_roles() \ No newline at end of file diff --git a/players.py b/players.py index e4f6069..2e17f52 100644 --- a/players.py +++ b/players.py @@ -13,15 +13,22 @@ class Player: self.lives = 0 self.max_lives = 0 self.game = None - + self.is_my_turn = False + self.is_waiting_for_action = True + self.has_played_bang = False + def join_game(self, game): self.game = game + print(f'I {self.id} joined {game}') def set_role(self, role: roles.Role): self.role = role + print(f'I {self.id} am a {role.name}') def set_character(self, character: characters.Character): + self.available_characters = [] self.character = character + print(f'I {self.id} chose character {character.name}') def prepare(self): self.max_lives = self.character.max_lives + self.role.health_mod @@ -31,13 +38,65 @@ class Player: def set_available_character(self, available): self.available_characters = available + print(f'I {self.id} have to choose between {available}') def play_turn(self): - print('not implemented') + self.is_my_turn = True + self.is_waiting_for_action = True + self.has_played_bang = False + print(f'I {self.id} was notified that it is my turn') + print(f'lives: {self.lives}/{self.max_lives} hand: {[str(c) for c in self.hand]}') + + def get_playable_cards(self): + playable_cards = [] + for i in range(len(self.hand)): + card = self.hand[i] + if type(card) == cards.Bang and self.has_played_bang and not any([type(c) == cards.Volcanic for c in self.equipment]): + continue + elif type(card) == cards.Birra and self.lives >= self.max_lives: + continue + else: + playable_cards.append(i) + return playable_cards + + def play_card(self, hand_index: int, againts=None): + if not (0 <= hand_index < len(self.hand)): + print('illegal') + return + card: cards.Card = self.hand.pop(hand_index) + print(self.id, 'is playing ', card, ' against:', againts) + if card.is_equipment and card.name not in [c.name for c in self.equipment]: + if card.is_weapon: + for i in range(len(self.equipment)): + if self.equipment[i].is_weapon: + game.deck.scrap(self.equipment[i]) + self.equipment[i] = card + break + else: + self.equipment.append(card) + else: + if type(card) == cards.Bang and self.has_played_bang and not any([type(c) == cards.Volcanic for c in self.equipment]): + print('you retard') + game.deck.scrap(card) + pass + + def get_sight(self): + aim = 0 + for card in self.equipment: + aim += card.sight_mod + if card.is_weapon: + aim += card.range + return 1 + self.character.sight_mod + aim + + def get_visibility(self): + covers = 0 + for card in self.equipment: + covers += card.vis_mod + return self.character.visibility_mod + covers def end_turn(self): if len(self.hand) > self.max_lives: - print("discard a card") + print(f"I {self.id} have to many cards in my hand and I can't end the turn") else: game.next_turn() diff --git a/roles.py b/roles.py index a1ee589..fee4ef0 100644 --- a/roles.py +++ b/roles.py @@ -13,8 +13,7 @@ class Role(ABC): class Sheriff(Role): def __init__(self): - super().__init__("Sceriffo", +1) - self.goal = "Elimina tutti i Fuorilegge e il Rinnegato!" + super().__init__("Sceriffo", "Elimina tutti i Fuorilegge e il Rinnegato!", health_mod=+1) self.max_players = 1 def on_player_death(self, alive_players: list): @@ -25,8 +24,7 @@ class Sheriff(Role): class Vice(Role): def __init__(self): - super().__init__("Vice") - self.goal = "Proteggi lo Sceriffo! Elimina tutti i Fuorilegge e il Rinnegato!" + super().__init__("Vice", "Proteggi lo Sceriffo! Elimina tutti i Fuorilegge e il Rinnegato!") self.max_players = 2 def on_player_death(self, alive_players: list): @@ -36,8 +34,7 @@ class Vice(Role): class Outlaw(Role): def __init__(self): - super().__init__("Fuorilegge") - self.goal = "Elimina lo Sceriffo!" + super().__init__("Fuorilegge", "Elimina lo Sceriffo!") self.max_players = 3 def on_player_death(self, alive_players: list): @@ -47,8 +44,7 @@ class Outlaw(Role): class Renegade(Role): def __init__(self): - super().__init__("Rinnegato") - self.goal = "Rimani l'ultimo personaggio in gioco!" + super().__init__("Rinnegato", "Rimani l'ultimo personaggio in gioco!") self.max_players = 1 def on_player_death(self, alive_players: list):