āĻ¸ā§āĻ‡āĻĢāĻŸā§‡ āĻāĻ•āĻŸāĻŋ āĻŽā§‡āĻŽāĻ°āĻŋ āĻ•āĻžāĻ°ā§āĻĄ āĻ—ā§‡āĻŽ āĻ˛ā§‡āĻ–āĻž

āĻ¸ā§āĻ‡āĻĢāĻŸā§‡ āĻāĻ•āĻŸāĻŋ āĻŽā§‡āĻŽāĻ°āĻŋ āĻ•āĻžāĻ°ā§āĻĄ āĻ—ā§‡āĻŽ āĻ˛ā§‡āĻ–āĻž

āĻāĻ‡ āĻ¨āĻŋāĻŦāĻ¨ā§āĻ§āĻŸāĻŋ āĻāĻ•āĻŸāĻŋ āĻ¸āĻžāĻ§āĻžāĻ°āĻŖ āĻŽā§‡āĻŽāĻ°āĻŋ āĻĒā§āĻ°āĻļāĻŋāĻ•ā§āĻˇāĻŖ āĻ—ā§‡āĻŽ āĻ¤ā§ˆāĻ°āĻŋ āĻ•āĻ°āĻžāĻ° āĻĒā§āĻ°āĻ•ā§āĻ°āĻŋāĻ¯āĻŧāĻž āĻŦāĻ°ā§āĻŖāĻ¨āĻž āĻ•āĻ°ā§‡ āĻ¯āĻž āĻ†āĻŽāĻŋ āĻ¸āĻ¤ā§āĻ¯āĻŋāĻ‡ āĻĒāĻ›āĻ¨ā§āĻĻ āĻ•āĻ°āĻŋāĨ¤ āĻ¨āĻŋāĻœā§‡ āĻ­āĻžāĻ˛ā§‹ āĻšāĻ“āĻ¯āĻŧāĻžāĻ° āĻĒāĻžāĻļāĻžāĻĒāĻžāĻļāĻŋ, āĻ†āĻĒāĻ¨āĻŋ āĻ¯ā§‡āĻ¤ā§‡ āĻ¯ā§‡āĻ¤ā§‡ āĻ¸ā§āĻ‡āĻĢāĻŸ āĻ•ā§āĻ˛āĻžāĻ¸ āĻāĻŦāĻ‚ āĻĒā§āĻ°ā§‹āĻŸā§‹āĻ•āĻ˛ āĻ¸āĻŽā§āĻĒāĻ°ā§āĻ•ā§‡ āĻ†āĻ°āĻ“ āĻ•āĻŋāĻ›ā§ āĻļāĻŋāĻ–āĻŦā§‡āĻ¨āĨ¤ āĻ¤āĻŦā§‡ āĻ†āĻŽāĻ°āĻž āĻļā§āĻ°ā§ āĻ•āĻ°āĻžāĻ° āĻ†āĻ—ā§‡, āĻ†āĻ¸ā§āĻ¨ āĻ–ā§‡āĻ˛āĻžāĻŸāĻŋ āĻ¨āĻŋāĻœā§‡āĻ‡ āĻŦā§āĻāĻ¤ā§‡ āĻĒāĻžāĻ°āĻŋāĨ¤

āĻ†āĻŽāĻ°āĻž āĻŽāĻ¨ā§‡ āĻ•āĻ°āĻŋāĻ¯āĻŧā§‡ āĻĻāĻŋāĻšā§āĻ›āĻŋ: "Habr"-āĻāĻ° āĻ¸āĻ•āĻ˛ āĻĒāĻžāĻ āĻ•āĻĻā§‡āĻ° āĻœāĻ¨ā§āĻ¯ - "Habr" āĻĒā§āĻ°āĻšāĻžāĻ°āĻŽā§‚āĻ˛āĻ• āĻ•ā§‹āĻĄ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻ•āĻ°ā§‡ āĻ¯ā§‡āĻ•ā§‹āĻ¨ā§‹ Skillbox āĻ•ā§‹āĻ°ā§āĻ¸ā§‡ āĻ¨āĻĨāĻŋāĻ­ā§āĻ•ā§āĻ¤ āĻ•āĻ°āĻžāĻ° āĻ¸āĻŽāĻ¯āĻŧ 10 āĻ°ā§āĻŦā§‡āĻ˛ āĻ›āĻžāĻĄāĻŧāĨ¤

Skillbox āĻ¸ā§āĻĒāĻžāĻ°āĻŋāĻļ āĻ•āĻ°ā§‡: āĻļāĻŋāĻ•ā§āĻˇāĻžāĻ—āĻ¤ āĻ…āĻ¨āĻ˛āĻžāĻ‡āĻ¨ āĻ•ā§‹āĻ°ā§āĻ¸ "āĻĒā§‡āĻļāĻž āĻœāĻžāĻ­āĻž āĻŦāĻŋāĻ•āĻžāĻļāĻ•āĻžāĻ°ā§€".

āĻ•āĻŋāĻ­āĻžāĻŦā§‡ āĻŽā§‡āĻŽāĻ°āĻŋ āĻ•āĻžāĻ°ā§āĻĄ āĻ–ā§‡āĻ˛āĻ¤ā§‡ āĻšāĻ¯āĻŧ

āĻ—ā§‡āĻŽāĻŸāĻŋ āĻ•āĻžāĻ°ā§āĻĄā§‡āĻ° āĻāĻ•āĻŸāĻŋ āĻ¸ā§‡āĻŸ āĻĒā§āĻ°āĻĻāĻ°ā§āĻļāĻ¨ā§‡āĻ° āĻŽāĻžāĻ§ā§āĻ¯āĻŽā§‡ āĻļā§āĻ°ā§ āĻšāĻ¯āĻŧāĨ¤ āĻ¤āĻžāĻ°āĻž āĻŽā§āĻ– āĻ•āĻ°ā§‡ āĻļā§āĻ¯āĻŧā§‡ āĻĨāĻžāĻ•ā§‡ (āĻ¯āĻĨāĻžāĻ•ā§āĻ°āĻŽā§‡, āĻšāĻŋāĻ¤ā§āĻ° āĻ¨āĻŋāĻšā§‡)āĨ¤ āĻ†āĻĒāĻ¨āĻŋ āĻ¯ā§‡āĻ•ā§‹āĻ¨ā§‹ āĻāĻ•āĻŸāĻŋāĻ¤ā§‡ āĻ•ā§āĻ˛āĻŋāĻ• āĻ•āĻ°āĻ˛ā§‡, āĻ›āĻŦāĻŋāĻŸāĻŋ āĻ•āĻ¯āĻŧā§‡āĻ• āĻ¸ā§‡āĻ•ā§‡āĻ¨ā§āĻĄā§‡āĻ° āĻœāĻ¨ā§āĻ¯ āĻ–ā§‹āĻ˛ā§‡āĨ¤

āĻĒā§āĻ˛ā§‡āĻ¯āĻŧāĻžāĻ°ā§‡āĻ° āĻ•āĻžāĻœ āĻšāĻ˛ āĻāĻ•āĻ‡ āĻ›āĻŦāĻŋ āĻ¸āĻš āĻ¸āĻŽāĻ¸ā§āĻ¤ āĻ•āĻžāĻ°ā§āĻĄ āĻ–ā§āĻāĻœā§‡ āĻŦā§‡āĻ° āĻ•āĻ°āĻžāĨ¤ āĻ¯āĻĻāĻŋ, āĻĒā§āĻ°āĻĨāĻŽ āĻ•āĻžāĻ°ā§āĻĄ āĻ–ā§‹āĻ˛āĻžāĻ° āĻĒāĻ°ā§‡, āĻ†āĻĒāĻ¨āĻŋ āĻĻā§āĻŦāĻŋāĻ¤ā§€āĻ¯āĻŧāĻŸāĻŋ āĻ‰āĻ˛ā§āĻŸā§‡ āĻĻā§‡āĻ¨ āĻāĻŦāĻ‚ āĻ›āĻŦāĻŋāĻ—ā§āĻ˛āĻŋ āĻŽāĻŋāĻ˛ā§‡ āĻ¯āĻžāĻ¯āĻŧ, āĻ‰āĻ­āĻ¯āĻŧ āĻ•āĻžāĻ°ā§āĻĄāĻ‡ āĻ–ā§‹āĻ˛āĻž āĻĨāĻžāĻ•ā§‡āĨ¤ āĻ¸ā§‡āĻ—ā§āĻ˛ā§‹ āĻ¨āĻž āĻŽāĻŋāĻ˛āĻ˛ā§‡ āĻ•āĻžāĻ°ā§āĻĄāĻ—ā§āĻ˛ā§‹ āĻ†āĻŦāĻžāĻ° āĻŦāĻ¨ā§āĻ§ āĻšāĻ¯āĻŧā§‡ āĻ¯āĻžāĻ¯āĻŧāĨ¤ āĻ˛āĻ•ā§āĻˇā§āĻ¯ āĻšāĻ˛ āĻ¸āĻŦāĻ•āĻŋāĻ›ā§ āĻ–ā§‹āĻ˛āĻžāĨ¤

