เช เชฒเซเช เชเช เชธเชฐเชณ เชฎเซเชฎเชฐเซ เชคเชพเชฒเซเชฎ เชเซเชฎ เชฌเชจเชพเชตเชตเชพเชจเซ เชชเซเชฐเชเซเชฐเชฟเชฏเชพเชจเซเช เชตเชฐเซเชฃเชจ เชเชฐเซ เชเซ เชเซเชจเซ เชฎเชจเซ เชเชฐเซเชเชฐ เชเชจเชเชฆ เชเซ. เชชเซเชคเซ เชธเชพเชฐเชพ เชนเซเชตเชพ เชเชชเชฐเชพเชเชค, เชคเชฎเซ เชเชพเช เชคเซเชฏเชพเชฐเซ เชคเชฎเซ เชธเซเชตเชฟเชซเซเช เชเซเชฒเชพเชธ เช
เชจเซ เชชเซเชฐเซเชเซเชเซเชฒเซเชธ เชตเชฟเชถเซ เชฅเซเชกเซเช เชตเชงเซ เชถเซเชเซ เชถเชเชถเซ. เชชเชฐเชเชคเซ เชเชชเชฃเซ เชถเชฐเซ เชเชฐเซเช เชคเซ เชชเชนเซเชฒเชพเช, เชเชพเชฒเซ เชฐเชฎเชคเชจเซ เช เชธเชฎเชเซเช.
เช เชฎเซ เชฏเชพเชฆ เชเชฐเชพเชตเซเช เชเซเช: Habrเชจเชพ เชคเชฎเชพเชฎ เชตเชพเชเชเซ เชฎเชพเชเซ - Habr เชชเซเชฐเซเชฎเซ เชเซเชกเชจเซ เชเชชเชฏเซเช เชเชฐเซเชจเซ เชเซเชเชชเชฃ เชธเซเชเชฟเชฒเชฌเซเชเซเชธ เชเซเชฐเซเชธเชฎเชพเช เชจเซเชเชงเชฃเซ เชเชฐเชคเซ เชตเชเชคเซ 10 เชฐเซเชฌเชฒ เชกเชฟเชธเซเชเชพเชเชจเซเช.
เชธเซเชเชฟเชฒเชฌเซเชเซเชธ เชญเชฒเชพเชฎเชฃ เชเชฐเซ เชเซ: เชถเซเชเซเชทเชฃเชฟเช เชเชจเชฒเชพเชเชจ เชเซเชฐเซเชธ
"เชชเซเชฐเซเชซเซเชถเชจ เชเชพเชตเชพ เชกเซเชตเชฒเชชเชฐ" .
เชฎเซเชฎเชฐเซ เชเชพเชฐเซเชก เชเซเชตเซ เชฐเซเชคเซ เชฐเชฎเชตเซเช
เชฐเชฎเชค เชเชพเชฐเซเชกเซเชธเชจเชพ เชธเชฎเซเชนเชจเชพ เชชเซเชฐเชฆเชฐเซเชถเชจ เชธเชพเชฅเซ เชถเชฐเซ เชฅเชพเชฏ เชเซ. เชคเซเช เชฎเซเชขเชพ เชจเซเชเซ เชธเซเช เชเชพเชฏ เชเซ (เช เชจเซเชเซเชฐเชฎเซ, เชเชฌเซ เชจเซเชเซ). เชเซเชฏเชพเชฐเซ เชคเชฎเซ เชเซเชเชชเชฃ เชเช เชชเชฐ เชเซเชฒเชฟเช เชเชฐเซ เชเซ, เชคเซเชฏเชพเชฐเซ เชเชฌเซ เชฅเซเชกเซ เชธเซเชเชเชก เชฎเชพเชเซ เชเซเชฒเซ เชเซ.
เชเซเชฒเชพเชกเซเชจเซเช เชเชพเชฐเซเชฏ เช เช เชเชฟเชคเซเชฐเซเชตเชพเชณเชพ เชฌเชงเชพ เชเชพเชฐเซเชกเซเชธ เชถเซเชงเชตเชพเชจเซเช เชเซ. เชเซ, เชชเซเชฐเชฅเชฎ เชเชพเชฐเซเชก เชเซเชฒเซเชฏเชพ เชชเชเซ, เชคเชฎเซ เชฌเซเชเชพเชจเซ เชซเซเชฐเชตเซ เช เชจเซ เชเชฟเชคเซเชฐเซ เชฎเซเชณ เชเชพเชฏ, เชคเซ เชฌเชเชจเซ เชเชพเชฐเซเชก เชเซเชฒเซเชฒเชพ เชฐเชนเซ เชเซ. เชเซ เชคเซเช เชฎเซเชณ เชเชพเชคเชพ เชจเชฅเซ, เชคเซ เชเชพเชฐเซเชก เชซเชฐเซเชฅเซ เชฌเชเชง เชเชฐเชตเชพเชฎเชพเช เชเชตเซ เชเซ. เชงเซเชฏเซเชฏ เชฌเชงเซเช เชเซเชฒเชตเชพเชจเซเช เชเซ.
เชชเซเชฐเซเชเซเชเซเช เชฎเชพเชณเชเซเช
เช เชฐเชฎเชคเชจเซเช เชธเชฐเชณ เชธเชเชธเซเชเชฐเชฃ เชฌเชจเชพเชตเชตเชพ เชฎเชพเชเซ เชคเชฎเชพเชฐเซ เชจเซเชเซเชจเชพ เชเชเชเซเชจเซ เชเชฐเซเชฐ เชชเชกเชถเซ:
- เชเช เชจเชฟเชฏเชเชคเซเชฐเช: GameController.swift.
- เชเช เชฆเซเชถเซเชฏ: CardCell.swift.
- เชฌเซ เชฎเซเชกเชฒ: MemoryGame.swift เช เชจเซ Card.swift.
- เชเชเชเซเชจเซ เชธเชเชชเซเชฐเซเชฃ เชธเซเช เชเชชเชฒเชฌเซเชง เชเซ เชคเซเชจเซ เชเชพเชคเชฐเซ เชเชฐเชตเชพ เชฎเชพเชเซ Main.storyboard.
เช เชฎเซ เชฐเชฎเชคเชจเชพ เชธเซเชฅเซ เชธเชฐเชณ เชเชเช, เชเชพเชฐเซเชกเซเชธเชฅเซ เชชเซเชฐเชพเชฐเชเชญ เชเชฐเซเช เชเซเช.
เชเชพเชฐเซเชก.เชธเซเชตเชฟเชซเซเช
เชเชพเชฐเซเชก เชฎเซเชกเซเชฒเชฎเชพเช เชคเซเชฐเชฃ เชเซเชฃเชงเชฐเซเชฎเซ เชนเชถเซ: เชฆเชฐเซเชเชจเซ เชเชณเชเชตเชพ เชฎเชพเชเซ id, เชเชพเชฐเซเชกเชจเซ เชธเซเชฅเชฟเชคเชฟ (เชเซเชชเชพเชฏเซเชฒ เช เชฅเชตเชพ เชเซเชฒเซเชฒเซ) เชธเซเชชเชทเซเช เชเชฐเชตเชพ เชฎเชพเชเซ เชฌเชคเชพเชตเชตเชพเชฎเชพเช เชเชตเซเชฒ เชฌเซเชฒเชฟเชฏเชจ เชเชฒ เช เชจเซ เชเชพเชฐเซเชก เชชเชฐเชจเซ เชเชฌเซเช เชฎเชพเชเซ เชเชฐเซเชเชตเชฐเซเช URL.
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
}
ID เชเชพเชฐเซเชกเชจเซ เชธเชฐเชเชพเชฎเชฃเซ เชเชฐเชตเชพเชจเซ เชชเชฆเซเชงเชคเชฟ.
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 เชเซเชฐเซเชก เชธเซเช เชเชฐเซเช เชเซเช. เชฎเซเชกเซเชฒเชฎเชพเช เชเชพเชฐเซเชกเซเชธ (เชเซเชฐเซเชก เชชเชฐ เชเชพเชฐเซเชกเซเชธเชจเซ เชเชฐเซ), เชเชพเชฐเซเชกเซเชธ เชชเชนเซเชฒเชพเชฅเซ เช เชเซเชฒเซเชฒเชพ เชเชพเชฐเซเชกเซเชธ เชธเชพเชฅเซ เชฌเชคเชพเชตเซเชฒ เชเชฐเซ เช เชจเซ เชฐเชฎเชคเชจเซ เชธเซเชฅเชฟเชคเชฟเชจเซ เชเซเชฐเซ เช เชเชฐเชตเชพ เชฎเชพเชเซ เชฌเซเชฒเชฟเชฏเชจ เชตเซเชฐเซเชเชฌเชฒ เชเช เชชเซเชฒเซเชเชเช เชเซเชตเซ เชชเซเชฐเซเชชเชฐเซเชเซเช เชนเชถเซ.
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 เชตเซเชฐเซเชเชฌเชฒเชจเซ true เชฎเชพเช เชถเชฐเซ เชเชฐเชตเชพ เชฎเชพเชเซเชจเซ เชชเซเชฐเชฅเชฎ เชชเชฆเซเชงเชคเชฟ เชเชนเซเช เชเซเช.
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 เชเชฒเซเชเซเชถเชจ เชตเซเชฏเซ เชฆเซเชตเชพเชฐเชพ เชฐเชเซ เชเชฐเชตเชพเชฎเชพเช เชเชตเชถเซ. เชเซ เชคเชฎเซ เชนเชเซ เชธเซเชงเซ เชเชฒเซเชเซเชถเชจ เชตเซเชฏเซเชฅเซ เชชเชฐเชฟเชเชฟเชค เชจเชฅเซ, เชคเซ เชคเซ เช
เชนเซเช เชเซ
เช เชฎเซ เชเซเชฎ เชเชเชเซเชฐเซเชฒเชฐเชจเซ เชเชชเซเชฒเชฟเชเซเชถเชจเชจเชพ เชฐเซเช เชเชเชเซเชฐเซเชฒเชฐ เชคเชฐเซเชเซ เชเซเช เชตเซเชถเซเช. เชเซเชฎ เชเชเชเซเชฐเซเชฒเชฐ เชชเชพเชธเซ เชเชฒเซเชเซเชถเชจ เชตเซเชฏเซ เชนเชถเซ เชเซเชจเซ เช เชฎเซ IBOutlet เชคเชฐเซเชเซ เชธเชเชฆเชฐเซเชญ เชเชชเซเชถเซเช. เชฌเซเชเซ เชธเชเชฆเชฐเซเชญ IBAction onStartGame() เชฌเชเชจเชจเซ เชเซ, เช เชเช UIButton เชเซ, เชคเชฎเซ เชคเซเชจเซ PLAY เชจเชพเชฎเชจเชพ เชธเซเชเซเชฐเซเชฌเซเชฐเซเชกเชฎเชพเช เชเซเช เชถเชเซ เชเซ.
เชจเชฟเชฏเชเชคเซเชฐเชเซเชจเชพ เช เชฎเชฒเซเชเชฐเชฃ เชตเชฟเชถเซ เชฅเซเชกเซเช:
- เชชเซเชฐเชฅเชฎ, เช เชฎเซ เชฌเซ เชฎเซเชเซเชฏ เชเชฌเซเชเซเชเซเช เชถเชฐเซ เชเชฐเซเช เชเซเช - เชเซเชฐเซเชก: เชเซเชฎ = เชฎเซเชฎเชฐเซเชเซเชฎ(), เช เชจเซ เชเชพเชฐเซเชกเซเชธเชจเซ เชธเชฎเซเชน: เชเชพเชฐเซเชกเซเชธ = [เชเชพเชฐเซเชก]().
- เช เชฎเซ เชชเซเชฐเชพเชฐเชเชญเชฟเช เชเชฒเซเชจเซ viewDidLoad เชคเชฐเซเชเซ เชธเซเช เชเชฐเซเช เชเซเช, เช เชชเชนเซเชฒเซ เชชเชฆเซเชงเชคเชฟ เชเซ เชเซเชจเซ เชฐเชฎเชค เชเชพเชฒเซ เชฐเชนเซ เชนเซเชฏ เชคเซเชฏเชพเชฐเซ เชเชนเซเชตเชพเชฎเชพเช เชเชตเซ เชเซ.
- เชเชฒเซเชเซเชถเชจ เชตเซเชฏเซ เชเซเชชเชพเชฏเซเชฒ เชชเชฐ เชธเซเช เชเซ เชเชพเชฐเชฃ เชเซ เชเซเชฏเชพเช เชธเซเชงเซ เชตเชชเชฐเชพเชถเชเชฐเซเชคเชพ PLAY เชฆเชฌเชพเชตเชถเซ เชจเชนเซเช เชคเซเชฏเชพเช เชธเซเชงเซ เชคเชฎเชพเชฎ เชเชพเชฐเซเชก เชเซเชชเชพเชฏเซเชฒเชพ เชเซ.
- เชเซเชฎ เชเซเชฎ เชเชชเชฃเซ PLAY เชฆเชฌเชพเชตเซเช เชเซเช เชคเซเชฎ, onStartGame IBAction เชตเชฟเชญเชพเช เชถเชฐเซ เชฅเชพเชฏ เชเซ, เช เชจเซ เช เชฎเซ เชเชฒเซเชเซเชถเชจ เชตเซเชฏเซ 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 เชฎเชพเช เชเชฒเซเชเซเชถเชจ เชตเซเชฏเซ เชฎเชพเชเซ เชฒเชพเชเซ เชเชฐเซ เชฐเชนเซเชฏเชพ เชเซเช. เชนเชตเซ เชเชชเชฃเซเช เชชเซเชคเชพเชจเซเช เชตเชฐเซเชเชจ เชฌเชจเชพเชตเซเช. เชธเชฟเชจเซเชเซเชเซเชธ เชเชจเชพ เชเซเชตเซ เชฆเซเชเชพเชถเซ:
protocol MemoryGameProtocol {
//protocol definition goes here
}
เช เชฎเซ เชเชพเชฃเซเช เชเซเช เชเซ เชชเซเชฐเซเชเซเชเซเชฒ เช เชฎเชจเซ เชตเชฐเซเชเชจเชพ เช เชฎเชฒเซเชเชฐเชฃ เชฎเชพเชเซ เชจเชฟเชฏเชฎเซ เช เชฅเชตเชพ เชธเซเชเชจเชพเชเชจเซ เชตเซเชฏเชพเชเซเชฏเชพเชฏเชฟเชค เชเชฐเชตเชพเชจเซ เชฎเชเชเซเชฐเซ เชเชชเซ เชเซ, เชคเซเชฅเซ เชเชพเชฒเซ เชคเซ เชถเซเช เชนเซเชตเซเช เชเซเชเช เชคเซ เชตเชฟเชถเซ เชตเชฟเชเชพเชฐเซเช. เชคเชฎเชพเชฐเซ เชเซเชฒ เชเชพเชฐเชจเซ เชเชฐเซเชฐ เชเซ.
- เชฐเชฎเชคเชจเซ เชถเชฐเซเชเชค: เชฎเซเชฎเชฐเซเชเซเชฎเชกเซเชกเชธเซเชเชพเชฐเซเช.
- เชคเชฎเชพเชฐเซ เชเชพเชฐเซเชกเชจเซ เชเชนเซเชฐเซ เชจเซเชเซ เชเชฐเชตเชพเชจเซ เชเชฐเซเชฐ เชเซ: memoryGameShowCards.
- เชคเชฎเชพเชฐเซ เชเชพเชฐเซเชกเชจเซ เชเชนเซเชฐเซ เชจเซเชเซ เชเชฐเชตเชพเชจเซ เชเชฐเซเชฐ เชเซ: memoryGameHideCards.
- เชฐเชฎเชคเชจเซ เช เชเชค: memoryGameDidEnd.
เชคเชฎเชพเชฎ เชเชพเชฐ เชชเชฆเซเชงเชคเชฟเช เชฎเซเชเซเชฏ เชตเชฐเซเช เชฎเชพเชเซ เชฒเชพเชเซ เชเชฐเซ เชถเชเชพเชฏ เชเซ, เชเซ เชเซเชฎ เชเชเชเซเชฐเซเชฒเชฐ เชเซ.
เชฎเซเชฎเชฐเซเชเซเชฎเชกเซเชกเชธเซเชเชพเชฐเซเช
เชเซเชฏเชพเชฐเซ เช เชชเชฆเซเชงเชคเชฟ เชเชฒเชพเชตเชตเชพเชฎเชพเช เชเชตเซ เชเซ, เชคเซเชฏเชพเชฐเซ เชฐเชฎเชค เชถเชฐเซ เชฅเชตเซ เชเซเชเช (เชตเชชเชฐเชพเชถเชเชฐเซเชคเชพ PLAY เชฆเชฌเชพเชตเชถเซ). เช เชนเซเช เช เชฎเซ collectionView.reloadData() เชชเชฐ เชเซเชฒ เชเชฐเซเชจเซ เชธเชพเชฎเชเซเชฐเซเชจเซ เชซเชฐเซเชฅเซ เชฒเซเชก เชเชฐเซเชถเซเช, เชเซ เชเชพเชฐเซเชกเซเชธเชจเซ เชถเชซเชฒ เชเชฐเชถเซ.
func memoryGameDidStart(_ game: MemoryGame) {
collectionView.reloadData()
}
เชฎเซเชฎเชฐเซเชเซเชฎเชถเซเชเชพเชฐเซเชกเซเชธ
เช เชฎเซ เช เชชเชฆเซเชงเชคเชฟเชจเซ เชธเชเชเซเชฐเชน SDViewSelectItemAt เชฎเชพเชเชฅเซ เชเซเชฒ เชเชฐเซเช เชเซเช. เชชเซเชฐเชฅเชฎ เชคเซ เชชเชธเชเชฆ เชเชฐเซเชฒ เชเชพเชฐเซเชก เชฌเชคเชพเชตเซ เชเซ. เชชเชเซ เชเชพเชฐเซเชกเซเชธ เชฌเชคเชพเชตเซเชฒ เชเชฐเซเชฎเชพเช เชเช เชฎเซเชณ เชจ เชเชพเชคเซเช เชเชพเชฐเซเชก เชเซ เชเซ เชเซเชฎ เชคเซ เชเซเชตเชพ เชฎเชพเชเซ เชคเชชเชพเชธเซ (เชเซ เชฌเชคเชพเชตเซเชฒ เชเชพเชฐเซเชกเซเชธเชจเซ เชธเชเชเซเชฏเชพ เชตเชฟเชเชฟเชคเซเชฐ เชเซ). เชเซ เชคเซเชฏเชพเช เชเช เชนเซเชฏ, เชคเซ เชชเชธเชเชฆ เชเชฐเซเชฒ เชเชพเชฐเซเชก เชคเซเชจเซ เชธเชพเชฅเซ เชธเชฐเชเชพเชตเชตเชพเชฎเชพเช เชเชตเซ เชเซ. เชเซ เชเชฟเชคเซเชฐเซ เชธเชฐเชเชพ เชนเซเชฏ, เชคเซ เชฌเชเชจเซ เชเชพเชฐเซเชก เชฌเชคเชพเชตเชตเชพเชฎเชพเช เชเชตเซเชฒเชพ เชเชพเชฐเซเชกเซเชธเชฎเชพเช เชเชฎเซเชฐเชตเชพเชฎเชพเช เชเชตเซ เชเซ เช เชจเซ เชธเชพเชฎเชธเชพเชฎเซ เชฐเชนเซ เชเซ. เชเซ เช เชฒเช-เช เชฒเช เชนเซเชฏ, เชคเซ เชเชพเชฐเซเชก เชเซเชกเซ เชเซ เชเชพเชฐเซเชกเซเชธ เชฌเชคเชพเชตเชตเชพเชฎเชพเช เชเชตเซ เชเซ เช เชจเซ เชฌเชเชจเซ เชฎเซเชขเชพ เชจเซเชเซ เชเชฐเชตเชพเชฎเชพเช เชเชตเซ เชเซ.
เชฎเซเชฎเชฐเซเชเซเชฎเชนเชพเชเชกเชเชพเชฐเซเชกเซเชธ
เชเซ เชเชพเชฐเซเชก เชฎเซเชณ เชเชพเชคเชพ เชจเชฅเซ, เชคเซ เช เชชเชฆเซเชงเชคเชฟ เชเชนเซเชตเชพเชฎเชพเช เชเชตเซ เชเซ เช เชจเซ เชเชพเชฐเซเชกเชจเซ เชเชฌเซเช เชเซเชชเชพเชตเชตเชพเชฎเชพเช เชเชตเซ เชเซ.
เชฌเชคเชพเชตเซเชฒ = เชเซเชเซเช.
เชฎเซเชฎเชฐเซGameDidEnd
เชเซเชฏเชพเชฐเซ เช เชชเชฆเซเชงเชคเชฟเชจเซ เชฌเซเชฒเชพเชตเชตเชพเชฎเชพเช เชเชตเซ เชเซ, เชคเซเชฏเชพเชฐเซ เชคเซเชจเซ เช เชฐเซเชฅ เช เชเซ เชเซ เชฌเชงเชพ เชเชพเชฐเซเชกเซเชธ เชชเชนเซเชฒเซเชฅเซ เช เชเชพเชนเซเชฐ เชฅเช เชเชฏเชพ เชเซ เช เชจเซ เชเชพเชฐเซเชกเซเชธ เชฌเชคเชพเชตเชตเชพเชฎเชพเช เชเชตเซเชฒเซ เชธเซเชเชฟเชฎเชพเช เชเซ: cardsShown.count = cards.count, เชคเซเชฅเซ เชฐเชฎเชค เชธเชฎเชพเชชเซเชค เชฅเช เชเช เชเซ. isPlaying var เชจเซ เชเซเชเชพ เชชเชฐ เชธเซเช เชเชฐเชตเชพ เชฎเชพเชเซ เช เชฎเซ endGame() เชจเซ เชเซเชฒ เชเชฐเซเชฏเชพ เชชเชเซ เชชเชฆเซเชงเชคเชฟเชจเซ เชเชพเชธ เชเชนเซเชตเชพเชฎเชพเช เชเชตเซ เชเซ, เชเซ เชชเชเซ เชฐเชฎเชค เชธเชฎเชพเชชเซเชคเชฟ เชธเชเชฆเซเชถ เชฌเชคเชพเชตเชตเชพเชฎเชพเช เชเชตเซ เชเซ. เชคเซเชฎเช 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()
}
}
เชเชฐเซเชเชฐ, เชคเซ เชฌเชงเซ เช เชเซ. เชคเชฎเซ เช เชชเซเชฐเซเชเซเชเซเชเชจเซ เชเชชเชฏเซเช เชฐเชฎเชคเชจเซเช เชคเชฎเชพเชฐเซเช เชชเซเชคเชพเชจเซเช เชธเชเชธเซเชเชฐเชฃ เชฌเชจเชพเชตเชตเชพ เชฎเชพเชเซ เชเชฐเซ เชถเชเซ เชเซ.
เชนเซเชชเซ เชเซเชกเชฟเชเช!
เชธเซเชเชฟเชฒเชฌเซเชเซเชธ เชญเชฒเชพเชฎเชฃ เชเชฐเซ เชเซ:
- เชชเซเชฐเซเชเซเชเชฟเชเชฒ เชเซเชฐเซเชธ
"เชฎเซเชฌเชพเชเชฒ เชกเซเชตเชฒเชชเชฐ เชชเซเชฐเซ" .- เชเชจเชฒเชพเชเชจ เชเซเชฐเซเชธ เชฒเชพเชเซ เชเชฐเซเชฏเซ
"เชชเชพเชฏเชฅเซเชจ เชกเซเชเชพ เชเชจเชพเชฒเชฟเชธเซเช" .- เชฌเซ เชตเชฐเซเชทเชจเซ เชชเซเชฐเซเชเซเชเชฟเชเชฒ เชเซเชฐเซเชธ
"เชนเซเช เชชเซเชฐเซ เชตเซเชฌ เชกเซเชตเชฒเชชเชฐ เชเซเช" .
เชธเซเชฐเซเชธ: www.habr.com