Refactoring the Blog 2016

This is why you don’t make long term plans, kids. They never work out.

So a few weeks ago I started a blog series on a game that I am making. Then I got derailed by the brief fling with algorithms. I had hoped to get my focus back on completing this game. I haven’t published an app out on the store yet and I really wanted to write a program on my own all the way through to being shipped.

Sadly, this is going to stay on the back burner for a while longer.

I have a new project I am working on that I will announce soon that will be absorbing most of my time and attention.

I don’t like to abandon the blog (and now the podcast) when I have a project I am working on. The last year has been rather sparse during times I have been consumed with projects and I don’t want to do that.

I am going to try to integrate the new project into both the podcast and the blog. The whole point of both of them is to talk about all the new stuff I am learning, so I am hoping to continue to do that with the new project.

I feel bad because I really wanted to hold myself accountable to getting a project completed. I would like to continue to do that and come back to this later.

My understanding is that a lot of people besides me have pet projects and the ruins of previous hobbies fossilizing in their basements.

I need to spend a little bit of time figuring out how to approach integrating my new project into my long term projects.

So, goodbye Godori. I will get back to you eventually. I hope.

Why I am Discontinuing my Algorithms Series

I have spent the last week doing some soul searching and I have decided I am going to discontinue the planned algorithms and data structures series I was going to do on this blog.

My calculation was if I attempted to solve one problem in Cracking the Code interview each day it would take me about six months to get through the whole book. That was before I encountered several road blocks with attempting to implement a custom data structure that was not really intended for this use and required me to greatly extend its functionality.

I made the mistake of reading the beginning of Cracking the Code Interview and to my horror, found a lot of the same things I was saying in my post about the algorithms of discrimination, except they were being touted as features and not bugs.

The author indicated that companies know you probably won’t use algorithms on a day to day basis, but that they’re being used as a proxy to see if you got a computer science degree. They’re assuming if you got a computer science degree you’re a good programmer.

I am a hacker. I love to build things. I love to wander off into unexplored areas of our field to figure out how something works because I enjoy doing it. I love to craft code and make things work. I am fascinated by how to actually grow a complex code base in a way that is sustainable. I am interested in figuring out how to break up a seemingly insurmountable task into pieces that can be accomplished. I am interested in figuring out how to make my code better and I am willing to write absolutely terrible code initially that I know I will go back and fix to get to that point. I am interested in how my user interacts with my code and making sure it’s seamless and intuitive.

I know that not all companies are the same, but my experience of interviewing at companies that use algorithms screening is quite bad. I feel like I am being treated like a criminal whose guilt is assumed and I have to prove my innocence but I don’t get a chance to call a lawyer.

I have never had an interview at a company doing an algorithm screen where anyone has bothered to read my resume. Most of them ask me how they’re supposed to know if I know how to code or not without this screen. Well, I have written books that are published and available. I write about code on this blog. I speak about code at conferences. I post code on GitHub.

A lot of these companies are also ones where they expect relocation. Relocating is a massive deal for me. I have a stable and cheap living situation at the moment. I have parents to watch my second pug while I take the first pug with me to conferences. I have issues with depression and other mental health that are exacerbated by being in urban areas.

If a company is going to demand that I uproot my life, greatly increase my cost of living, and give up the stability of working from the place I feel most comfortable, I want them to not treat me like a criminal. At the very least read my resume. Don’t put me in a situation where I don’t get to speak to an actual human being until I jump through some hoop to prove that I got a computer science degree.

I heard a lot of people telling me that I am shitty developer because I am refusing to spend a few months learning data structures and sorting algorithms.

I disagree.

I feel learning this stuff without context is yak shaving. It’s future engineering. It’s learning something before you need to know it. It’s important to know it is out there, but it is not vital to learn it before you need it. If you spend all your time learning things before you need them, then you won’t build anything.

I learned so much about my code after I started implementing it. I wrote what I thought were solid data structures until I tried to work with them in my code. I found I had underlying assumptions about it that were wrong and I had to go back and add functions and properties to correct for my assumptions.

We like to think that the world can be simplified with algorithms in text books, but they rarely account for the complexity of the real world. You wind up adding bits and pieces to deal with edge cases and your artfully crafted algorithm turns into a house with pieces tacked on. Why not go into it knowing that you’re doing something complex and ugly rather than simple and elegant but imaginary?

There is the argument that I won’t understand how programs work if I don’t learn data structures and algorithms. Again, I disagree.

There are so many things we could use as a proxy for actual engineering knowledge. Why not ask candidates to write things out in assembly language? Why not ask them about computer architecture? Why not ask them how they would break out a large project into smaller pieces? Why not ask them about how they would test their code?

How many people have used a disassembled on their code to look at what the machine is actually doing? I just found out this is something I can do and it’s magical to me. It’s far more interesting to me than memorizing the difference between a bubble sort and a quick sort when I will always just use the sort() function on collection types in Swift anyway.

For whatever reason, this is the thing that we use as a proxy for being a good developer and I am not doing it.

I am interviewing companies and ones that behave like this are ones I don’t want to work for. If this is a small component of a larger hiring process, I am willing to engage in it, but not as a barrier to entry to even get to talk to a human being.

So instead of trying to please large companies and shave all my edges off and submit to conformity, I am going to build things. I am aware that there are algorithms and solutions out there that could make my code cleaner and work better. Once I get something working I will go back and refactor it to resolve many of the issues that I know are there. My understanding was that refactoring was part of being a great developer too. If you disagree with that, then I really hope I am not stuck maintaining your legacy code.

I have faith that if I keep learning and working on cool projects and contributing to the programming community that there is a place for me somewhere. It may not be one of those big companies on the West Coast, but I think the world is big enough to accommodate a lot of different kinds of people.

Code Interview Concepts: Swift Linked List Enhancement

The current project I am working on is to work my way through Cracking the Code Interview creating a Swift implementation of each algorithm and data structure problem listed.

