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

无法修改Blackjack游戏中Player类Total属性值的技术问题

问题根源:你的Total属性每次读取都会重新计算,直接覆盖了设置的值

嘿,我一眼就发现问题所在了——你定义的Total属性,每次读取它的时候都会重新计算手牌的总和,这就导致你用setter设置的0根本留不住!

咱们来拆解一下你的代码:

1. Total属性的核心问题

看你Player类里的Total属性实现:

public int Total { 
    get { 
        total = 0; // 每次读取都先把total重置为0
        foreach (int card in hand) { 
            total += card; // 然后重新计算手牌总和
        } 
        return total; 
    } 
    set { this.total = value; } 
}

你以为用player1.Total = 0把total字段设成0了,但只要接下来一读取player1.Total(比如后面的Console.WriteLine,甚至Bust属性的getter里调用Total),getter就会立刻把total重置为0,然后重新遍历hand计算总和——等于你设置的0直接被覆盖了!

2. Bust属性的额外问题

再看你的Bust属性:

private readonly int blackjack = 21; 
public bool Bust { 
    get { return Bust = Total > blackjack; } 
    private set { } 
}

这里的getter里写了return Bust = Total > blackjack,这是在给Bust属性赋值,但你的setter是空实现,完全没必要。而且每次访问Bust都会触发Total的getter,进一步加剧了“重新计算覆盖值”的问题。


解决方案:两种思路任选

思路1:让Total存储计算结果,只在手牌变化时更新

这种方式更高效,避免重复计算。我们把Total的getter改成直接返回存储的字段,然后通过方法来更新手牌和对应的total值:

修改后的Player类:

public class Player 
{
    private int total;
    private List<int> hand = new List<int>(); // 初始化手牌列表

    public int Total 
    {
        get { return total; }
        // 如果不需要外部直接设置Total,可以把set改成私有
        private set { total = value; } 
    }

    // 添加卡片时同步更新total
    public void AddCard(int card)
    {
        hand.Add(card);
        total += card;
    }

    // 重置手牌和total的方法
    public void ResetHand()
    {
        hand.Clear();
        total = 0;
    }

    // 修正Bust属性,直接返回判断结果
    public bool Bust 
    {
        get { return Total > 21; }
    }
}

然后在Game类的CompareHands里,调用重置方法代替直接设置Total:

private void CompareHands() 
{
    // 测试输出
    Console.WriteLine($"player total: {player1.Total}, is bust: {player1.Bust}");
    Console.WriteLine($"house total: {house.Total}, is bust: {house.Bust}");

    if (player1.Bust) 
        player1.ResetHand(); 
    if (house.Bust) 
        house.ResetHand();

    // 再次输出
    Console.WriteLine($"player total: {player1.Total}, is bust: {player1.Bust}");
    Console.WriteLine($"house total: {house.Total}, is bust: {house.Bust}");
    // 后续逻辑...
}

思路2:把Total做成只读计算属性,通过清空手牌来重置

如果你坚持让Total每次读取都计算(虽然没必要,重复计算影响性能),那可以去掉setter,因为Total的值完全由hand决定,设置它没有意义。要重置的话直接清空hand即可:

修改后的Player类片段:

public class Player 
{
    private List<int> hand = new List<int>();

    // 只读属性,每次读取计算总和
    public int Total 
    {
        get { 
            int sum = 0;
            foreach (int card in hand) sum += card;
            return sum;
        }
        // 去掉setter,因为它的值由hand决定
    }

    public void ClearHand()
    {
        hand.Clear();
    }

    public bool Bust 
    {
        get { return Total > 21; }
    }
}

然后Game类里改成:

if (player1.Bust) 
    player1.ClearHand(); 
if (house.Bust) 
    house.ClearHand();

这样下次读取Total时,因为hand是空的,自然会返回0。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:04:40