First implementation and testing client
parent
3346ca8a3d
commit
1db6116b74
@ -0,0 +1,136 @@
|
||||
from enum import Enum, auto
|
||||
from random import shuffle
|
||||
|
||||
class Suit(Enum):
|
||||
CLUBS = auto()
|
||||
HEARTS = auto()
|
||||
DIAMONDS = auto()
|
||||
SPADES = auto()
|
||||
|
||||
class Game:
|
||||
def __init__(self):
|
||||
self.foundations = {suit: 1 for suit in Suit}
|
||||
self.deck = self.get_random_pile()
|
||||
self.carpet = set(self.deck[-20:])
|
||||
self.free_cells = 0
|
||||
self.moves = 0
|
||||
self.deck = self.deck[:-20]
|
||||
self.offers = [self.deck.pop()]
|
||||
|
||||
def get_random_pile(self):
|
||||
cards = {(suit, value) for suit in Suit for value in range(2, 13+1)}
|
||||
deck = list(cards)
|
||||
shuffle(deck)
|
||||
return deck
|
||||
|
||||
def can_drop(self, card):
|
||||
suit, value = card
|
||||
return self.foundations[suit] == value - 1
|
||||
# FIXME: use this function.
|
||||
def can_move(self):
|
||||
if len(self.deck) > 0: return True
|
||||
if len(self.offers) > 0 and self.can_drop(self.offers[-1]): return True
|
||||
if any(self.can_drop(card) for card in self.carpet): return True
|
||||
if self.free_cells > 0: return True
|
||||
return False
|
||||
|
||||
def count_move(self):
|
||||
self.moves += 1
|
||||
|
||||
# Possible moves
|
||||
def drop_from_carpet(self, card):
|
||||
if card not in self.carpet:
|
||||
raise ValueError()
|
||||
suit, value = card
|
||||
if self.foundations[suit] != value - 1:
|
||||
raise ValueError()
|
||||
self.count_move()
|
||||
self.carpet.remove(card)
|
||||
self.free_cells += 1
|
||||
self.foundations[suit] = value;
|
||||
def autodrop(self):
|
||||
# This is independent for each suit.
|
||||
for suit in Suit:
|
||||
while (suit, self.foundations[suit]+1) in self.carpet:
|
||||
self.drop_from_carpet((suit, self.foundations[suit]+1))
|
||||
def drop_card_from_offer(self): # to the foundations
|
||||
if len(self.offers) == 0:
|
||||
raise ValueError()
|
||||
offered_card = self.offers[-1]
|
||||
suit, value = offered_card
|
||||
if self.foundations[suit] != value - 1:
|
||||
raise ValueError()
|
||||
self.count_move()
|
||||
self.offers.pop()
|
||||
self.foundations[suit] = value
|
||||
if len(self.offers) == 0 and len(self.deck) > 0:
|
||||
self.count_move()
|
||||
self.offers.append(self.deck.pop())
|
||||
def flip_deck(self):
|
||||
if len(self.deck) == 0:
|
||||
raise ValueError()
|
||||
self.count_move()
|
||||
self.offers.append(self.deck.pop())
|
||||
def get_card_from_deck(self):
|
||||
if len(self.offers) == 0:
|
||||
raise ValueError()
|
||||
if self.free_cells < 1:
|
||||
raise ValueError()
|
||||
self.count_move()
|
||||
self.carpet.add(self.offers.pop())
|
||||
self.free_cells -= 1
|
||||
if len(self.offers) == 0 and len(self.deck) > 0:
|
||||
self.count_move()
|
||||
self.offers.append(self.deck.pop())
|
||||
def game_result(self): # None for not finished, True for win, False for fail
|
||||
if all(self.foundations[suit] == 13 for suit in Suit):
|
||||
return True
|
||||
if self.can_move(): return None
|
||||
return False
|
||||
def print(self):
|
||||
from pprint import pprint
|
||||
# Print game state
|
||||
print(f'Moves: {self.moves}\nFree cells: {self.free_cells}\nCards in deck: {len(self.deck)}\nAvailable card: {self.offers[-1] if len(self.offers) > 0 else "None"}')
|
||||
print('Foundations:')
|
||||
pprint(self.foundations)
|
||||
print('Carpet:')
|
||||
pprint(self.carpet)
|
||||
|
||||
if __name__ == '__main__':
|
||||
## A simple testing game:
|
||||
from textwrap import dedent
|
||||
|
||||
game = Game()
|
||||
game.print()
|
||||
while game.game_result() is None:
|
||||
q = input('pafdg? ')
|
||||
try:
|
||||
if q.startswith('p'):
|
||||
game.print()
|
||||
if q.startswith('a'):
|
||||
game.autodrop()
|
||||
if q.startswith('f'):
|
||||
game.flip_deck()
|
||||
if q.startswith('d'):
|
||||
game.drop_card_from_offer()
|
||||
if q.startswith('g'):
|
||||
game.get_card_from_deck()
|
||||
if q.startswith('?'):
|
||||
print(dedent("""\
|
||||
p: print state
|
||||
a: autodrop carpet
|
||||
f: flip deck
|
||||
d: drop from offers
|
||||
g: get from offers
|
||||
?: this help.
|
||||
"""))
|
||||
except ValueError as e:
|
||||
print(e)
|
||||
print('Try again!')
|
||||
print(f'Game ended in {game.moves}.')
|
||||
if game.game_result():
|
||||
print('You won!')
|
||||
else:
|
||||
print('You lost:')
|
||||
game.print()
|
||||
|
Loading…
Reference in New Issue