Ke kākau ʻana i kahi pāʻani kāleka hoʻomanaʻo ma Swift

Ke kākau ʻana i kahi pāʻani kāleka hoʻomanaʻo ma Swift

Hōʻike kēia ʻatikala i ke kaʻina hana o ka hana ʻana i kahi pāʻani hoʻomaʻamaʻa hoʻomanaʻo maʻalahi aʻu i makemake nui ai. Ma waho aʻe o ka maikaʻi iā ia iho, e aʻo hou ʻoe e pili ana i nā papa Swift a me nā protocols i kou hele ʻana. Akā ma mua o ka hoʻomaka ʻana, e hoʻomaopopo kākou i ka pāʻani ponoʻī.

Hoʻomaopopo mākou iā ʻoe: no ka poʻe heluhelu a pau o "Habr" - kahi ho'ēmi o 10 rubles i ka wā e kākau inoa ai i kekahi papa Skillbox e hoʻohana ana i ka code promotional "Habr".

Manaʻo ʻo Skillbox: Papa hoʻonaʻauao pūnaewele "Ka mea hoʻomohala ʻoihana Java".

Pehea e pāʻani ai i ka Memory Card

Hoʻomaka ka pāʻani me kahi hōʻikeʻike o kahi hoʻonohonoho kāleka. Moe ke alo i lalo (e like me ke kiʻi i lalo). Ke kaomi ʻoe i kekahi, wehe ke kiʻi no kekahi mau kekona.

ʻO ka hana a ka mea pāʻani ke ʻimi i nā kāleka āpau me nā kiʻi like. Inā, ma hope o ka wehe ʻana i ke kāleka mua, hoʻohuli ʻoe i ka lua a paʻa nā kiʻi, e wehe mau nā kāleka ʻelua. Inā like ʻole lākou, pani hou ʻia nā kāleka. ʻO ka pahuhopu e wehe i nā mea a pau.

Papahana papahana

No ka hana ʻana i kahi mana maʻalahi o kēia pāʻani, pono ʻoe i kēia mau ʻāpana:

  • Hoʻokahi Mana Mana: GameController.swift.
  • Hoʻokahi Nānā: CardCell.swift.
  • ʻElua mau hiʻohiʻona: MemoryGame.swift a me Card.swift.
  • Main.storyboard e hōʻoia i ka loaʻa ʻana o ka pūʻulu holoʻokoʻa.

Hoʻomaka mākou me ka mea maʻalahi o ka pāʻani, nā kāleka.

Kāleka.swift

ʻEkolu mau waiwai o ke kŘkohu kāleka: id no ka hoʻomaopopo ʻana i kēlā me kēia mea, kahi hoʻololi boolean i hōʻike ʻia e kuhikuhi i ke kūlana o ke kāleka (huna a hāmama paha), a me artworkURL no nā kiʻi ma nā kāleka.

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

Pono ʻoe i kēia mau ala e hoʻomalu i ka pilina o nā mea hoʻohana me nā palapala ʻāina:

Ke ala no ka hōʻike ʻana i ke kiʻi ma ke kāleka. Maʻaneʻi mākou e hoʻihoʻi i nā waiwai āpau i ka paʻamau. No ka id, hana mākou i kahi id maʻamau ma ke kāhea ʻana iā NSUUIS().uuidString.

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

Ke ala no ka hoʻohālikelike ʻana i nā kāleka ID.

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

Ke ala e hana ai i kope o kēlā me kēia kāleka - i mea e loaʻa ai ka nui o nā mea like. E hoʻihoʻi kēia ʻano i ke kāleka me nā waiwai like.

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

A pono hoʻokahi ala hou e hoʻopaʻa i nā kāleka i ka hoʻomaka. E hoʻonui mākou i ka papa Array.

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

A eia ka hoʻokō ʻana i ke code no ke ʻano Kāleka me nā waiwai a me nā ʻano hana.

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

Hele i mua.

