This commit is contained in:
Alberto Xamin 2020-11-15 23:13:17 +01:00
parent 28a8cd02b5
commit 768415d2ed
No known key found for this signature in database
GPG Key ID: 4F026F48309500A2
6 changed files with 205 additions and 48 deletions

View File

@ -1,12 +1,12 @@
from typing import List, Set, Dict, Tuple, Optional from typing import List, Set, Dict, Tuple, Optional
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from enum import Enum from enum import IntEnum
class Suit(Enum): class Suit(IntEnum):
DIAMONDS = 1 # ♦ DIAMONDS = 0 # ♦
CLUBS = 2 # ♣ CLUBS = 1 # ♣
HEARTS = 3 # ♥ HEARTS = 2 # ♥
SPADES = 4 # ♠ SPADES = 3 # ♠
class Card(ABC): class Card(ABC):
sym = { sym = {
@ -15,7 +15,7 @@ class Card(ABC):
'Q': 12, 'Q': 12,
'K': 13 '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__() super().__init__()
self.name = name self.name = name
self.suit = suit self.suit = suit
@ -26,6 +26,14 @@ class Card(ABC):
self.number = self.sym[number] self.number = self.sym[number]
self.is_equipment = is_equipment self.is_equipment = is_equipment
self.is_weapon = is_weapon 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): class Barile(Card):
def __init__(self, suit, number): def __init__(self, suit, number):
@ -37,11 +45,11 @@ class Dinamite(Card):
class Mirino(Card): class Mirino(Card):
def __init__(self, suit, number): 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): class Mustang(Card):
def __init__(self, suit, number): 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): class Prigione(Card):
def __init__(self, suit, number): def __init__(self, suit, number):
@ -49,23 +57,23 @@ class Prigione(Card):
class Remington(Card): class Remington(Card):
def __init__(self, suit, number): 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): class RevCarabine(Card):
def __init__(self, suit, number): 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): class Schofield(Card):
def __init__(self, suit, number): 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): class Volcanic(Card):
def __init__(self, suit, number): 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): class Winchester(Card):
def __init__(self, suit, number): 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): class Bang(Card):
def __init__(self, suit, number): def __init__(self, suit, number):
@ -105,7 +113,7 @@ class Mancato(Card):
class Panico(Card): class Panico(Card):
def __init__(self, suit, number): def __init__(self, suit, number):
super().__init__(suit, 'Panico!', number) super().__init__(suit, 'Panico!', number, range=1)
class Saloon(Card): class Saloon(Card):
def __init__(self, suit, number): def __init__(self, suit, number):

View File

@ -8,21 +8,21 @@ class Character(ABC):
self.sight_mod = 0 self.sight_mod = 0
self.visibility_mod = 0 self.visibility_mod = 0
@abstractmethod # @abstractmethod
def on_hurt(self, dmg: int): # def on_hurt(self, dmg: int):
pass # pass
@abstractmethod # @abstractmethod
def on_pick(self, card): # tipo dinamite e prigione # def on_pick(self, card): # tipo dinamite e prigione
pass # pass
@abstractmethod # @abstractmethod
def on_empty_hand(self): # def on_empty_hand(self):
pass # pass
@abstractmethod # @abstractmethod
def on_empty_hand(self): # def on_empty_hand(self):
pass # pass
class BartCassidy(Character): class BartCassidy(Character):
def __init__(self): def __init__(self):
@ -35,5 +35,78 @@ class BlackJack(Character):
def __init__(self): def __init__(self):
super().__init__("Black Jack", max_lives=4) 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(): def all_characters():
return [BartCassidy(), BlackJack()] return [
BartCassidy(),
BlackJack(),
CalamityJanet(),
ElGringo(),
JesseJones(),
Jourdonnais(),
KitCarlson(),
LuckyDuke(),
PaulRegret(),
PedroRamirez(),
RoseDoolan(),
SidKetchum(),
SlabTheKiller(),
SuzyLafayette(),
VultureSam(),
WillyTheKid(),
]

18
deck.py
View File

@ -1,28 +1,30 @@
from typing import List, Set, Dict, Tuple, Optional from typing import List, Set, Dict, Tuple, Optional
import random import random
import cards from cards import Card, get_starting_deck
class Deck: class Deck:
def __init__(self): def __init__(self):
super().__init__() super().__init__()
self.cards: List[cards.Card] = random.shuffle(cards.get_starting_deck()) self.cards: List[Card] = get_starting_deck()
self.scrap_pile: List[cards.Card] = [] 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: def peek(self, n_cards: int) -> list:
return self.cards[:n_cards] return self.cards[:n_cards]
def peek_scrap_pile(self,) -> cards.Card: def peek_scrap_pile(self,) -> Card:
if len(self.scrap_pile) > 0: if len(self.scrap_pile) > 0:
return self.scrap_pile[-1] return self.scrap_pile[-1]
else: else:
return None return None
def pick_and_scrap(self) -> cards.Card: def pick_and_scrap(self) -> Card:
card = self.cards.pop(0) card = self.cards.pop(0)
self.scrap_pile.append(card) self.scrap_pile.append(card)
return card return card
def draw(self) -> cards.Card: def draw(self) -> Card:
card = self.cards.pop(0) card = self.cards.pop(0)
if len(self.cards) == 0: if len(self.cards) == 0:
self.cards = self.scrap_pile[:-1].copy() self.cards = self.scrap_pile[:-1].copy()
@ -30,11 +32,11 @@ class Deck:
self.scrap_pile = self.scrap_pile[-1:] self.scrap_pile = self.scrap_pile[-1:]
return card return card
def draw_from_scrap_pile(self) -> cards.Card: def draw_from_scrap_pile(self) -> Card:
if len(self.scrap_pile) > 0: if len(self.scrap_pile) > 0:
return self.scrap_pile.pop(0) return self.scrap_pile.pop(0)
else: else:
return self.draw() return self.draw()
def scrap(self, card: cards.Card): def scrap(self, card: Card):
self.scrap_pile.append(card) self.scrap_pile.append(card)

