As the course progresses through lectures six, seven, and eight, Paul Hegarty discusses views and how to extend them with custom drawings and touch event handling. Paul also spends a significant amount of time introducing collection views, which are used to lay out other views inside them. Protocols, gestures, and autolayout wrap-up the topics that lead to the next homework.
Assignment 3: Graphical Set is a significant update to the version of Matchismo from Assignment 2 and requires implementing both the standard Set game cards and modifications to the Card Match game. The Set game cards must have the standard game symbols (i.e., diamond, squiggle, and oval) drawn using Core Graphics and/or UIBezierPath. The game must start with 12 cards dealt, allow the player to request 3 more cards to be dealt at any time, and the view must automatically scroll to show the new dealt cards. Matched Set cards must be removed, and the remaining cards must automatically fill the missing spaces freed by the removed cards.
Both Set and Card Match games must allow the user to abandon and restart the game at any time. Both games must also lay themselves out to look and work properly in both landscape and portrait orientations on both the iPhone 4 and iPhone 5 using autolayout.
This assignment also has a large number of optional requirements such as animating the removal of cards; letting a player choose the number of cards to be dealt when starting the Card Match game; adding a section to display “found matches” to the games; modifying the Set scoring system to take into account whether a Set exists in the current cards in play when a user requests 3 more cards to be dealt; implementing a “cheat” button to identify a Set in the currently dealt cards; and, making the Set game a two player game.
This version of Matchismo implements updated versions of both Card Match and Set games based on Assignment 2’s code but using new card sets and adding new game features.
The updated Card Match game starts with 22 game cards dealt by default, but permits the player to enter a different number of cards to start with whenever a game is restarted. The game plays and scores the same as in its previous version. At the bottom of the display the “Deal” button has been renamed “Restart” in order to reflect its function more accurately. The score is now shown at the bottom of the display too. A simple dialog box with a single text input field lets the player type the number of cards to use when starting a new game. The text input field permits entering neither characters other than numbers nor invalid numbers.
Similarly, the updated Set game starts with 12 game cards dealt, and permits the player to deal 3 additional cards, up to the maximum of 81 cards in a Set card deck, at any given time. The game plays and scores the same as in its previous version. At the bottom of the display the message area has been modified to show three slots with the currently selected cards; the borders of the card slots change colors to represent the match results of selected card sets. The game also provides buttons for the player to either deal new cards or restart the game. The score is shown at the bottom of the display too, and the control to scrub through game messages has been removed.
Right off the bat I’ll say that this assignment had me blurting “There’s got to be a better way to do this” more often than I’d expected. 😎 It was a fun exercise, though, because it made me go beyond the topics presented in class.
My version of Matchismo for this assignment implements all required tasks plus two of the six optional requirements. I simply decided to hold up to the time I gave myself to work on it, and that’s all the work I could fit in. Yet, I am more than happy with what I put together.
As far as the code goes, I started things up with a custom SetCardView which uses UIBezierPaths to draw all the Set game cards. This class follow’s Paul’s PlayingCardView groundwork. I quickly learned I detest drawing with code. 😮 On the plus side, SetCardView worked like a charm too for my new mini-cards.
CardMatchingGame needed some massaging to be a good UICollectionViewDataSource helper. Specifically, I added methods to the model to keep a card deck for the lifetime of a game, query and draw cards from the deck, and remove cards from the current set of dealt cards.
The game view controllers needed some work too. In addition to generalizing methods that would make sense for PlayingCardGameViewController and SetCardGameViewController to inherit and/or override, CardGameViewController‘s updateUI method had to be re-done.
UIView‘s transitionWithView is sweet! I tried not to abuse the animation effects and used them where it made sense, for example, for card selections and removals as well as to call attention to the mini-cards after a set match/no-match.
Working with UIAlertView and UITextField is not the most exciting thing in the world, but the later’s shouldChangeCharactersInRange delegate method was perfect to make the input field behave the way I wanted.
I’m not a fan of autolayout to set the constraints of UI components. Although I succeeded in setting up the UIs to behave the way they needed to in both landscape and portrait orientations on both the iPhone 4 and iPhone 5, part of the exercise became trial and error. I guess this is something I need to revisit later.
I touched neither the Scoreboard nor the Settings screens, or their corresponding code because they were not relevant for this assignment. Both screens work and look exactly as they did in the previous version of the application. I’d not used autolayout on these screens, so they look yucky when the device is re-oriented.
The full Xcode project with my solution to Assignment 3 is available here.