āĻĒā§āĻ°āĻ•āĻ˛ā§āĻĒ āĻ•āĻžāĻ āĻžāĻŽā§‹

āĻāĻ‡ āĻ—ā§‡āĻŽāĻŸāĻŋāĻ° āĻāĻ•āĻŸāĻŋ āĻ¸āĻšāĻœ āĻ¸āĻ‚āĻ¸ā§āĻ•āĻ°āĻŖ āĻ¤ā§ˆāĻ°āĻŋ āĻ•āĻ°āĻ¤ā§‡ āĻ†āĻĒāĻ¨āĻžāĻ° āĻ¨āĻŋāĻŽā§āĻ¨āĻ˛āĻŋāĻ–āĻŋāĻ¤ āĻ‰āĻĒāĻžāĻĻāĻžāĻ¨āĻ—ā§āĻ˛āĻŋāĻ° āĻĒā§āĻ°āĻ¯āĻŧā§‹āĻœāĻ¨:

  • āĻāĻ• āĻ•āĻ¨ā§āĻŸā§āĻ°ā§‹āĻ˛āĻžāĻ°: GameController.swiftāĨ¤
  • āĻ“āĻ¯āĻŧāĻžāĻ¨ āĻ­āĻŋāĻ‰: CardCell.swiftāĨ¤
  • āĻĻā§āĻŸāĻŋ āĻŽāĻĄā§‡āĻ˛: MemoryGame.swift āĻāĻŦāĻ‚ Card.swiftāĨ¤
  • āĻ‰āĻĒāĻžāĻĻāĻžāĻ¨āĻ—ā§āĻ˛āĻŋāĻ° āĻ¸āĻŽā§āĻĒā§‚āĻ°ā§āĻŖ āĻ¸ā§‡āĻŸ āĻ‰āĻĒāĻ˛āĻŦā§āĻ§ āĻ°āĻ¯āĻŧā§‡āĻ›ā§‡ āĻ¤āĻž āĻ¨āĻŋāĻļā§āĻšāĻŋāĻ¤ āĻ•āĻ°āĻ¤ā§‡ Main.storyboardāĨ¤

āĻ†āĻŽāĻ°āĻž āĻ—ā§‡āĻŽā§‡āĻ° āĻ¸āĻšāĻœāĻ¤āĻŽ āĻ‰āĻĒāĻžāĻĻāĻžāĻ¨, āĻ•āĻžāĻ°ā§āĻĄ āĻĻāĻŋāĻ¯āĻŧā§‡ āĻļā§āĻ°ā§ āĻ•āĻ°āĻŋāĨ¤

Card.swift

āĻ•āĻžāĻ°ā§āĻĄā§‡āĻ° āĻŽāĻĄā§‡āĻ˛ā§‡āĻ° āĻ¤āĻŋāĻ¨āĻŸāĻŋ āĻŦā§ˆāĻļāĻŋāĻˇā§āĻŸā§āĻ¯ āĻĨāĻžāĻ•āĻŦā§‡: āĻĒā§āĻ°āĻ¤āĻŋāĻŸāĻŋāĻ•ā§‡ āĻļāĻ¨āĻžāĻ•ā§āĻ¤ āĻ•āĻ°āĻžāĻ° āĻœāĻ¨ā§āĻ¯ āĻ†āĻ‡āĻĄāĻŋ, āĻ•āĻžāĻ°ā§āĻĄā§‡āĻ° āĻ¸ā§āĻĨāĻŋāĻ¤āĻŋ (āĻ˛ā§āĻ•āĻžāĻ¨ā§‹ āĻŦāĻž āĻ–ā§‹āĻ˛āĻž) āĻ¨āĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āĻŸ āĻ•āĻ°āĻžāĻ° āĻœāĻ¨ā§āĻ¯ āĻāĻ•āĻŸāĻŋ āĻŦā§āĻ˛āĻŋāĻ¯āĻŧāĻžāĻ¨ āĻ­ā§‡āĻ°āĻŋāĻ¯āĻŧā§‡āĻŦāĻ˛ āĻāĻŦāĻ‚ āĻ•āĻžāĻ°ā§āĻĄā§‡āĻ° āĻšāĻŋāĻ¤ā§āĻ°āĻ—ā§āĻ˛āĻŋāĻ° āĻœāĻ¨ā§āĻ¯ āĻ†āĻ°ā§āĻŸāĻ“āĻ¯āĻŧāĻžāĻ°ā§āĻ• āĻ‡āĻ‰āĻ†āĻ°āĻāĻ˛āĨ¤

class Card {        
    var id: String    
    var shown: Bool = false    
    var artworkURL: UIImage!
}

āĻŽāĻžāĻ¨āĻšāĻŋāĻ¤ā§āĻ°ā§‡āĻ° āĻ¸āĻžāĻĨā§‡ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ°āĻ•āĻžāĻ°ā§€āĻ° āĻŽāĻŋāĻĨāĻ¸ā§āĻ•ā§āĻ°āĻŋāĻ¯āĻŧāĻž āĻ¨āĻŋāĻ¯āĻŧāĻ¨ā§āĻ¤ā§āĻ°āĻŖ āĻ•āĻ°āĻ¤ā§‡ āĻ†āĻĒāĻ¨āĻžāĻ° āĻāĻ‡ āĻĒāĻĻā§āĻ§āĻ¤āĻŋāĻ—ā§āĻ˛āĻŋāĻ°āĻ“ āĻĒā§āĻ°āĻ¯āĻŧā§‹āĻœāĻ¨ āĻšāĻŦā§‡:

āĻāĻ•āĻŸāĻŋ āĻ•āĻžāĻ°ā§āĻĄā§‡ āĻāĻ•āĻŸāĻŋ āĻ›āĻŦāĻŋ āĻĒā§āĻ°āĻĻāĻ°ā§āĻļāĻ¨ā§‡āĻ° āĻĒāĻĻā§āĻ§āĻ¤āĻŋāĨ¤ āĻāĻ–āĻžāĻ¨ā§‡ āĻ†āĻŽāĻ°āĻž āĻ¸āĻŽāĻ¸ā§āĻ¤ āĻŦā§ˆāĻļāĻŋāĻˇā§āĻŸā§āĻ¯ āĻĄāĻŋāĻĢāĻ˛ā§āĻŸā§‡ āĻ°āĻŋāĻ¸ā§‡āĻŸ āĻ•āĻ°āĻŋāĨ¤ āĻ†āĻ‡āĻĄāĻŋāĻ° āĻœāĻ¨ā§āĻ¯, āĻ†āĻŽāĻ°āĻž NSUUIS().uuidString āĻ•āĻ˛ āĻ•āĻ°ā§‡ āĻāĻ•āĻŸāĻŋ āĻ°ā§āĻ¯āĻžāĻ¨ā§āĻĄāĻŽ āĻ†āĻ‡āĻĄāĻŋ āĻ¤ā§ˆāĻ°āĻŋ āĻ•āĻ°āĻŋāĨ¤

init(image: UIImage) {        
    self.id = NSUUID().uuidString        
    self.shown = false        
    self.artworkURL = image    
}

āĻ†āĻ‡āĻĄāĻŋ āĻ•āĻžāĻ°ā§āĻĄ āĻ¤ā§āĻ˛āĻ¨āĻž āĻ•āĻ°āĻžāĻ° āĻĒāĻĻā§āĻ§āĻ¤āĻŋāĨ¤

func equals(_ card: Card) -> Bool {
    return (card.id == id)    
}

