You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

双人Rack-O纸牌Python程序问题:卡顿+胜负判断实现

双人Rack-O纸牌游戏问题求助:玩家2回合停滞+胜负判断函数编写

问题描述

  • 玩家1回合运行正常,但进入玩家2回合时程序停止
  • 刚学习函数知识,不清楚如何编写判断游戏胜负的函数

以下是我的代码:

import random


def main():
   # displays the intro
   intro()
   # assigns and shuffles the deck
   deck = [x for x in range(1, 61)]
   random.shuffle(deck)
  # asks for the size of the rack
   rack_size = int(input('Enter the size of the rack to use. '
                                'Must be between 5 and 10: '))
   print()
  # starts the discard pile after passing out the needed cards for a rack
   discard = deck[rack_size * 2]
  # the deck top card after starting discard pile
   new_card = deck[rack_size * 2 + 1]
  # assigns the players hands
   player_rack1, player_rack2 = get_rack(deck, rack_size)
  # allows players to pick and change cards
   place_card(player_rack1, player_rack2, new_card, discard)
  
def instructions():
 # prints the instructions of the game
    print()
    print('The goal of the game is to get the cards in your rack of cards')
    print('into ascending order. Your rack has ten slots numbered 1 to 10.')
    print('During your turn you can draw the top card of the deck or take')
    print('the top card of the discard pile.')
    print('If you draw the top card of the deck, you can use that card to')
    print('replace a card in one slot of your rack. The replaced card '
 'goes to')
    print('the discard pile.')
    print('Alternatively you can simply choose to discard the drawn card.')
    print('If you take the top card of the discard pile you must use it to')
    print('replace a card in one slot of your rack. The replaced card goes')
    print('to the top of the discard pile.')
    print()

def intro():
 # displays the introduction for the game
    print('----- Welcome to Rack - O! -----')
    display = input('Enter y to display instructions: ')
 # displays instructions is user wants to see them
    if display == 'Y' or display == 'y':
        instructions()
    else:
        print()
 # asks user for the seed and sets the seed
    seed = int(input('Enter number for initial seed: '))
    random.seed(seed)

def get_rack(cards, hand):
 # assigns the shuffled cards to the player racks
    player_one_hand = cards[:hand]
    player_two_hand = cards[hand:hand * 2]
    return player_one_hand, player_two_hand

def take_turn(throw, player_hand):
 
    player = 1
    while player <= 2:
        print('Player', player, 'turn.')
        print('Your current rack', player_hand)
        print('Top of discard pile', throw)
        choice = input('Enter d to draw anything else to take '
                       'top of discard pile: ')
        print()
        player += 1
        throw = player_hand[0]
        return choice

def place_card(player_hand1, player_hand2, new, throw):
 # if the user take the card from the discard pile
    if take_turn(throw, player_hand1) != 'd':
        print('Enter the card number to replace with the', throw, ': ', end='')
        choice = int(input())
        # error checks if the user picks a card that is not in their rack
        while choice not in player_hand1:
            print(choice, 'is not is your rack.')
            print('Enter the card number to replace with the', throw, ': ', end='')
            choice = int(input())
 # replaces and assigns the card they replaced to the rack
        else:
           index = player_hand1.index(choice)
           player_hand1.remove(choice)
           player_hand1.insert(index, throw)
           print('The rack after the turn', player_hand1), print()
           take_turn(throw, player_hand2)
 # if the player doesn't take from the discard pile
    else:
      print('drew the', new[0])
      new_choice = input('Enter p to place card, anything else to discard it: ')
      if new_choice == 'p':
          print('Enter the card number to replace with the', new[0], ': ',
end='')
          choose = int(input())
          index = player_hand2.index(choose)
          player_hand2.remove(choose)
          player_hand2.insert(index, new[0])
          print('The rack after the turn', player_hand2)
main()

问题修复与解决方案