I decided to tackle the Linked List structure first because it was really annoying me how many people told me this was something I MUST learn how to do.

Fortunately the Swift Algorithm Club had an implementation I could look over. I really didn’t see the point in trying to reinvent the wheel, so I figured I could just drag and drop their implementation into a Playground and create a linked list so I could just focus on completing the questions.

(I strongly recommend reading through the tutorial they published recently explaining how to implement this yourself. It’s a great read!)

One issue I encountered was when I attempted to drag and drop the file into a playground. I recently discovered you can have multiple files in Playgrounds and was super excited about it.

I got a compiler error. I looked up the issue and found I needed to import the sources file. No worries. I added it then I got an additional error:

Playground execution failed: error: RemoveDuplicates.playground:8:12: error: 'LinkedList' initializer is inaccessible due to 'internal' protection level
let list = LinkedList()

Huh. That was weird.

I looked over the class and I didn’t see anything that was private. The class and most of the methods were listed as public.

I reached out to the Algorithm Club and they indicated that it was missing a public initializer.

I forked the repository and added a public initializer:

public init() {}

So cool. I should be able to access things now. Huzzah.

I went to go and figure out how to start working on implementing my code questions. The first one talks about iterating through a linked list to remove duplicate values.

I went to start working on this. I realized that there wasn’t a way to simply pass in an already existing data structure to turn into a linked list. I would have to add each node to the linked list one by one.

This seemed like an inconvenience, so I reached out to them again to ask if there was an easier way to do this. They helpfully suggested that I add an extension to the linked list class to let me do this.

Because they did such a great job setting up the class, creating an extension to do this was pretty easy:

extension LinkedList {
  public convenience init(array: Array) {
    self.init()
        
    for element in array {
      self.append(element)
    }
  }
}

I wanted to make sure this actually worked and would be this easy, so I created a test case in their Playground for the Linked List:

let fibonacci = [1, 1, 2, 3, 5, 8,]
let arrayList = LinkedList(array: fibonacci)
print(arrayList)

I forked the repository and submitted this as a pull request.

Conclusion

I really wanted to do an algorithms post every day. I am glad I was able to do one today. It was frustrating to encounter some road blocks, but it was incredibly awesome that the Algorithm Club was around to answer my questions and that I am able to contribute some enhancements to this to make it more useful.

It’s also nice that I was able to use this in a project and find things that were not considered by the original creators and to be able to make it more useful.

Even though I didn’t get to work on my problem set for the evening, it was nice to have a team to work with to solve a problem with code. That’s what I like about programming and I don’t get to do this as much as I would like.

Code Interview Concepts: Linked Lists Overview

This is a new series of posts of me going out and learning common data structures and algorithms that you are asked to implement in code interviews. I am not writing this series of posts because I have gone to the Dark Side. I still think this is stupid, but I care about trying to help self-taught people navigate the waters of finding employment and sadly this is a hoop people have to jump through.

I want to give people resources and to also try to give them hope that if they learn this one last thing they can break through the bureaucratic walls keeping them out. I don’t want them to give up or feel like there is an endless number of things they are required to do. We all know this sucks and it’s bullshit. If you bomb one interview, remember what you were asked, study hard, and keep trying.

Figured since I complained so much about this stupid thing, I may as well start with it.

Honestly, if you want the best explanation of this data structure, check out the explanation in the Swift Algorithm Club repository. I have had a lot of people helpfully suggest I read Wayne Bishop’s book, but I honestly think that Ray’s Algorithm Club is a better resource and it has the additional benefit of being free.

The value in a set of posts like this will be seen later. There are lists of sample questions asked during code interviews that use data structures and algorithms to solve problems. I am going to generate posts going over these common problems and try to show how they can be done in Swift.

I am not writing up this series of posts as a resource for other people, but it could still be of some use for someone. I am writing this up because the best way that I have to be engaged with learning something is to attempt to explain it to someone else in a coherent manner.

Overview

A linked list is simply a series of items that connect to one another. A singly linked list goes only one way. A doubly linked list points both backwards and forwards.

led_strips_strip-direction

If you look at the image of the NeoPixel strip, this kind of illustrates the idea of how a linked list might work. Each pixel is wired in and connected to the ones around it. The data flows in one direction. You can’t skip one pixel to get to the next one. The color starts with the head of the strip and is passed through to each of the pixels in series. Every pixel has a pixel it receives data from and one that it passes data to. It’s like the game Telephone from when you were a kid.

Linked List vs Array

Arrays are faster than linked lists, but they are less flexible than linked lists. Linked lists are not indexed like arrays, so in order to navigate to a node in a linked list, you have to iterate all the way through the list to get where you want to. This means if you want to add things to a linked list, you should add it towards the beginning of the list to make sure you can get to it faster.

Pointers

Linked lists use pointers to elements rather than indexing. This is one reason that this data structure makes me crazy.

One of the big reasons I am grudgingly doing this series of posts is because I know we got to the point a while ago where basically all languages were based on concepts from C. One reason we are asked about linked lists is to prove that we understand the concept of pointers.

Except Swift is a hybrid functional language.

Swift has to work with C and Objective-C and has unsafe mutable pointers, but you’re not really supposed to implement them directly in production Swift. Yes, you can force the issue and use things like pointers when you don’t have to, but that’s really bad programming.

Another reason I am grudgingly doing this is because I want to gain a better understanding of which these fundamental data structures honestly don’t work well with things like Swift. I would argue that creating a data structure based on pointers in Swift is a bad implementation decision. There are probably ways around using pointers, but why bother implementing something like this then?

Should You Implement This in Production Code?

No. There are a lot of other better ways to do this stuff. This is a really simple thing to implement, which is one reason this stupid question gets asked a lot.

Swift 3 Linked List

Here is a brief overview of the code put out by the Swift Algorithm Club:

public class LinkedListNode {
  var value: T
  var next: LinkedListNode?
  weak var previous: LinkedListNode?
  
  public init(value: T) {
    self.value = value
  }
}

public class LinkedList {
  public typealias Node = LinkedListNode
  
  fileprivate var head: Node?
  
  public var isEmpty: Bool {
    return head == nil
  }
  
  public var first: Node? {
    return head
  }
  
  public var last: Node? {
    if var node = head {
      while case let next? = node.next {
        node = next
      }
      return node
    } else {
      return nil
    }
  }
  
  public var count: Int {
    if var node = head {
      var c = 1
      while case let next? = node.next {
        node = next
        c += 1
      }
      return c
    } else {
      return 0
    }
  }

I am impressed that The Algorithm Club created an implementation of a linked list without throwing around mutable unsafe pointers. Their implementation can be found here. I will be using this as the basis for the answers I will be implementing from Cracking the Code Interview in future posts.

There is a lot more code in their implementation and I highly recommend looking it over if you need to use this in a code interview.

Conclusion

I don’t really know what else to say about this. Someone else created a really good implementation of this and I don’t see the point in reinventing the wheel. I think the value in this will be in the future posts when I explore some of the common problems people ask you to do in order to show your understanding of this data structure.

Again, I am trying to make information available rather than trying to show how clever I am for coming up with things. If I can find a good solution someone else has implemented I am happy to use it.

Super Mario Brothers

I have written on here before that I did not get to play video games as a kid. The closest I got to a Nintendo was watching my daycare owner’s kids playing Super Mario Brothers on the NES from the couch because I never got to join them.

When I watched them play, they knew where all the hidden shortcuts were. They knew to jump in certain places to hit invisible boxes and to travel over the side of a wall to get to a pipe that allows them to skip a bunch of levels.

I wondered as a kid how they found all these short cuts. I realized at a certain point that someone else showed them. Someone created a guide that talked about where all the easter eggs were and people either found them through reading that guide or watching someone else play.

There are speed records where someone can get all the way through the game from beginning to end in just over five minutes. It became a thing to try to get through the game as fast as possible.

As a kid I didn’t really understand that. I thought the point of the game was to play the game. I was told by people rolling their eyes that the point of the game was to beat the game.

I wrote a post yesterday talking about my being upset about the algorithm questions that are asked at programming interviews.

I have gotten a lot of push back on this.

I have been accused of being incompetent and not being a real programmer. I am confronted by people who are angry with me for not just accepting that if I read an algorithms and data structures book that I will be a better programmer.

I feel I am being misunderstood.

I feel like a a lot of people telling me this are like the people who I watched playing Super Mario Brothers as a kid. I think that they have been told there is some bible of short cuts that get you through the game faster. They don’t look around on their own or explore the game. They’ve been given a set of instructions that gets them through the game faster and they can’t comprehend why someone would not take a short cut that they know is there.

The impression I am getting from people is that they are blindly accepting that these are strict rules that we are supposed to follow and if we don’t follow them then we’re ignorant and wrong.

I think about all of the levels that the game designers created that no one ever looks at because everyone is in such a hurry to get to the end and beat the game.

I don’t care about beating the game.

I care about playing the game.

I don’t want to accept that there is only one way to be a programmer. I like to find things out for myself. I want to explore more than one way to do things. I don’t want someone telling me my code is wrong because it’s not the way they would do it because they only know one “right” way. I think there are a lot of right ways.

I did not mean to imply there was no point in learning algorithms. I am sure they have their place. I’m sure the right algorithm in the right place would completely change the way I think about my code. It’s just that over the last two years I have seen so many people implement lots of terrible code that they think is “best” because they read in a book somewhere that things have to be a certain way.

I had someone try to create a protocol around a class that would never be subclassed because it’s what he thought Apple wanted him to do because he didn’t think critically about how to use polymorphism properly. I have had people suggest I simplify my code by doubling the code base and add three or four data structures to get around using an if statement.

Singletons are evil. React is evil. JavaScript is evil. Use MVVMMVVMMVMVC. Emacs over Vim!

There was a lot of push back against Swift when it first came out because it was different. People lashed out at it because it was not what they were expecting or familiar with.

I feel like sometimes we over-engineer things instead of looking for simple solutions. We think we have to place a thing in another thing and guard against the possibility that someone in the future will do. We have to force a tool to act like another tool in order to conform to some protocol rather than using it how it’s supposed to be used. We want everything to be one size fits all because it makes life easier to think that way.

Right now I am trying to see if a simple solution will work for me before I implement a more complex one. I don’t want to just blindly apply something because a stranger on the Internet tells me to.

Just reading an algorithms book doesn’t make you a good programmer. Understanding a problem and when to implement the right algorithm makes you a programmer.

I want to figure that out for myself rather than having a bunch of people talk down to me about how I can beat the game in five minutes. I am actively refactoring my code to implement better solutions, but I don’t want that to be my first step. I want to screw up and do stupid shit so I can learn from it and figure out how to do it better. Sometimes when you think you know all the answers you don’t look for new ones and if you’re not learning anything new then what’s the point?

I’m sorry for people misunderstanding my desire to figure things out for myself as being willfully ignorant or contemptuous for good software development. You learn more from your own mistakes than you do from other people’s. The last time I checked, thinking for yourself was still allowed. I don’t care if you hate me, or think I am wrong or ignorant or stupid. I am entitled to my own reality and you are too.

The Algorithms of Discrimination

This is a cross post between this blog and my podcast. I realized that this blog has more reach than the podcast does because it’s new, so I am posting the script from that podcast here.

Transcript

This is a special episode of Janie Rants.

I have been asked a lot of questions about a series of tweets I posted on Twitter last night. In these tweets, I said that this was the first time I felt like I was unwelcome in the iOS programming community.

Like many things on the internet, this is a long and complicated story and it was not really conducive to the short format and tempers of Twitter, so I will try to do my best to explain myself here.

At the moment I am between jobs and I am trying to figure out how to proceed. I am trying to see if I can make it as a contractor but I have also been looking into obtaining regular work as well.

I posted a blog post a few weeks ago about an experience I had interviewing at a rather large and well known company that had a white board interview where I was being asked to implement a linked list in Java.

I expressed that I felt this was a useless task.

I got a lot of pushback from people on Twitter about this. A lot of older programmers chastised me that you can’t be a great programmer if you don’t understand data structures and algorithms. I tried to make the point that if you are an iOS developer that most of your job is to have knowledge of the iOS frameworks and that the language is secondary. Someone who had never owned a Mac or opened Xcode could theoretically get a job as an iOS developer.

I continued to get pushback about the absolute importance of algorithms and how someone implemented a linked list once in their career. I asked whether it was more important to be able to answer a question about something you might do once in ten years or about something you would use every single day. I don’t think I got a response to that.

I did a phone screen where I was once again told that the tech aspect of the screen involved doing an algorithm test. I expressed frustration on Facebook about once again being asked to do an algorithm test for an iOS position.

One person on there told me if I spent all the time I used complaining about algorithms to actually learning them I would know them by now. He also criticized me for not being willing to implement well known algorithms and structures that are simply not part of the Swift Standard Library. This hurt my feelings because this was a person I considered a friend.

Another person made the comment that really prompted my series of tweets last night. He said that he asked algorithm questions because he wanted to make sure he worked with the “right” people who has the “right” skills and could talk “his” language.

I know that to most of you listening out there, you probably hear that and don’t give it a second thought. Let me decode this for you.

Algorithm questions are not a way to make sure you’re hiring someone who is capable of coding. Algorithm questions are a way to discriminate against certain kinds of people.

I know, you think I am paranoid. You think this is some kind of conspiracy theory or that I am somehow claiming sexism because I am a bad programmer or I am too lazy to learn these things. Please hear me out.

My first experience learning programming was from Code Cademy online. I accepted a terrible job that my ex-husband would not let me quit where our team lead did not know what we were supposed to be doing, so he told everyone to pretend to work and to look busy.

To keep the suicidal thoughts at bay, I went on Code Cademy to learn programming. I had taken some programming classes, but had only coded things once and subsequently never practiced it enough to understand it.

I discovered that if I wrote code forty hours a week that I could learn programming. I could type code as easily as I type an email and the logic finally made sense. This was a revelation to me. I had given up on programming because I thought it was too hard and I could never learn it. I found that if I put in enough time and effort I could learn how to code.

I got myself fired from that job and went on unemployment. In the state of Wisconsin, if you’re on unemployment you can stay on it as long as you’re going to school to learn a trade. I re-enrolled at the local tech college and started taking iOS classes to learn iPhone programming.

A lot of people learn programming from sites like Ray Wenderlich or from the Big Nerd Ranch books. Lots of people spend thousands of dollars going to code bootcamps.

President Obama has talked about how he wants all kids to know how to code. Apple has added Swift Playgrounds to the iPad to teach kids to code. We’re inundated with messages everywhere that learning programming will lead to a better life. We’ll get better jobs and earn more money and be able to start companies.

None of these paths to programming include algorithms or data structures.

I spent two years trying to scrape up enough iOS experience to be able to get an entry level job. It was brutal learning Objective-C. It was brutal learning about the Model View Controller design pattern. Asynchronous closures. Memory management.

iOS is not a simple framework to learn. There are a lot of moving parts and there is a tremendous barrier to entry to get to a point where you have accumulated enough experience of working with the frameworks and the devices and the compilers to be able to be somewhat proficient with iOS.

So why the fuck do we quiz people of fucking algorithms?

We do that to keep people like me out.

If you have a six week coding boot camp, you’re going to teach people the bare minimum that they need to make something useful. You’re not going to spend weeks talking about data structures and algorithms.

The only people who know about data structures and algorithms are people who got computer science degrees or have been around for so long that they learned it on their own.

This discriminatory practice is written off as a meritocracy. Anyone can learn this stuff if they’re ambitious and smart, so it’s the standard against which all people are held.

Let me tell you about another standard we don’t think about: The SATs.

We think of the SATs as being fair. Everyone receives the same test. Everyone has the same time limit. Everyone has the same equipment. It’s fair, right.

Nope.

If you come from an upper middle class family, you probably had some help with the SATs. I went to a private Catholic high school that specialized in college prep. My parents bought me books that helped me figure out how to get better scores on the SATs. I had practice tests I could take with instructions about what the right answer was and why. It explained to me how to see a trick question and gave me strategies for getting around them.

Both of my parents had college degrees and were in education. It was expected that I would go to college. I didn’t have to have a job because my parents paid for my college, so all I had to do when I was in high school was study. When I didn’t like the score I got on the first test, I took it again. I could take the test as many times as I wanted and each time I took it my score got better because I got practice.

I can stand by my scores and talk about how I earned them through hard work and how the system is a meritocracy because I did marginally better than a few other people with the same privilege I had. But that’s not a complete story.

Take a student living in a poor community in Mississippi. This student might go to a school where they teach creationism instead of evolution. This student has no expectation of ever going to college. This student doesn’t know that there are resources out there to help them do better on the test. They don’t know about the trick questions. Their school doesn’t offer algebra because no one would take it anyway.

Does the test honestly reflect this person’s potential?

This theoretical person could be a genius. But they don’t have the cultural context to know what they are supposed to do in order to move from the sphere they are now to the better one brought by money and education.

I know so many of my classmates from my school who have trouble finding jobs. There are so many road blocks that are set up to keep the wrong people out. You have to have a GitHub repository and a Stack Overflow account with a certain amount of points. You have to contribute to open source. You have to present at meet ups.

We create so many barriers to entry for people who are culturally unfamiliar with what the community expects and we set these up to keep people out. We like to feel like we’ve earned our place in the community and we don’t want to deal with helping more people enter that we have to compete with.

Knowing algorithms and data structures means that you were privileged enough to get a computer science degree. It means you had enough free time that you learned this stuff on your own if you’re self taught. This assumes you have the money to take time off to learn something that will help you get better jobs.

If you’re struggling to make ends meet because you’re a single parent who can’t get past the velvet ropes to the land of coding opportunity, you do not have time to learn these things. You are told you’re not welcome and you give up.

None of this would bother me so much were it not for how completely useless this exercise is. Yes, knowing data structures and algorithms makes you a better programmer at some point, but if you’re interviewing someone for a job doing iOS development, there are so many other things that are iOS specific that no one ever asks about because for the most part these places don’t know them. You’re getting interviewed by people who don’t know anything about what we do who for some reason are in charge of determining whether you understand things or not. It’s bullshit.

The people who have the privilege to get through this red tape just kind of shrug and accept it’s a necessary evil. Some of them even embrace it and will fight with you tooth and nail about why it’s important for someone to know something they haven’t used in five years.

Yes, I could go and learn algorithms and data structures. I am holding my nose and accepting that this is probably something I must do in order to get better jobs, but that doesn’t mean that I should endorse them because I have the privilege of being able to take a few months off of work to learn something that’s nearly completely useless.

By filtering out anyone who comes from a non-traditional background, we’re ensuring a monoculture in programming. We want diversity, but only if the people we bring in think the same way we do. That’s not true diversity.

We need people who never went to college. We need people who learned by hacking and being tenacious and getting something working. We need people who come from diverse backgrounds who can bring new perspectives to what we do so that we can use technology to make people’s lives better and not just find more invasive ways to gather user data for targeted marketing.

Over the last year I have not felt that this community values those voices anymore. I went into iOS over web and Java because I felt that this community was welcoming to anyone with a curious mind and drive to do better and based on the responses I am getting from people I don’t feel that way anymore. I want there to be opportunity out there for people who are like I was four years ago. In order for that to happen, we need to change how we do our hiring practices or we’re all going to be poorer for it.

Thank you.

Game Development Journal 12: Checking for a Match

Generally speaking, a turn in Godori is quite simple. You have a hand of cards. On your turn, you play a card. The game board has a collection of cards on it. If the suit of the card you play matches the suit of one of the cards on the board, you capture it. Then a card is played from the draw pile. If that suit matches any on the board, you capture those as well.

From this simple explanation, you can either capture two, four, or zero cards. But there is an exception to this rule. What happens if you made a match on the card you played and then the same suit comes up from the draw pile?

In that situation, you do not capture any cards. All three cards remain on the board until another player or the deck plays the final card in the suit. At that point you capture all four cards.

I have to write programming logic to account for all of these scenarios. Because it’s possible for your cards to get stuck on the board, the way I am approaching this is that I am creating a temporary array of all the cards concerned in a turn.

These are all of the possible numbers of cards in play and how they would be distributed:

