Category Archives: Uncategorized

Tic Tac Toe in Swift with a UICollectionView

I’m starting to ramp up how much work I put into using Swift to eventually switch over to using it completely over Objective-C now that Apple has released version 1.0 with iOS 8.

One of my first projects was to make a simple Tic Tac Toe game in Swift. What started out as something relatively simple, as Tic Tac Toe isn’t the most complex game, turned into something much more involved.

Utilizing standard UIKit components and implementing a MinMax algorithm to make the AI unbeatable, I set out to make a barebones, but fully functional, game of Tic Tac Toe in Swift.

Without going into too much nitty gritty detail here on my website, I’d implore you to just browse through the source code over on GitHub. I’ll lay out some of the more important parts which I enjoyed making.

UICollectionView as the Tic Tac Toe Board

Instead of manually laying out 9 buttons or interaction enabled views, I instead went with what could be considered overkill and created the board using a 3×3 grid UICollectionView. I chose to do this for several reasons:

  1. Subclassing the UICollectionViewFlowLayout is neither difficult nor scary and getting familiar with the UICollectionViewLayout protocol is pretty important
  2. The UICollectionViewFlowLayout allows you to make a grid with even spacing pretty darn easily and pretty much straight out of the box. Just make sure you have 3 sections with 3 rows each.
  3. Built in item selecting meant I could hook that into my board pretty easily:
    func collectionView(collectionView: UICollectionView!, didSelectItemAtIndexPath indexPath: NSIndexPath) {
        if manager.placedPiece(indexPath.row, y: indexPath.section) {
            setPlayersLabel()
        }
    }
  4. Automatically scales any any resolutions to work on both the iPhone and iPad as well as easy to customize just like any other standard UIKit control.

Keeping all Tic Tac Toe logic in the GameManager

This meant all of my display logic was handled in my UIViewController and any sort of item placing was handled in the GameManager class. One particular good example was the item placing that I showed above in #3. The if manager.placedPiece(indexPath.row, y: indexPath.section attempts to place a piece at the provided indexPath coordinates for the current player. If it’s successful it’ll return true and tell the UIViewController to change its display of whose current turn it is.

This way the UIViewController doesn’t really ever need to tell the GameManager what to do; however, the GameManager can notify the UIViewController when it should update something accordingly, like in the actual placedPiece method:

func placedPiece(x : Int, y : Int) -> Bool {
    let piece = board.pieceAt(x, y: y)
    if piece.isOpen {
        if whoseTurnIsIt == 1 {
            piece?.playerOwner = player1
        }
        else {
            piece?.playerOwner = player2
        }
        viewController.collectionView.reloadItemsAtIndexPaths([NSIndexPath(forRow: x, inSection: y)])
        nextTurn()
        return true
    }
    
    return false
}

The code is pretty readable, but the last part where we reload the UICollectionView’s cell at the location given means we update the UI to display the newly placed piece if need be, instead of just reloadData-ing the entire UICollectionView. Sure – performance wise a 3×3 grid isn’t going to kill anything but this is a matter of principles, right?

The Unbeatable AI

This was a requirement that I seriously didn’t think would take that long but ended up being a lot more involved than I thought. I started out by doing my best to handle all of the cases by hand. I was able to make the AI unbeatable EXCEPT for cases when I, the user, would create “Forks” (Turns where in the next turn I’d have two ways to possibly win). Here’s the logic for the AI’s turn:

  1. Check if the middle piece is open. If it is, place it, otherwise choose a corner and place it only if it’s the AI’s first turn.
  2. Check if the AI has two pieces in a row and can place a third, and if so place it there to win (horizontal, vertical and diagonal)
  3. Check if the player has two pieces in a row and can place a third, and if so place it there to block the player from winning (horizontal, vertical and diagonal)
  4. Check for a fork – This was what I was missing and will explain in a bit
  5. Place it in the center if it’s open
  6. Place it in any free corner
  7. Place it in any free side piece

For the longest time, I couldn’t figure out how to do #4. Searching Google suggested I create a MinMax algorithm for the AI to determine which move gives it the best chances to win. I fortunately found an example of how to do this in Java, to which I then converted over to Swift.

MinMax in Swift

I’m not going to try to reexplain how the MinMax algorithm works in this instance as the link provided will do a much better job at it; however, if the score that it returned to my when checking for any forks the AI should make met a positive score, the AI would place an item there. This made the AI unbeatable!

unbeatable tic tac toe AI

Wrapping up

In the end, I was pretty happy with how this turned out! Now, if I was a good developer I’d go ahead and write some tests to make sure my logic was sound… but we can save that for another day.

 

Fixed!

Turns out I had renabled a very old configuration for this website that was causing things to break. I’d become frustrated in trying to debug it about a year ago and had given up.

Not sure what made me look into it again, but I was able to find out the issue pretty easily and now we’re back up and running. Time to fix all of this and clean it up.

A lot has changed in the past year and a half.

jQuery Help – Odd .click() declaring in IE

I’ve run into a very weird issue that I’ve neither seen before nor do I have any clue how to fix it. This happened when I redesigned/coded my rush page functionality on the ZAX Portal.

My weird issue is that when I redeclare the .click() functionality on an element on my page, the code executes the actual functions within the new declaration. Sounds weird right? Here’s the setup:

In my showRushee() function, I change our image’s source (it’s a + to – image), remove the previous onclick function, and add a new .click() functionality that calls hideRushee().

function showRushee(rusheeId,myClass){
$("#"+rusheeId+"_collapser").attr("src","'.ADDRESS.'images/expanded.png");
$("#"+rusheeId+"_collapser").attr("onclick","");
$("#"+rusheeId+"_collapser").unbind("click");
$("#"+rusheeId+"_collapser").click(function() {
hideRushee(rusheeId,myClass);
});

There’s some more that happens afterward, but it seems pretty straight forward right? Well, here’s a screenshot of what is actually happening using IE’s web developer debugger.

I ended up putting a breakpoint within the hideRushee() function in order to see if it was being called. Once it reached the breakpoint, I went one step up in the call stack which is what you see above.

I don’t really understand why this is happening. This code works in Firefox, Chrome and Safari just perfectly. This code also works after you click on the expander once again, so it only happens the first time it is clicked. Does anyone have any idea what’s going on?