ʻO ke kumu hoʻohālike ʻelua ʻo MemoryGame, ma ʻaneʻi mākou i hoʻonohonoho i kahi pahu 4 * 4. E loaʻa i ke kŘkohu nā waiwai e like me nā kāleka (kahi ʻano o nā kāleka ma ka mānoanoa), kahi kāleka hōʻike ʻia me nā kāleka i wehe mua ʻia, a me kahi hoʻololi boolean isPlaying e nānā i ke kūlana o ka pāʻani.

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

Pono pū mākou e hoʻomohala i nā ʻano e hoʻomalu i ka pilina o nā mea hoʻohana me ka pā.

ʻO ke ʻano e hoʻokaʻawale i nā kāleka i loko o kahi pā.

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

Ke ala no ka hana ʻana i kahi pāʻani hou. Maanei mākou e kāhea ai i ke ala mua e hoʻomaka ai i ka hoʻonohonoho mua a hoʻomaka i ka ʻano hoʻololi isPlaying i ʻoiaʻiʻo.

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

Inā makemake mākou e hoʻomaka hou i ka pāʻani, a laila hoʻonoho mākou i ka ʻokoʻa isPlaying i ka wahaheʻe a wehe i ka hoʻonohonoho mua o nā kāleka.

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

Ke ala no ka hōʻoia ʻana i nā kāleka kaomi. E pili ana iā ia ma hope.

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

He ala e hoʻihoʻi i ke kūlana o kahi kāleka kikoʻī.

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

Ke nānā nei i ka hoʻokō ʻana o ke kāleka i koho ʻia me ka maʻamau.

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

Heluhelu kēia ʻano hana i ka mea hope loa i ka hui **cardsShown** a hoʻihoʻi i ke kāleka like ʻole.

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 a me GameController.swift

ʻIke ʻia ka Main.storyboard penei:

Ke kākau ʻana i kahi pāʻani kāleka hoʻomanaʻo ma Swift

I ka hoʻomaka ʻana, pono ʻoe e hoʻonohonoho i ka pāʻani hou e like me viewDidLoad i ka mea hoʻoponopono, me nā kiʻi no ka pā. I ka pāʻani, e hōʻike ʻia kēia mau mea āpau e kahi 4 * 4 collectionView. Inā ʻaʻole ʻoe i kamaʻāina me collectionView, eia nō hiki iā ʻoe ke loaʻa ka ʻike āu e pono ai.

E hoʻonohonoho mākou i ka GameController e like me ke kumu hoʻoponopono o ka noi. E loaʻa i ka GameController kahi collectionView a mākou e kuhikuhi ai he IBOutlet. ʻO kekahi ʻōlelo ʻē aʻe i ka pihi IBAction onStartGame(), he UIButton kēia, hiki iā ʻoe ke ʻike iā ia ma ka papa moʻolelo i kapa ʻia ʻo PLAY.

He mea liʻiliʻi e pili ana i ka hoʻokō ʻana i nā mea hoʻokele:

  • ʻO ka mea mua, hoʻomaka mākou i ʻelua mau mea nui - ka mākia: pāʻani = MemoryGame(), a me kahi pūʻulu kāleka: kāleka = [Kāleka]().
  • Hoʻonoho mākou i nā mea hoʻololi mua e like me viewDidLoad, ʻo ia ke ala mua i kapa ʻia ʻoiai e holo ana ka pāʻani.
  • Ua hoʻonohonoho ʻia ka collectionView i hūnā ʻia no ka mea ua hūnā ʻia nā kāleka a pau a paʻi ka mea hoʻohana iā PLAY.
  • Ke paʻi mākou iā PLAY, hoʻomaka ka ʻāpana onStartGame IBAction, a hoʻonoho mākou i ka waiwai collectionView isHidden i wahaheʻe i hiki ke ʻike ʻia nā kāleka.
  • I kēlā me kēia manawa e koho ai ka mea hoʻohana i kāleka, kāhea ʻia ke ʻano hana didSelectItemAt. Ma ke ala a mākou i kapa ai ʻo didSelectCard e hoʻokō i ka loiloi pāʻani nui.

Eia ka hoʻokō GameController hope loa:

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

