ΠŸΠΈΡˆΡƒΠ²Π°ΡšΠ΅ ΠΈΠ³Ρ€Π° со мСмориски ΠΊΠ°Ρ€Ρ‚ΠΈΡ‡ΠΊΠΈ Π²ΠΎ Swift

ΠŸΠΈΡˆΡƒΠ²Π°ΡšΠ΅ ΠΈΠ³Ρ€Π° со мСмориски ΠΊΠ°Ρ€Ρ‚ΠΈΡ‡ΠΊΠΈ Π²ΠΎ Swift

Оваа ΡΡ‚Π°Ρ‚ΠΈΡ˜Π° Π³ΠΎ ΠΎΠΏΠΈΡˆΡƒΠ²Π° процСсот Π½Π° создавањС Сдноставна ΠΈΠ³Ρ€Π° Π·Π° ΠΎΠ±ΡƒΠΊΠ° Π½Π° ΠΌΠ΅ΠΌΠΎΡ€ΠΈΡ˜Π° која навистина ΠΌΠΈ сС Π΄ΠΎΠΏΠ°Ρ“Π°. ОсвСн ΡˆΡ‚ΠΎ Π΅ Π΄ΠΎΠ±Ρ€ΠΎ само ΠΏΠΎ сСбС, ќС Π½Π°ΡƒΡ‡ΠΈΡ‚Π΅ ΠΌΠ°Π»ΠΊΡƒ повСќС Π·Π° часовитС ΠΈ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»ΠΈΡ‚Π΅ Π½Π° Swift Π΄ΠΎΠ΄Π΅ΠΊΠ° ΠΎΠ΄ΠΈΡ‚Π΅. Но, ΠΏΡ€Π΅Π΄ Π΄Π° Π·Π°ΠΏΠΎΡ‡Π½Π΅ΠΌΠ΅, Π΄Π° ја Ρ€Π°Π·Π±Π΅Ρ€Π΅ΠΌΠ΅ самата ΠΈΠ³Ρ€Π°.

ΠŸΠΎΡ‚ΡΠ΅Ρ‚ΡƒΠ²Π°ΠΌΠ΅: Π·Π° ситС Ρ‡ΠΈΡ‚Π°Ρ‚Π΅Π»ΠΈ Π½Π° β€žΠ₯Π°Π±Ρ€β€œ - попуст ΠΎΠ΄ 10 Ρ€ΡƒΠ±Π»ΠΈ ΠΏΡ€ΠΈ Π·Π°ΠΏΠΈΡˆΡƒΠ²Π°ΡšΠ΅ Π½Π° кој Π±ΠΈΠ»ΠΎ курс Skillbox ΠΊΠΎΡ€ΠΈΡΡ‚Π΅Ρ˜ΡœΠΈ Π³ΠΎ ΠΏΡ€ΠΎΠΌΠΎΡ‚ΠΈΠ²Π½ΠΈΠΎΡ‚ ΠΊΠΎΠ΄ β€žΠ₯Π°Π±Ρ€β€œ.

Skillbox ΠΏΡ€Π΅ΠΏΠΎΡ€Π°Ρ‡ΡƒΠ²Π°: Π•Π΄ΡƒΠΊΠ°Ρ‚ΠΈΠ²Π΅Π½ онлајн курс β€žΠŸΡ€ΠΎΡ„Π΅ΡΠΈΡ˜Π° Java ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ΅Ρ€β€œ.

Како Π΄Π° ΠΈΠ³Ρ€Π°Ρ‚Π΅ мСмориска ΠΊΠ°Ρ€Ρ‚ΠΈΡ‡ΠΊΠ°

Π˜Π³Ρ€Π°Ρ‚Π° Π·Π°ΠΏΠΎΡ‡Π½ΡƒΠ²Π° со Π΄Π΅ΠΌΠΎΠ½ΡΡ‚Ρ€Π°Ρ†ΠΈΡ˜Π° Π½Π° сСт Π½Π° ΠΊΠ°Ρ€Ρ‚ΠΈ. Π’ΠΈΠ΅ Π»Π΅ΠΆΠ°Ρ‚ со Π»ΠΈΡ†Π΅Ρ‚ΠΎ Π½Π°Π΄ΠΎΠ»Ρƒ (соодвСтно, сликата Π½Π°Π΄ΠΎΠ»Ρƒ). Кога ќС ΠΊΠ»ΠΈΠΊΠ½Π΅Ρ‚Π΅ Π½Π° кој Π±ΠΈΠ»ΠΎ, сликата сС ΠΎΡ‚Π²ΠΎΡ€Π° Π½Π΅ΠΊΠΎΠ»ΠΊΡƒ сСкунди.