21
game.py
View File

@ -16,13 +16,15 @@ class Game:
def add_player(self, player: players.Player): def add_player(self, player: players.Player):
player.join_game(self) player.join_game(self)
self.players.append(player) self.players.append(player)
print(f'Added player {player.id} to game')
def choose_characters(self): 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)): for i in range(len(self.players)):
self.players[i].set_available_character(char_cards[i*2:i*2+2]) self.players[i].set_available_character(char_cards[i*2:i*2+2])
def start_game(self): def start_game(self):
print('GAME IS STARING')
if self.started: if self.started:
return return
self.started = True self.started = True
@ -43,6 +45,11 @@ class Game:
self.players[i].hand.append(self.deck.draw()) self.players[i].hand.append(self.deck.draw())
self.play_turn() 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): def play_turn(self):
self.players[self.turn].play_turn() self.players[self.turn].play_turn()
@ -50,3 +57,15 @@ class Game:
self.turn = (self.turn + 1) % len(self.players) self.turn = (self.turn + 1) % len(self.players)
self.play_turn() 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()

View File

@ -13,15 +13,22 @@ class Player:
self.lives = 0 self.lives = 0
self.max_lives = 0 self.max_lives = 0
self.game = None self.game = None
self.is_my_turn = False
self.is_waiting_for_action = True
self.has_played_bang = False
def join_game(self, game): def join_game(self, game):
self.game = game self.game = game
print(f'I {self.id} joined {game}')
def set_role(self, role: roles.Role): def set_role(self, role: roles.Role):
self.role = role self.role = role
print(f'I {self.id} am a {role.name}')
def set_character(self, character: characters.Character): def set_character(self, character: characters.Character):
self.available_characters = []
self.character = character self.character = character
print(f'I {self.id} chose character {character.name}')
def prepare(self): def prepare(self):
self.max_lives = self.character.max_lives + self.role.health_mod self.max_lives = self.character.max_lives + self.role.health_mod
@ -31,13 +38,65 @@ class Player:
def set_available_character(self, available): def set_available_character(self, available):
self.available_characters = available self.available_characters = available
print(f'I {self.id} have to choose between {available}')
def play_turn(self): 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): def end_turn(self):
if len(self.hand) > self.max_lives: 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: else:
game.next_turn() game.next_turn()

View File

@ -13,8 +13,7 @@ class Role(ABC):
class Sheriff(Role): class Sheriff(Role):
def __init__(self): def __init__(self):
super().__init__("Sceriffo", +1) super().__init__("Sceriffo", "Elimina tutti i Fuorilegge e il Rinnegato!", health_mod=+1)
self.goal = "Elimina tutti i Fuorilegge e il Rinnegato!"
self.max_players = 1 self.max_players = 1
def on_player_death(self, alive_players: list): def on_player_death(self, alive_players: list):
@ -25,8 +24,7 @@ class Sheriff(Role):
class Vice(Role): class Vice(Role):
def __init__(self): def __init__(self):
super().__init__("Vice") super().__init__("Vice", "Proteggi lo Sceriffo! Elimina tutti i Fuorilegge e il Rinnegato!")
self.goal = "Proteggi lo Sceriffo! Elimina tutti i Fuorilegge e il Rinnegato!"
self.max_players = 2 self.max_players = 2
def on_player_death(self, alive_players: list): def on_player_death(self, alive_players: list):
@ -36,8 +34,7 @@ class Vice(Role):
class Outlaw(Role): class Outlaw(Role):
def __init__(self): def __init__(self):
super().__init__("Fuorilegge") super().__init__("Fuorilegge", "Elimina lo Sceriffo!")
self.goal = "Elimina lo Sceriffo!"
self.max_players = 3 self.max_players = 3
def on_player_death(self, alive_players: list): def on_player_death(self, alive_players: list):
@ -47,8 +44,7 @@ class Outlaw(Role):
class Renegade(Role): class Renegade(Role):
def __init__(self): def __init__(self):
super().__init__("Rinnegato") super().__init__("Rinnegato", "Rimani l'ultimo personaggio in gioco!")
self.goal = "Rimani l'ultimo personaggio in gioco!"
self.max_players = 1 self.max_players = 1
def on_player_death(self, alive_players: list): def on_player_death(self, alive_players: list):