我在保存分数方面遇到了一些问题。我的想法是将所有分数保存到 PokerScores.json 中,然后在比赛的每次结束时为获胜者添加分数。此外,用户可以在牌组洗牌后(继续玩时)重置已保存的分数,但如果他决定保留分数,终端将从 json 文件中选取已保存的数据。但问题是终端不断告诉我有一个错误(这肯定是我创建的函数之一,因为有关游戏的代码的其余部分正在工作)并且我没有理解我写错的内容。预先感谢
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()
下次,放置您收到的错误而不是整个代码会更有帮助。
您遇到的问题可能是由第 206 行中的 if 条件引起的。如果程序在没有先进入前一个 if 块的情况下进入该块,则会出现错误,因为未设置变量 change_chance。
解决方案是在 if-else 结构之外设置此变量,如下所示:
...
#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)
...
关于标点系统,你不断地覆盖PokerScores.json的内容。我知道您希望累积分数直到用户决定重置,因此您需要读取 JSON 文件(如果存在),对结果求和,然后将其写回 JSON 文件。这是一种方法:
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)
如果您愿意,可以将
import os
行添加到文件顶部。
请记住每次启动游戏时使用文件中的标点符号,以便标点符号显示正确。
另一个问题是您加载分数但不返回它们,因此您应该更改 load_scores 方法,如下所示:
#LOAD SCORE
def load_scores():
try:
with open("PokerScores.json", "r") as file:
return json.load(file)
except FileNotFoundError:
return [0, 0, 0]
最后,如果你不希望每轮的分数都被覆盖,你必须删除这里将分数设置回 0 的行:
#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)
我所做的只是在scores变量不存在的情况下将scores设置为[0,0,0],如下所示:
scores = [0, 0, 0] if not scores else scores
但是你可以尝试一下,直到找到你想要的行为。