Nick Harris

Super Euchre and Machine Learning

As much as I loved learning about ARKit at Swift by Northwest, the talk that really caught me intellectually was Chris Parrish‘s talk about machine learning.

Chris’s talk was based on an iPad app that could learn if a user had drawn a circle, square or triangle with their finger.

I haven’t dug into how it all works at all so I’m basing this post just on how Chris described how neural networks work and how the things he was describing relate to how I wrote Super Euchre.

What I got out of Chris’s talk was that machine learning is done by taking an action and passing it through an mesh of manipulators that adjust some outcome value either positively or negatively. The end result is then used to make some decision.

This is – at a very high level – how Super Euchre’s AI works.

My code for Super Euchre takes an array of cards and assigns a weight to them based on what suit could be called trump. The total of those weights is what is used to make decisions about calling trump. It gets adjusted based on a set of inputs around game state. If the total weight after all the adjustments meets certain totals then calling trump for a particular suit is either passed, called, called alone or called alone with help.

Playing a particular card is still done the original way I wrote all of Euchre which is a big if/else statement. I’ve been wanting to move that to a weight based approach as well. I never did it simply because I wasn’t sure if the weight based idea was the best.

After seeing Chris’s talk I’m absolutely convinced that weight based decision making is the way to go.

What I want to do now is learn about Core ML and see if I can use how a user plays their hand to train the AI players. If that works I wonder if I can then pool all active users and how they play their hands to train AI players.

I have alpha server code that can take data played by all active users of Euchre and store it for processing. Its something I’ve wanted to do for years but haven’t deployed. 

If I can use that data to pump through some sort of Core ML setup to make Euchre amazing?

Sign me up.

Just need to dig in more and see if its feasible… and ethical…

 

Written by Nick Harris

November 19, 2017 at 6:00 am

Posted in Uncategorized

On The Bench

I’ve been working with or in iOS consulting firms for the last 5 years. Consulting firms run on having billable devs on the payroll that can move to a project at any given time to meet demands but have to balance having too many devs on the payroll when there are no projects for them.

When you’re a full time employee at a consulting firm and have no billable project you’re “on the bench”. Pretty much dead weight. You’re not doing anything billable for the company but your salary is guaranteed.

There’s a bunch of ways companies deal with the bench. Most go for the option of never having one.

This works great for the bottom line, but this means rolling devs on and off of projects when the work ramps up on one and dies on another usually with limited knowledge of the new project to be  productive day one.

I have an idea.

Devs get burned out on projects cause its the same stuff over and over. They look forward to the bench time to reinvigorate. But some projects and/or lean running consulting firms never have that time. So you don’t have down time as a dev. You’re rolled from one project to the next with no ramp up.

15%

I like the idea of 15% time that bigger companies can employ. As a dev you get 15% of your time to explore new things, expand your knowledge and come back to your team with a different perspective.

What if a consulting firm twisted this and put people on a different project one day every two every weeks?

The expectation wouldn’t be to deliver anything. You just spend a day poking around at something, learning how another project does things and maybe offering some solutions.

From a dev standpoint you get one day away from your project to look at something new and different. You get to checkout another projects code and see how they’re doing things. You might see something your team is trying to solve, or you might see something you’ve solved that they’re trying to solve. Both teams win.

From a consulting firm management standpoint you’re building up a bench of devs that can jump on a project without ramp up and avoiding the “non-billable” bench.

Its like a rolling bench where everyone learns, everyone’s billable and a devs can jump in without the steep ramp up.

Obviously this means tweaking how you do estimates and work statements by padding a few hours on each project at the benefit of interchangeable and knowledgable devs. That’s a big win. Not to mention stimulating your devs problem solving itch on something their not explicitly responsible for.

I’d like this at my work place 🙂

Written by Nick Harris

April 27, 2017 at 2:58 am

Posted in Uncategorized

Strange Things at Serpent Mound

