Reputation: 31
I'm having troubles with comparing high cards in my poker program. I wanted to do it with suit symbols instead of letters, so I've complicate a simple program and transformed it to a "medium" level of programming. And yes, still needing answer
import random, time, json
from random import shuffle
from collections import Counter
from enum import Enum
class CardSuits(Enum):
Hearts = "Hearts"
Diamonds = "Diamonds"
Clubs = "Clubs"
Spades = "Spades"
class CardValues(Enum):
Two = 2
Three = 3
Four = 4
Five = 5
Six = 6
Seven = 7
Eight = 8
Nine = 9
Ten = 10
Jack = 11
Queen = 12
King = 13
Ace = 14
class Card:
_symbols = {"Hearts": "♥️", "Diamonds": "♦️", "Clubs": "♣️", "Spades": "♠"}
_numbers = {2: "2",
3: "3",
4: "4",
5: "5",
6: "6",
7: "7",
8: "8",
9: "9",
10: "10",
11: "J",
12: "Q",
13: "K",
14: "A"}
def __init__(self, suit: CardSuits, value: CardValues) -> None:
self.suit = suit
self.value = value
def __str__(self) -> str:
return f"{self._numbers[self.value.value]}{self._symbols[self.suit.name]}"
def __repr__(self) -> str:
return f"{self._numbers[self.value.value]}{self._symbols[self.suit.name]}"
#GAME START
def start():
play = input("You wanna play? ")
if play.lower() in ("yes", "sure", "yeah"):
all_cards = [Card(suits, value) for suits in CardSuits for value in CardValues]
shuffle(all_cards)
unique_cards = set()
while len(unique_cards) < 5:
unique_cards.add(random.choice(all_cards))
cards = list(unique_cards)
print("Your cards are:", ", ".join(str(card) for card in cards))
time.sleep(4)
#OPPONENTS CARD CREATION
# First opponent
unique_cards = set()
while len(unique_cards) < 5:
unique_cards.add(random.choice(all_cards))
first_opponent_cards = list(unique_cards)
# Second
unique_cards = set()
while len(unique_cards) < 5:
unique_cards.add(random.choice(all_cards))
second_opponent_cards = list(unique_cards)
#CHECKING PHASE
def checking_phase(cards):
High_Card, Pair, Two_Pair, Three_of_a_Kind, Straight, Flush, Full, Four_of_a_Kind, Straight_Flush, Royal_Flush = ("High Card", "Pair", "Two Pair", "Three of a Kind", "Straight", "Flush", "Full", "Four of a Kind", "Straight Flush", "Royal Flush")
if is_royal_flush:
return Royal_Flush
#elif series for returning other combinations
else:
return High_Card
user_hand = checking_phase(cards)
first_opponent_hand = checking_phase(first_opponent_cards)
second_opponent_hand = checking_phase(second_opponent_cards)
#SCORE DASHBOARD
players = [user_hand, first_opponent_hand, second_opponent_hand]
scores = [0, 0, 0] if not scores else scores
# Determina il giocatore con la combinazione più alta
max_hand_index = max(range(len(players)), key=lambda i: players[i])
# Incrementa il punteggio del giocatore con la combinazione più alta
if user_hand == "High Card" and first_opponent_hand == "High Card" and second_opponent_hand == "High Card":
cards_remove_cycle = 0
user_high = max(card.value.value for card in cards)
first_op_high = max(card.value.value for card in first_opponent_cards)
second_op_high = max(card.value.value for card in second_opponent_cards)
high_list = [user_high, first_op_high, second_op_high]
#caso in cui ci siano due o più player con max identici
if user_high == first_op_high or user_high == second_op_high or first_op_high == second_op_high:
print("Eureka! it works")
comparing_HC_cycle = 0
for player in players:
for card in cards:
user_copyli = cards[:]
first_copyli = first_opponent_cards[:]
second_copyli = second_opponent_cards[:]
high_copyli = [user_copyli, first_copyli, second_copyli]
# max_HC_value = max(high_copyli)
max_HC_value = max(max(card.value.value for card in hand) for hand in high_copyli)
# Filtra la lista high_copyli per rimuovere i giocatori senza la carta più alta
high_copyli = [hand for hand in high_copyli if max(card.value.value for card in hand) == max_HC_value]
if user_high in user_copyli:
user_copyli.remove(user_high)
if first_op_high in first_copyli:
first_copyli.remove(first_op_high)
if second_op_high in second_copyli:
second_copyli.remove(second_op_high)
user_high = max(card.value.value for card in cards)
first_op_high = max(card.value.value for card in first_opponent_cards)
second_op_high = max(card.value.value for card in second_opponent_cards)
comparing_HC_cycle += 1
if comparing_HC_cycle > 4:
winner_index = players.index(player)
scores[winner_index] += 1
print("arriva, ma non funzia")
break
else: #caso in cui il max di ogni player sia diverso, quindi solo 1 vincitore
high_card_winner = max(high_list)
HC_winner_index = high_list.index(high_card_winner)
scores[HC_winner_index] += 1
else:
scores[max_hand_index] += 1
winning_player = ["You", "First opponent", "Second opponent"]
if winning_player[max_hand_index] == "You":
print("You won!")
else:
print(f"{winning_player[max_hand_index]} won. May you'll be luckier next time")
score_phrase = """
SCORE: User: {} | First opponent: {} | Second opponent: {} """
print(score_phrase.format(scores[0], scores[1], scores[2]))
I've improved my code with answer suggestions, but the problem is that every time the code works, it gives user the score, even if it has the lowest card. My idea was (in case of 2 or more players have the same max card) to create a copy-list of player hands and removing the equal cards (at the same time disqualifying a player if he has a lower high card), until the player with the highest card remains (unless 2 players have the same cards, in that case there would be a pair). To clarify, all the other combinations works, I'm having problems only with comparing high cards. Thank you in advance
Upvotes: 0
Views: 129
Reputation: 178021
Use simple number values for the cards and suits and display then nicely with symbols.
Use functools.total_ordering
decorator and define __eq__
and __lt__
for your class to enable all comparisons.
Minimal example:
import functools
@functools.total_ordering
class Card:
_symsuit = '♥♦♣♠'
_symvalue = '23456789TJQKA'
def __init__(self, suit, value):
self.suit = suit
self.value = value
def __repr__(self):
return f'Card(suit={self.suit}, value={self.value})'
def __str__(self):
return f'{self._symvalue[self.value]}{self._symsuit[self.suit]}'
def __lt__(self, other):
return self.value < other.value # ignores suit
def __eq__(self, other):
return self.value == other.value # ignores suit
deck = [Card(suit, value) for suit in range(4) for value in range(13)]
print(deck)
a, b = deck[:2]
print(f'{a} < {b} is {a < b}')
print(f'{a} > {b} is {a > b}')
print(f'{a} <= {b} is {a <= b}')
print(f'{a} >= {b} is {a >= b}')
print(f'{a} == {b} is {a == b}')
b = deck[13]
print(f'{a} < {b} is {a < b}')
print(f'{a} > {b} is {a > b}')
print(f'{a} <= {b} is {a <= b}')
print(f'{a} >= {b} is {a >= b}')
print(f'{a} == {b} is {a == b}')
Output:
[Card(suit=0, value=0), Card(suit=0, value=1), Card(suit=0, value=2), Card(suit=0, value=3), Card(suit=0, value=4), Card(suit=0, value=5), Card(suit=0, value=6), Card(suit=0, value=7), Card(suit=0, value=8), Card(suit=0, value=9), Card(suit=0, value=10), Card(suit=0, value=11), Card(suit=0, value=12), Card(suit=1, value=0), Card(suit=1, value=1), Card(suit=1, value=2), Card(suit=1, value=3), Card(suit=1, value=4), Card(suit=1, value=5), Card(suit=1, value=6), Card(suit=1, value=7), Card(suit=1, value=8), Card(suit=1, value=9), Card(suit=1, value=10), Card(suit=1, value=11), Card(suit=1, value=12), Card(suit=2, value=0), Card(suit=2, value=1), Card(suit=2, value=2), Card(suit=2, value=3), Card(suit=2, value=4), Card(suit=2, value=5), Card(suit=2, value=6), Card(suit=2, value=7), Card(suit=2, value=8), Card(suit=2, value=9), Card(suit=2, value=10), Card(suit=2, value=11), Card(suit=2, value=12), Card(suit=3, value=0), Card(suit=3, value=1), Card(suit=3, value=2), Card(suit=3, value=3), Card(suit=3, value=4), Card(suit=3, value=5), Card(suit=3, value=6), Card(suit=3, value=7), Card(suit=3, value=8), Card(suit=3, value=9), Card(suit=3, value=10), Card(suit=3, value=11), Card(suit=3, value=12)]
2♥ < 3♥ is True
2♥ > 3♥ is False
2♥ <= 3♥ is True
2♥ >= 3♥ is False
2♥ == 3♥ is False
2♥ < 2♦ is False
2♥ > 2♦ is False
2♥ <= 2♦ is True
2♥ >= 2♦ is True
2♥ == 2♦ is True
Upvotes: 0
Reputation: 1249
Add __gt__
method to your Card
class to support >
operator.
class Card:
def __gt__(self, other):
'''return True or False'''
...
See documentation for more details.
Upvotes: 0