0

我正在关注 YouTube 上的斯坦福 CS193 SwiftUI iOS 开发课程,我很难理解某段代码是如何工作的。

import Foundation

struct MemoryGame<CardContent> where CardContent: Equatable {
    private(set) var cards: Array<Card>
    
    **private var indexOfTheOneAndOnlyFaceUpCard: Int?**
    mutating func choose(_ card: Card) {
        if let chosenIndex = cards.firstIndex(where: { $0.id == card.id }),
           !cards[chosenIndex].isFaceUp,
           !cards[chosenIndex].isMatched
        {
            **if let potentialMatchIndex = indexOfTheOneAndOnlyFaceUpCard** {
                **if cards[chosenIndex].content == cards[potentialMatchIndex].content** {
                    cards[chosenIndex].isMatched = true
                    cards[potentialMatchIndex].isMatched = true
                }
                indexOfTheOneAndOnlyFaceUpCard = nil
            } else {
                for index in cards.indices {
                    cards[index].isFaceUp = false
                }
                indexOfTheOneAndOnlyFaceUpCard = chosenIndex
            }
            cards[chosenIndex].isFaceUp.toggle()
        }
        print("\(cards)")
    }

我在我关注的行周围加上了星号。我不明白如何cards[chosenIndex].content与 进行比较cards[potentialMatchIndex].content,这源于我不了解if let potentialMatchIndex = indexOfTheOneAndOnlyFaceUpCard生产线的工作方式。我相信我对选项以及这段代码的运行方式有一个大致的了解,但我真的不明白数据/值来自哪里indexOfTheOneAndOnlyFaceUpCard这是供参考的视频。他在 1:12:40 开始谈论这些代码行。感谢您提前提供任何帮助!

4

1 回答 1

1

在记忆游戏中,一个回合分两个阶段进行。

  1. 首先,将一张牌面朝上。

  2. 然后,用户选择另一张卡。那时,可能会发生以下两种情况之一:新卡与正面卡匹配或不匹配。但无论哪种方式,这一轮都结束了,所有牌现在都面朝下。

因此,当用户选择一张牌时,如果有一张正面朝上的牌,我们就在轮子的中间,我们安排事情所以没有正面朝上的牌;回合结束了。

如果没有正面朝上的牌,我们就在回合开始,我们只需将选择的牌正面朝上,等待回合的第二部分。

因此,就跟踪面朝上牌的变量而言,逻辑是这样的:

var faceupCard : Card? = nil
if let card = faceupCard {
    faceupCard = nil
} else {
    faceupCard = chosenCard
}

所以很清楚,当以这种方式削减时:如果卡片正面朝上,则使其不正面;如果不是正面朝上,那就让它正面朝上。


在我看来,您感到困惑的原因是这是编写代码的一种非常糟糕的方式。牌面朝上被用作我们是在转牌中间还是转牌开始的信号。那是可怕的编程。表明我们处于什么阶段的方法是有一个枚举,它的工作是说明我们处于什么阶段!当你在编程时,你应该说出你的意思,而不是像这里所做的那样以两种不同的方式使用一个值(两者都跟踪哪张牌是正面朝上的,并表示我们在回合的哪个阶段)。


您可能会感到困惑的另一个原因是,一切都必须根据索引来完成,因为 Card 是一种值类型(结构)。我们不能循环遍历卡片,或者直接指向正面朝上的卡片,甚至询问卡片是否正面朝上;我们必须循环遍历卡片数组中的索引,并跟踪正面朝上卡片的索引。

于 2021-06-07T21:45:09.340 回答