Ever since I read about The Great Serpent Mound in the Haunted Ohio books when I was a kid I’ve wanted to go. I didn’t have anything going on today so I decided to make the drive. I’ve heard a few stories about strange things that happen there but I didn’t expect anything would happen to me. I just wanted to see it.

But a strange thing happened to me.

I’ve had my iPhone for over a year. I’ve never had any problems with it. Today while I was walking around Serpent Mound taking pictures it suddenly turned itself off. When I tried to turn it back on it had the dead battery graphic. I know it wasn’t dead. I had it on the charger the whole way there. It was at 100%. After another try or two it restarted but was down to 40%. When I tried to take another picture it turned itself off again. I repeated this at least a dozen times. It would show the dead battery graphic, then startup on the next try, stay on for about 5 seconds, then turn off again.

I decided to put it back on the charger in my car just to see what would happen. After a few minutes of charging with it on, I unplugged it and took a picture of my steering wheel to make sure it wasn’t going to turn off again. It was working fine. So I went back out to take the pictures I wanted from the observation tower. Lo and behold, after taking pictures for another 5 minutes it went right back to turning itself off. I decided to go ahead and leave.

I put it back on the charger in my car and left. About 20 miles down the road is the abandon Belfast Elementary School. Its creepy looking so I decided to stop and take some pictures of it as well. My phone worked fine. Its worked fine the rest of the day. I expect it will continue to work fine.

I love a good ghost story and unexplained things. That’s only the second time something truly unexplained has happened to me (I once caught a voice say “you’re in the hole” while using my iPhones’ voice recorder in a cell at the Ohio State Reformatory).

Today was awesome. I was dumbfounded. Serpent Mound really is a strange, special place.

IMG 0141

IMG 0142

IMG 0144

IMG 0164

IMG 0171

IMG 0173

IMG 0176

IMG 0178

IMG 0180

IMG 0181

IMG 0184

IMG 0185

Written by Nick Harris

December 28, 2016 at 2:12 am

Posted in Uncategorized

Ad Rev

Back in June when I released Super Euchre! and Solitary Solitaire I started an experiment. I wanted to see if the banner ads I had always used in Euchre were worth it or if moving to interstitial ads was a better way to go.

Banner ads are always present. I personally hate them. While I’m using an app they’re always there taking up space the app could be using and ruining the overall design of the interface.

Interstitial ads are ads that overtake the app (sometimes with a timer before you can dismiss them). They’re way more intrusive then banner ads, but they’re also easier to mold to your user experience. An ad that over takes your app in the middle of reading an article is incredibly annoying. Presenting one when you’re in a “paused” frame of mind is more seamless.

With that in mind, Solitaire only shows an interstitial ad after you’re already playing a game but have given up and are trying to start a new one. You’re in a position of change within the app already so pausing your transition for a few seconds to present an ad is the least intrusive opportunity.

Euchre has an always present banner ad.

The Results

I think its hard to deny that interstitial ads are the way to go in my case at this point.

1. They’re less annoying
2. They pay MUCH better
3. They are less annoying and pay MUCH better

Between my two apps, Solitaire has about 10% the install base of Euchre but produces 20% of the overall ad revenue.

Here are the numbers:

Screen Shot 2016 11 30 at 9 20 25 PMScreen Shot 2016 11 30 at 9 48 45 PM

The Plan

I plan on moving Euchre away from the banner ad to an interstitial only on loss this weekend. The impressions will fall off dramatically but the RPM should rocket. Users will have a better experience and I’ll make more per install.

There’s more to digest here but its mid-week and my head is in the middle of a refactor for my day job, but I hope to revisit this.

Those are real numbers though. If you’re better at business math then I am, send me a note about what you think. 

Written by Nick Harris

December 1, 2016 at 5:09 am

Posted in Uncategorized

Apple Watch Series 2

My friend and old co-worker Brent Simmons on the Apple Watch (cherry picked from a post about Apple in general):

