cowiz20/wiz_game.py

259 lines
7.2 KiB
Python
Raw Normal View History

2020-04-05 16:00:48 +02:00
import random
2020-04-06 21:59:31 +02:00
from operator import attrgetter
2020-04-05 16:00:48 +02:00
def chunks(lst, n):
"""Yield successive n-sized chunks from lst."""
for i in range(0, len(lst), n):
yield lst[i:i + n]
class Card:
def __init__(self, color, value):
self.color = color
self.value = value
def __str__(self):
sc = self.color if self.color else ' '
sv = str(self.value)
return sc+' '+sv
def __repr__(self):
return str(self)
2020-04-13 16:14:36 +02:00
def get_higher_card(card1: Card, card2: Card, trump_color: str):
"""
compares two cards, assuming card1 was played first and card2 played second.
returns: True if card2 beats card1, otherwise False
"""
if card2.value == 'N':
# no way to win in 'N' comes in second
return False
elif card1.value == 'Z':
# no way to win if 'Z' was already played
return False
elif card1.value == 'N':
# any other than 'N' will beat us here, and the special case
# where card2 also is 'N' was already handled above
return True
elif card2.value == 'Z':
# we only lose if card1 is also 'Z', and that was handled above,
# so this is an easy case also
return True
else:
if card1.color == card2.color:
if card1.value > card2.value:
return False
else:
return True
elif card2.color == trump_color:
return True
else:
return False
2020-04-05 16:00:48 +02:00
class Player:
def __init__(self, name, player_id):
self.name = name
self.id = player_id
self.cards = []
def set_cards(self, cards):
2020-04-06 21:59:31 +02:00
self.cards = sorted(cards, key=attrgetter('color', 'value'))
2020-04-05 16:00:48 +02:00
2020-04-12 15:27:05 +02:00
#def show_cards(self):
# print(self.cards)
2020-04-05 16:00:48 +02:00
2020-04-06 22:42:31 +02:00
def play_card(self, card_idx):
c = self.cards[card_idx]
self.cards.remove(c)
return c
2020-04-12 15:27:05 +02:00
class Table:
def __init__(self):
#self.played_cards = {0: None, 1: None, 2: None, 3: None, 4: None, 5: None}
2020-04-13 16:14:36 +02:00
self.players = list()
self.played_cards = list()
2020-04-12 15:27:05 +02:00
self.num_cards_played = 0
self.trump_card = None
def init(self):
2020-04-13 16:14:36 +02:00
self.players.clear()
self.played_cards.clear()
2020-04-12 15:27:05 +02:00
self.num_cards_played = 0
self.trump_card = None
def add_player(self, p: Player):
2020-04-13 16:14:36 +02:00
self.players.append(p)
def clear_table(self, start_player):
self.played_cards.clear()
p1 = self.players[start_player:]
p2 = self.players[:start_player]
for p in p1:
t = (p, None)
self.played_cards.append(t)
for p in p2:
t = (p, None)
self.played_cards.append(t)
2020-04-12 15:27:05 +02:00
self.num_cards_played = 0
def play_card(self, player: Player, card: Card):
2020-04-13 16:14:36 +02:00
t = (player, card)
self.played_cards[player.id] = t
2020-04-12 15:27:05 +02:00
self.num_cards_played += 1
2020-04-06 22:42:31 +02:00
2020-04-05 16:00:48 +02:00
class WizGame:
def __init__(self):
self.players = []
self.card_deck = []
2020-04-05 23:27:33 +02:00
self.trump_card = None
2020-04-06 22:42:31 +02:00
self.table = Table()
2020-04-13 16:14:36 +02:00
self.start_player = 0
self.active_player = 0
2020-04-12 15:27:05 +02:00
self.current_round = 1
2020-04-13 16:14:36 +02:00
self.num_tricks_played = 0
2020-04-05 16:00:48 +02:00
def create_deck(self):
2020-04-12 15:27:05 +02:00
self.card_deck = []
2020-04-05 16:00:48 +02:00
for color in ["b", "r", "g", "y"]:
2020-04-05 23:27:33 +02:00
for val in range(1, 14):
2020-04-05 16:00:48 +02:00
self.card_deck.append(Card(color, val))
2020-04-05 23:27:33 +02:00
for _ in range(1, 5):
2020-04-06 21:59:31 +02:00
self.card_deck.append(Card('-', 'Z'))
2020-04-05 23:27:33 +02:00
for _ in range(1, 5):
2020-04-06 21:59:31 +02:00
self.card_deck.append(Card('-', 'N'))
2020-04-12 15:27:05 +02:00
#print(self.card_deck)
2020-04-05 16:00:48 +02:00
2020-04-13 16:14:36 +02:00
def set_trump_color(self, trump_color):
if self.trump_card.value != 'Z':
return False
else:
if trump_color not in ["b", "r", "g", "y"]:
return False
else:
self.trump_card.color = trump_color
return True
2020-04-05 23:27:33 +02:00
def get_trump_color(self):
card = self.trump_card
if card:
if card.color:
return card.color
elif card.value == 'Z':
return 'choose'
else:
return None
2020-04-05 16:00:48 +02:00
else:
2020-04-05 23:27:33 +02:00
return None
2020-04-05 16:00:48 +02:00
def deal_cards(self, cards_per_player):
random.shuffle(self.card_deck)
cs = list(chunks(self.card_deck, cards_per_player))
2020-04-05 23:27:33 +02:00
for idx, p in enumerate(self.players):
2020-04-05 16:00:48 +02:00
p.set_cards(cs[idx])
2020-04-12 15:27:05 +02:00
#p.show_cards()
2020-04-05 16:00:48 +02:00
if len(cs) > len(self.players):
cc = cs[len(self.players)]
c = cc[0]
2020-04-05 23:27:33 +02:00
self.trump_card = c
2020-04-05 16:00:48 +02:00
else:
2020-04-05 23:27:33 +02:00
self.trump_card = None
2020-04-05 16:00:48 +02:00
2020-04-13 16:14:36 +02:00
def add_player(self, name: str):
2020-04-05 16:00:48 +02:00
if len(self.players) < 6:
2020-04-13 16:14:36 +02:00
player_id = len(self.players)
2020-04-12 15:27:05 +02:00
p = Player(name, player_id)
self.players.append(p)
self.table.add_player(p)
2020-04-13 16:14:36 +02:00
# def get_active_player(self):
# return self.players[self.active_player]
def get_trick_winner(self):
cards = self.table.played_cards
high_player, high_card = cards[0]
2020-04-05 16:00:48 +02:00
2020-04-13 16:14:36 +02:00
for player, card in cards[1:]:
if get_higher_card(high_card, card, self.trump_card.color):
high_card = card
high_player = player
return high_player, high_card
def is_trick_finished(self):
if self.table.num_cards_played < len(self.players):
2020-04-12 15:27:05 +02:00
return False
else:
return True
2020-04-13 16:14:36 +02:00
def is_hand_finished(self):
h = self.is_trick_finished()
if h and self.num_tricks_played == self.current_round:
return True
else:
return False
def next_hand(self):
max_hands = len(self.card_deck)/len(self.players)
if self.current_round <= max_hands:
2020-04-12 15:27:05 +02:00
self.current_round += 1
2020-04-13 16:14:36 +02:00
self.start_player += 1
if self.start_player >= len(self.players):
self.start_player = 0
2020-04-12 15:27:05 +02:00
self.active_player = self.start_player
2020-04-13 16:14:36 +02:00
self.table.clear_table(self.start_player)
2020-04-12 15:27:05 +02:00
self.deal_cards(self.current_round)
2020-04-13 16:14:36 +02:00
self.num_tricks_played = 0
2020-04-12 15:27:05 +02:00
return True
else:
return False
2020-04-13 16:14:36 +02:00
def next_trick(self):
self.table.clear_table(self.start_player)
self.start_player = self.get_trick_winner().id
2020-04-12 15:27:05 +02:00
def init_game(self):
self.create_deck()
self.current_round = 1
self.active_player = 0
self.start_player = 0
2020-04-13 16:14:36 +02:00
self.table.clear_table(self.start_player)
2020-04-12 15:27:05 +02:00
self.deal_cards(1)
2020-04-06 22:42:31 +02:00
self.table.num_players = len(self.players)
2020-04-12 15:27:05 +02:00
def play_card(self, player, card):
p = self.players[player]
c = p.play_card(card)
self.table.play_card(p, c)
self.next_player()
2020-04-13 16:14:36 +02:00
if self.is_trick_finished():
self.num_tricks_played += 1
2020-04-12 15:27:05 +02:00
def next_player(self):
2020-04-13 16:14:36 +02:00
if not self.is_hand_finished():
self.active_player += 1
if self.active_player >= len(self.players):
self.active_player = 0
else:
self.active_player = None
def get_prev_player(self):
if self.start_player == 0:
return len(self.players)-1
else:
return self.start_player-1
2020-04-12 15:27:05 +02:00
def is_players_turn(self, player):
2020-04-13 16:14:36 +02:00
if self.is_trick_finished():
return False;
2020-04-12 15:27:05 +02:00
if player == self.active_player:
return True
else:
return False
2020-04-05 16:00:48 +02:00
the_game = WizGame()