Π—Π°Π΄Π°Ρ‡Π°Ρ‚Π° Π½Π° ΠΈΠ³Ρ€Π°Ρ‡ΠΎΡ‚ Π΅ Π΄Π° Π³ΠΈ ΠΏΡ€ΠΎΠ½Π°Ρ˜Π΄Π΅ ситС ΠΊΠ°Ρ€Ρ‚ΠΈ со исти слики. Ако, ΠΏΠΎ ΠΎΡ‚Π²ΠΎΡ€Π°ΡšΠ΅Ρ‚ΠΎ Π½Π° ΠΏΡ€Π²Π°Ρ‚Π° ΠΊΠ°Ρ€Ρ‚ΠΈΡ‡ΠΊΠ°, ја ΠΏΡ€Π΅Π²Ρ€Ρ‚ΠΈΡ‚Π΅ Π²Ρ‚ΠΎΡ€Π°Ρ‚Π° ΠΈ сликитС сС совпаѓаат, Π΄Π²Π΅Ρ‚Π΅ ΠΊΠ°Ρ€Ρ‚ΠΈ остануваат ΠΎΡ‚Π²ΠΎΡ€Π΅Π½ΠΈ. Π”ΠΎΠΊΠΎΠ»ΠΊΡƒ Π½Π΅ сС совпаѓаат, ΠΊΠ°Ρ€Ρ‚ΠΈΡ‚Π΅ ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎ сС Π·Π°Ρ‚Π²ΠΎΡ€Π°Π°Ρ‚. Π¦Π΅Π»Ρ‚Π° Π΅ Π΄Π° сС ΠΎΡ‚Π²ΠΎΡ€ΠΈ сС.

Π‘Ρ‚Ρ€ΡƒΠΊΡ‚ΡƒΡ€Π° Π½Π° ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ΠΎΡ‚

Π—Π° Π΄Π° ΠΊΡ€Π΅ΠΈΡ€Π°Ρ‚Π΅ Сдноставна Π²Π΅Ρ€Π·ΠΈΡ˜Π° Π½Π° ΠΎΠ²Π°Π° ΠΈΠ³Ρ€Π°, ΠΏΠΎΡ‚Ρ€Π΅Π±Π½ΠΈ Π²ΠΈ сС слСднивС ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΈ:

  • Π•Π΄Π΅Π½ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π΅Ρ€: GameController.swift.
  • Π•Π΄Π΅Π½ ΠΏΠΎΠ³Π»Π΅Π΄: CardCell.swift.
  • Π”Π²Π° ΠΌΠΎΠ΄Π΅Π»ΠΈ: MemoryGame.swift ΠΈ Card.swift.
  • Main.storyboard Π·Π° Π΄Π° сС осигура Π΄Π΅ΠΊΠ° Ρ†Π΅Π»ΠΈΠΎΡ‚ сСт Π½Π° ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΈ Π΅ достапСн.

Π—Π°ΠΏΠΎΡ‡Π½ΡƒΠ²Π°ΠΌΠ΅ со Π½Π°Ρ˜Π΅Π΄Π½ΠΎΡΡ‚Π°Π²Π½Π°Ρ‚Π° ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π° Π½Π° ΠΈΠ³Ρ€Π°Ρ‚Π°, ΠΊΠ°Ρ€Ρ‚ΠΈΡ‚Π΅.

ΠšΠ°Ρ€Ρ‚ΠΈΡ‡ΠΊΠ°.свифт