Here’s a case: my wife bought a Fitbit when I bought my Apple watch. I envy her iPhone app which is so much cooler than Apple’s fitness software; I envy her not having to charge her device every night; I envy her not having to wear a heavy thing on her wrist.

And her Fitbit does sleep tracking, which I’d like to do — but my Apple watch is charging while I sleep, and there’s no way I’d be comfortable sleeping with that bulky thing on my wrist anyway.

 I was not a fan of my original Apple Watch. The battery sucked. It was slow. The apps seemed useless. The sports band was uncomfortable. 

When WatchOS 3 came out I started to change my mind. I was part of a team that developed my first professionally released watch app. I also made my own for fun app

So I bought an Apple Watch Series 2 this year instead of upgrading my iPhone (which is a 6S+). I also bought one of the nylon weave bands.

The results?

I put my watch on this morning at 6:45am. Here’s the battery at 9pm:

IMG 3351

For fun I decided to charge it for 20 minutes – about what it would take for me to take a shower and get dressed in the morning:

 IMG 3353

I’ve slept with it on many nights. The band is definitely the difference. I don’t even notice I have it on anymore. I’m more surprised when I look at my wrist and its not there then being annoyed at the band making me uncomfortable.

I also find myself taking time to meet my exercise and move goals everyday. I had a perfect month in October for both. I’m on track for the same in November. Forcing myself to do something that registers as exercise for 30 minutes everyday is pretty easy during the week as I walk ~2 miles to/from the train to the office but on weekends it really drives me to get outside. I’ve been doing 7 miles a day on the bike over the weekend the last two months or doing my own 30 minute workouts in the basement on days when that’s not feasible.

This morning when I saw the Thanksgiving Challenge I was in right away. I’ve been fighting with the idea that I might not hit my goal that day so maybe slipping for a day this month was OK. But now I’m even more driven to keep up the pace.

Is the Apple Watch perfect? No. But I’m happy that the engineering efforts at Apple are being spent on them instead of monitors and routers. I’m an Apple convert that never bought those things anyway. I could get what I needed elsewhere at a better price.

Next up for me I suppose is seeing if CloudKit can replace Dropbox and Flickr.

I don’t really trust in Apple web services…

Written by Nick Harris

November 22, 2016 at 4:43 am

Posted in Uncategorized

Limiting the Number of Lines in a UITextView

Intro

I have a UILabel in my app that shows a maximum 4 lines of text. If the user taps on it, the view becomes editable and the user can change the text in a UITextView.

Problem

I want to limit the user to only 4 lines when they’re editing the text in the UITextView.

First Attempt – Default Behavior

By default a user can add as many lines of text as they want to a UITextView and the view will update itself to make sure the last line is visible.

This is no good for me since the user can enter more lines then I’m going to show when they’re done editing.

Second Attempt – maximumNumberOfLines

According to the docs for NSTextContainer.maximumNumberOfLines:

The layout manager uses the value of this property to determine the maximum number of lines associated with the text container. The default value of this property is 0, which indicates that there is no limit.

In Xcode 8 and iOS 10 the only effect this parameter has on a UITextView is that the last line after the max is no longer made visible. The user can keep entering text all they want but its no longer visible in the UITextView.

My Fix

The fix I came up with was to count the number of line breaks by using CharacterSet.newLines in textView:shouldChangeTextInRange:replacementText: of the UITextViewDelegate before allowing a user change.

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {

    let existingLines = textView.text.components(separatedBy: CharacterSet.newlines)
    let newLines = text.components(separatedBy: CharacterSet.newlines)
    let linesAfterChange = existingLines.count + newLines.count - 1

    return linesAfterChange <= textView.textContainer.maximumNumberOfLines
}

This works as intended.

But this feels like a hack around a UIKit bug.

Is it?

Written by Nick Harris

September 11, 2016 at 4:41 am

Posted in Uncategorized