āĻĒā§āĻ°āĻ¤āĻŋāĻŸāĻŋ āĻ•āĻžāĻ°ā§āĻĄā§‡āĻ° āĻāĻ•āĻŸāĻŋ āĻ•āĻĒāĻŋ āĻ¤ā§ˆāĻ°āĻŋ āĻ•āĻ°āĻžāĻ° āĻĒāĻĻā§āĻ§āĻ¤āĻŋ - āĻ¯āĻžāĻ¤ā§‡ āĻāĻ•āĻŸāĻŋ āĻŦā§ƒāĻšāĻ¤ā§āĻ¤āĻ° āĻ¸āĻ‚āĻ–ā§āĻ¯āĻž āĻ…āĻ­āĻŋāĻ¨ā§āĻ¨ āĻĒā§‡āĻ¤ā§‡. āĻāĻ‡ āĻĒāĻĻā§āĻ§āĻ¤āĻŋāĻŸāĻŋ āĻāĻ•āĻ‡ āĻŽāĻžāĻ¨ āĻ¸āĻš āĻ•āĻžāĻ°ā§āĻĄ āĻĢā§‡āĻ°āĻ¤ āĻĻā§‡āĻŦā§‡āĨ¤

func copy() -> Card {        
    return Card(card: self)    
}
 
init(card: Card) {        
    self.id = card.id        
    self.shown = card.shown        
    self.artworkURL = card.artworkURL    
}

āĻāĻŦāĻ‚ āĻļā§āĻ°ā§āĻ¤ā§‡ āĻ•āĻžāĻ°ā§āĻĄāĻ—ā§āĻ˛āĻŋ āĻāĻ˛ā§‹āĻŽā§‡āĻ˛ā§‹ āĻ•āĻ°āĻžāĻ° āĻœāĻ¨ā§āĻ¯ āĻ†āĻ°āĻ“ āĻāĻ•āĻŸāĻŋ āĻĒāĻĻā§āĻ§āĻ¤āĻŋāĻ° āĻĒā§āĻ°āĻ¯āĻŧā§‹āĻœāĻ¨ā§ˇ āĻ†āĻŽāĻ°āĻž āĻāĻŸāĻŋāĻ•ā§‡ āĻ…ā§āĻ¯āĻžāĻ°ā§‡ āĻ•ā§āĻ˛āĻžāĻ¸ā§‡āĻ° āĻāĻ•āĻŸāĻŋ āĻāĻ•ā§āĻ¸āĻŸā§‡āĻ¨āĻļāĻ¨ āĻ•āĻ°āĻŦāĨ¤

extension Array {    
    mutating func shuffle() {        
        for _ in 0...self.count {            
            sort { (_,_) in arc4random() < arc4random() }        
        }   
    }
}

āĻāĻŦāĻ‚ āĻāĻ–āĻžāĻ¨ā§‡ āĻ¸āĻŽāĻ¸ā§āĻ¤ āĻŦā§ˆāĻļāĻŋāĻˇā§āĻŸā§āĻ¯ āĻāĻŦāĻ‚ āĻĒāĻĻā§āĻ§āĻ¤āĻŋ āĻ¸āĻš āĻ•āĻžāĻ°ā§āĻĄ āĻŽāĻĄā§‡āĻ˛ā§‡āĻ° āĻ•ā§‹āĻĄā§‡āĻ° āĻŦāĻžāĻ¸ā§āĻ¤āĻŦāĻžāĻ¯āĻŧāĻ¨āĨ¤

class Card {
    
    var id: String
    var shown: Bool = false
    var artworkURL: UIImage!
    
    static var allCards = [Card]()
 
    init(card: Card) {
        self.id = card.id
        self.shown = card.shown
        self.artworkURL = card.artworkURL
    }
    
    init(image: UIImage) {
        self.id = NSUUID().uuidString
        self.shown = false
        self.artworkURL = image
    }
    
    func equals(_ card: Card) -> Bool {
        return (card.id == id)
    }
    
    func copy() -> Card {
        return Card(card: self)
    }
}
 
extension Array {
    mutating func shuffle() {
        for _ in 0...self.count {
            sort { (_,_) in arc4random() < arc4random() }
        }
    }
}

āĻ†āĻŽāĻ°āĻž āĻ†āĻ°āĻ“ āĻāĻ—āĻŋāĻ¯āĻŧā§‡ āĻ¯āĻžāĻ‡

āĻĻā§āĻŦāĻŋāĻ¤ā§€āĻ¯āĻŧ āĻŽāĻĄā§‡āĻ˛āĻŸāĻŋ āĻšāĻ˛ MemoryGame, āĻāĻ–āĻžāĻ¨ā§‡ āĻ†āĻŽāĻ°āĻž āĻāĻ•āĻŸāĻŋ 4*4 āĻ—ā§āĻ°āĻŋāĻĄ āĻ¸ā§‡āĻŸ āĻ•āĻ°ā§‡āĻ›āĻŋāĨ¤ āĻŽāĻĄā§‡āĻ˛āĻŸāĻŋāĻ¤ā§‡ āĻ•āĻžāĻ°ā§āĻĄ (āĻ—ā§āĻ°āĻŋāĻĄā§‡ āĻ•āĻžāĻ°ā§āĻĄā§‡āĻ° āĻāĻ•āĻŸāĻŋ āĻ…ā§āĻ¯āĻžāĻ°ā§‡), āĻ‡āĻ¤āĻŋāĻŽāĻ§ā§āĻ¯ā§‡ āĻ–ā§‹āĻ˛āĻž āĻ•āĻžāĻ°ā§āĻĄ āĻ¸āĻš āĻāĻ•āĻŸāĻŋ āĻ•āĻžāĻ°ā§āĻĄ āĻĻā§‡āĻ–āĻžāĻ¨ā§‹ āĻ…ā§āĻ¯āĻžāĻ°ā§‡ āĻāĻŦāĻ‚ āĻ—ā§‡āĻŽā§‡āĻ° āĻ¸ā§āĻĨāĻŋāĻ¤āĻŋ āĻŸā§āĻ°ā§āĻ¯āĻžāĻ• āĻ•āĻ°āĻžāĻ° āĻœāĻ¨ā§āĻ¯ āĻāĻ•āĻŸāĻŋ āĻŦā§āĻ˛āĻŋāĻ¯āĻŧāĻžāĻ¨ āĻ­ā§‡āĻ°āĻŋāĻ¯āĻŧā§‡āĻŦāĻ˛ isPlaying āĻāĻ° āĻŽāĻ¤ā§‹ āĻŦā§ˆāĻļāĻŋāĻˇā§āĻŸā§āĻ¯ āĻĨāĻžāĻ•āĻŦā§‡ā§ˇ

class MemoryGame {        
    var cards:[Card] = [Card]()    
    var cardsShown:[Card] = [Card]()    
    var isPlaying: Bool = false
}

āĻ†āĻŽāĻžāĻĻā§‡āĻ° āĻ—ā§āĻ°āĻŋāĻĄā§‡āĻ° āĻ¸āĻžāĻĨā§‡ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ°āĻ•āĻžāĻ°ā§€āĻ° āĻŽāĻŋāĻĨāĻ¸ā§āĻ•ā§āĻ°āĻŋāĻ¯āĻŧāĻž āĻ¨āĻŋāĻ¯āĻŧāĻ¨ā§āĻ¤ā§āĻ°āĻŖ āĻ•āĻ°āĻžāĻ° āĻĒāĻĻā§āĻ§āĻ¤āĻŋāĻ—ā§āĻ˛āĻŋāĻ“ āĻŦāĻŋāĻ•āĻžāĻļ āĻ•āĻ°āĻ¤ā§‡ āĻšāĻŦā§‡āĨ¤

āĻāĻ•āĻŸāĻŋ āĻĒāĻĻā§āĻ§āĻ¤āĻŋ āĻ¯āĻž āĻāĻ•āĻŸāĻŋ āĻ—ā§āĻ°āĻŋāĻĄā§‡ āĻ•āĻžāĻ°ā§āĻĄ āĻāĻ˛ā§‹āĻŽā§‡āĻ˛ā§‹ āĻ•āĻ°ā§‡āĨ¤

func shuffleCards(cards:[Card]) -> [Card] {       
    var randomCards = cards        
    randomCards.shuffle()                
 
    return randomCards    
}