ΠœΠΎΠ΄Π΅Π»ΠΎΡ‚ Π½Π° ΠΊΠ°Ρ€Ρ‚ΠΈΡ‡ΠΊΠ°Ρ‚Π° ќС ΠΈΠΌΠ° Ρ‚Ρ€ΠΈ ΡΠ²ΠΎΡ˜ΡΡ‚Π²Π°: id Π·Π° ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΡƒΠ²Π°ΡšΠ΅ Π½Π° сСкоја ΠΎΠ΄ Π½ΠΈΠ², Π±ΡƒΠ»ΠΎΠ²Π° ΠΏΡ€ΠΎΠΌΠ΅Π½Π»ΠΈΠ²Π° ΠΏΡ€ΠΈΠΊΠ°ΠΆΠ°Π½Π° Π·Π° ΠΎΠ΄Ρ€Π΅Π΄ΡƒΠ²Π°ΡšΠ΅ Π½Π° статусот Π½Π° ΠΊΠ°Ρ€Ρ‚ΠΈΡ‡ΠΊΠ°Ρ‚Π° (скриСна ΠΈΠ»ΠΈ ΠΎΡ‚Π²ΠΎΡ€Π΅Π½Π°) ΠΈ artworkURL Π·Π° сликитС Π½Π° ΠΊΠ°Ρ€Ρ‚ΠΈΡ‡ΠΊΠΈΡ‚Π΅.

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

ЌС Π²ΠΈ Ρ‚Ρ€Π΅Π±Π°Π°Ρ‚ ΠΈ ΠΎΠ²ΠΈΠ΅ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΈ Π·Π° Π΄Π° ја ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΠΈΡ€Π°Ρ‚Π΅ ΠΈΠ½Ρ‚Π΅Ρ€Π°ΠΊΡ†ΠΈΡ˜Π°Ρ‚Π° Π½Π° корисницитС со ΠΌΠ°ΠΏΠΈΡ‚Π΅:

Начин Π·Π° ΠΏΡ€ΠΈΠΊΠ°ΠΆΡƒΠ²Π°ΡšΠ΅ слика Π½Π° ΠΊΠ°Ρ€Ρ‚ΠΈΡ‡ΠΊΠ°. ОвдС Π³ΠΈ рСсСтирамС ситС ΡΠ²ΠΎΡ˜ΡΡ‚Π²Π° Π½Π° стандардни. Π—Π° ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΡ˜Π°, Π³Π΅Π½Π΅Ρ€ΠΈΡ€Π°ΠΌΠ΅ случаСн id со ΠΏΠΎΠ²ΠΈΠΊΡƒΠ²Π°ΡšΠ΅ Π½Π° 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    
}

И ΡƒΡˆΡ‚Π΅ Π΅Π΄Π΅Π½ ΠΌΠ΅Ρ‚ΠΎΠ΄ Π΅ ΠΏΠΎΡ‚Ρ€Π΅Π±Π΅Π½ Π·Π° Π΄Π° сС ΠΈΠ·ΠΌΠ΅ΡˆΠ°Π°Ρ‚ ΠΊΠ°Ρ€Ρ‚ΠΈΡ‚Π΅ Π½Π° ΠΏΠΎΡ‡Π΅Ρ‚ΠΎΠΊΠΎΡ‚. ЌС Π³ΠΎ Π½Π°ΠΏΡ€Π°Π²ΠΈΠΌΠ΅ ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΡƒΠ²Π°ΡšΠ΅ Π½Π° класата Array.

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

И Ρ‚ΡƒΠΊΠ° Π΅ ΠΈΠΌΠΏΠ»Π΅ΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡ˜Π°Ρ‚Π° Π½Π° ΠΊΠΎΠ΄ΠΎΡ‚ Π·Π° ΠΌΠΎΠ΄Π΅Π»ΠΎΡ‚ Card со ситС ΡΠ²ΠΎΡ˜ΡΡ‚Π²Π° ΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΈ.

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 Π½Π° false ΠΈ Π³ΠΎ отстранувамС ΠΏΠΎΡ‡Π΅Ρ‚Π½ΠΈΠΎΡ‚ распорСд Π½Π° ΠΊΠ°Ρ€Ρ‚ΠΈΡ‡ΠΊΠΈΡ‚Π΅.

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
}

