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

如何修改SwiftUI记忆游戏代码实现指定卡片配对?

SwiftUI记忆游戏指定卡片配对修改方案

核心思路

原来的匹配逻辑依赖卡片content相等,现在要实现不同内容但指定配对,需要给每个卡片添加pairID标识,相同配对的卡片共享同一个pairID,匹配时判断pairID是否一致即可。

1. 修改MemoryGame卡片模型

给Card结构体新增pairID属性,用于标识配对组:

struct Card<Content: Equatable>: Identifiable {
    let id = UUID()
    var isFaceUp = false
    var isMatched = false
    var content: Content
    let pairID: Int // 新增:相同配对的卡片使用同一个ID
}

2. 调整MemoryGame初始化与匹配逻辑

修改初始化方法,支持传入配对内容数组;同时更新匹配判断逻辑:

class MemoryGame<Content: Equatable>: ObservableObject {
    @Published private(set) var cards: [Card<Content>]
    
    // 初始化方法改为接收配对内容数组,每个元素是一组需要配对的两个内容
    init(pairs: [(Content, Content)]) {
        cards = []
        for (pairIndex, pairContent) in pairs.enumerated() {
            // 给每组配对的两张卡片设置相同的pairID
            cards.append(Card(content: pairContent.0, pairID: pairIndex))
            cards.append(Card(content: pairContent.1, pairID: pairIndex))
        }
        cards.shuffle()
    }
    
    // 核心:修改匹配判断逻辑,从content相等改为pairID相等
    private func checkForMatch() {
        guard let firstIndex = indexOfTheOneAndOnlyFaceUpCard,
              let secondIndex = faceUpCardIndices.last,
              firstIndex != secondIndex else { return }
        
        if cards[firstIndex].pairID == cards[secondIndex].pairID {
            cards[firstIndex].isMatched = true
            cards[secondIndex].isMatched = true
        }
        
        cards[firstIndex].isFaceUp = false
        cards[secondIndex].isFaceUp = false
    }
    
    // 以下原有辅助方法保持不变
    private var faceUpCardIndices: [Int] {
        cards.indices.filter { cards[$0].isFaceUp }
    }
    
    private var indexOfTheOneAndOnlyFaceUpCard: Int? {
        faceUpCardIndices.count == 1 ? faceUpCardIndices.first : nil
    }
    
    func choose(_ card: Card<Content>) {
        guard let chosenIndex = cards.firstIndex(where: { $0.id == card.id }),
              !cards[chosenIndex].isFaceUp,
              !cards[chosenIndex].isMatched else { return }
        
        if let potentialMatchIndex = indexOfTheOneAndOnlyFaceUpCard {
            checkForMatch()
        } else {
            for index in cards.indices {
                cards[index].isFaceUp = false
            }
        }
        cards[chosenIndex].isFaceUp.toggle()
    }
}

3. 更新FinalMemoryGame的数据源

修改为传入指定的图片配对组:

class FinalMemoryGame: ObservableObject {
    // 定义需要配对的图片组,每一组是两张要配对的图片
    static let pairedImages = [
        (Image("Beagle"), Image("BeagleInformation")),
        (Image("Poodle"), Image("PoodleInformation")),
        // 可添加更多配对组
    ]
    
    @Published private var model = MemoryGame(pairs: pairedImages)
    
    // 暴露给视图的属性与方法保持不变
    var cards: [MemoryGame<Image>.Card] { model.cards }
    
    func choose(_ card: MemoryGame<Image>.Card) {
        model.choose(card)
    }
}

4. ContentView与CardView无需修改

原视图代码可以直接复用,因为CardView只是负责显示卡片的content(也就是图片),配对逻辑已经在模型层处理完成。

常见错误排查

  • 若之前修改时出现匹配失效,大概率是仍在判断content相等而非pairID;
  • 初始化卡片时要确保每组配对的两张卡片pairID完全一致;
  • 注意pairID的枚举要从0开始,每组配对对应唯一索引。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 08:01:20