pick and draw logic
This commit is contained in:
parent
f4a5f2d015
commit
9e5888e5ed
@ -1,12 +1,13 @@
|
|||||||
from abc import ABC, abstractmethod
|
from abc import ABC, abstractmethod
|
||||||
|
|
||||||
class Character(ABC):
|
class Character(ABC):
|
||||||
def __init__(self, name: str, max_lives: int, sight_mod: int = 0, visibility_mod: int = 0):
|
def __init__(self, name: str, max_lives: int, sight_mod: int = 0, visibility_mod: int = 0, pick_mod: int = 0):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.name = name
|
self.name = name
|
||||||
self.max_lives = max_lives
|
self.max_lives = max_lives
|
||||||
self.sight_mod = 0
|
self.sight_mod = 0
|
||||||
self.visibility_mod = 0
|
self.visibility_mod = 0
|
||||||
|
self.pick_mod = 0
|
||||||
|
|
||||||
# @abstractmethod
|
# @abstractmethod
|
||||||
# def on_hurt(self, dmg: int):
|
# def on_hurt(self, dmg: int):
|
||||||
@ -57,7 +58,7 @@ class KitCarlson(Character):
|
|||||||
|
|
||||||
class LuckyDuke(Character):
|
class LuckyDuke(Character):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__("Lucky Duke", max_lives=4)
|
super().__init__("Lucky Duke", max_lives=4, pick_mod=1)
|
||||||
|
|
||||||
class PaulRegret(Character):
|
class PaulRegret(Character):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
9
game.py
9
game.py
@ -16,7 +16,7 @@ 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')
|
print(f'Added player {player.name} to game')
|
||||||
|
|
||||||
def choose_characters(self):
|
def choose_characters(self):
|
||||||
char_cards = random.sample(all_characters(), len(self.players)*2)
|
char_cards = random.sample(all_characters(), len(self.players)*2)
|
||||||
@ -48,7 +48,10 @@ class Game:
|
|||||||
def get_visible_players(self, player):
|
def get_visible_players(self, player):
|
||||||
i = self.players.index(player)
|
i = self.players.index(player)
|
||||||
sight = player.get_sight()
|
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))+self.players[j].get_visibility() <= 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)) + self.players[j].get_visibility() <= sight]
|
||||||
|
|
||||||
|
def next_player(self):
|
||||||
|
return self.players[(self.turn + 1) % len(self.players)]
|
||||||
|
|
||||||
def play_turn(self):
|
def play_turn(self):
|
||||||
self.players[self.turn].play_turn()
|
self.players[self.turn].play_turn()
|
||||||
@ -68,4 +71,4 @@ game.add_player(p3)
|
|||||||
game.start_game()
|
game.start_game()
|
||||||
for p in game.players:
|
for p in game.players:
|
||||||
p.set_character(random.choice(p.available_characters))
|
p.set_character(random.choice(p.available_characters))
|
||||||
game.distribute_roles()
|
game.distribute_roles()
|
||||||
|
98
players.py
98
players.py
@ -1,11 +1,21 @@
|
|||||||
|
from enum import IntEnum
|
||||||
|
import json
|
||||||
|
|
||||||
import roles
|
import roles
|
||||||
import cards
|
import cards
|
||||||
import characters
|
import characters
|
||||||
|
|
||||||
|
class PendingAction(IntEnum):
|
||||||
|
PICK = 0
|
||||||
|
DRAW = 1
|
||||||
|
PLAY = 2
|
||||||
|
RESPOND = 3
|
||||||
|
WAIT = 4
|
||||||
|
|
||||||
class Player:
|
class Player:
|
||||||
def __init__(self, id):
|
def __init__(self, name):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.id = id
|
self.name = name
|
||||||
self.hand: cards.Card = []
|
self.hand: cards.Card = []
|
||||||
self.equipment: cards.Card = []
|
self.equipment: cards.Card = []
|
||||||
self.role: roles.Role = None
|
self.role: roles.Role = None
|
||||||
@ -16,19 +26,22 @@ class Player:
|
|||||||
self.is_my_turn = False
|
self.is_my_turn = False
|
||||||
self.is_waiting_for_action = True
|
self.is_waiting_for_action = True
|
||||||
self.has_played_bang = False
|
self.has_played_bang = False
|
||||||
|
self.pending_action: PendingAction = None
|
||||||
|
self.available_characters = []
|
||||||
|
self.was_shot = False
|
||||||
|
|
||||||
def join_game(self, game):
|
def join_game(self, game):
|
||||||
self.game = game
|
self.game = game
|
||||||
print(f'I {self.id} joined {game}')
|
print(f'I {self.name} joined {self.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}, my goal is "{role.goal}"')
|
print(f'I {self.name} am a {role.name}, my goal is "{role.goal}"')
|
||||||
|
|
||||||
def set_character(self, character: characters.Character):
|
def set_character(self, character: characters.Character):
|
||||||
self.available_characters = []
|
self.available_characters = []
|
||||||
self.character = character
|
self.character = character
|
||||||
print(f'I {self.id} chose character {character.name}')
|
print(f'I {self.name} 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
|
||||||
@ -38,30 +51,71 @@ 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}')
|
print(f'I {self.name} have to choose between {available}')
|
||||||
|
|
||||||
def play_turn(self):
|
def play_turn(self):
|
||||||
|
print(f'I {self.name} was notified that it is my turn')
|
||||||
|
self.was_shot = False
|
||||||
self.is_my_turn = True
|
self.is_my_turn = True
|
||||||
self.is_waiting_for_action = True
|
self.is_waiting_for_action = True
|
||||||
self.has_played_bang = False
|
self.has_played_bang = False
|
||||||
print(f'I {self.id} was notified that it is my turn')
|
if any([isinstance(c) == cards.Dinamite or isinstance(c) == cards.Prigione for c in self.equipment]):
|
||||||
print(f'lives: {self.lives}/{self.max_lives} hand: {[str(c) for c in self.hand]}')
|
self.pending_action = PendingAction.PICK
|
||||||
print(f'I {self.id} can see {[p.get_public_description() for p in self.game.get_visible_players(self)]}')
|
|
||||||
|
# # print(f'lives: {self.lives}/{self.max_lives} hand: {[str(c) for c in self.hand]}')
|
||||||
|
# print(f'I {self.name} can see {[p.get_public_description() for p in self.game.get_visible_players(self)]}')
|
||||||
|
# ser = self.__dict__.copy()
|
||||||
|
# ser.pop('game')
|
||||||
|
# print(json.dumps(ser, default=lambda o: o.__dict__, indent=4))
|
||||||
|
def draw(self):
|
||||||
|
for i in range(2):
|
||||||
|
self.hand.append(self.game.deck.draw())
|
||||||
|
self.pending_action = PendingAction.PLAY
|
||||||
|
|
||||||
|
def pick(self):
|
||||||
|
pickable_cards = 1 + self.character.pick_mod
|
||||||
|
for i in range(len(self.equipment)):
|
||||||
|
if isinstance(self.equipment[i]) == cards.Dinamite:
|
||||||
|
while pickable_cards > 0:
|
||||||
|
pickable_cards -= 1
|
||||||
|
picked: cards.Card = self.game.deck.pick_and_scrap()
|
||||||
|
print(f'Did pick {picked}')
|
||||||
|
if picked.suit == cards.Suit.SPADES and 2 <= picked.number <= 9 and pickable_cards == 0:
|
||||||
|
self.lives -= 3
|
||||||
|
self.game.deck.scrap(self.equipment.pop(i))
|
||||||
|
print(f'{self.name} Boom, -3 hp')
|
||||||
|
else:
|
||||||
|
self.game.next_player().equipment.append(self.equipment.pop(i))
|
||||||
|
if any([isinstance(c) == cards.Dinamite or isinstance(c) == cards.Prigione for c in self.equipment]):
|
||||||
|
return
|
||||||
|
for i in range(len(self.equipment)):
|
||||||
|
if isinstance(self.equipment[i]) == cards.Prigione:
|
||||||
|
while pickable_cards > 0:
|
||||||
|
pickable_cards -= 1
|
||||||
|
picked: cards.Card = self.game.deck.pick_and_scrap()
|
||||||
|
print(f'Did pick {picked}')
|
||||||
|
if picked.suit != cards.Suit.HEARTS and pickable_cards == 0:
|
||||||
|
self.game.deck.scrap(self.equipment.pop(i))
|
||||||
|
self.end_turn(forced=True)
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
break
|
||||||
|
self.pending_action = PendingAction.DRAW
|
||||||
|
|
||||||
def get_playable_cards(self):
|
def get_playable_cards(self):
|
||||||
playable_cards = []
|
playable_cards = []
|
||||||
for i in range(len(self.hand)):
|
for i in range(len(self.hand)):
|
||||||
card = self.hand[i]
|
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]):
|
if isinstance(card) == cards.Bang and self.has_played_bang and not any([isinstance(c) == cards.Volcanic for c in self.equipment]):
|
||||||
continue
|
continue
|
||||||
elif type(card) == cards.Birra and self.lives >= self.max_lives:
|
elif isinstance(card) == cards.Birra and self.lives >= self.max_lives:
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
playable_cards.append(i)
|
playable_cards.append(i)
|
||||||
return playable_cards
|
return playable_cards
|
||||||
|
|
||||||
def get_public_description(self):
|
def get_public_description(self):
|
||||||
s = f"{self.id} {'Sheriff ⭐️' if type(self.role) == roles.Sheriff else ''} ({self.lives}/{self.max_lives} ⁍) {len(self.hand)} Cards in hand, "
|
s = f"{self.name} {'Sheriff ⭐️' if isinstance(self.role) == roles.Sheriff else ''} ({self.lives}/{self.max_lives} ⁍) {len(self.hand)} Cards in hand, "
|
||||||
s += f"equipment {[str(c) for c in self.equipment]}"
|
s += f"equipment {[str(c) for c in self.equipment]}"
|
||||||
return s
|
return s
|
||||||
|
|
||||||
@ -70,21 +124,20 @@ class Player:
|
|||||||
print('illegal')
|
print('illegal')
|
||||||
return
|
return
|
||||||
card: cards.Card = self.hand.pop(hand_index)
|
card: cards.Card = self.hand.pop(hand_index)
|
||||||
print(self.id, 'is playing ', card, ' against:', againts)
|
print(self.name, 'is playing ', card, ' against:', againts)
|
||||||
if card.is_equipment and card.name not in [c.name for c in self.equipment]:
|
if card.is_equipment and card.name not in [c.name for c in self.equipment]:
|
||||||
if card.is_weapon:
|
if card.is_weapon:
|
||||||
for i in range(len(self.equipment)):
|
for i in range(len(self.equipment)):
|
||||||
if self.equipment[i].is_weapon:
|
if self.equipment[i].is_weapon:
|
||||||
game.deck.scrap(self.equipment[i])
|
self.game.deck.scrap(self.equipment[i])
|
||||||
self.equipment[i] = card
|
self.equipment[i] = card
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
self.equipment.append(card)
|
self.equipment.append(card)
|
||||||
else:
|
else:
|
||||||
if type(card) == cards.Bang and self.has_played_bang and not any([type(c) == cards.Volcanic for c in self.equipment]):
|
if isinstance(card) == cards.Bang and self.has_played_bang and not any([isinstance(c) == cards.Volcanic for c in self.equipment]):
|
||||||
print('you retard')
|
print('you retard')
|
||||||
game.deck.scrap(card)
|
self.game.deck.scrap(card)
|
||||||
pass
|
|
||||||
|
|
||||||
def get_sight(self):
|
def get_sight(self):
|
||||||
aim = 0
|
aim = 0
|
||||||
@ -100,9 +153,8 @@ class Player:
|
|||||||
covers += card.vis_mod
|
covers += card.vis_mod
|
||||||
return self.character.visibility_mod + covers
|
return self.character.visibility_mod + covers
|
||||||
|
|
||||||
def end_turn(self):
|
def end_turn(self, forced=False):
|
||||||
if len(self.hand) > self.max_lives:
|
if len(self.hand) > self.max_lives and not forced:
|
||||||
print(f"I {self.id} have to many cards in my hand and I can't end the turn")
|
print(f"I {self.name} have to many cards in my hand and I can't end the turn")
|
||||||
else:
|
else:
|
||||||
game.next_turn()
|
self.game.next_turn()
|
||||||
|
|
||||||
|
8
roles.py
8
roles.py
@ -17,7 +17,7 @@ class Sheriff(Role):
|
|||||||
self.max_players = 1
|
self.max_players = 1
|
||||||
|
|
||||||
def on_player_death(self, alive_players: list):
|
def on_player_death(self, alive_players: list):
|
||||||
if not any([type(p.role) == Outlaw or type(p.role) == Renegade for p in alive_players]):
|
if not any([isinstance(p.role) == Outlaw or isinstance(p.role) == Renegade for p in alive_players]):
|
||||||
print("The Sheriff won!")
|
print("The Sheriff won!")
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@ -28,7 +28,7 @@ class Vice(Role):
|
|||||||
self.max_players = 2
|
self.max_players = 2
|
||||||
|
|
||||||
def on_player_death(self, alive_players: list):
|
def on_player_death(self, alive_players: list):
|
||||||
if not any([type(p.role) == Outlaw or type(p.role) == Renegade for p in alive_players]):
|
if not any([isinstance(p.role) == Outlaw or isinstance(p.role) == Renegade for p in alive_players]):
|
||||||
print("The Vice won!")
|
print("The Vice won!")
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@ -38,7 +38,7 @@ class Outlaw(Role):
|
|||||||
self.max_players = 3
|
self.max_players = 3
|
||||||
|
|
||||||
def on_player_death(self, alive_players: list):
|
def on_player_death(self, alive_players: list):
|
||||||
if not any([type(p.role) == Sheriff for p in alive_players]):
|
if not any([isinstance(p.role) == Sheriff for p in alive_players]):
|
||||||
print("The Outlaw won!")
|
print("The Outlaw won!")
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@ -48,6 +48,6 @@ class Renegade(Role):
|
|||||||
self.max_players = 1
|
self.max_players = 1
|
||||||
|
|
||||||
def on_player_death(self, alive_players: list):
|
def on_player_death(self, alive_players: list):
|
||||||
if len(alive_players) == 1 and type(alive_players[0]) == Renegade:
|
if len(alive_players) == 1 and isinstance(alive_players[0]) == Renegade:
|
||||||
print("The Renegade won!")
|
print("The Renegade won!")
|
||||||
pass
|
pass
|
||||||
|
Loading…
Reference in New Issue
Block a user