Овој ΠΌΠ΅Ρ‚ΠΎΠ΄ Π³ΠΎ Ρ‡ΠΈΡ‚Π° послСдниот Π΅Π»Π΅ΠΌΠ΅Π½Ρ‚ Π²ΠΎ Π½ΠΈΠ·Π°Ρ‚Π° **cardsShown** ΠΈ ја Π²Ρ€Π°ΡœΠ° ΠΊΠ°Ρ€Ρ‚ΠΈΡ‡ΠΊΠ°Ρ‚Π° ΡˆΡ‚ΠΎ Π½Π΅ сС совпаѓа.

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 ΠΈΠ·Π³Π»Π΅Π΄Π° Π²Π°ΠΊΠ°:

ΠŸΠΈΡˆΡƒΠ²Π°ΡšΠ΅ ΠΈΠ³Ρ€Π° со мСмориски ΠΊΠ°Ρ€Ρ‚ΠΈΡ‡ΠΊΠΈ Π²ΠΎ Swift

ΠŸΡ€Π²ΠΈΡ‡Π½ΠΎ, Ρ‚Ρ€Π΅Π±Π° Π΄Π° ја поставитС Π½ΠΎΠ²Π°Ρ‚Π° ΠΈΠ³Ρ€Π° ΠΊΠ°ΠΊΠΎ viewDidLoad Π²ΠΎ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π΅Ρ€ΠΎΡ‚, Π²ΠΊΠ»ΡƒΡ‡ΡƒΠ²Π°Ρ˜ΡœΠΈ Π³ΠΈ ΠΈ сликитС Π·Π° ΠΌΡ€Π΅ΠΆΠ°Ρ‚Π°. Π’ΠΎ ΠΈΠ³Ρ€Π°Ρ‚Π°, сСто ΠΎΠ²Π° ќС Π±ΠΈΠ΄Π΅ прСтставСно со 4*4 collectionView. Ако сè ΡƒΡˆΡ‚Π΅ Π½Π΅ стС Π·Π°ΠΏΠΎΠ·Π½Π°Π΅Π½ΠΈ со collectionView, Π΅Π²Π΅ Π³ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° Π³ΠΈ Π΄ΠΎΠ±ΠΈΠ΅Ρ‚Π΅ ΠΏΠΎΡ‚Ρ€Π΅Π±Π½ΠΈΡ‚Π΅ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ.

ЌС Π³ΠΎ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€ΠΈΡ€Π°ΠΌΠ΅ GameController ΠΊΠ°ΠΊΠΎ root ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π΅Ρ€ Π½Π° Π°ΠΏΠ»ΠΈΠΊΠ°Ρ†ΠΈΡ˜Π°Ρ‚Π°. GameController ќС ΠΈΠΌΠ° collectionView кој ќС Π³ΠΎ Ρ€Π΅Ρ„Π΅Ρ€ΠΈΡ€Π°ΠΌΠ΅ ΠΊΠ°ΠΊΠΎ IBOoutlet. Π”Ρ€ΡƒΠ³Π° Ρ€Π΅Ρ„Π΅Ρ€Π΅Π½Ρ†Π° Π΅ Π½Π° ΠΊΠΎΠΏΡ‡Π΅Ρ‚ΠΎ IBAction onStartGame(), ΠΎΠ²Π° Π΅ UIButton, ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° Π³ΠΎ Π²ΠΈΠ΄ΠΈΡ‚Π΅ Π²ΠΎ ΠΏΡ€ΠΈΠΊΠ°Π·Π½Π°Ρ‚Π° Π½Π°Ρ€Π΅Ρ‡Π΅Π½Π° PLAY.