  • Two Cards: In this case, neither the card you played nor the card from the draw pile matched any suits currently in play. Both cards would be distributed to the game board.
  • Three Cards: There are two cases where you get three cards. You either made a match with either the card you played or the card that was drawn and the other card was not a match or all three cards are the same suit and they stay on the board.
  • Four Cards: The card you played and the drawn card each found another card on the board to pair with and you get all four cards.
  • Five Cards: You captured a set of three with one of your cards or one that was drawn, but the other card did not match.
  • Six Cards: Lucky you! You captured a complete suit and picked up another match from the board with the other card.
    • I can represent this logic in a method with a switch statement:

          func checkForMatch(cards:[Card]) {
              
              let numberOfCards = cards.count
              
              switch numberOfCards {
              case 2:
                  cardsInPlay += cards
              case 3:
                  let countCards = countSuits(cards: cards)
                  players[currentPlayer].capturedCards += countCards.playerCards
                  cardsInPlay += countCards.gameCards
              case 4:
                  players[currentPlayer].capturedCards += cards
              case 5:
                  let countCards = countSuits(cards: cards)
                  players[currentPlayer].capturedCards += countCards.playerCards
                  cardsInPlay += countCards.gameCards
              case 6:
                  players[currentPlayer].capturedCards += cards
              default:
                  break
              }
          }
      