Introducing Super Euchre 2.0 and Solitary Solitaire 1.0

If you’ve been following along with my blog about my re-write of Euchre, my Solitaire challenge and me learning Swift and wondered if I’d ever release them to the App Store, well the wait is over!
(then some thoughts on the last couple of months)

Super Euchre 2.0

Icon 180

https://itunes.apple.com/us/app/super-euchre!/id697411524?ls=1&mt=8

– Brand New Layout and Card Faces
– New Game Replay
– Stats
– iPad Landscape and Multitasking Support
– Stats synchronization between devices

Solitary Solitaire 1.0

Icon 180

https://itunes.apple.com/us/app/solitary-solitaire/id1123243052?ls=1&mt=8

– Single or three card deal
– Auto play a winning hand
– Best time, score and moves
– iCloud syncing of games
– iCloud syncing of best time, score and moves
– Landscape support for iPhone 4S through iPad Pro
– Multitasking support on iPad

Swift

Both apps a written completely in Swift 2.2 from my standpoint. I get that the Objective-C runtime powers them but there is not one line of Objective-C in my repositories. I’ve been writing Objective-C for about half my career at this point (7 out of 15 years) and I still like the language. Its odd and quirky but I can make the devices I love do things with it so its cool by me.

Swift though… I love Swift!

Super Euchre in particular was much easier to code this time around. Higher level functions like sets, map and filter made writing the player logic much easier. I realize now that I could have accomplished the same type of approaches in ObjC using more NSPredicates but in actuality my past code was littered with tons of for loops. The Swift code to me is much easier to read and understand.

After higher level functions, my second favorite aspect of the switch to Swift is how much more I pay attention to mutability. For the player logic I decided to use NSOperations to compute some type of decision. In the past I’d have that code in one monolithic class. Using NSOperations allowed me to concentrate just on one small piece of logic making it easily testable. As far as mutability, all of my operations and even internal functions never mutate any of their input parameters. All operations have a operationResult parameter that holds the computation. No function uses the inout keyword. Even functions that do something as simple as sorting use a return value and @warn_unsed_result to remind myself that none of my functions ever mutate. I really like this approach and plan on using it in the future.

Auto Layout / Adaptive Layout

I haven’t used Xcode 8 yet but what I saw in the Platforms State of the Union at WWDC I think would have made both these games SOOOO much easier to create. If you’ve ever created landscape layouts with size classes you probably know what I mean. Interface Builder in Xcode 7 means working in a canvas that doesn’t have the same dimensions as any device you’re creating it for. Xcode 8 looks like a much better experience.

Multitasking was incredibly simple for both since I was already supporting devices from 4S up to the iPad Pro. Getting the layout right for the other devices meant multitasking was already done. I think users of such stupid time wasting card games will appreciate it!

One thing I did do different with auto layout in both of these games is to use placeholder views in the storyboards then adding all the actual views on viewWillAppear. The placeholder views give me the correct frame when the game starts (and also after rotation or switching multitasking size). What it saved me – particularly for Solitaire – was having every card in play represented on the storyboard. It made all the animations easier. Because the views that I add on viewWillAppear don’t have any auto layout constraints, I can animate their frames instead of updating their constraints (via tons of IBOutlets). I’m not sure that I’d do this very often in the future but this approach worked really well for these games.

iCloud Key / Value Storage

Both games use NSCoding and NSUbiquitousKeyValueStore to sync not only stats and best scores across devices but also unfinished games. I’m still not sold on this. It works well enough that I don’t think most people will notice how long the lag between synchronizing on one device and getting the update on another device can really be. I’m guessing in real world use, the 1 to 5 minutes won’t be noticed. We’ll see. I have a feeling this will be the biggest source of complaints and bad reviews.

App Store Preview Videos

When I first started figuring out how to do these I was so close to throwing in the towel and skipping them. I’m glad I didn’t. Once I figured out how to have an easily re-playable sequence in both games and liked what was being shown, recording and editing in iMovie for 5 different devices was pretty quick (iPhone 5, iPhone 6, iPhone 6S+, iPad, iPad Pro).