ΠœΠ°Π»ΠΊΡƒ Π·Π° ΠΈΠΌΠΏΠ»Π΅ΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡ˜Π°Ρ‚Π° Π½Π° ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΠΎΡ€ΠΈΡ‚Π΅:

  • ΠŸΡ€Π²ΠΎ, Π½ΠΈΠ΅ ΠΈΠ½ΠΈΡ†ΠΈΡ˜Π°Π»ΠΈΠ·ΠΈΡ€Π°ΠΌΠ΅ Π΄Π²Π° Π³Π»Π°Π²Π½ΠΈ ΠΎΠ±Ρ˜Π΅ΠΊΡ‚ΠΈ - ΠΌΡ€Π΅ΠΆΠ°Ρ‚Π°: ΠΈΠ³Ρ€Π° = MemoryGame(), ΠΈ Π·Π±ΠΈΡ€ Π½Π° ΠΊΠ°Ρ€Ρ‚ΠΈ: ΠΊΠ°Ρ€Ρ‚ΠΈ = [Card]().
  • ΠŸΠΎΡ‡Π΅Ρ‚Π½ΠΈΡ‚Π΅ ΠΏΡ€ΠΎΠΌΠ΅Π½Π»ΠΈΠ²ΠΈ Π³ΠΈ поставивмС ΠΊΠ°ΠΊΠΎ viewDidLoad, ΠΎΠ²Π° Π΅ ΠΏΡ€Π²ΠΈΠΎΡ‚ ΠΌΠ΅Ρ‚ΠΎΠ΄ ΡˆΡ‚ΠΎ сС ΠΏΠΎΠ²ΠΈΠΊΡƒΠ²Π° Π΄ΠΎΠ΄Π΅ΠΊΠ° Ρ€Π°Π±ΠΎΡ‚ΠΈ ΠΈΠ³Ρ€Π°Ρ‚Π°.
  • collectionView Π΅ поставСн Π½Π° скриСн бидСјќи ситС ΠΊΠ°Ρ€Ρ‚ΠΈΡ‡ΠΊΠΈ сС скриСни Π΄ΠΎΠ΄Π΅ΠΊΠ° корисникот Π½Π΅ притиснС PLAY.
  • Π’Π΅Π΄Π½Π°Ρˆ ΡˆΡ‚ΠΎΠΌ ќС притиснСмС PLAY, Π·Π°ΠΏΠΎΡ‡Π½ΡƒΠ²Π° Π΄Π΅Π»ΠΎΡ‚ onStartGame IBAction ΠΈ Π³ΠΎ поставивмС ΡΠ²ΠΎΡ˜ΡΡ‚Π²ΠΎΡ‚ΠΎ collectionView isHidden Π½Π° false Π·Π° Π΄Π° ΠΌΠΎΠΆΠ°Ρ‚ ΠΊΠ°Ρ€Ρ‚ΠΈΡ‡ΠΊΠΈΡ‚Π΅ Π΄Π° станат Π²ΠΈΠ΄Π»ΠΈΠ²ΠΈ.
  • БСкој ΠΏΠ°Ρ‚ ΠΊΠΎΠ³Π° корисникот ΠΈΠ·Π±ΠΈΡ€Π° ΠΊΠ°Ρ€Ρ‚ΠΈΡ‡ΠΊΠ°, сС ΠΏΠΎΠ²ΠΈΠΊΡƒΠ²Π° ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΡ‚ didSelectItemAt. Π’ΠΎ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΡ‚ ΡˆΡ‚ΠΎ Π³ΠΎ Π½Π°Ρ€Π΅ΠΊΡƒΠ²Π°ΠΌΠ΅ didSelectCard Π·Π° Π΄Π° сС ΠΈΠΌΠΏΠ»Π΅ΠΌΠ΅Π½Ρ‚ΠΈΡ€Π° Π³Π»Π°Π²Π½Π°Ρ‚Π° Π»ΠΎΠ³ΠΈΠΊΠ° Π½Π° ΠΈΠ³Ρ€Π°Ρ‚Π°.

Π•Π²Π΅ ја ΠΊΠΎΠ½Π΅Ρ‡Π½Π°Ρ‚Π° ΠΈΠΌΠΏΠ»Π΅ΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡ˜Π° Π½Π° GameController:

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)
    }
}

Π‘Π΅Π³Π° Π΄Π° Ρ€Π°Π·Π³ΠΎΠ²Π°Ρ€Π°ΠΌΠ΅ ΠΌΠ°Π»ΠΊΡƒ Π·Π° Π²Π°ΠΆΠ½ΠΈΡ‚Π΅ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»ΠΈ.

ΠŸΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»ΠΈ