      The two, four, and six options are easy. If there are two they go to the board. If there are four or six the player captures all of them.

      The hard cases to deal with are the sets of three or five. If there are three, then there is a case where the player gets no cards and a case where the player gets two cards and one goes back to the board. If there are five cards, then the player gets four cards and the board gets one, but which cards go where?

      As a person, this is easy to determine. I look at the cards all at once and I pick out the ones that don’t match. Trying to explain this to the computer is difficult.

      I have to check the suit property on each card and compare them to find the ones that match.

      This is made more difficult by the fact that I don’t know what suit I am dealing with. It’s easy to check to see if all the cards are from the .December suit, but to check a random blob of five cards where four will be one of twelve suits and the last one will be another means that I can’t simply loop through the array of cards checking to see if they’re a specific suit. I have to compare them to one another.

      The only think I have available to me to limit the amount of conditional logic is to know the order that the cards are entered into the array. I know that if I have three cards then either the card I played matched or the card from the draw stack matched. There would be no scenario where the first and third card would match without also matching the second card.

      A similar pattern exists with the five card option. If you capture a complete suit of cards, then there will be four cards in a row in the array with the same suit. Instead of having to check each card in the array for the mismatching card, I theoretically only have to check the first two cards and the last two cards. If the first two match, the last card will not. If the last two match, then the first one won’t.

      This is the current implementation I have:

          func countSuits(cards:[Card]) -> (playerCards:[Card], gameCards:[Card]) {
              
              if cards.count == 3 {
                  // I don't think there is a situation where the first and third card would match
                  // Either the first and second or second and third cards will match
                  if cards[0].cardSuit == cards[1].cardSuit && cards[0].cardSuit == cards[2].cardSuit {
                      return ([], cards)
                  } else if cards[0].cardSuit == cards[1].cardSuit {
                      return([cards[0], cards[1]], [cards[2]])
                  } else {
                      return([cards[1], cards[2]], [cards[0]])
                  }
              } else {
                  // Four cards will match and one will not. If arrays work the way I think they're supposed to, 
                  // in this case either the first four cards will match or the last four will.
                  if cards[0].cardSuit == cards[1].cardSuit {
                      return([cards[0], cards[1], cards[2], cards[3]], [cards[4]])
                  } else {
                      return([cards[1], cards[2], cards[3], cards[4]], [cards[0]])
                  }
              }
              
          }
      

      Again, I understand that this implementation is really ugly. Everything is hard coded. There are a lot of if/else statements and array positions. There are a lot of ways this can go wrong.

      Conclusions

      I know there is probably a better way to deal with this. It’s possible that there is a class in the Gameplay Kit framework that would handle this better.

      I am planning to explore better ways to deal with this. I also am planning to write unit tests for this when I move this stuff over to a project where I can include them.

      There is simply a lot of state and conditional logic in this application because it’s a game. I saw a bunch of people on Twitter recently talking about how embarrassed we’re going to be in ten years because we use if/else statements. I have not heard any suggestions about how to get around this.

      I know writing conditional logic is ugly and there are people reading this who want to completely rewrite my code. This is a question I deal with every day.

      There is a certain level of necessary complexity. There are a lot of conditions present in the rules of the game that need to be accommodated for. Simon Allardice talked about how when you’re teaching something there is a certain level of necessary complexity. I know myself and lot of people get frustrated when we do a tutorial for something like OpenGL and we have a spinning cube of death. It’s like, this is cool, but I can’t apply this knowledge to anything.

      There are certain circumstances that get chosen for teaching purposes because they’re easy and not messy. There is the world as it is and the world as we wish it would be.

      I see situations in here where it’s like “Oh this is simple! I can just set this up like this. Except it doesn’t work in this case, or this one, or this one…”

      I am trying to avoid setting up a bunch of spaghetti code or putting in a bunch of unnecessary objects to embed other object with even more objects.

      Programming is an iterative process. This code will change down the road. I would rather get something done now and go back and change it later when I get a better idea of what I need than spend all my time waxing poetic about how I could do this with a map() if I didn’t have to account for these edge cases. Bad code that actually gets written trumps perfect code that can only live in your head.

Game Development Journal 11: Dealing Cards

One thing I find fulfilling and frustrating about game development is that there are a lot of things we do in real life without thinking too much about it that are somewhat tricky to represent in code.

One of the big challenges with machine learning is figuring out how to explain to a computer that the blob of data it has represents a pug. A person can look at a picture of a pug and know it’s some kind of smush-faced dog. They might mistake it for a bulldog or something similar, but they won’t look at it and say it’s a table.

The thing I am dealing with right now is dealing a hand in my card game. The cards are dealt into five different collections: Three player hands, the cards currently in play on the table, and the cards in the draw pile.

In real life, a deck is basically a mutable array. You deal the top four cards to the first player, then the same to the next two, then deal three more to each collection and what’s left turns into the draw pile.

Swift doesn’t really think that way. Swift likes immutability. The game has a certain amount of state. The players will play their cards until there are no more, which means that the array will by necessity have to be mutable so that the cards that have been played can be removed from the hand and moved to the player’s captured cards.

It’s possible to make this work, but it’s not super pretty. It’s fighting against the way Swift wants to work.

I really did not want to have to go through and assign each card individually in this function. Since it follows a pattern, where the players each get four cards, then the table gets three, then everything gets three, it seems like it should be automatable.

I have some concerns about how to approach this. This is my first attempt:

    func dealCards(shuffledDeck:[Card]) {

        // Deal four cards to the first player and each one after that
        players[currentPlayer].hand[0...3] = shuffledDeck[0...3]
        nextPlayer()
        players[currentPlayer].hand[0...3] = shuffledDeck[4...7]
        nextPlayer()
        players[currentPlayer].hand[0...3] = shuffledDeck[8...11]
        nextPlayer()
        
        // Deal three cards to the table
        cardsInPlay[0...2] = shuffledDeck[12...14]
        
        // Deal three  more cards to each player
        players[currentPlayer].hand[4...6] = shuffledDeck[15...17]
        nextPlayer()
        players[currentPlayer].hand[4...6] = shuffledDeck[18...20]
        nextPlayer()
        players[currentPlayer].hand[4...6] = shuffledDeck[21...23]
        nextPlayer()
        
        
        // deal three cards to the table
        cardsInPlay[3...5] = shuffledDeck[24...26]
        
        // put the rest in the draw pile
        drawPile[0...21] = shuffledDeck[27...47]
    }

Yes, I know. This is reeking of Code Smell. I have two blocks of code that are nearly identical except for the indices on the shuffled deck. This depends on me keeping track of where I am in my array of cards. It also depends upon me knowing how many cards are in my array.

This makes me deeply uncomfortable. I am not entirely certain how to set up conditional logic for this. If this was before, I would use nested For loops, but those seem to be going the way of the dinosaur.

I suspect this is a situation where map() would probably be the best approach, but I feel like it’s complicated to express. I have to keep track of how many elements are being added to each array and where I am at in the shuffled deck. I even just noticed that I put the wrong terminating index at the end of this method that I went back and changed. There are a lot of ways this can go wrong.

I want to leave this here for the time being and try to think through a better approach to this. I don’t want to add a bunch of functional garbage that is less clear and more complicated than what I have now. I know there are better ways to do this, but I also know there are a lot worse ways to do this.

I do not want to over engineer this. Nothing in this function is going to change. There will never be more than 48 cards in the deck. There will always be three players. I know a lot of the reason we don’t hard code stuff is to add flexibility for changing requirements. But I know these requirements won’t change.

Also, I feel comfortable when I read this method about what it is that it does. It follows the same logical structure that you would if you were actually dealing a deck of cards. I know as a programmer this looks terrible, but me as a person it feels logical because this is the process I would go through if I was actually dealing a hand of Godori.

Conclusions

I will probably refactor this based on input from other people.

I think a lot about human versus computer. I know as a programmer there are more efficient ways for me to do things than I have in this code in particular. But I am also a human being. I have my own biases of how I personally process information.

I have to maintain this code. If I look at this in a year not only do I clearly understand how it works, but I also have an understanding of the game logic about how the cards are to be dealt.

I am probably justifying myself too much, but I am really struggling with this. The reason we have the abstraction of programming languages instead of writing everything in assembly language or machine language is to make programming more human friendly. Does writing more verbose code that is more clear to me but breaks best programming practices make me a hack? Or are we making things harder than they have to be in the name of trying to be 10x programmers?

Only time will tell.

Video Game Research: Persona 3

Nearly two years ago I decided to try and get into video games. I kind of fell off the wagon on this hobby and I am trying to pick it up back up again.

This series of posts is about me playing through video games from the perspective as a noob. I am planning to play through a few games that most people have already played through, such as:

  • Zelda
  • Mario
  • Pokemon
  • Mass Effect

My only familiarity with some of these is of sitting on the couch at daycare watching the children of the person running the daycare playing these games. I was never allowed to play and it made me slightly bitter.

I am generating a list of games and franchises that are indicative of common game mechanics within modern gaming. I am also looking for examples of great gameplay and narrative.

The first game that I played all the way through from beginning to end was Persona 3. I started this game over a few times because I was playing it on my PS3 and I would go months without turning it on. I finally realized I could buy the game for the Vita and for about ten glorious months I had a fun game to play in the bath with a glass of wine after a long day at work. The fact that the Vita version came with the option to play as a female was a definite bonus!

This game is rather long. I beat the game after playing it 72 hours. I finished it at the beginning of the year before I started this series.

Since it is the first game I finished, I wanted to talk about it here even though I finished it a while ago.

Game Overview

Female Protagonist from Persona 3

Female Protagonist from Persona 3

You play as a high school student who has special abilities in this game. At midnight each night, your high school turns into a portal to Hell where monsters known as Shadows attach you.

You fight these shadows using a Persona. A Persona is similar to a Patronus from Harry Potter in that it is something that you have within yourself that can fight and protect you on your behalf. Most of the people in your team only have one Persona, but you have the ability to bring forward many Personas.

This game takes place over a school year. In addition to fighting these Shadows at night, you have to make sure you do well on your midterms and establish relationships with the people around you. Your relationships strengthen your Personas. They’re also the primary mechanic around how to advance the story so it’s not just a grinding exercise.

Combat Mechanics

A Shadow from Persona 3 with its strengths and weaknesses.

A Shadow from Persona 3 with its strengths and weaknesses.

The combat is turn based. Your team encounters a Shadow or a group of Shadows. Each Shadow and Persona has strengths and weaknesses.

There are six elements in Persona:

  • Fire
  • Ice
  • Wind
  • Electricity
  • Light
  • Darkness

Until you get to the last levels of the game, most Shadows have at least one weakness. The other students on your team have two strengths, which means if you have the right team of people you can always make sure you have any Shadow’s weaknesses covered. It’s important to lean on other members of your team because you have a limited amount of “spirit energy” to attack with. If you do all the attacks by yourself you will not get as far as you would by spreading this burden out to the rest of your team.

Your Personas also are capable of physical attacks, but generally speaking you don’t utilize those as much in the game.

On each turn, each Person and Shadow has a chance to implement an attack. If you sneak on a Shadow before it notices you, you can usually wipe it out before it has a chance to attack you.

I can understand why some people might find this combat system to be easy or repetitive. I actually liked this aspect of it. I set the difficulty as low as it would go.

I found it really soothing to have this mechanic in place where you don’t die very often. When I am mentally tired, doing the repetitive motions of killing all the bad guys in one or two attacks was incredibly satisfying.

The Orpheus Persona in both female and male configuration

The Orpheus Persona in both female and male configuration

I get discouraged really easily. I have played a few games where you learn by dying a lot. It makes me feel very hopped up and upset when I can’t kill things on the first few tries. I understand that this is the appeal to a lot of people who are hard core gamers, so I appreciated being allowed to have softball combat challenges thrown at me. It was also nice that it was turn based so that I was not in a hurry to mash buttons at just the right time. Right now I am trying to work through a game with combat and I am finding it frustrating.

I like this combat setup better than when I tried Final Fantasy. I know they’re both turn based strategy games, but I like this a lot better. It’s similar to the Pokemon battle mechanics.

So if you’re a noob looking for something that is a step up from a casual game, Persona 3 on the Vita is really good. It has less shallow gameplay than something like Bejeweled, but it has easy enough game play that it hits the same mental centers that something like that also hits.

Story

The thing that separates something like Persona from a casual game is having a long running story.

The story revolves around the people you meet in the game and various events that happen throughout the school year.

When you first start a game, you have a limited number of people you can befriend and interact with. As time goes by, more people are added.

Elizabeth and Igor

Elizabeth and Igor

It’s important to make sure you manage your time properly to max out your social links. Some of your social links only have a short period of time when they are active. Some require you to max out some social skill, such as charm or courage. Even if a social link path is open, you may not be able to pursue that relationship until you up that stat.

There is a lot of time management involved with the game. If you spend all your time grinding away at the combat, you do not have enough time to do things that increase your statistics. If you don’t spend enough time studying you will not do well on your exams, but if you spend all your time studying you will never make friends, which help you do better with your combat.

I want to go back and play through the game again now that I have a better understanding of when things happen in the game. I have been holding off on it because I am trying to play a lot of different kinds of games rather than just playing the same one over and over again. But there are definitely different choices I would make if I do ever get to play this again.

Conclusion

If you’re not a gamer and you’re looking to play something, I definitely recommend this. It’s not something that requires you to have a large base of knowledge about how games like this work. The tutorial setup is useful without dragging on for too long.

Having the option to play as a girl was really awesome. I did find that there were certain things I reacted to differently as a female player than I did as a male player. One of the characters is friendly and when you’re a guy you don’t think about it. When you’re a girl, his behavior can come off as creepy at first. As the game progresses you get more comfortable with him, but it was definitely not something I expected to feel when I switched from a boy to a girl.

If you ever wanted to play a game where you could pretend to be Buffy the Vampire Slayer, this is definitely a good choice. Even though the game is long and somewhat repetitive, it’s a good repetitive. I was incredibly sad when the game was over because I wasn’t sure I would find anything else I enjoyed this much.

Game Development Journal 10: Changing the Player Enum to an Array

Back when I created my Player class, I was trying to figure out how to organize players. I needed to have three players that I would keep in a specific order. My initial idea was to put them in an enum:

enum Players {
    case PlayerA
    case PlayerB
    case PlayerC
}

This was really bothering me. I knew I wanted some way to switch between players and we would always have a current player.

I was trying to figure out how to make this work and I realized I made a grievous error. I was misusing Enumerations.

Enumerations are good for things where you have options that result in you doing something. The example used in the Swift programming book from Apple does a really good job of showing what they mean by that:

enum Direction {
    case North
    case South
    case East
    case West
}

Having these directions in an enum allows you to create conditional logic where you have different actions based on what direction is currently selected.

It is not good at directly affecting and changing any of the case statements in the enum.

I need a data structure that holds three players. I need to know the order the players are in. I have to be able to affect the properties based on things that happen in the code.

I thought about putting these in a dictionary, but I realized that wasn’t really optimal. Dictionaries have orders, but they’re meant to correlate to keys and values. I just need to know what the current player is so I can set its properties and move on to the next one reliably.

I decided I needed an array of players. This array of players has to be initialized in the Game class and passed into the Hand class. The Player needs to be initialized with the initial amount of money that each player starts with.

I created a function that generates an array of players:

func createPlayers(startingMoney:Int) -> [Player] {
    let player = Player(money: startingMoney)
    return Array(repeatElement(player, count: 3))
}

I can then call this function in the Game class and set it to a variable that I can pass to the Hand class. The Hand plays through a round, determines the winner, and returns it to the Game so the Game can determine if another round should be played.

This means that I needed to add a few methods to the Player class to accommodate for these implementation details:

    init(money:Int) {
        currentMoney = money
        numberOfDeferrals = 0
        numberOfPoints = 0
    }
    
    // Reset Players
    mutating func resetPlayer() {
        hand.removeAll()
        capturedCards.removeAll()
        numberOfDeferrals = 0
        numberOfPoints = 0
    }

When the Player is initialized, it is created with the starting amount of money. When a Hand is completed, a Player’s properties need to be reset.

This clarifies a lot of what I need to do in the Hand Class. Now that I know I am using an array of players rather than an enum, I can create all of my properties that I need for a Hand:

    /*
      1. Players
      2. Current Player
      3. Shuffled Deck
      4. Cards on Board
      5. Draw Pile
    */

    var players:[Player]
    var currentPlayer:Player
    let shuffledDeck = shuffleDeck(deck: deck)
    var cardsInPlay = [Card]()
    var drawPile = [Card]()

As per my work in my previous post on figuring out what components I need, I have been able to figure out what type each of my properties are.

I made a mistake when creating my initializer. At first I made the current player a Player object. My initializer looked like this:

    init(playerArray:[Player], firstPlayer:Player) {
        players = playerArray
        currentPlayer = players[firstPlayer]
        dealCards(shuffledDeck: shuffledDeck)
    }

I thought that made a lot of sense, to make the currentPlayer an instance of the Player struct, but I realized that doing this divorced it from the player array.

The game logic basically requires a player to complete their turn and for the process to continue with the next player. By pulling out the current player from the array and making a copy of it in the current player, I have no way of knowing if that player is the first player or the hundredth. I need to persist where I am in my cycle of players because the current player keeps changing.

So I changed my currentPlayer property to:

var currentPlayer:Int = 0

and my initializer to:

    init(playerArray:[Player], firstPlayer:Int) {
        players = playerArray
        currentPlayer = firstPlayer
        dealCards(shuffledDeck: shuffledDeck)
    }

Now being able to go to the next player is fairly simple. I created a method to move to the next player in the array:

   func nextPlayer() {
        if currentPlayer == 2 {
            currentPlayer = 0
        } else {
            currentPlayer += 1
        }
    }

I made this a method on the Hand class. I had hoped to make this into a standalone function so it would be easier to test and be reusable within the application, but I decided against that for two reasons:

  • It makes the function a lot messier. I have to pass in the current index and pass back the return function. I would much rather just call nextPlayer() and not worry about it.
  • I don’t think I actually need this anywhere else in the code. There is no point in over engineering the app adding a bunch of stuff you won’t need.

Conclusions

I am in the process of building out the dealCards() method. I have to deal four cards to each player, then deal three to the table, then three more to each player, and then three to the table. I have to switch players several times and organize all the arrays properly.

I would like to be able to pinch off the first few elements of one array and give them to another array. I know I need to copy those elements and probably remove them from the shuffled deck array.

I can think of some really inefficient ways of doing this. I might write that method out inefficiently first so I can see where all the repeated code is. Writing bad code is an underestimated way to find your way to good code. Embrace bad code!!