progress
This commit is contained in:
parent
28a8cd02b5
commit
768415d2ed
38
cards.py
38
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):
|
||||
|
@ -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
18
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)
|
21
game.py
21
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()
|
65
players.py
65
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()
|
||||
|
||||
|
12
roles.py
12
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):
|
||||
|
Loading…
Reference in New Issue
Block a user