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 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):

View File

@ -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()]
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
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)

21
game.py
View File

@ -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()

View File

@ -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()

View File

@ -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):