āĻāĻ•āĻŸāĻŋ āĻ¨āĻ¤ā§āĻ¨ āĻ—ā§‡āĻŽ āĻ¤ā§ˆāĻ°āĻŋ āĻ•āĻ°āĻžāĻ° āĻĒāĻĻā§āĻ§āĻ¤āĻŋāĨ¤ āĻāĻ–āĻžāĻ¨ā§‡ āĻ†āĻŽāĻ°āĻž āĻĒā§āĻ°āĻžāĻĨāĻŽāĻŋāĻ• āĻŦāĻŋāĻ¨ā§āĻ¯āĻžāĻ¸ āĻļā§āĻ°ā§ āĻ•āĻ°āĻžāĻ° āĻœāĻ¨ā§āĻ¯ āĻĒā§āĻ°āĻĨāĻŽ āĻĒāĻĻā§āĻ§āĻ¤āĻŋāĻ•ā§‡ āĻ•āĻ˛ āĻ•āĻ°āĻŋ āĻāĻŦāĻ‚ isPlaying āĻ­ā§‡āĻ°āĻŋāĻ¯āĻŧā§‡āĻŦāĻ˛āĻŸāĻŋāĻ•ā§‡ āĻ¸āĻ¤ā§āĻ¯ā§‡ āĻ†āĻ°āĻŽā§āĻ­ āĻ•āĻ°āĻŋāĨ¤

func newGame(cardsArray:[Card]) -> [Card] {       
    cards = shuffleCards(cards: cardsArray)        
    isPlaying = true            
 
    return cards    
}

āĻ†āĻŽāĻ°āĻž āĻ¯āĻĻāĻŋ āĻ—ā§‡āĻŽāĻŸāĻŋ āĻĒā§āĻ¨āĻ°āĻžāĻ¯āĻŧ āĻšāĻžāĻ˛ā§ āĻ•āĻ°āĻ¤ā§‡ āĻšāĻžāĻ‡, āĻ¤āĻžāĻ°āĻĒāĻ° āĻ†āĻŽāĻ°āĻž isPlaying āĻ­ā§‡āĻ°āĻŋāĻ¯āĻŧā§‡āĻŦāĻ˛āĻŸāĻŋāĻ•ā§‡ āĻŽāĻŋāĻĨā§āĻ¯āĻžāĻ¤ā§‡ āĻ¸ā§‡āĻŸ āĻ•āĻ°āĻŋ āĻāĻŦāĻ‚ āĻ•āĻžāĻ°ā§āĻĄāĻ—ā§āĻ˛āĻŋāĻ° āĻĒā§āĻ°āĻžāĻĨāĻŽāĻŋāĻ• āĻ˛ā§‡āĻ†āĻ‰āĻŸāĻŸāĻŋ āĻ¸āĻ°āĻŋāĻ¯āĻŧā§‡ āĻĢā§‡āĻ˛āĻŋāĨ¤

func restartGame() {        
    isPlaying = false                
    cards.removeAll()        
    cardsShown.removeAll()    
}

āĻ•ā§āĻ˛āĻŋāĻ• āĻ•āĻ°āĻž āĻ•āĻžāĻ°ā§āĻĄ āĻ¯āĻžāĻšāĻžāĻ‡ āĻ•āĻ°āĻžāĻ° āĻĒāĻĻā§āĻ§āĻ¤āĻŋāĨ¤ āĻ¤āĻžāĻ° āĻ¸āĻŽā§āĻĒāĻ°ā§āĻ•ā§‡ āĻ†āĻ°āĻ“ āĻĒāĻ°ā§‡āĨ¤

func cardAtIndex(_ index: Int) -> Card? {        
    if cards.count > index {            
        return cards[index]        
    } else {            
        return nil        
    }    
}

āĻāĻ•āĻŸāĻŋ āĻĒāĻĻā§āĻ§āĻ¤āĻŋ āĻ¯āĻž āĻāĻ•āĻŸāĻŋ āĻ¨āĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āĻŸ āĻ•āĻžāĻ°ā§āĻĄā§‡āĻ° āĻ…āĻŦāĻ¸ā§āĻĨāĻžāĻ¨ āĻĢā§‡āĻ°āĻ¤ āĻĻā§‡āĻ¯āĻŧāĨ¤

func indexForCard(_ card: Card) -> Int? {        
    for index in 0...cards.count-1 {            
        if card === cards[index] {                
            return index            
        }      
    }
        
    return nil    
}

āĻ¸ā§āĻŸā§āĻ¯āĻžāĻ¨ā§āĻĄāĻžāĻ°ā§āĻĄā§‡āĻ° āĻ¸āĻžāĻĨā§‡ āĻ¨āĻŋāĻ°ā§āĻŦāĻžāĻšāĻŋāĻ¤ āĻ•āĻžāĻ°ā§āĻĄā§‡āĻ° āĻ¸āĻŽā§āĻŽāĻ¤āĻŋ āĻĒāĻ°ā§€āĻ•ā§āĻˇāĻž āĻ•āĻ°āĻž āĻšāĻšā§āĻ›ā§‡āĨ¤

func unmatchedCardShown() -> Bool {
    return cardsShown.count % 2 != 0
}

āĻāĻ‡ āĻĒāĻĻā§āĻ§āĻ¤āĻŋāĻŸāĻŋ **āĻ•āĻžāĻ°ā§āĻĄ āĻĻā§‡āĻ–āĻžāĻ¨ā§‹** āĻ…ā§āĻ¯āĻžāĻ°ā§‡āĻ¤ā§‡ āĻļā§‡āĻˇ āĻ‰āĻĒāĻžāĻĻāĻžāĻ¨āĻŸāĻŋ āĻĒāĻĄāĻŧā§‡ āĻāĻŦāĻ‚ āĻ…-āĻŽā§āĻ¯āĻžāĻšāĻŋāĻ‚ āĻ•āĻžāĻ°ā§āĻĄāĻŸāĻŋ āĻĢā§‡āĻ°āĻ¤ āĻĻā§‡āĻ¯āĻŧāĨ¤

func didSelectCard(_ card: Card?) {        
    guard let card = card else { return }                
    
    if unmatchedCardShown() {            
        let unmatched = unmatchedCard()!                        
        
        if card.equals(unmatched) {          
            cardsShown.append(card)            
        } else {                
            let secondCard = cardsShown.removeLast()      
        }                    
    } else {            
        cardsShown.append(card)        
    }                
    
    if cardsShown.count == cards.count {            
        endGame()        
    }    
}

Main.storyboard āĻāĻŦāĻ‚ GameController.swift

Main.storyboard āĻāĻ°āĻ•āĻŽ āĻ•āĻŋāĻ›ā§ āĻĻā§‡āĻ–āĻžāĻ¯āĻŧ:

āĻ¸ā§āĻ‡āĻĢāĻŸā§‡ āĻāĻ•āĻŸāĻŋ āĻŽā§‡āĻŽāĻ°āĻŋ āĻ•āĻžāĻ°ā§āĻĄ āĻ—ā§‡āĻŽ āĻ˛ā§‡āĻ–āĻž

āĻĒā§āĻ°āĻžāĻĨāĻŽāĻŋāĻ•āĻ­āĻžāĻŦā§‡, āĻ†āĻĒāĻ¨āĻžāĻ•ā§‡ āĻ¨āĻ¤ā§āĻ¨ āĻ—ā§‡āĻŽāĻŸāĻŋāĻ•ā§‡ āĻ•āĻ¨ā§āĻŸā§āĻ°ā§‹āĻ˛āĻžāĻ°ā§‡ āĻ­āĻŋāĻ‰āĻĄāĻŋāĻĄāĻ˛ā§‹āĻĄ āĻšāĻŋāĻ¸āĻžāĻŦā§‡ āĻ¸ā§‡āĻŸ āĻ•āĻ°āĻ¤ā§‡ āĻšāĻŦā§‡, āĻ—ā§āĻ°āĻŋāĻĄā§‡āĻ° āĻœāĻ¨ā§āĻ¯ āĻšāĻŋāĻ¤ā§āĻ°āĻ—ā§āĻ˛āĻŋ āĻ¸āĻšāĨ¤ āĻ—ā§‡āĻŽāĻŸāĻŋāĻ¤ā§‡, āĻāĻ‡ āĻ¸āĻŽāĻ¸ā§āĻ¤āĻ—ā§āĻ˛āĻŋ āĻāĻ•āĻŸāĻŋ 4*4 āĻ¸āĻ‚āĻ—ā§āĻ°āĻš āĻ­āĻŋāĻ‰ āĻĻā§āĻŦāĻžāĻ°āĻž āĻĒā§āĻ°āĻ¤āĻŋāĻ¨āĻŋāĻ§āĻŋāĻ¤ā§āĻŦ āĻ•āĻ°āĻž āĻšāĻŦā§‡āĨ¤ āĻ†āĻĒāĻ¨āĻŋ āĻ¯āĻĻāĻŋ āĻāĻ–āĻ¨āĻ“ collectionView āĻāĻ° āĻ¸āĻžāĻĨā§‡ āĻĒāĻ°āĻŋāĻšāĻŋāĻ¤ āĻ¨āĻž āĻšāĻ¨ āĻ¤āĻŦā§‡ āĻāĻŸāĻŋ āĻāĻ–āĻžāĻ¨ā§‡ āĻ†āĻĒāĻ¨āĻŋ āĻ†āĻĒāĻ¨āĻžāĻ° āĻĒā§āĻ°āĻ¯āĻŧā§‹āĻœāĻ¨ā§€āĻ¯āĻŧ āĻ¤āĻĨā§āĻ¯ āĻĒā§‡āĻ¤ā§‡ āĻĒāĻžāĻ°ā§‡āĻ¨.