I have much more appreciation for app developers who have a preview video. I also think you get a better idea of how the app feels with a video rather then just screenshots. Will they drive more downloads? I don’t know. But now I know how to make them so that’s another skill in the toolset.

Test Flight

Loved it. Would use it again. I should note that I haven’t tried any of the newer beta distribution platforms, but Test Flight did everything I needed it to do with very little friction.

AdMob

Monetizing an app with advertising is always a little controversial. I wrote these two games to teach myself Swift, get more experience with auto layout and multitasking as well as learning the latest version of iTunes Connect which I hadn’t touched in 2.5 years. I see them more as my playground to learn and use the latest and greatest Apple technology. I don’t think I’d learn as much if I didn’t release them. Having real users is critical in learning and understanding the entire Apple ecosystem. But I want my expectations from users to be realistic. I get to learn new fun things and they get to play them at the cost of a few ads. If I want to completely redesign an app to learn something new (which I did with Super Euchre) I don’t feel the same obligation to users that I would if I were charging them. That may seem cynical and an altruistic approach of completely free apps may be more palatable for a user but I did spend 4 months working on these games. Realistically I expect to make about $100/month pre-tax on these games. I’m already practically giving them away.

I am curious though if banner ads really do underperform against interstitial ads. Euchre has a banner add while Solitaire has an interstitial ad when starting a new game. It should be interesting to see which wins.

Overall

I hope people enjoy these games. These last few months have been a lot of fun creating them, getting them to testers and polishing them off. I’ve learned a ton!

Then WWDC happened.

Now to update both code bases to Swift 3.0…

Written by Nick Harris

June 23, 2016 at 6:59 am

Posted in Uncategorized

Protocol Oriented Programming

The term “Protocol Oriented Programming” has been thrown around a ton over the last year. If you’re wondering what it means, here’s an example that I dealt with tonight while working on Euchre…

Problem

Over the weekend I implemented a way to save multiple in progress games and have iCould key/value storage sync them across devices. The initial implementation was pretty dumb and saved any game in progress. This lead to a long list of saved games just in my testing. That’s not a great user experience. The user should make the decision to save their current game or delete it.

In the app the user can start a new game from the regular Game View or they can elect to resume a game which shows the Saved Games View:

Screen Shot 2016 06 06 at 11 03 37 PM     Screen Shot 2016 06 06 at 11 03 52 PM

Both of the views need to be able to prompt the user to save their current game. They both also have different actions once the user makes their decision.

Protocol Oriented Programming Solution

The best way to solve this was to first create a protocol named SaveGameProtocol that has the current GameController that I want to archive:

protocol SaveGameProtocol {

    var gameController: GameController? { get set }
}

 

Next was to add an extension to that protocol that does the save / delete prompting and handles the users decision before invoking a completion handler. This makes the extension very generic. It does its save / delete job but leaves the rest up to whatever SaveGameProtocol adhering UIViewController that wants to call it.

extension SaveGameProtocol where Self: UIViewController {

    func promptUserSaveCurrentGame(completionAction:(()->())) {

        let alertController = UIAlertController(title: NSLocalizedString("save_game_alert_title", tableName: "GamePlay", comment: ""), message: nil, preferredStyle: .Alert)

        let saveGameAction = UIAlertAction(title: NSLocalizedString("save_game_button", tableName: "GamePlay", comment: ""), style: .Default) {
            action in

            if let currentGameController = self.gameController {
                SavedGamesManager.sharedInstance.saveGame(currentGameController)
            }

            completionAction()
        }
        alertController.addAction(saveGameAction)

        let deleteGameAction = UIAlertAction(title: NSLocalizedString("delete_game_button", tableName: "GamePlay", comment: ""), style: .Destructive) {
            action in

            if let currentGameController = self.gameController {
                SavedGamesManager.sharedInstance.deleteGame(currentGameController)
            }

            completionAction()
        }
        alertController.addAction(deleteGameAction)

        presentViewController(alertController, animated: true, completion: nil)
    }
}

 