Π Π°Π±ΠΎΡ‚Π°Ρ‚Π° со ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»ΠΈ Π΅ Ρ˜Π°Π΄Ρ€ΠΎΡ‚ΠΎ Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ€Π°ΡšΠ΅Ρ‚ΠΎ Π½Π° Swift. ΠŸΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»ΠΈΡ‚Π΅ ΠΎΠ±Π΅Π·Π±Π΅Π΄ΡƒΠ²Π°Π°Ρ‚ моТност Π΄Π° сС Π΄Π΅Ρ„ΠΈΠ½ΠΈΡ€Π°Π°Ρ‚ ΠΏΡ€Π°Π²ΠΈΠ»Π° Π·Π° класа, структура ΠΈΠ»ΠΈ Π½Π°Π±Ρ€ΠΎΡ˜ΡƒΠ²Π°ΡšΠ΅. Овој ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏ Π²ΠΈ ΠΎΠ²ΠΎΠ·ΠΌΠΎΠΆΡƒΠ²Π° Π΄Π° ΠΏΠΈΡˆΡƒΠ²Π°Ρ‚Π΅ ΠΌΠΎΠ΄ΡƒΠ»Π°Ρ€Π΅Π½ ΠΈ ΠΏΡ€ΠΎΡˆΠΈΡ€Π»ΠΈΠ² ΠΊΠΎΠ΄. Π’ΡΡƒΡˆΠ½ΠΎΡΡ‚, ΠΎΠ²Π° Π΅ шСма ΡˆΡ‚ΠΎ вСќС ја ΠΈΠΌΠΏΠ»Π΅ΠΌΠ΅Π½Ρ‚ΠΈΡ€Π°ΠΌΠ΅ Π·Π° collectionView Π²ΠΎ GameController. Π‘Π΅Π³Π° ајдС Π΄Π° Π½Π°ΠΏΡ€Π°Π²ΠΈΠΌΠ΅ своја Π²Π΅Ρ€Π·ΠΈΡ˜Π°. Бинтаксата ќС ΠΈΠ·Π³Π»Π΅Π΄Π° Π²Π°ΠΊΠ°:

protocol MemoryGameProtocol {
    //protocol definition goes here
}

Π—Π½Π°Π΅ΠΌΠ΅ Π΄Π΅ΠΊΠ° ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»ΠΎΡ‚ Π½ΠΈ ΠΎΠ²ΠΎΠ·ΠΌΠΎΠΆΡƒΠ²Π° Π΄Π° Π΄Π΅Ρ„ΠΈΠ½ΠΈΡ€Π°ΠΌΠ΅ ΠΏΡ€Π°Π²ΠΈΠ»Π° ΠΈΠ»ΠΈ инструкции Π·Π° ΠΈΠΌΠΏΠ»Π΅ΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡ˜Π° Π½Π° класа, ΠΏΠ° ајдС Π΄Π° размислимС ΠΊΠ°ΠΊΠ²ΠΈ Ρ‚Ρ€Π΅Π±Π° Π΄Π° Π±ΠΈΠ΄Π°Ρ‚. Π’ΠΈ Ρ‚Ρ€Π΅Π±Π°Π°Ρ‚ Π²ΠΊΡƒΠΏΠ½ΠΎ Ρ‡Π΅Ρ‚ΠΈΡ€ΠΈ.

  • ΠŸΠΎΡ‡Π΅Ρ‚ΠΎΠΊ Π½Π° ΠΈΠ³Ρ€Π°Ρ‚Π°: memoryGameDidStart.
  • Π’Ρ€Π΅Π±Π° Π΄Π° ја свртитС ΠΊΠ°Ρ€Ρ‚ΠΈΡ‡ΠΊΠ°Ρ‚Π° со Π»ΠΈΡ†Π΅Ρ‚ΠΎ Π½Π°Π΄ΠΎΠ»Ρƒ: memoryGameShowCards.
  • Π’Ρ€Π΅Π±Π° Π΄Π° ја свртитС ΠΊΠ°Ρ€Ρ‚ΠΈΡ‡ΠΊΠ°Ρ‚Π° со Π»ΠΈΡ†Π΅Ρ‚ΠΎ Π½Π°Π΄ΠΎΠ»Ρƒ: memoryGameHideCards.
  • ΠšΡ€Π°Ρ˜ Π½Π° ΠΈΠ³Ρ€Π°Ρ‚Π°: memoryGameDidEnd.

Π‘ΠΈΡ‚Π΅ Ρ‡Π΅Ρ‚ΠΈΡ€ΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΈ ΠΌΠΎΠΆΠ΅ Π΄Π° сС ΠΈΠΌΠΏΠ»Π΅ΠΌΠ΅Π½Ρ‚ΠΈΡ€Π°Π°Ρ‚ Π·Π° Π³Π»Π°Π²Π½Π°Ρ‚Π° класа, која Π΅ GameController.