āĻ†āĻŽāĻ°āĻž āĻ—ā§‡āĻŽ āĻ•āĻ¨ā§āĻŸā§āĻ°ā§‹āĻ˛āĻžāĻ°āĻ•ā§‡ āĻ…ā§āĻ¯āĻžāĻĒā§āĻ˛āĻŋāĻ•ā§‡āĻļāĻ¨āĻŸāĻŋāĻ° āĻ°ā§āĻŸ āĻ•āĻ¨ā§āĻŸā§āĻ°ā§‹āĻ˛āĻžāĻ° āĻšāĻŋāĻ¸āĻžāĻŦā§‡ āĻ•āĻ¨āĻĢāĻŋāĻ—āĻžāĻ° āĻ•āĻ°āĻŦāĨ¤ āĻ—ā§‡āĻŽ āĻ•āĻ¨ā§āĻŸā§āĻ°ā§‹āĻ˛āĻžāĻ°ā§‡āĻ° āĻāĻ•āĻŸāĻŋ āĻ•āĻžāĻ˛ā§‡āĻ•āĻļāĻ¨ āĻ­āĻŋāĻ‰ āĻĨāĻžāĻ•āĻŦā§‡ āĻ¯āĻž āĻ†āĻŽāĻ°āĻž āĻāĻ•āĻŸāĻŋ IBOutlet āĻšāĻŋāĻ¸āĻžāĻŦā§‡ āĻ‰āĻ˛ā§āĻ˛ā§‡āĻ– āĻ•āĻ°āĻŦāĨ¤ āĻ†āĻ°ā§‡āĻ•āĻŸāĻŋ āĻ°ā§‡āĻĢāĻžāĻ°ā§‡āĻ¨ā§āĻ¸ āĻšāĻ˛ IBAction onStartGame() āĻŦā§‹āĻ¤āĻžāĻŽ, āĻāĻŸāĻŋ āĻāĻ•āĻŸāĻŋ UIButton, āĻ†āĻĒāĻ¨āĻŋ āĻāĻŸāĻŋ PLAY āĻ¨āĻžāĻŽāĻ• āĻ¸ā§āĻŸā§‹āĻ°āĻŋāĻŦā§‹āĻ°ā§āĻĄā§‡ āĻĻā§‡āĻ–āĻ¤ā§‡ āĻĒāĻžāĻ°ā§‡āĻ¨āĨ¤

āĻ•āĻ¨ā§āĻŸā§āĻ°ā§‹āĻ˛āĻžāĻ° āĻŦāĻžāĻ¸ā§āĻ¤āĻŦāĻžāĻ¯āĻŧāĻ¨ āĻ¸āĻŽā§āĻĒāĻ°ā§āĻ•ā§‡ āĻāĻ•āĻŸā§:

  • āĻĒā§āĻ°āĻĨāĻŽā§‡, āĻ†āĻŽāĻ°āĻž āĻĻā§āĻŸāĻŋ āĻĒā§āĻ°āĻ§āĻžāĻ¨ āĻ…āĻŦāĻœā§‡āĻ•ā§āĻŸ āĻļā§āĻ°ā§ āĻ•āĻ°āĻŋ - āĻ—ā§āĻ°āĻŋāĻĄ: āĻ—ā§‡āĻŽ = āĻŽā§‡āĻŽāĻ°āĻŋāĻ—ā§‡āĻŽ(), āĻāĻŦāĻ‚ āĻ¤āĻžāĻ¸ā§‡āĻ° āĻāĻ•āĻŸāĻŋ āĻ¸ā§‡āĻŸ: āĻ•āĻžāĻ°ā§āĻĄ = [āĻ•āĻžāĻ°ā§āĻĄ]()āĨ¤
  • āĻ†āĻŽāĻ°āĻž āĻ­āĻŋāĻ‰āĻĄāĻŋāĻĄāĻ˛ā§‹āĻĄ āĻšāĻŋāĻ¸āĻžāĻŦā§‡ āĻĒā§āĻ°āĻžāĻĨāĻŽāĻŋāĻ• āĻ­ā§‡āĻ°āĻŋāĻ¯āĻŧā§‡āĻŦāĻ˛ āĻ¸ā§‡āĻŸ āĻ•āĻ°āĻŋ, āĻ—ā§‡āĻŽāĻŸāĻŋ āĻšāĻ˛āĻžāĻ•āĻžāĻ˛ā§€āĻ¨ āĻāĻŸāĻŋāĻ‡ āĻĒā§āĻ°āĻĨāĻŽ āĻĒāĻĻā§āĻ§āĻ¤āĻŋ āĻ¯āĻž āĻŦāĻ˛āĻž āĻšāĻ¯āĻŧāĨ¤
  • CollectionView āĻ˛ā§āĻ•āĻžāĻ¨ā§‹ āĻ…āĻŦāĻ¸ā§āĻĨāĻžāĻ¯āĻŧ āĻ¸ā§‡āĻŸ āĻ•āĻ°āĻž āĻšāĻ¯āĻŧā§‡āĻ›ā§‡ āĻ•āĻžāĻ°āĻŖ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ°āĻ•āĻžāĻ°ā§€ āĻĒā§āĻ˛ā§‡ āĻĒā§āĻ°ā§‡āĻ¸ āĻ¨āĻž āĻ•āĻ°āĻž āĻĒāĻ°ā§āĻ¯āĻ¨ā§āĻ¤ āĻ¸āĻŽāĻ¸ā§āĻ¤ āĻ•āĻžāĻ°ā§āĻĄ āĻ˛ā§āĻ•āĻžāĻ¨ā§‹ āĻĨāĻžāĻ•ā§‡āĨ¤
  • āĻ¯āĻ¤ āĻ¤āĻžāĻĄāĻŧāĻžāĻ¤āĻžāĻĄāĻŧāĻŋ āĻ†āĻŽāĻ°āĻž PLAY āĻŸāĻŋāĻĒā§āĻ¨, onStartGame IBAction āĻŦāĻŋāĻ­āĻžāĻ— āĻļā§āĻ°ā§ āĻšāĻ¯āĻŧ, āĻāĻŦāĻ‚ āĻ†āĻŽāĻ°āĻž collectionView isHidden āĻĒā§āĻ°āĻĒāĻžāĻ°ā§āĻŸāĻŋāĻŸāĻŋāĻ•ā§‡ āĻŽāĻŋāĻĨā§āĻ¯āĻžāĻ¤ā§‡ āĻ¸ā§‡āĻŸ āĻ•āĻ°āĻŋ āĻ¯āĻžāĻ¤ā§‡ āĻ•āĻžāĻ°ā§āĻĄāĻ—ā§āĻ˛āĻŋ āĻĻā§ƒāĻļā§āĻ¯āĻŽāĻžāĻ¨ āĻšāĻ¤ā§‡ āĻĒāĻžāĻ°ā§‡āĨ¤
  • āĻĒā§āĻ°āĻ¤āĻŋāĻŦāĻžāĻ° āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ°āĻ•āĻžāĻ°ā§€ āĻāĻ•āĻŸāĻŋ āĻ•āĻžāĻ°ā§āĻĄ āĻ¨āĻŋāĻ°ā§āĻŦāĻžāĻšāĻ¨ āĻ•āĻ°ā§‡, didSelectItemAt āĻĒāĻĻā§āĻ§āĻ¤āĻŋ āĻŦāĻ˛āĻž āĻšāĻ¯āĻŧāĨ¤ āĻĒāĻĻā§āĻ§āĻ¤āĻŋāĻ¤ā§‡ āĻ†āĻŽāĻ°āĻž āĻŽā§‚āĻ˛ āĻ—ā§‡āĻŽā§‡āĻ° āĻ¯ā§āĻ•ā§āĻ¤āĻŋ āĻĒā§āĻ°āĻ¯āĻŧā§‹āĻ— āĻ•āĻ°āĻ¤ā§‡ didSelectCard āĻŦāĻ˛āĻŋāĨ¤