I kēia manawa e kamaʻilio liʻiliʻi e pili ana i nā protocols koʻikoʻi.

Pūnaewele

ʻO ka hana pū me nā protocols ke kumu o ka polokalamu Swift. Hāʻawi nā protocols i ka hiki ke wehewehe i nā lula no kahi papa, hale, a helu ʻana paha. ʻAe kēia kumu iā ʻoe e kākau i nā code modular a extensible. ʻO ka ʻoiaʻiʻo, he kumu kēia a mākou e hoʻokō nei no ka collectionView ma GameController. I kēia manawa e hana kāua i kā mākou mana iho. E like me kēia ka syntax:

protocol MemoryGameProtocol {
    //protocol definition goes here
}

Ua ʻike mākou he protocol hiki iā mākou ke wehewehe i nā lula a i ʻole nā ​​ʻōlelo aʻoaʻo no ka hoʻokō ʻana i kahi papa, no laila e noʻonoʻo kākou i ka mea e pono ai. Pono ʻoe i ʻehā i ka huina.

  • Hoʻomaka pāʻani: memoryGameDidStart.
  • Pono ʻoe e hoʻohuli i ke kāleka i lalo: memoryGameShowCards.
  • Pono ʻoe e hoʻohuli i ke kāleka i lalo: memoryGameHideCards.
  • Pau ka pāʻani: memoryGameDidEnd.

Hiki ke hoʻokō ʻia nā ʻano hana ʻehā no ka papa nui, ʻo ia ʻo GameController.

memoryGameDidStart

Ke holo ʻia kēia ʻano hana, pono e hoʻomaka ka pāʻani (pehi ka mea hoʻohana iā PLAY). Ma ʻaneʻi e hoʻouka hou mākou i ka ʻike ma ke kāhea ʻana i ka collectionView.reloadData(), nāna e hoʻopaʻa i nā kāleka.

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

memoryGameShowCards

Kāhea mākou i kēia ʻano mai ka collectionSDViewSelectItemAt. Hōʻike mua ia i ke kāleka i koho ʻia. A laila e nānā e ʻike inā he kāleka like ʻole i loko o nā kāleka hōʻike ʻia (inā ʻokoʻa ka helu o nā kāleka hōʻike). Inā loaʻa kekahi, hoʻohālikelike ʻia ke kāleka i koho ʻia me ia. Inā like nā kiʻi, hoʻohui ʻia nā kāleka ʻelua i nā kāleka hōʻike ʻia a kū i ke alo i luna. Inā ʻokoʻa, haʻalele ke kāleka i nā kāleka Hōʻike a huli ʻia nā maka ʻelua i lalo.

memoryGameHideCards

Inā like ʻole nā ​​kāleka, kāhea ʻia kēia ʻano a hūnā ʻia nā kiʻi kāleka.

hoikeia = wahahee.

memoryGameDidEnd

Ke kāhea ʻia kēia ʻano hana, ʻo ia ka mea ua hōʻike mua ʻia nā kāleka āpau a aia i ka papa inoa cardsShown: cardsShown.count = cards.count, no laila ua pau ka pāʻani. Ua kapa ʻia ke ʻano ma hope o kā mākou kāhea ʻana i ka endGame () e hoʻonohonoho i ka isPlaying var i wahaheʻe, a laila hōʻike ʻia ka memo hope o ka pāʻani. Hoʻohana ʻia ʻo alertController ma ke ʻano he hōʻailona no ka mea hoʻoponopono. Ua kapa ʻia ʻo viewDidDisappear a ua hoʻonohonoho hou ʻia ka pāʻani.

Eia ke ʻano o ia mea a pau i 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()
    }
}

Ke kākau ʻana i kahi pāʻani kāleka hoʻomanaʻo ma Swift
ʻOiaʻiʻo, ʻo ia wale nō. Hiki iā ʻoe ke hoʻohana i kēia papahana e hana i kāu mana ponoʻī o ka pāʻani.

Hauʻoli coding!

Manaʻo ʻo Skillbox:

Source: www.habr.com

Pākuʻi i ka manaʻo hoʻopuka