memoryGameDidStart

Кога ќС сС ΠΈΠ·Π²Ρ€ΡˆΠΈ овој ΠΌΠ΅Ρ‚ΠΎΠ΄, ΠΈΠ³Ρ€Π°Ρ‚Π° Ρ‚Ρ€Π΅Π±Π° Π΄Π° Π·Π°ΠΏΠΎΡ‡Π½Π΅ (корисникот притиска PLAY). ОвдС Сдноставно ќС ја Π²Ρ‡ΠΈΡ‚Π°ΠΌΠ΅ содрТината со ΠΏΠΎΠ²ΠΈΠΊΡƒΠ²Π°ΡšΠ΅ Π½Π° collectionView.reloadData(), ΡˆΡ‚ΠΎ ќС Π³ΠΈ измСша ΠΊΠ°Ρ€Ρ‚ΠΈΡ‡ΠΊΠΈΡ‚Π΅.

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

MemoryGameShowCards

Овој ΠΌΠ΅Ρ‚ΠΎΠ΄ Π³ΠΎ Π½Π°Ρ€Π΅ΠΊΡƒΠ²Π°ΠΌΠ΅ ΠΎΠ΄ collectionSDViewSelectItemAt. ΠŸΡ€Π²ΠΎ ја ΠΏΡ€ΠΈΠΊΠ°ΠΆΡƒΠ²Π° ΠΈΠ·Π±Ρ€Π°Π½Π°Ρ‚Π° ΠΊΠ°Ρ€Ρ‚ΠΈΡ‡ΠΊΠ°. ΠŸΠΎΡ‚ΠΎΠ° ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡƒΠ²Π° Π΄Π°Π»ΠΈ ΠΈΠΌΠ° нСспорСдлива ΠΊΠ°Ρ€Ρ‚ΠΈΡ‡ΠΊΠ° Π²ΠΎ Π½ΠΈΠ·Π°Ρ‚Π° cardsShown (Π°ΠΊΠΎ Π±Ρ€ΠΎΡ˜ΠΎΡ‚ Π½Π° cardsShown Π΅ Π½Π΅ΠΏΠ°Ρ€Π΅Π½). Π”ΠΎΠΊΠΎΠ»ΠΊΡƒ постои, ΠΈΠ·Π±Ρ€Π°Π½Π°Ρ‚Π° ΠΊΠ°Ρ€Ρ‚ΠΈΡ‡ΠΊΠ° сС спорСдува со Π½Π΅Π°. Ако сликитС сС исти, Π΄Π²Π΅Ρ‚Π΅ ΠΊΠ°Ρ€Ρ‚ΠΈΡ‡ΠΊΠΈ сС Π΄ΠΎΠ΄Π°Π²Π°Π°Ρ‚ Π½Π° ΠΊΠ°Ρ€Ρ‚ΠΈΡ‡ΠΊΠΈ ΠŸΡ€ΠΈΠΊΠ°ΠΆΠ°Π½ΠΈ ΠΈ остануваат свртСни Π½Π°Π³ΠΎΡ€Π΅. Ако Π΅ Ρ€Π°Π·Π»ΠΈΡ‡Π½ΠΎ, ΠΊΠ°Ρ€Ρ‚ΠΈΡ‡ΠΊΠ°Ρ‚Π° остава ΠΊΠ°Ρ€Ρ‚ΠΈΡ‡ΠΊΠΈ ΠŸΡ€ΠΈΠΊΠ°ΠΆΠ°Π½ΠΈ ΠΈ Π΄Π²Π΅Ρ‚Π΅ сС свртСни со Π»ΠΈΡ†Π΅Ρ‚ΠΎ Π½Π°Π΄ΠΎΠ»Ρƒ.

MemoryGameHideCards

Ако ΠΊΠ°Ρ€Ρ‚ΠΈΡ‡ΠΊΠΈΡ‚Π΅ Π½Π΅ сС совпаѓаат, овој ΠΌΠ΅Ρ‚ΠΎΠ΄ сС ΠΏΠΎΠ²ΠΈΠΊΡƒΠ²Π° ΠΈ сликитС Π½Π° ΠΊΠ°Ρ€Ρ‚ΠΈΡ‡ΠΊΠ°Ρ‚Π° сС сокриСни.