āĻāĻ–āĻžāĻ¨ā§‡ āĻšā§‚āĻĄāĻŧāĻžāĻ¨ā§āĻ¤ āĻ—ā§‡āĻŽ āĻ•āĻ¨ā§āĻŸā§āĻ°ā§‹āĻ˛āĻžāĻ° āĻŦāĻžāĻ¸ā§āĻ¤āĻŦāĻžāĻ¯āĻŧāĻ¨:

class GameController: UIViewController {
 
    @IBOutlet weak var collectionView: UICollectionView!
    
    let game = MemoryGame()
    var cards = [Card]()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        game.delegate = self
        
        collectionView.dataSource = self
        collectionView.delegate = self
        collectionView.isHidden = true
        
        APIClient.shared.getCardImages { (cardsArray, error) in
            if let _ = error {
                // show alert
            }
            
            self.cards = cardsArray!
            self.setupNewGame()
        }
    }
    
    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        
        if game.isPlaying {
            resetGame()
        }
    }
    
    func setupNewGame() {
        cards = game.newGame(cardsArray: self.cards)
        collectionView.reloadData()
    }
    
    func resetGame() {
        game.restartGame()
        setupNewGame()
    }
    
    @IBAction func onStartGame(_ sender: Any) {
        collectionView.isHidden = false
    }
}
 
// MARK: - CollectionView Delegate Methods
extension GameController: UICollectionViewDelegate, UICollectionViewDataSource {
    
    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1
    }
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return cards.count
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CardCell", for: indexPath) as! CardCell
        cell.showCard(false, animted: false)
        
        guard let card = game.cardAtIndex(indexPath.item) else { return cell }
        cell.card = card
        
        return cell
    }
    
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        let cell = collectionView.cellForItem(at: indexPath) as! CardCell
        
        if cell.shown { return }
        game.didSelectCard(cell.card)
        
        collectionView.deselectItem(at: indexPath, animated:true)
    }
}

āĻāĻ–āĻ¨ āĻ—ā§āĻ°ā§āĻ¤ā§āĻŦāĻĒā§‚āĻ°ā§āĻŖ āĻĒā§āĻ°ā§‹āĻŸā§‹āĻ•āĻ˛ āĻ¸āĻŽā§āĻĒāĻ°ā§āĻ•ā§‡ āĻāĻ•āĻŸā§ āĻ•āĻĨāĻž āĻŦāĻ˛āĻž āĻ¯āĻžāĻ•āĨ¤

āĻĒā§āĻ°ā§‹āĻŸā§‹āĻ•āĻ˛

āĻĒā§āĻ°ā§‹āĻŸā§‹āĻ•āĻ˛ā§‡āĻ° āĻ¸āĻžāĻĨā§‡ āĻ•āĻžāĻœ āĻ•āĻ°āĻž āĻ¸ā§āĻ‡āĻĢāĻŸ āĻĒā§āĻ°ā§‹āĻ—ā§āĻ°āĻžāĻŽāĻŋāĻ‚ āĻāĻ° āĻŽā§‚āĻ˛āĨ¤ āĻĒā§āĻ°ā§‹āĻŸā§‹āĻ•āĻ˛ āĻāĻ•āĻŸāĻŋ āĻļā§āĻ°ā§‡āĻŖā§€, āĻ•āĻžāĻ āĻžāĻŽā§‹, āĻŦāĻž āĻ—āĻŖāĻ¨āĻžāĻ° āĻœāĻ¨ā§āĻ¯ āĻ¨āĻŋāĻ¯āĻŧāĻŽ āĻ¸āĻ‚āĻœā§āĻžāĻžāĻ¯āĻŧāĻŋāĻ¤ āĻ•āĻ°āĻžāĻ° āĻ•ā§āĻˇāĻŽāĻ¤āĻž āĻĒā§āĻ°āĻĻāĻžāĻ¨ āĻ•āĻ°ā§‡āĨ¤ āĻāĻ‡ āĻ¨ā§€āĻ¤āĻŋāĻŸāĻŋ āĻ†āĻĒāĻ¨āĻžāĻ•ā§‡ āĻŽāĻĄā§āĻ˛āĻžāĻ° āĻāĻŦāĻ‚ āĻāĻ•ā§āĻ¸āĻŸā§‡āĻ¨āĻ¸āĻŋāĻŦāĻ˛ āĻ•ā§‹āĻĄ āĻ˛āĻŋāĻ–āĻ¤ā§‡ āĻĻā§‡āĻ¯āĻŧāĨ¤ āĻĒā§āĻ°āĻ•ā§ƒāĻ¤āĻĒāĻ•ā§āĻˇā§‡, āĻāĻŸāĻŋ āĻāĻ•āĻŸāĻŋ āĻĒā§āĻ¯āĻžāĻŸāĻžāĻ°ā§āĻ¨ āĻ¯āĻž āĻ†āĻŽāĻ°āĻž āĻ‡āĻ¤āĻŋāĻŽāĻ§ā§āĻ¯ā§‡āĻ‡ GameController-āĻ collectionView āĻāĻ° āĻœāĻ¨ā§āĻ¯ āĻĒā§āĻ°āĻ¯āĻŧā§‹āĻ— āĻ•āĻ°āĻ›āĻŋāĨ¤ āĻāĻ–āĻ¨ āĻ†āĻŽāĻžāĻĻā§‡āĻ° āĻ¨āĻŋāĻœāĻ¸ā§āĻŦ āĻ¸āĻ‚āĻ¸ā§āĻ•āĻ°āĻŖ āĻ¤ā§ˆāĻ°āĻŋ āĻ•āĻ°āĻž āĻ¯āĻžāĻ•. āĻ¸āĻŋāĻ¨āĻŸā§āĻ¯āĻžāĻ•ā§āĻ¸ āĻāĻ‡ āĻŽāĻ¤ āĻĻā§‡āĻ–āĻžāĻŦā§‡:

protocol MemoryGameProtocol {
    //protocol definition goes here
}

āĻ†āĻŽāĻ°āĻž āĻœāĻžāĻ¨āĻŋ āĻ¯ā§‡ āĻāĻ•āĻŸāĻŋ āĻĒā§āĻ°ā§‹āĻŸā§‹āĻ•āĻ˛ āĻ†āĻŽāĻžāĻĻā§‡āĻ° āĻāĻ•āĻŸāĻŋ āĻ•ā§āĻ˛āĻžāĻ¸ āĻŦāĻžāĻ¸ā§āĻ¤āĻŦāĻžāĻ¯āĻŧāĻ¨ā§‡āĻ° āĻœāĻ¨ā§āĻ¯ āĻ¨āĻŋāĻ¯āĻŧāĻŽ āĻŦāĻž āĻ¨āĻŋāĻ°ā§āĻĻā§‡āĻļāĻžāĻŦāĻ˛ā§€ āĻ¸āĻ‚āĻœā§āĻžāĻžāĻ¯āĻŧāĻŋāĻ¤ āĻ•āĻ°āĻ¤ā§‡ āĻĻā§‡āĻ¯āĻŧ, āĻ¤āĻžāĻ‡ āĻ†āĻ¸ā§āĻ¨ āĻ¸ā§‡āĻ—ā§āĻ˛āĻŋ āĻ•ā§€ āĻšāĻ“āĻ¯āĻŧāĻž āĻ‰āĻšāĻŋāĻ¤ āĻ¤āĻž āĻ¨āĻŋāĻ¯āĻŧā§‡ āĻ­āĻžāĻŦāĻŋāĨ¤ āĻ†āĻĒāĻ¨āĻžāĻ° āĻŽā§‹āĻŸ āĻšāĻžāĻ°āĻŸāĻŋ āĻĒā§āĻ°āĻ¯āĻŧā§‹āĻœāĻ¨āĨ¤

  • āĻ–ā§‡āĻ˛āĻž āĻļā§āĻ°ā§: memoryGameDidStart.
  • āĻ†āĻĒāĻ¨āĻžāĻ•ā§‡ āĻ•āĻžāĻ°ā§āĻĄā§‡āĻ° āĻŽā§āĻ– āĻ¨āĻŋāĻšā§‡ āĻ¨āĻžāĻŽāĻžāĻ¤ā§‡ āĻšāĻŦā§‡: memoryGameShowCardsāĨ¤
  • āĻ†āĻĒāĻ¨āĻžāĻ•ā§‡ āĻ•āĻžāĻ°ā§āĻĄā§‡āĻ° āĻŽā§āĻ– āĻ¨āĻŋāĻšā§‡ āĻ¨āĻžāĻŽāĻžāĻ¤ā§‡ āĻšāĻŦā§‡: memoryGameHideCardsāĨ¤
  • āĻ–ā§‡āĻ˛āĻž āĻļā§‡āĻˇ: memoryGameDidEnd.

