Reputation: 31
I'm having a little issue with saving scores. My idea was to saving all scores into PokerScores.json and then, every end of the match, add points to the winner. Also, the user could reset the saved scores after the deck shuffle (in countinue playing), but if he decide to maintain the score, the terminal would pick the saved data from the json file. But the problem is that the terminal keeps to telling me there is an error (it's surely one of the functions I've created, because the rest fo the code regarding game was working) and I'm not undestranding what I've written wrong. Thanks in advance
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 = "J"
Queen = "Q"
King = "K"
Ace = "A"
class Card:
_symbols = {"Hearts": "♥️", "Diamonds": "♦️", "Clubs": "♣️", "Spades": "♠"}
def __init__(self, suit: CardSuits, value: CardValues) -> None:
self.suit = suit
self.value = value
def __str__(self) -> str:
return f"{self.value.value}{self._symbols[self.suit.name]}"
def __repr__(self) -> str:
return f"{self.value.value}{self._symbols[self.suit.name]}"
#LOAD SCORE
def load_scores():
try:
with open("PokerScores.json", "r") as file:
json.load(file)
except FileNotFoundError:
return [0, 0, 0]
#SAVING SCORE
def save_scores(scores):
with open("PokerScores.json", "w") as file:
json.dump(scores, file)
#GAME START
def start():
scores = load_scores()
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)
#CHANGE PHASE
while True:
change_cards = input("Want to change cards? ")
if change_cards.lower() == "yes":
quantity = input("Which cards? ")
card_input_index = ["first", "second", "third", "fourth", "fifth"]
if quantity.lower() == "none":
break
elif quantity.lower() in card_input_index:
index = card_input_index.index(quantity.lower())
cards[index] = random.choice(all_cards)
print("Your new cards are:", ", ".join(str(card) for card in cards))
break
elif " " in quantity:
change_indices = quantity.lower().split()
if all(index in card_input_index for index in change_indices):
#controlla se tutti gli indici dati dall'utente siano presenti in card_input_index
#in questo modo non si ha più il problema che salta il passaggio del cambio delle
#carte se si scrive una parola a caso con uno spazio
for index in change_indices:
if index in card_input_index:
card_index = card_input_index.index(index)
cards[card_index] = random.choice(all_cards)
print("Your new cards are: ", ", ".join(str(card) for card in cards))
break
else:
print("Invalid cards selected")
elif quantity.lower() == "all":
unique_cards = set()
while len(unique_cards) < 5:
unique_cards.add(random.choice(all_cards))
cards = list(unique_cards)
print("Your new cards are:", ", ".join(str(card) for card in cards))
break
else:
print("Invalid cards selected")
elif change_cards.lower() == "no":
break
#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):
# dictionary for card values definition
custom_value_order = {
CardValues.Two : 2,
CardValues.Three : 3,
CardValues.Four : 4,
CardValues.Five : 5,
CardValues.Six : 6,
CardValues.Seven : 7,
CardValues.Eight : 8,
CardValues.Nine : 9,
CardValues.Ten : 10,
CardValues.Jack : 11,
CardValues.Queen : 12,
CardValues.King : 13,
CardValues.Ace : 14
}
#Straight
sorted_card_values = [custom_value_order[card.value] for card in cards]
sorted_card_values.sort()
is_straight = (max(sorted_card_values) - min(sorted_card_values) + 1) == len(cards)
#Flush
is_flush = len(set(card.suit for card in cards)) == 1
#Straight Flush
is_straight_flush = all([is_straight, is_flush]) # La funzione all() richiede un iterabile come argomento, come una lista, una tupla o un altro tipo di sequenza. Tuttavia, is_straight e is_flush sono valori booleani singoli, non un iterabile di valori, quindi bisogna usare le parentesi quadre per prenderli come singoli
#oppure is_straight_flush = is_straight and is_flush
#Royal Flush
max_straight = [CardValues.Ace, CardValues.King, CardValues.Queen, CardValues.Jack, CardValues.Ten]
is_royal_flush = is_straight_flush and all(card.value in max_straight for card in cards)
#Other combinations
cards_values_only = [card.value for card in cards]
cards_count = Counter(cards_values_only)
counts = list(cards_count.values())
counts.sort(reverse=True)
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 is_straight_flush:
return Straight_Flush
elif counts == [4, 1]:
return Four_of_a_Kind
elif counts == [3, 2]:
return Full
elif is_flush:
return Flush
elif is_straight:
return Straight
elif counts == [3, 1, 1]:
return Three_of_a_Kind
elif counts == [2, 2, 1]:
return Two_Pair
elif counts == [2, 1, 1, 1]:
return Pair
else:
return High_Card
time.sleep(2)
user_hand = checking_phase(cards)
first_opponent_hand = checking_phase(first_opponent_cards)
second_opponent_hand = checking_phase(second_opponent_cards)
#SE AVVERSARI HANNO CARTA ALTA COME COMBINAZIONE, C'È UNA POSSIBILITÀ DEL 50% CHE CAMBINO TUTTE LE CARTE
if first_opponent_hand == "High Card":
change_chance = ["yes", "no"]
yes_or_no = random.choice(change_chance)
if yes_or_no == "yes":
unique_cards = set()
while len(unique_cards) < 5:
unique_cards.add(random.choice(all_cards))
first_opponent_cards = list(unique_cards)
first_opponent_hand = checking_phase(first_opponent_cards)
if second_opponent_hand == "High Card":
yes_or_no = random.choice(change_chance)
if yes_or_no == "yes":
unique_cards = set()
while len(unique_cards) <5:
unique_cards.add(random.choice(all_cards))
second_opponent_cards = list(unique_cards)
second_opponent_hand = checking_phase(second_opponent_cards)
print(f"""
Your hand: {user_hand}
1st Opponent hand: {first_opponent_hand} ( {", ".join(str(card) for card in first_opponent_cards)} )
2nd Opponent hand: {second_opponent_hand} ( {", ".join(str(card) for card in second_opponent_cards)} )
""")
#SCORE DASHBOARD
players = [user_hand, first_opponent_hand, second_opponent_hand]
scores = [0, 0, 0]
# 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
scores[max_hand_index] += 1
save_scores(scores)
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]))
time.sleep(5)
#CONTINUE PLAYING
while True:
continue_playing = input("You want to keep playing? ")
if continue_playing.lower() == "yes":
wanna_shuffle = input("Wanna shuffle the deck? ")
if wanna_shuffle.lower() == "yes":
shuffle(all_cards)
print("Deck shuffled")
break
elif wanna_shuffle.lower() == "no":
break
else:
continue
elif continue_playing.lower() == "no":
exit()
score_reset = input("Want to maintain the score or reset it? ")
if score_reset.lower() in ("reset", "reset it"):
test_file = open("PokerScores.json", "w")
test_file.write(json.dumps([0, 0, 0]))
test_file.close()
break
elif score_reset.lower() in ("maintain", "maintain it"):
break
start()
else:
exit()
start()
Upvotes: 0
Views: 106
Reputation: 193
Next time, it would be more helpful to put the error that you get instead of the whole code.
The issue you are getting is probably caused by the if condition in line 206. If the program enters that block without having entered the previous if block first, an error will occur because the variable change_chance is not set.
The solution is to set this variable outside the if-else structure like this:
...
#SE AVVERSARI HANNO CARTA ALTA COME COMBINAZIONE, C'È UNA POSSIBILITÀ DEL 50% CHE CAMBINO TUTTE LE CARTE
change_chance = ["yes", "no"]
if first_opponent_hand == "High Card":
yes_or_no = random.choice(change_chance)
if yes_or_no == "yes":
unique_cards = set()
while len(unique_cards) < 5:
unique_cards.add(random.choice(all_cards))
first_opponent_cards = list(unique_cards)
first_opponent_hand = checking_phase(first_opponent_cards)
if second_opponent_hand == "High Card":
yes_or_no = random.choice(change_chance)
if yes_or_no == "yes":
unique_cards = set()
while len(unique_cards) <5:
unique_cards.add(random.choice(all_cards))
second_opponent_cards = list(unique_cards)
second_opponent_hand = checking_phase(second_opponent_cards)
...
Regarding the punctuation system, you are constantly overwriting the contents of PokerScores.json. I understand that you want to accumulate the scores until the user decides to reset, so you need to read the JSON file if it exists, sum the results and then write them back into the JSON file. Here is a way to do it:
def save_scores(score):
import os
filename = "PokerScores.json"
old_score = None
# We check if the file exists and if it is empty
if os.path.exists(filename) and os.path.getsize(filename) > 0:
# If it exists, we read the existing score
with open(filename, 'r') as file:
old_score = json.load(file)
if old_score:
# If there are previous scores, we make a sum of the previous and the new
score = [existing + new for existing, new in zip(old_score, score)]
# Write the scores back to the JSON file
with open(filename, 'w') as file:
json.dump(score, file)
You can add the import os
line to the top of the file if you wish.
Just remember to use the puntuation in the file each time you start the game so that the punctuation is shown correclty.
Another issue is that you load the scores but do not return them, so you should change your load_scores method, like this:
#LOAD SCORE
def load_scores():
try:
with open("PokerScores.json", "r") as file:
return json.load(file)
except FileNotFoundError:
return [0, 0, 0]
Finally, if you don't want the scores to be overwritten each round, you have to remove the line that sets the scores back to 0 here:
#SCORE DASHBOARD
players = [user_hand, first_opponent_hand, second_opponent_hand]
scores = [0, 0, 0]
# 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
scores[max_hand_index] += 1
save_scores(scores)
You could set the scores to [0,0,0] if the scores variable does not exist, with something similar to this (just a suggestion):
scores = [0, 0, 0] if not scores else scores
but you should play around until you find the behaviour you want.
Upvotes: 1