There is a trick here though. In order to present the UIAlertController using presentViewController we need to make sure the caller is a UIViewController subclass. That can be enforced by using a where clause on the extension:

extension SaveGameProtocol where Self: UIViewController

 

The last step was to set both my views to conform to the SaveGameProtocol then call the extension with whatever code each needs to continue.

Screen Shot 2016 06 06 at 11 20 34 PM     Screen Shot 2016 06 06 at 11 20 20 PM

And that’s it! Shared save game prompting code for any UIViewControllers that needs it!

Swifty!

Hat tip back to Natasha the Robot  for the pattern.

Written by Nick Harris

June 7, 2016 at 5:41 am

Posted in Uncategorized

Core Animation

Core Animation is by far my favorite framework to mess around with. Its been my favorite since I started writing Euchre way back for iPhoneOS 2.1. Its simple to use and can be incredibly powerful in calling attention to UI elements when they change. Its also very easy to over do it with animations. I liken it to salt and pepper in cooking. You can enhance your app with just a pinch but too much and it ruins everything else you’re trying to do.

I’ve been playing around with how to show trick winners and hand winners in Euchre for the umpteenth time over the last two evenings. Its one of the parts of continuously re-creating a Euchre game for iOS that I really love. This effort is especially meaningful after getting a grip on how to represent the game in AutoLayout.

I overdid my animations in Super Euchre (the version available in the App Store) particularly around when a team wins a trick or a hand. The state of the game was over represented on the view and the animations to those changes were jarring. With my new take on Euchre I cut those down substantially while still doing subtle things to draw attention:

 

I like it but I’d be interested in hearing thoughts*.

PS:
I had a blast with animations on Solitaire. Dragging piles was a little challenging but fun.

 

*I don’t present myself as a designer. I’m just a developer who wants to tinker with the design of my own apps that make little money.

Written by Nick Harris

May 11, 2016 at 5:31 am

Posted in Uncategorized

Top Toolbar Design

I saw this screenshot from the Starbucks app tonight. I was curious (I’m not a Starbucks guy) so I downloaded the app myself.

Screen Shot 2016 05 05 at 10 29 57 PM

Personally I like the design a lot. But what really caught my eye is the use of a top of view toolbar instead of a bottom tab bar.

For my Solitaire experiment I decided to go with the same top toolbar approach. When I went back to working on Euchre I made the same decision.

Screen Shot 2016 05 05 at 10 30 23 PM     Screen Shot 2016 05 05 at 10 31 43 PM

The biggest reason for me was the perception of persistence that tab bar views have. Each tab feels like something that’s always active in the app. For my dumb card games, things like rules or best scores don’t need to feel like they persist. You can bring them up when you’re interested but can then dismiss them and feel like they’re “gone”. Using animations can enhance that feeling for the user instead of the flat feeling of switching between tabs. Presenting modal views on top of your base view feels more interactive to me then tabs.

I’ve also accidentally tapped another tab when holding my phone and jumping me from what I was trying to do. Having the navigation buttons further away from my “work area” means I need to make a more definitive action to switch my working context.

The Starbucks app seems to do exactly what I’ve been attempting to do with my horrible design skills. Views appear from the bottom and overlay the base view while leaving the menu visible. Swipe gestures can be used to dismiss them instead of reaching all the way for the top toolbar. Its not a difficult effect to do and I really like the feel of the app more then I would if they had used a tab bar. There are some things they could do to tighten down the animation (adjusting the background image after viewDidAppear is rather jarring) but all in all I do like this approach to app navigation.

Are there other apps taking this approach?

Written by Nick Harris

May 6, 2016 at 4:48 am

Posted in Uncategorized