Sau Daim Npav Nco Kev Ua Si hauv Swift

Sau Daim Npav Nco Kev Ua Si hauv Swift

Kab lus no piav qhia txog cov txheej txheem ntawm kev tsim cov kev ua si nco yooj yim uas kuv nyiam heev. Dhau li ntawm qhov zoo ntawm nws tus kheej, koj yuav kawm me ntsis ntxiv txog Swift cov chav kawm thiab cov txheej txheem thaum koj mus. Tab sis ua ntej peb pib, cia peb nkag siab qhov kev ua si nws tus kheej.

Peb nco qab: rau txhua tus neeg nyeem Habr - 10 ruble luv nqi thaum tso npe rau hauv ib chav kawm Skillbox siv Habr promo code.

Skillbox pom zoo: Kev kawm online chav kawm "Profession Java developer".

Ua si Memory Card li cas

Qhov kev ua si pib nrog kev ua qauv qhia ntawm ib daim npav. Lawv pw ntsej muag (feem ntau, duab hauv qab). Thaum koj nyem rau ntawm ib qho twg, cov duab qhib rau ob peb feeb.

Tus neeg ua si txoj haujlwm yog nrhiav txhua daim npav nrog cov duab tib yam. Yog tias, tom qab qhib thawj daim npav, koj tig dua thib ob thiab cov duab sib tw, ob daim npav tseem qhib. Yog tias lawv tsis sib xws, daim npav raug kaw dua. Lub hom phiaj yog qhib txhua yam.

Qhov project qauv

Txhawm rau tsim ib qho yooj yim version ntawm qhov kev ua si no koj xav tau cov khoom hauv qab no:

  • Ib Tus Tswj: GameController.swift.
  • Ib Saib: CardCell.swift.
  • Ob tug qauv: MemoryGame.swift thiab Card.swift.
  • Main.storyboard los xyuas kom meej tias tag nrho cov txheej txheem muaj.

Peb pib nrog qhov yooj yim feem ntawm qhov kev ua si, daim npav.

Card.swift

Daim npav qauv yuav muaj peb yam khoom: id txhawm rau txheeb xyuas txhua tus, qhov sib txawv ntawm boolean qhia kom qhia meej cov xwm txheej ntawm daim npav (pom zais lossis qhib), thiab artworkURL rau cov duab ntawm daim npav.

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

Koj tseem yuav xav tau cov txheej txheem no los tswj cov neeg siv kev cuam tshuam nrog cov duab qhia:

Txoj kev los tso saib cov duab ntawm ib daim npav. Ntawm no peb rov pib dua tag nrho cov khoom rau lub neej ntawd. Rau id, peb tsim ib tug random id los ntawm hu rau NSUUIS().uuidString.

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

Txoj kev sib piv daim npav ID.

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

Txoj kev los tsim ib daim qauv ntawm txhua daim npav - nyob rau hauv thiaj li yuav tau txais ib tug loj tus naj npawb ntawm zoo tib yam sawv daws yuav. Txoj kev no yuav rov qab daim npav nrog cov txiaj ntsig zoo sib xws.

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

Thiab ib txoj hauv kev ntxiv yog xav tau los hloov daim npav thaum pib. Peb yuav ua kom nws txuas ntxiv ntawm chav Array.

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

Thiab ntawm no yog qhov kev siv ntawm cov cai rau daim npav qauv nrog tag nrho cov khoom thiab txoj hauv kev.

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

Mus ua ntej.

Tus qauv thib ob yog MemoryGame, ntawm no peb teeb 4 * 4 daim phiaj. Tus qauv yuav muaj cov khoom xws li daim npav (ib daim npav ntawm daim phiaj), daim npav Qhia array nrog cov npav twb qhib lawm, thiab qhov sib txawv boolean yog ua si los taug qab cov xwm txheej ntawm qhov kev ua si.

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

Peb kuj yuav tsum tau tsim txoj hauv kev los tswj cov neeg siv kev sib cuam tshuam nrog daim phiaj.

Ib txoj kev uas shuffles cards nyob rau hauv ib daim phiaj.

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

Txoj kev tsim ib qho kev ua si tshiab. Ntawm no peb hu rau thawj txoj kev los pib qhov kev teeb tsa thawj zaug thiab pib qhov isPlaying hloov pauv mus rau qhov tseeb.

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

Yog tias peb xav rov pib qhov kev ua si, tom qab ntawd peb teeb tsa isPlaying hloov pauv mus rau qhov tsis tseeb thiab tshem tawm thawj qhov teeb tsa ntawm daim npav.

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

Txoj kev rau kev txheeb xyuas cov ntawv clicked. Ntau ntxiv txog nws tom qab.

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

Ib txoj hauv kev uas rov qab txoj haujlwm ntawm ib daim npav tshwj xeeb.

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

Tshawb xyuas kev ua raws li daim npav xaiv nrog tus qauv.

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

Txoj kev no nyeem cov ntsiab lus kawg hauv **cardsShown** array thiab xa rov qab daim npav tsis sib xws.

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 thiab GameController.swift

Main.storyboard zoo li no:

Sau Daim Npav Nco Kev Ua Si hauv Swift

