如何将扑克“程序”的分数保存在json文件中

问题描述 投票:0回答:1

我在保存分数方面遇到了一些问题。我的想法是将所有分数保存到 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()
python json python-3.x poker
1个回答
0
投票

下次,放置您收到的错误而不是整个代码会更有帮助。

您遇到的问题可能是由第 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

但是你可以尝试一下,直到找到你想要的行为。

© www.soinside.com 2019 - 2024. All rights reserved.