āĻ¸āĻŽāĻ¸ā§āĻ¤ āĻšāĻžāĻ°āĻŸāĻŋ āĻĒāĻĻā§āĻ§āĻ¤āĻŋāĻ‡ āĻŽā§‚āĻ˛ āĻļā§āĻ°ā§‡āĻŖā§€āĻ° āĻœāĻ¨ā§āĻ¯ āĻĒā§āĻ°āĻ¯āĻŧā§‹āĻ— āĻ•āĻ°āĻž āĻ¯ā§‡āĻ¤ā§‡ āĻĒāĻžāĻ°ā§‡, āĻ¯āĻž āĻ—ā§‡āĻŽ āĻ•āĻ¨ā§āĻŸā§āĻ°ā§‹āĻ˛āĻžāĻ°āĨ¤

āĻŽā§‡āĻŽāĻ°āĻŋ āĻ—ā§‡āĻŽāĻĄāĻŋāĻĄāĻ¸ā§āĻŸāĻžāĻ°ā§āĻŸ

āĻāĻ‡ āĻĒāĻĻā§āĻ§āĻ¤āĻŋāĻŸāĻŋ āĻšāĻžāĻ˛āĻžāĻ¨ā§‹ āĻšāĻ˛ā§‡, āĻ—ā§‡āĻŽāĻŸāĻŋ āĻļā§āĻ°ā§ āĻšāĻ“āĻ¯āĻŧāĻž āĻ‰āĻšāĻŋāĻ¤ (āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ°āĻ•āĻžāĻ°ā§€ āĻĒā§āĻ˛ā§‡ āĻŸāĻŋāĻĒā§‡)āĨ¤ āĻāĻ–āĻžāĻ¨ā§‡ āĻ†āĻŽāĻ°āĻž āĻļā§āĻ§ā§āĻŽāĻžāĻ¤ā§āĻ° collectionView.reloadData() āĻ•āĻ˛ āĻ•āĻ°ā§‡ āĻŦāĻŋāĻˇāĻ¯āĻŧāĻŦāĻ¸ā§āĻ¤ā§ āĻĒā§āĻ¨āĻ°āĻžāĻ¯āĻŧ āĻ˛ā§‹āĻĄ āĻ•āĻ°āĻŦ, āĻ¯āĻž āĻ•āĻžāĻ°ā§āĻĄāĻ—ā§āĻ˛āĻŋāĻ•ā§‡ āĻāĻ˛ā§‹āĻŽā§‡āĻ˛ā§‹ āĻ•āĻ°āĻŦā§‡āĨ¤

func memoryGameDidStart(_ game: MemoryGame) {
    collectionView.reloadData()
}

āĻŽā§‡āĻŽāĻ°āĻŋ āĻ—ā§‡āĻŽāĻļā§‹āĻ•āĻžāĻ°ā§āĻĄ

āĻ†āĻŽāĻ°āĻž āĻ¸āĻ‚āĻ—ā§āĻ°āĻš āĻāĻ¸āĻĄāĻŋāĻ­āĻŋāĻ‰ āĻ¸āĻŋāĻ˛ā§‡āĻ•ā§āĻŸ āĻ†āĻ‡āĻŸā§‡āĻŽāĻ†āĻŸ āĻĨā§‡āĻ•ā§‡ āĻāĻ‡ āĻĒāĻĻā§āĻ§āĻ¤āĻŋāĻŸāĻŋāĻ•ā§‡ āĻ•āĻ˛ āĻ•āĻ°āĻŋāĨ¤ āĻĒā§āĻ°āĻĨāĻŽā§‡ āĻāĻŸāĻŋ āĻ¨āĻŋāĻ°ā§āĻŦāĻžāĻšāĻŋāĻ¤ āĻ•āĻžāĻ°ā§āĻĄ āĻĻā§‡āĻ–āĻžāĻ¯āĻŧāĨ¤ āĻ¤āĻžāĻ°āĻĒāĻ°ā§‡ āĻ•āĻžāĻ°ā§āĻĄ āĻĻā§‡āĻ–āĻžāĻ¨ā§‹ āĻ…ā§āĻ¯āĻžāĻ°ā§‡āĻ¤ā§‡ āĻāĻ•āĻŸāĻŋ āĻ…āĻŽāĻŋāĻ˛ āĻ•āĻžāĻ°ā§āĻĄ āĻ†āĻ›ā§‡ āĻ•āĻŋāĻ¨āĻž āĻ¤āĻž āĻĒāĻ°ā§€āĻ•ā§āĻˇāĻž āĻ•āĻ°ā§‡ āĻĻā§‡āĻ–ā§āĻ¨ (āĻ¯āĻĻāĻŋ āĻĻā§‡āĻ–āĻžāĻ¨ā§‹ āĻ•āĻžāĻ°ā§āĻĄā§‡āĻ° āĻ¸āĻ‚āĻ–ā§āĻ¯āĻž āĻŦāĻŋāĻœā§‹āĻĄāĻŧ āĻšāĻ¯āĻŧ)āĨ¤ āĻ¯āĻĻāĻŋ āĻāĻ•āĻŸāĻŋ āĻĨāĻžāĻ•ā§‡ āĻ¤āĻŦā§‡ āĻ¨āĻŋāĻ°ā§āĻŦāĻžāĻšāĻŋāĻ¤ āĻ•āĻžāĻ°ā§āĻĄāĻŸāĻŋ āĻāĻ° āĻ¸āĻžāĻĨā§‡ āĻ¤ā§āĻ˛āĻ¨āĻž āĻ•āĻ°āĻž āĻšāĻ¯āĻŧāĨ¤ āĻ›āĻŦāĻŋ āĻāĻ•āĻ‡ āĻšāĻ˛ā§‡, āĻ‰āĻ­āĻ¯āĻŧ āĻ•āĻžāĻ°ā§āĻĄāĻ‡ āĻ•āĻžāĻ°ā§āĻĄā§‡ āĻ¯ā§‹āĻ— āĻ•āĻ°āĻž āĻšāĻ¯āĻŧ āĻĻā§‡āĻ–āĻžāĻ¨ā§‹ āĻšāĻ¯āĻŧ āĻāĻŦāĻ‚ āĻŽā§āĻ–ā§‹āĻŽā§āĻ–āĻŋ āĻĨāĻžāĻ•ā§‡āĨ¤ āĻ­āĻŋāĻ¨ā§āĻ¨ āĻšāĻ˛ā§‡, āĻ•āĻžāĻ°ā§āĻĄ āĻ›ā§‡āĻĄāĻŧā§‡ āĻ•āĻžāĻ°ā§āĻĄ āĻĻā§‡āĻ–āĻžāĻ¨ā§‹ āĻšāĻ¯āĻŧ āĻāĻŦāĻ‚ āĻ‰āĻ­āĻ¯āĻŧāĻ‡ āĻŽā§āĻ– āĻĨā§āĻŦāĻĄāĻŧā§‡ āĻĒāĻĄāĻŧā§‡āĨ¤

