After playing the card game with people for the first time, the game turned out to be rather boring. The way we played took absolutely no thought whatsoever and turned out to be very easy to automate. The game below is configured for four different players to complete the simple game until it ends. Each player's hand in printed, and the cards played in each round is shown till someone finishes. Whoever wins is shown at the end of the simulation, and the program quickly exits when complete.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 | import random
################################################################################
def main():
table = Table(['Matthew', 'Mark', 'Luke', 'John'])
table.deal_cards()
table.play_all()
def print_underline(string, line):
print('\n{}\n{}'.format(string, line * len(string)))
################################################################################
class Table:
def __init__(self, players):
self.players = [Player(name, Hand()) for name in players]
self.deck = Deck()
self.rounds = 0
def deal_cards(self):
self.deck.shuffle()
self.deck.setup_hands(self.players)
for player in self.players:
player.show_hand()
def play_once(self, tied=None):
if tied is None:
self.count_round()
collection = Pot()
for player in (self.players if tied is None else tied):
player.drop_card(collection)
if tied:
player.drop_bonus(collection, 3)
winner = collection.winner
if winner is not None:
collection.reward(winner)
else:
winner = self.play_once(collection.tied)
collection.reward(winner)
return winner
def count_round(self):
self.rounds += 1
print_underline('Starting round {}'.format(self.rounds), '=')
def play_all(self):
while not self.finished:
self.play_once()
self.show_winner()
def show_winner(self):
for player in self.players:
if player.hand.has_cards:
print()
print(player.name, 'wins!')
break
@property
def finished(self):
return sum(bool(player.hand.cards) for player in self.players) == 1
################################################################################
class Player:
def __init__(self, name, hand):
self.name, self.hand = name, hand
def drop_card(self, collection):
if self.hand.has_cards:
collection.add_card(self.hand.take_top(), self)
def drop_bonus(self, collection, count):
collection.add_bonus(self.hand.cards[:count])
self.hand.cards = self.hand.cards[count:]
def give_cards(self, cards):
self.hand.add_all(cards)
def show_hand(self):
print(self.name, 'has', self.hand)
################################################################################
class Hand:
def __init__(self):
self.cards = []
def __str__(self):
return ', '.join(map(str, self.cards))
def add_card(self, card):
self.cards.append(card)
def take_top(self):
return self.cards.pop(0)
def add_all(self, cards):
self.cards.extend(cards)
@property
def has_cards(self):
return bool(self.cards)
################################################################################
class Deck:
def __init__(self):
self.cards = [Card(s, r) for s in Card.SUITE for r in Card.RANKS]
def shuffle(self):
random.shuffle(self.cards)
def setup_hands(self, players):
hands = [player.hand for player in players]
while len(self.cards) >= len(players):
for hand in hands:
hand.add_card(self.cards.pop())
return hands
################################################################################
class Card:
SUITE = 'H D S C'.split()
RANKS = '2 3 4 5 6 7 8 9 10 J Q K A'.split()
def __init__(self, suite, rank):
self.suite, self.rank = suite, rank
def __str__(self):
return '{}-{}'.format(self.rank, self.suite)
@property
def value(self):
return self.RANKS.index(self.rank)
################################################################################
class Pot:
def __init__(self):
self.cards = []
self.players = []
self.bonus = []
def add_card(self, card, player):
self.cards.append(card)
self.players.append(player)
def add_bonus(self, cards):
self.bonus.extend(cards)
@property
def winner(self):
self.show_pot()
values = [card.value for card in self.cards]
self.best = max(values)
if values.count(self.best) == 1:
return self.players[values.index(self.best)]
def show_pot(self):
for player, card in zip(self.players, self.cards):
print('{} laid down a {}.'.format(player.name, card))
def reward(self, player):
player.give_cards(self.cards)
player.give_cards(self.bonus)
@property
def tied(self):
for card, player in zip(self.cards, self.players):
if card.value == self.best:
yield player
################################################################################
if __name__ == '__main__':
main()
|
This simple program is original, and the older versions were not referenced when writing this:
- War Game (Version 1) - Recipe 440621
- War Game (Version 2) - Recipe 440622
- War Game (Version 3) - Recipe 442483
- War Game (Version 4) - Recipe 464727