Thaum xub thawj, koj yuav tsum teeb tsa qhov kev ua si tshiab li viewDidLoad hauv tus maub los, suav nrog cov duab rau daim phiaj. Hauv qhov kev ua si, tag nrho cov no yuav sawv cev los ntawm 4 * 4 collectionView. Yog tias koj tseem tsis tau paub txog collectionView, ntawm no nws yog koj tuaj yeem tau txais cov ntaub ntawv koj xav tau.

Peb yuav teeb tsa GameController ua daim ntawv thov lub hauv paus tswj hwm. GameController yuav muaj collectionView uas peb yuav siv raws li ib qho IBOoutlet. Lwm qhov kev siv yog rau IBAction onStartGame() khawm, qhov no yog UIButton, koj tuaj yeem pom nws hauv zaj dab neeg hu ua PLAY.

Ib me ntsis txog kev siv cov controllers:

  • Ua ntej, peb pib ua ob yam khoom tseem ceeb - daim phiaj: kev ua si = MemoryGame(), thiab ib daim npav: daim npav = [Card]().
  • Peb teeb tsa qhov pib hloov pauv raws li viewDidLoad, qhov no yog thawj txoj hauv kev hu ua thaum qhov kev ua si khiav.
  • collectionView yog teem rau zais vim tias txhua daim npav raug muab zais kom txog thaum tus neeg siv nias PLAY.
  • Thaum peb nias PLAY, ntu onStartGame IBAction pib, thiab peb teeb tsa collectionView isHidden cov cuab yeej rau cuav kom cov ntawv teev lus pom.
  • Txhua zaus tus neeg siv xaiv ib daim npav, didSelectItemAt txoj kev hu ua. Nyob rau hauv txoj kev peb hu ua didSelectCard los siv lub ntsiab kev ua si logic.

Nov yog qhov kawg GameController siv:

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

Tam sim no cia peb tham me ntsis txog cov txheej txheem tseem ceeb.

Raws tu qauv

Ua haujlwm nrog cov txheej txheem yog qhov tseem ceeb ntawm Swift programming. Cov txheej txheem muab lub peev xwm los txhais cov cai rau cov chav kawm, qauv, lossis kev suav sau. Lub hauv paus ntsiab lus no tso cai rau koj los sau cov code modular thiab extensible code. Qhov tseeb, qhov no yog tus qauv uas peb twb tau siv rau collectionView hauv GameController. Tam sim no cia peb ua peb tus kheej version. Lub syntax yuav zoo li no:

protocol MemoryGameProtocol {
    //protocol definition goes here
}

Peb paub tias cov txheej txheem tso cai rau peb los txhais cov cai lossis cov lus qhia rau kev siv cov chav kawm, yog li cia peb xav txog qhov lawv yuav tsum ua. Koj xav tau plaub tag nrho.

  • Game pib: memoryGameDidStart.
  • Koj yuav tsum tig daim npav ntsej muag: memoryGameShowCards.
  • Koj yuav tsum tig daim npav ntsej muag: memoryGameHideCards.
  • Game kawg: memoryGameDidEnd.

Tag nrho plaub txoj kev tuaj yeem siv rau hauv chav kawm tseem ceeb, uas yog GameController.

memoryGameDidStart

Thaum txoj kev no khiav, qhov kev ua si yuav tsum pib (tus neeg siv nias PLAY). Ntawm no peb tsuas yog rov rub cov ntsiab lus los ntawm kev hu mus rau collectionView.reloadData(), uas yuav hloov cov ntawv.

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

memoryGameShowCards

Peb hu cov qauv no los ntawm collectionSDViewSelectItemAt. Ua ntej nws pom daim npav xaiv. Tom qab ntawd txheeb xyuas seb puas muaj daim npav tsis sib xws hauv daim npavShown array (yog tias tus lej ntawm daim npavShown yog khib). Yog tias muaj ib qho, daim npav xaiv tau muab piv nrog nws. Yog tias cov duab zoo ib yam, ob daim npav ntxiv rau daim npavShown thiab nyob twj ywm ntsej muag. Yog tias txawv, daim npav tawm daim npavShown thiab ob qho tib si tig ntsej muag.

memoryGameHideCards

Yog tias daim npav tsis sib xws, txoj kev no raug hu thiab cov duab daim npav raug muab zais.

qhia = cuav.

memoryGameDidEnd

Thaum txoj kev no hu ua, nws txhais tau hais tias txhua daim npav twb tau nthuav tawm thiab nyob hauv daim npavShown: cardsShown.count = cards.count, yog li qhov kev ua si dhau lawm. Cov txheej txheem hu ua tshwj xeeb tom qab peb tau hu ua endGame() los teeb tsa lub isPlaying var rau qhov tsis tseeb, tom qab uas cov lus kawg game tau qhia. Tsis tas li ntawd alertController yog siv los ua qhov taw qhia rau tus maub los. viewDidDisappear raug hu thiab qhov kev ua si rov pib dua.

Nov yog txhua yam zoo li hauv 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()
    }
}

Sau Daim Npav Nco Kev Ua Si hauv Swift
Qhov tseeb, yog tag nrho. Koj tuaj yeem siv qhov project no los tsim koj tus kheej version ntawm qhov kev ua si.

Zoo siab coding!

Skillbox pom zoo:

Tau qhov twg los: www.hab.com

Ntxiv ib saib