一、玩家2回合停滞的问题

核心问题出在take_turn和place_card的逻辑混乱:

  1. take_turn里的while循环完全无效,第一次执行就return choice直接退出函数,还错误地把两个玩家的回合硬塞在一个函数里
  2. place_card只处理了玩家1的部分情况,调用take_turn(player_hand2)后没有后续处理逻辑,程序自然停滞
  3. 牌堆处理错误——原来只取了单张卡片,没有保留完整的剩余牌堆,无法支持多轮抽卡

修复后的关键函数:

def take_turn(player_num, player_hand, discard_top, deck):
    print(f'Player {player_num} turn.')
    print(f'Your current rack: {player_hand}')
    print(f'Top of discard pile: {discard_top}')
    choice = input('Enter d to draw from deck, anything else to take discard pile top: ')
    print()

    if choice.lower() != 'd':
        # 拿弃牌堆顶的牌,必须替换手牌中的一张
        print(f'You took {discard_top} from discard pile.')
        while True:
            replace_card = int(input(f'Enter the card in your rack to replace with {discard_top}: '))
            if replace_card in player_hand:
                break
            print(f'{replace_card} is not in your rack. Try again.')
        # 替换手牌
        idx = player_hand.index(replace_card)
        player_hand[idx] = discard_top
        # 被替换的牌成为新的弃牌堆顶
        new_discard = replace_card
        return player_hand, new_discard, deck
    else:
        # 抽牌堆顶的牌
        if not deck:
            print('Deck is empty!')
            return player_hand, discard_top, deck
        drawn_card = deck.pop(0)
        print(f'You drew {drawn_card}.')
        place_choice = input('Enter p to place this card, anything else to discard it: ')
        print()
        if place_choice.lower() == 'p':
            while True:
                replace_card = int(input(f'Enter the card in your rack to replace with {drawn_card}: '))
                if replace_card in player_hand:
                    break
                print(f'{replace_card} is not in your rack. Try again.')
            idx = player_hand.index(replace_card)
            player_hand[idx] = drawn_card
            new_discard = replace_card
        else:
            # 直接弃掉抽到的牌
            new_discard = drawn_card
        return player_hand, new_discard, deck

重构游戏主循环:

修改place_card为游戏循环,直到有人获胜:

def place_card(player_rack1, player_rack2, deck, discard_top):
    while True:
        # 玩家1回合
        player_rack1, discard_top, deck = take_turn(1, player_rack1, discard_top, deck)
        print(f'Player 1\'s rack after turn: {player_rack1}\n')
        if is_winner(player_rack1):
            print('Player 1 wins!')
            break
        
        # 玩家2回合
        player_rack2, discard_top, deck = take_turn(2, player_rack2, discard_top, deck)
        print(f'Player 2\'s rack after turn: {player_rack2}\n')
        if is_winner(player_rack2):
            print('Player 2 wins!')
            break

修正main函数中的牌堆处理:

def main():
    intro()
    deck = [x for x in range(1, 61)]
    random.shuffle(deck)
    rack_size = int(input('Enter the size of the rack to use. Must be between 5 and 10: '))
    print()
    # 分配手牌后,剩余的牌作为抽牌堆
    player_rack1, player_rack2 = get_rack(deck, rack_size)
    # 剩余牌堆:去掉分配给两个玩家的牌
    remaining_deck = deck[rack_size * 2:]
    # 初始化弃牌堆顶
    discard_top = remaining_deck.pop(0) if remaining_deck else None
    # 开始游戏循环
    place_card(player_rack1, player_rack2, remaining_deck, discard_top)

二、胜负判断函数

Rack-O的胜负条件是手牌严格按升序排列,直接对比手牌和排序后的手牌即可:

def is_winner(rack):
    # 判断手牌是否为升序排列
    return rack == sorted(rack)

内容的提问来源于stack exchange,提问作者hacker606

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 05:40:25