ΠΏΡ€ΠΈΠΊΠ°ΠΆΠ°Π½ = Π½Π΅Ρ‚ΠΎΡ‡Π½ΠΎ.

memoryGameDidEnd

Кога ќС сС ΠΏΠΎΠ²ΠΈΠΊΠ° овој ΠΌΠ΅Ρ‚ΠΎΠ΄, Ρ‚ΠΎΠ° Π·Π½Π°Ρ‡ΠΈ Π΄Π΅ΠΊΠ° ситС ΠΊΠ°Ρ€Ρ‚ΠΈ сС вСќС ΠΎΡ‚ΠΊΡ€ΠΈΠ΅Π½ΠΈ ΠΈ сС Π½Π°ΠΎΡ“Π°Π°Ρ‚ Π²ΠΎ списокот cardsShown: cardsShown.count = cards.count, Ρ‚Π°ΠΊΠ° ΡˆΡ‚ΠΎ ΠΈΠ³Ρ€Π°Ρ‚Π° Π΅ Π·Π°Π²Ρ€ΡˆΠ΅Π½Π°. ΠœΠ΅Ρ‚ΠΎΠ΄ΠΎΡ‚ сС Π½Π°Ρ€Π΅ΠΊΡƒΠ²Π° ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎ ΠΎΡ‚ΠΊΠ°ΠΊΠΎ ја ΠΏΠΎΠ²ΠΈΠΊΠ°Π²ΠΌΠ΅ endGame() Π·Π° Π΄Π° Π³ΠΎ поставимС isPlaying var Π½Π° false, ΠΏΠΎ ΡˆΡ‚ΠΎ сС ΠΏΡ€ΠΈΠΊΠ°ΠΆΡƒΠ²Π° ΠΏΠΎΡ€Π°ΠΊΠ°Ρ‚Π° Π·Π° ΠΊΡ€Π°Ρ˜ Π½Π° ΠΈΠ³Ρ€Π°Ρ‚Π°. Π˜ΡΡ‚ΠΎ Ρ‚Π°ΠΊΠ°, alertController сС користи ΠΊΠ°ΠΊΠΎ ΠΈΠ½Π΄ΠΈΠΊΠ°Ρ‚ΠΎΡ€ Π·Π° ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΠΎΡ€ΠΎΡ‚. Π‘Π΅ ΠΏΠΎΠ²ΠΈΠΊΡƒΠ²Π° viewDidDisappear ΠΈ ΠΈΠ³Ρ€Π°Ρ‚Π° сС рСсСтира.

Π•Π²Π΅ ΠΊΠ°ΠΊΠΎ ΠΈΠ·Π³Π»Π΅Π΄Π° сСто Ρ‚ΠΎΠ° Π²ΠΎ GameController:

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()
    }
}

ΠŸΠΈΡˆΡƒΠ²Π°ΡšΠ΅ ΠΈΠ³Ρ€Π° со мСмориски ΠΊΠ°Ρ€Ρ‚ΠΈΡ‡ΠΊΠΈ Π²ΠΎ Swift
Π’ΡΡƒΡˆΠ½ΠΎΡΡ‚, Ρ‚ΠΎΠ° Π΅ сè. ΠœΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° Π³ΠΎ користитС овој ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ Π·Π° Π΄Π° ΠΊΡ€Π΅ΠΈΡ€Π°Ρ‚Π΅ своја сопствСна Π²Π΅Ρ€Π·ΠΈΡ˜Π° Π½Π° ΠΈΠ³Ρ€Π°Ρ‚Π°.

Π‘Ρ€Π΅ΡœΠ½ΠΎ ΠΊΠΎΠ΄ΠΈΡ€Π°ΡšΠ΅!

Skillbox ΠΏΡ€Π΅ΠΏΠΎΡ€Π°Ρ‡ΡƒΠ²Π°:

Π˜Π·Π²ΠΎΡ€: www.habr.com

Π”ΠΎΠ΄Π°Π΄Π΅Ρ‚Π΅ ΠΊΠΎΠΌΠ΅Π½Ρ‚Π°Ρ€