āĻŽā§‡āĻŽāĻ°āĻŋ āĻ—ā§‡āĻŽāĻšāĻžāĻ‡āĻĄāĻ•āĻžāĻ°ā§āĻĄ

āĻ¯āĻĻāĻŋ āĻ•āĻžāĻ°ā§āĻĄāĻ—ā§āĻ˛āĻŋ āĻŽā§‡āĻ˛ā§‡ āĻ¨āĻž, āĻāĻ‡ āĻĒāĻĻā§āĻ§āĻ¤āĻŋāĻŸāĻŋ āĻŦāĻ˛āĻž āĻšāĻ¯āĻŧ āĻāĻŦāĻ‚ āĻ•āĻžāĻ°ā§āĻĄā§‡āĻ° āĻ›āĻŦāĻŋāĻ—ā§āĻ˛āĻŋ āĻ˛ā§āĻ•āĻžāĻ¨ā§‹ āĻšāĻ¯āĻŧāĨ¤

āĻĻā§‡āĻ–āĻžāĻ¨ā§‹ = āĻŽāĻŋāĻĨā§āĻ¯āĻžāĨ¤

āĻŽā§‡āĻŽāĻ°āĻŋ āĻ—ā§‡āĻŽāĻĄāĻŋāĻĄāĻāĻ¨ā§āĻĄ

āĻ¯āĻ–āĻ¨ āĻāĻ‡ āĻĒāĻĻā§āĻ§āĻ¤āĻŋāĻŸāĻŋ āĻŦāĻ˛āĻž āĻšāĻ¯āĻŧ, āĻāĻ° āĻŽāĻžāĻ¨ā§‡ āĻšāĻ˛ āĻ¯ā§‡ āĻ¸āĻŽāĻ¸ā§āĻ¤ āĻ•āĻžāĻ°ā§āĻĄ āĻ‡āĻ¤āĻŋāĻŽāĻ§ā§āĻ¯ā§‡āĻ‡ āĻĒā§āĻ°āĻ•āĻžāĻļ āĻ•āĻ°āĻž āĻšāĻ¯āĻŧā§‡āĻ›ā§‡ āĻāĻŦāĻ‚ āĻ•āĻžāĻ°ā§āĻĄ āĻĻā§‡āĻ–āĻžāĻ¨ā§‹ āĻ¤āĻžāĻ˛āĻŋāĻ•āĻžāĻ¯āĻŧ āĻ°āĻ¯āĻŧā§‡āĻ›ā§‡: cardsShown.count = cards.count, āĻ¤āĻžāĻ‡ āĻ—ā§‡āĻŽāĻŸāĻŋ āĻļā§‡āĻˇāĨ¤ āĻĒāĻĻā§āĻ§āĻ¤āĻŋāĻŸāĻŋāĻ•ā§‡ āĻŦāĻŋāĻļā§‡āĻˇāĻ­āĻžāĻŦā§‡ āĻŦāĻ˛āĻž āĻšāĻ¯āĻŧ āĻ¯āĻ–āĻ¨ āĻ†āĻŽāĻ°āĻž endGame() āĻ•ā§‡ āĻ•āĻ˛ āĻ•āĻ°ā§‡ isPlaying var-āĻ•ā§‡ āĻŽāĻŋāĻĨā§āĻ¯āĻž āĻ¸ā§‡āĻŸ āĻ•āĻ°āĻžāĻ° āĻœāĻ¨ā§āĻ¯, āĻ¤āĻžāĻ°āĻĒāĻ°ā§‡ āĻ—ā§‡āĻŽā§‡āĻ° āĻļā§‡āĻˇ āĻŦāĻžāĻ°ā§āĻ¤āĻžāĻŸāĻŋ āĻĻā§‡āĻ–āĻžāĻ¨ā§‹ āĻšāĻ¯āĻŧāĨ¤ āĻāĻ›āĻžāĻĄāĻŧāĻžāĻ“ alertController āĻ¨āĻŋāĻ¯āĻŧāĻžāĻŽāĻ•ā§‡āĻ° āĻœāĻ¨ā§āĻ¯ āĻāĻ•āĻŸāĻŋ āĻ¸ā§‚āĻšāĻ• āĻšāĻŋāĻ¸āĻžāĻŦā§‡ āĻŦā§āĻ¯āĻŦāĻšā§ƒāĻ¤ āĻšāĻ¯āĻŧāĨ¤ viewDidDisappear āĻŦāĻ˛āĻž āĻšāĻ¯āĻŧ āĻāĻŦāĻ‚ āĻ—ā§‡āĻŽāĻŸāĻŋ āĻ°āĻŋāĻ¸ā§‡āĻŸ āĻ•āĻ°āĻž āĻšāĻ¯āĻŧāĨ¤

āĻ—ā§‡āĻŽ āĻ•āĻ¨ā§āĻŸā§āĻ°ā§‹āĻ˛āĻžāĻ°ā§‡ āĻāĻŸāĻŋ āĻ•ā§‡āĻŽāĻ¨ āĻĻā§‡āĻ–āĻžāĻ¯āĻŧ āĻ¤āĻž āĻāĻ–āĻžāĻ¨ā§‡:

extension GameController: MemoryGameProtocol {
    func memoryGameDidStart(_ game: MemoryGame) {
        collectionView.reloadData()
    }
 
 
    func memoryGame(_ game: MemoryGame, showCards cards: [Card]) {
        for card in cards {
            guard let index = game.indexForCard(card)
                else { continue
            }        
            
            let cell = collectionView.cellForItem(
                at: IndexPath(item: index, section:0)
            ) as! CardCell
 
            cell.showCard(true, animted: true)
        }
    }
 
    func memoryGame(_ game: MemoryGame, hideCards cards: [Card]) {
        for card in cards {
            guard let index = game.indexForCard(card)
                else { continue
            }
            
            let cell = collectionView.cellForItem(
                at: IndexPath(item: index, section:0)
            ) as! CardCell
    
            cell.showCard(false, animted: true)
        }
    }
 
    func memoryGameDidEnd(_ game: MemoryGame) {
        let alertController = UIAlertController(
            title: defaultAlertTitle,
            message: defaultAlertMessage,
            preferredStyle: .alert
        )
 
        let cancelAction = UIAlertAction(
            title: "Nah", style: .cancel) {
            [weak self] (action) in
            self?.collectionView.isHidden = true
        }
 
        let playAgainAction = UIAlertAction(
            title: "Dale!", style: .default) {
            [weak self] (action) in
            self?.collectionView.isHidden = true
 
            self?.resetGame()
        }
 
        alertController.addAction(cancelAction)
        alertController.addAction(playAgainAction)
        
        self.present(alertController, animated: true) { }
    
        resetGame()
    }
}

āĻ¸ā§āĻ‡āĻĢāĻŸā§‡ āĻāĻ•āĻŸāĻŋ āĻŽā§‡āĻŽāĻ°āĻŋ āĻ•āĻžāĻ°ā§āĻĄ āĻ—ā§‡āĻŽ āĻ˛ā§‡āĻ–āĻž
āĻ†āĻ¸āĻ˛ā§‡, āĻ¯ā§‡ āĻ¸āĻŦ. āĻ†āĻĒāĻ¨āĻŋ āĻ—ā§‡āĻŽāĻŸāĻŋāĻ° āĻ¨āĻŋāĻœāĻ¸ā§āĻŦ āĻ¸āĻ‚āĻ¸ā§āĻ•āĻ°āĻŖ āĻ¤ā§ˆāĻ°āĻŋ āĻ•āĻ°āĻ¤ā§‡ āĻāĻ‡ āĻĒā§āĻ°āĻ•āĻ˛ā§āĻĒāĻŸāĻŋ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻ•āĻ°āĻ¤ā§‡ āĻĒāĻžāĻ°ā§‡āĻ¨āĨ¤

āĻļā§āĻ­ āĻ•ā§‹āĻĄāĻŋāĻ‚!

Skillbox āĻ¸ā§āĻĒāĻžāĻ°āĻŋāĻļ āĻ•āĻ°ā§‡:

āĻ‰āĻ¤ā§āĻ¸: www.habr.com

āĻāĻ•āĻŸāĻŋ āĻŽāĻ¨ā§āĻ¤āĻŦā§āĻ¯ āĻœā§āĻĄāĻŧā§āĻ¨