Thursday, May 9, 2013

The State Pattern

During my apprenticeship, I've encountered ideas I learned about in college. When I say this, I do not mean to imply that I learned everything I could about each topic. In fact, my apprenticeship has taken those foundations and replaced what I knew with a much better understanding. One example of this is a state machine.

A state machine describes how something behaves given a current state and transitions to the next state. It doesn't have to be software either. You can make a state machine diagram for traffic lights, for example. The key properties are that a state machine can only be in one state at a time, there are a certain number of possible states, and there are transitions from one state to another. One area of programming that makes extensive use of state machines is game programming.

In college, I was taught to implement state machines in a simple way. It boils down to a rather large class with a function for each action the state machine can take, a variable containing the current state, and a large switch statement. In all likelihood, I've written something like the following before.

While this state machine doesn't really do anything, it works. There's a bigger issue than it not doing anything though. It's possible that there are additional things wrong with it but that case statement in take_action causes me pain and is a glaring example of an OCP violation. I'm not pleased by having to check the state every time that I want something to happen. Before this apprenticeship, I would have accepted this as the cost of writing a program.

I now know that an answer to my issue is the state pattern. This pattern encapsulates each game state in an object. Each of these state objects conform to the same interface and correspond to single game state. In this way, my state machine no longer cares about checking the current state when it takes each action because the state variable is an object. That object already knows what to do in the current situation. This allows me to alter my current program to look more like the following.

Using the state pattern, I was able to move the take_action method out into each of the state classes and eliminate it from the state machine. My state machine should still behave the same way, but it favors creating more classes to additional whens in a case statement. Now, as long as the transitions between states are correct, I can call take_action within my run method and let each state class do what it's supposed to.

While I find this to be a very interesting pattern, I'm more surprised by my reaction to it. Before this apprenticeship and exposure to the SOLID principles, I would have just accepted that my code became unmanageable  That doesn't mean that I would have been alright with it. Most likely I would have tried to fix it, given up in disgust, and told myself that it's because I don't know what I'm doing. I probably would have taken a break from programming and tried to forget it ever happened. Before, if I had read the state pattern, it would have looked like needless complexity. Instead, I see it now as a way to continue using state machines without violating SOLID principles and leading me to more maintainable code.

Things feel different now. I can recognise when I'm going down a bad path. I know that there are ways to avoid it. Unfortunately, I sometimes realize this halfway down the bad path. There's still a long way to go before I know everything I need to. While that's only a subset of all knowledge and given how long it's taken me to get where I am, it's doubtful I'll ever know everything I should. I'm okay with that though. It just means I need to keep in mind how much farther there is to go.

Tuesday, April 30, 2013

A Dynamic Factory

During my last iteration, one of my stories was to implement a way to start a new game for my iOS/Java/Ruby hodgepodge of a Tic Tac Toe game. This meant that I would need to have my server respond to multiple commands.

At that point, the only command it responded to was to make a move. I would post a request with the body equal to something like "square=1" and it would make a move in square 1. I didn't think it would be much work to allow it to respond to another command, but I quickly noticed a problem. If I added an if statement to check the command I was sending, what would happen when I needed to add yet another command? This looked like a clear open/closed violation.

I struggled to find a solution. After a couple missteps, I almost decided to put off fixing the issue and just implement the if statement, delaying the decision. Thankfully I decided to talk to my mentor, who suggested using a factory. I was familiar this pattern, having used it in the past. This is what my factory looked like.

require "newgame_handler"
require "square_handler"

class RequestHandler
  def self.create(request)
    name = find_key(request)

    if name == "newgame"
      NewgameHandler.new
    else
      SquareHandler.new
    end
  end

  ...
end

For every command I needed, I could just create a new class. My factory did make it easier to add new commands to my server, but it still felt wrong. This solution didn't really conform to the open/closed principle. Whenever I needed to add a new command, I would need yet another if statement. I really wasn't thrilled at that prospect. When I brought this up with my mentor, he showed me a Ruby function called Module.const_get.

Module.const_get allows you to pull in a constant that is loaded and floating around while your Ruby program is running by specifying its name. What made this so useful in my situation is that classes are constants. So now, using this function, I could grab a reference to my NewgameHandler by passing const_get the string "NewgameHandler." This gave me a way out of wrestling with my potential if/else chain.

require "newgame_handler"
require "square_handler"

class RequestHandler
  def self.create(request)
    name = find_key(request)
    Module.const_get(format_name(name)).new
  end

  ...
end

Here is my class after another iteration. As it stands, it makes use of Ruby's Module.const_get method and is now a dynamic factory. It instantiates classes on the fly, based on the command sent, and uses those created handlers to process the game. I'm starting to sense a pattern though. Maybe you can see it too. I still haven't gotten away from explicitly modifying the class for every new command. The new wrinkle, that I didn't notice before, is that I still have to require the file that the class lives in.

After slightly more searching, I ended up with current solution. I was able to remove the explicit requires by requiring the files based on the command name.

require "nil_handler"

class RequestHandler
  def self.create(request)
    name = find_key(request)
    begin
      require "#{name}_handler"
      Module.const_get(format_name(name)).new
    rescue NameError, LoadError
      NilHandler.new
    end
  end

  def self.find_key(request)
    request["Body"].keys.first
  rescue
    ""
  end

  def self.format_name(name)
    name.length > 0 ? "#{name.capitalize}Handler" : ""
  end
end

This solution does have its drawbacks. What if I can't load the right file or try to get a constant that doesn't exist? That's why I added in a NilHandler that does nothing with the request. That way my server keeps chugging along when there's a load error or a name error. There are still some potential security concerns because this handler could instantiate a class that I wasn't ready for. The worst I can see happening though is my server crashing because the returned class doesn't respond to the same interface as the other handlers.

It's possible that this solution was a bit of overkill for two commands or that it was premature. While, I'm not entirely sure about either of those, I did think it was pretty cool.

Thursday, April 11, 2013

An Update (Because It's Probably Due)

It's been a rough week. I've learned a lot, but that doesn't diminish the frustration. Looking back, there are probably some shorter paths I could have taken, but that's easy to say now.

My first task was to get my iOS app set up for continuous building on Travis. Thankfully they recently added support for objective-c. The setup is really simple. You add a single line to the config specifying your language is objective-c. That went pretty quickly, as you would suspect. The next part didn't.

My first build gave me certificate errors when Travis tried to run xcodebuild. "That's weird," I said to myself. I was surprised because running my build locally was pretty smooth. So I tweaked something, committed, and error. Tweak, commit, error. Towards the end of the day, I found my issue.

It turns out that xcodebuild will use the specified version of the sdk you want and will try and build it for the device, which of course needs to be signed. The way around this is to specify iphonesimulator, and a version if you want, with the -sdk flag. I submitted an issue to Travis and in the meantime copied their script and modified it by hand.

That wasn't the only issue I had with Travis. My next issue was a linking error where it couldn't find libOCDSpec2.a and thus couldn't build my application. I should have gotten to the fix earlier. Thirty-five builds later, I had a working solution.

For some reason, xcodebuild was not finding and building the OCDSpec2 project, so that lib file wasn't being generated. I still don't know why, but there's a fix. I compiled the project manually and copied that file into my project and linked against that one. Problem solved, but if OCDSpec2 updates I'll have to repeat the process.

My second task was to add Fitnesse testing into my project. Thankfully Eric Meyer had templates for XCode made for this. I missed a crucial step when I cloned his project though. I forgot to clone the submodule. This lead to about an hour or two of trial and error before I realized something. The files that the template copied into my project were blank. Something was wrong. Thankfully adding the submodules fixed the issue pretty quickly.

I was able to complete all three stories for my ipm on Wednesday. Thankfully the spike of Franklin (my http server) and Tic-Tac-Toe played on an iOS app took less time than expected. During the meeting, I got my next batch of stories. End-to-end player vs player and a gameover message.

The player vs player story is what I'm struggling with right now. It feels gigantic. I have to wire up Franklin, TTT, and iOS with unit tests and Fitnesse tests. It sounds like a lot, at least to me, considering I'm relatively new to iOS. Today was spent trying to get the interface setup with a view and then I worked on how the iOS app would talk to the server. I made some progress there and hopefully once that's done it'll start falling into place.

If this post sounds a little upset, it's probably because it's been a frustrating week. For a majority of it, I fell like I've been fighting software instead of writing code. That started to change this afternoon though. Hopefully now that I've gotten all this out, I can continue making progress tomorrow. If nothing else, I'm going to try and be better about my estimates.

Thursday, April 4, 2013

Piecing It Together

Yesterday I was given my next assignment. I knew it was coming, but it still sounds like a lot. The goal is to hook my Tic-Tac-Toe game up to my new web server. Then I need to create an iOS client that can play a game over a network, and eventually the internet. There's a bit more that goes into it too. I need to do things like setting up a continuous build and passing FitNesse tests as well.

This week is mostly practice though. I have to see how much work I think it will take to get each of the pieces working together. I also need to take care of the continuous build and a few other setup odds and ends. Then the whole project can start being broken down into stories. This is going to be an interesting change because now there will be hard deadlines. There's a lot to learn to make this work, but it does sound interesting. And hey, I should have something I can run on my phone by the end of this.

I want to try and write some more specific posts about what I'm doing to make all of this work but I've first got to make it work.

Thursday, March 28, 2013

I is for...

I is for Interface Segregation Principle.

This principle states that nothing should be forced to depend on methods that it doesn't use.

To illustrate this suppose there were a humongous class that handled making sandwiches (humongous sandwiches?). Now, as everyone knows, there are many kinds of sandwiches. There are toasted ones, open-face ones, and even bread-less ones. And while I'm not here to judge each sandwich, the point is that there are many different sandwiches and they are not all made the same way. To have each sandwich hold a reference to how to make anything but itself is wasteful. The bread-less sandwiches, as the name implies, don't have bread, so why should they know how to toast a piece of it?

Instead, each sandwich should depend on a reference to a subset of the large sandwich making class. This means that changes to how toasted sandwiches are made doesn't affect the bread-less ones, unless they are somehow also being toasted. I don't know enough about the different kinds of sandwiches.

In my own code, the closest I can come to this is the responders in my http server. I know that I've used them before, but that's alright, I think. The responders implement a very small interface. In fact, there's only one method and it's called respond. That isn't the only method that each responder has though. Some of them require additional methods to process the request cleanly and avoid an overly large respond method.

If I had pushed those methods up into the responder interface, instead of keeping them in the responders that required them, I would have been in violation of this principle. The responders that didn't use those extra methods could have just returned null or done nothing, but that would have been an unexpected behavior for anything relying on my responder interface. I'm not sure what principles that violates, but it can't be a good thing to do.

Again, if you don't agree with my description of this principle, please let me know. Also, I'm hungry again.


D is for...

D is for Dependency Inversion Principle.

This principle states two things. The first is that "high-level modules should not depend on a low-level modules." Instead, "both should depend on abstractions." The second is that "abstractions should not depend on details." In fact, "details should depend upon abstractions." This is a principle that I thought I understood until I sat down to write this post. It seems I was getting it slightly confused with Dependency Injection.

The idea is that changes made to low-level modules should not ripple up and disturb the high-level modules resting on top of them. The high-level module should depend in an abstraction, like an interface, instead of on a specific implementation of a low-level module. There is no way to eliminate ripples of change, but they can be confined to a minimum number of modules.

I will again be referring to my http server in this example. I keep coming back to Java to explain these principles because they are much easier to see with explicit interfaces.

In my server, I have a router that holds all of the possible routes that a request can take. This lives inside of and was also initialized by my server class. In order to make my server more flexible, I passed the router (complete with routes) into the server when the server was created. This is where I confused inversion with injection. I had merely altered the order in which the server and router objects were created. For my server, as it stands, this is good enough.

In order to truly invert the dependency, I would need to define a router interface and use that in the server. The interface to the router would be a part of the server and changes to the router should not affect the interface. Doing this would allow my server to remain unchanged even if I substituted an entirely new router in. In fact, I may have to make this change in the future. I'll wait until a real need arises though.

I feel as though I may have still gotten this one wrong, so please correct me if I am mistaken.

Wednesday, March 27, 2013

L is for...

L is for Liskov Substitution Principle

This principle essentially states that for a class N and a subclass of N called O then O can be substituted for N without breaking the program. Following this principle can help a program respect the Open/Closed principle. For this post, I have two examples. One where I successfully followed this principle and another where I fell into a classic trap.

Let's start with success. This example is again my responders in my http server. All of the responders implement a responder interface. Because they all do this, they are each interchangeable with the responder interface. Java confirms this by letting me use the interface as a function argument and not exploding when I instead pass in a specific responder.

This does not mean that all I had to do to follow this principle was to implement an interface. I had sorta violated it during a small presentation I gave on code smells, though I didn't know it at the time. During that presentation, I said that a square and a rectangle shared enough class data to be derived from a common class. After all, a square is a rectangle, right?

Without knowing it, probably because I hadn't read PPP yet, I had fallen into a classic trap. Mathematically a square is a rectangle but not in terms of setting attributes on a class. A square really only has one attribute, so updating the width also updates the height. On a rectangle, those two attributes can be updated independently.

The problem comes when I want to pass a square into a function that takes a rectangle. What should I expect setting the height to do? If it were a rectangle, then setting the height would not change the width. For a square, changing one changes the other. The confusion here is evidence that the proposed relationship between a square and a rectangle violates the Liskov Substitution Principle. Let's hope I can avoid that mistake in the future.

O is for...

O is for Open/Closed Principle.

This principle states that classes, modules, functions, etc. should be "open for extension, but closed for modification." In order to add new functionality to the software, one should not have to change the existing code. One should only need to add the new code with the desired functionality.

One way this principle manifests is with interfaces. Defining an interface and using that, instead of the implementations directly, allows the code that uses the interface to remain unchanged when new implementations are added. This is much easier to visualize in Java, where interfaces are explicitly defined, than in Ruby.

An example of where I have used this principle in my code is in the responders in my Java http server. Credit must go to Rick for our talk that moved me in this direction. In my server, there is a responder interface that defines a single respond method, which all responders must implement. The respond method takes in a request and returns a response. Each responder processes the requests differently. This allows me to have a FileSystemResponder, a RedirectResponder, or any kind of responder I want.

Adding these new responders does not change my existing code. The code depends on the responder interface and, as long as that interface doesn't change, my code doesn't care what kind of new responder I add. Because of this, my server can be made to respond in a new way with relatively little work. If I didn't use the interface, then my server might be limited to responding in a single way or require code changes for every responder.

Following this principle has made my server much more flexible and easily extendable.


Tuesday, March 26, 2013

S is for...

This is the first of five posts about my foray into the SOLID principles. I decided to start with S, but later letters may be out of order.

S is for Single Responsibility Principle.

This principle states that there should be one reason for a class or module to change. While it sounds simple enough, I have violated this principle. Like most of my examples, this one comes from my Ruby Tic-Tac-Toe application. Specifically, it comes from an early implementation of my board class.

A long time ago (January), when I began building my game board I gave to it the ability to store the positions of player pieces. Then, when I needed to draw the board, I gave it the ability to convert itself into a formatted string to print to the console. Still later, I allowed it to check itself for winners or a draw so that I could see if the game should be over. All of this functionality was packed into a single class.

class Board
  # square methods

  def to_s
    # formatting code
  end

  def game_over?
    # rules checking
  end
end

Not only did I violate SRP, I did it twice in the same class. Actually, I'm sure there are a lot of other principles violated and designs mangled...but that's not the point of this. The good news is that adding features caused me to right this wrong before I was given reading on SRP.

The fix came when I was adding my Qt gui. The goal was to add another gui to my game while maintaining support for the console version. My console version benefited from the string representation of my board, but Qt (and probably ever other kind of gui) did not. I decided to move the string formatting into the console-only portion of my code. I can now see how bad this could have been. If Ruby were a compiled language, then every time my console representation changed all other versions would need to be recompiled. That doesn't sound efficient at all.

class Board
  # square methods

  def game_over?
    # rules checking
  end
end

class ConsolePresenter
  def self.format_board(board)
    # formatting code
  end
end

I forget exactly why, but I also moved the winner/draw checking code into its own rules class. I think I was in a cleaning mood and removing it made my board feel simpler. However that happened, I was left with a board that only kept track of the pieces on it. The only reason it would need to change in the future is if I decided to store the pieces in a different way.

class Board
  # square methods
end

class Rules
  def self.game_over?(board)
    # checking rules
  end
end

class ConsolePresenter
  def self.format_board(board)
    # formatting code
  end
end

I'm glad now for two reasons. The first is that I fixed my code. The second is that I understand why it was important that I fixed it. I'm going to be going back into that code soon and the easier it is to work with the better that's going to make my life.

Wednesday, March 20, 2013

Overdue

It's been a while since my last post and it feels like I've done a lot of work. My web server now can parse querystrings and has threading. I've almost completed all of cob spec. I feel like I know the test suite pretty well now after going over every section and updating it. Now all of the test configuration lives in one place and it's obvious for apprentices new to the project how to set the necessary paths. Another bonus is that all of the tests live in a single suite. They're subdivided so the the threaded ones don't need to be run if you only want the single threaded tests. All in all, it's an improvement. There's still work to be done though. I need to finish up passing the test that Rylan and I wrote today.

Oh, a note on threading. I've found that more threads don't mean better performance. My server seems to do better using one thread per cpu core than 50 threads. For my current laptop that means 2 threads. I found some code though that lets me detect how many cores the jvm has available. The line is Runtime.getRuntime().availableProcessors(). That way if I run the server on a computer with more cores, I can easily take advantage of that fact.

Tuesday, March 12, 2013

Cob Spec Woes

I've been making progress on my Java server. There is a little more refactoring to go for the latest feature I implemented. After that I've got one more feature to add and I've "finished" with the single threaded portion. Finished is in quotes because two of the tests are passing but not actually testing anything. The tests for simple put and post don't actually test what they're supposed to. I made them pass by serving up an empty file at the appropriate url. That doesn't sound like a great test.

It seems like my contribution to cob spec is not going to be an additional test. It is going to be fixing the broken tests that are currently there. That reminds me, I've also got to fix the multi-threaded portion of the tests. Then I can start on threading each request that comes in. I've got a lot of green tests but so much more work to do. It is interesting though because I've never had to dig into code that I didn't write so much before. It's a much different experience than only dealing with one's own code. There's also a much steeper learning curve.

Monday, March 4, 2013

Serving Images

Today I tried to finish up serving images up over my server. I had previously managed to read files into a byte array. Sending that over to the client was easy, but I had to route the request first. That turned out to be easier than I though. For now, I'm checking if the file exists and returning the appropriate response headers. If it doesn't, I return 404 header. One nice thing about reading everything into a byte array is that I don't have to do separate processing for text or images. So I am able to serve html files as well now.

I still haven't settled on how I want to handle 404s though. I can either do them as a file that is read or I can generate them in my server. Not sure which is better but I'm leaning towards files. That would allow me to specify two locations, a default and an override location. That would allow someone running my server to create their own custom messages.

Tomorrow looks to be finishing this up and probably moving on to directory responses. It seems a logical jump from serving files. I'll also be working on my presentation on code smells. I still need some good examples and I'm finding it hard to write code that it bad in the specific ways I want. Maybe something to do would be to look at old code that I wrote in college. That sounds scary though.

Thursday, February 28, 2013

Abstractions

Writing a decoupled program depends on abstractions. This allows objects to use another object without caring about the details of how it is implemented. When I began my apprenticeship, over a month ago, I didn't fully understand why this is so useful. I understood why a program should have a minimal number of dependencies but couldn't make the logical jump to why abstractions are so important.

One of the first steps in my Tic-Tac-Toe program was building the board class. It was a minimal class and I stored the individual squares as a 1D array. I exposed the squares array as a public, read-only variable. Thus my game class could simply look at the desired square and check if it was empty or get its value. There wasn't an square_empty? method because I had granted access to my array.

class Board
  attr_reader :squares

  def initialize
    @squares = Array.new(9)
  end

  def set_square(index, value)
    @squares[index] = value
  end
end

If I had wanted I could have gotten rid of set_square and replaced attr_reader with attr_accessor and the effect would have been the same. I was having an issue with this code though. My game presented options to the player for squares 1 through 9. My array indexes were 0 through 8. So when I made a move or checked a square, I had to remember to subtract 1 from the square index. This was annoying enough that I modified my set_square method to do that automatically.

class Board
  attr_reader :squares

  def initialize
    @squares = Array.new(9)
  end

  def set_square(index, value)
    @squares[index-1] = value
  end
end

This left me with nagging issue. When I checked if a square was empty, I needed to subtract 1 from the index but not when I made a move. I realized that this inconsistency was pointless and that the only solution was to remove attr_reader. It wasn't doing anything helpful and was in fact making my game harder to work with. So I added the necessary methods to my board to replace the missing functionality and had this.

class Board
  def initialize
    @squares = Array.new(9)
  end

  def set_square(index, value)
    @squares[index-1] = value
  end

  def empty_square?(index)
    @squares[index-1].empty?
  end

  def square(index)
    @squares[index-1]
  end
end

Initially, this felt less efficient. After all, there are more lines of code doing the same functions as before. The immediate benefit I saw was that I no longer had to worry about subtracting 1 from the square index in my game class. The second benefit I didn't notice until later. This third version of my board allowed me to store the squares any way I saw fit. I could create any data structure I wanted for them. I could put them in a linked list, a hash, or even an array of square objects. This is where the usefulness of abstractions became clear to me. No matter how stored the squares now, it would not affect my game class. All I had to do was provide an interface to work with and I could store my squares on a computer at the South Pole and retrieve them over a network if I wanted.

This is a fairly simple example but I think it demonstrates the flexibility that abstractions allow. At the beginning of this project, I didn't understand why the flexibility mattered. I saw it as unnecessarily long code. It was only after a couple redesigns and multiple refactorings that I saw the benefits to me. It allowed me to make changes to how a class worked without affecting other classes that used it. It amazes me that I didn't see how useful this was at first. I guess that's one benefit of doing this apprenticeship.

Monday, February 25, 2013

Working Upward

Today was spent rewriting my mocks for testing sockets and server sockets. I've gotten them to a place where I think they're actually going to be useful for testing. Furthermore, I've put them in their own little wrappers. It's finally sinking in why wrapping is a good idea. Now my server won't care if I'm using fake sockets or the real deal. It should just do what it's supposed to do. My goal for tomorrow is to actually make it do the first part of what it should do.  It sounds like a huge jump, but really it shouldn't be bad. It's been really great to be working on this project at the same time as other apprentices. I've actually seen and helped solve problems that I'll encounter down the line. So yay for that, I guess. Anyway, we'll see what I can really do tomorrow.

Thursday, February 21, 2013

A New Project

I'm finally finished with Tic-Tac-Toe (even though I know I'm not). The good news is that I'm finished for now. I'll be revisiting this in the future, but for now I'm on to something new. Yesterday I started on my Java Http Server. Most of my time was not spent working on the server though. My first task was to make Rubyslim run on 1.9.3. Then I needed to update the internal test suite for Http Servers to 1.9.3 and make it work with the update to Rubyslim.

The first didn't take nearly as long as I expected. Updating the test suite was more work than I thought. Getting it to run on 1.9.3 and hooking in the new version of Rubyslim didn't take that long, but I had a new problem. The issue was that none of the tests were running. I don't mean that they were failing. I mean that they didn't even attempt to run. I eventually figured out that the configuration for the tests was outdated and managed to centralize and update it. So now instead of each test having its own config, that lives at the suite level. That occupied a good portion of my day.

I'm still trying to figure out where to start with the server. There are a lot of pieces that will need to be built, but aren't necessary now. I was happy that I was able to spike out a quick section of code and got a single test to run and pass in the test suite. The goal tomorrow will be to rebuild that code while writing tests. That's going to take some thought.

Monday, February 18, 2013

Almost But Not Quite Done

Today I spent most of my time cleaning up my Tic-Tac-Toe code and adding tests in a few areas that were lacking. I was feeling pretty confident until I said I was done. Then I hadn't added a Gemfile. Then it was missing version numbers and I needed a .rvmrc file as well. Oh, and hey, the Qt version keeps not letting the player make a move. To explain how this happened, let me say that the Qt version doesn't lend itself to testing (at least not in a way that I know of). This illustrates what a dangerous world it is without tests to back up assertions.

In the end, I finished everything except the Qt issue. That has to do with wanting to lock the board when it's not a human player's turn and then unlocking it when it is. The real problem I have with this is that I'm not even sure if it's necessary, but I have no way to accurately test it. So tomorrow, I'm going to remove the locking and see if anyone can break my game. If not, then the locking is probably not necessary.

Thursday, February 14, 2013

The (Hopefully) Last Bits

Everything seems to be coming together with my Tic-Tac-Toe app. I've gotten the command line worked out with the new way of handling player input. There's now a real runner living in between the game and the gui, which handles all the action. I was even able to spike out the Qt portion and get that running. As penance for horrible, untested code, I threw out what I wrote and intend to implement it for real tomorrow.

Surprisingly I'm on track to meet my estimate for this phase. I have a feeling more little issues will crop up to delay me though. They always do. This evening I had a vexing issue where I was accidentally breaking one test with another. The weird thing was that it was in another file. That turned out to be a difficult thing to track down. Now, I have an idea of where to head next. That's what's important.

Monday, February 11, 2013

Qt For Real

This weekend I managed to bring the console version of my Tic-Tac-Toe app back to life. It probably spent a little bit too long in pieces, but it is what it is. Still a little bit of work to go, but hopefully not to bad. Doing this allowed me to focus on the Qt portion of my app today. Thankfully the refactoring I did to my game made it really easy to make a window and make it so I could click and place moves on the board. That part was surprisingly easy. I think this just means that the rest of the program will take me a while. We'll see.

I spent this evening investigation dialog boxes. It looks deceptively easy to get a dialog box to come up and then return the value you want. I think the trick will be writing a custom dialog box. None of the built in ones seemed to use radio buttons. I suppose that I could use a pair of select dropdowns if I have to. I think this is it for tonight though. I've had enough for one day.

Friday, February 8, 2013

It Never Ends

This week has been quite busy. I don't think I've put this much work in for a while. That's why I declared Wednesday night a no work time. Thursday was back to work as usual on Tic Tac Toe. I was still having trouble with a circular dependency. After speaking with a craftsman, I was given an idea how to remove it. An interesting side effect of this change was that a whole file or two disappeared. The feeling of being able to get rid of code without losing functionality is a good feeling.

There is still a lot of work to do. I still haven't made any progress on the Qt version of my game. My mentor and I tried to find some solutions to my block today. This involved a white board, time, and a lot of convoluted drawings. I've got a couple ideas now though. My goal is to try and implement them this weekend so that I can start on the Qt version next week. I also need to spend some time with Rylan and rewrite our broker software. There's always more to do.

Tuesday, February 5, 2013

Oodles and Oodles of Rindlets

Wow, I've been exhausted lately. This weekend was pretty much a blur. I spent most of each day working on my Tic Tac Toe program. I pulled it apart and fit the pieces back together again. It allowed me to remove several unnecessary files and to reorganize things so that something can drive the game, instead of it driving itself. I feel like it will be easier to add the Qt stuff on top of what I currently have. I'm still trying to solve my command line issues though. I haven't worked out how to do player selection or how the driver will actually run the game.

Rindlets are the reason why I'm still at this point by Tuesday evening. The apprentice assignment this week has been very interesting but it's also a lot of work. There's so much wiring that has to go on to be able to make a stock purchase and then confirm it. There was a problem with confirmations and it was that they didn't exist until this morning. Rylan and I were asked to come in early to help Paul write some of the project code. It's really interesting seeing how people with more experience think about and write tests. I've still got so far to go.

While this morning was interesting, more issues kept cropping up. Necessary information was still missing from commands. When we talked to Paul about this, the response was, "Can you write it?" That was cool, but it felt like a lot of responsibility. It also meant that Rylan and I didn't get very far on our own stock broker today. Thankfully tomorrow seems to be a trial run. Still, I learned how to do a pull request on github. More importantly I learned the embarrassment that comes with not running tests before committing. I still can't believe that we actually submitted a pull request to master before we ran tests. I'm going to chalk that one up to the learning process. It's something that I do not intend to repeat on a shared project.

Anyway, I'm really tired right now. I think it's time for some rest. There's more work to do, but I'm not in a condition to do a good job. At least not right away.

Wednesday, January 30, 2013

Qt

Yesterday I settled on using Qt to build the gui version of my Tic-Tac-Toe app. There's still some weirdness because all the documentation is written in c++, but that's not really an issue. The problem I'm starting to see is that my app is not really built with a gui in mind. It works just fine as a console application. The game runs and asks for input or prints output whenever it needs to. With the gui, I need a way to "drive" the game. I think I need to be able to say, "Ok, the gui's ready. Now take a turn game. Oh and here's some input because it's a human player's turn." This is conjecture right now because I'm still trying to design the gui and figure out how to make Qt do what I want.

I had intended to spend today working on that, but plans changed. This morning I got pulled into helping prepare for the apprentice class. At first I wasn't sure what I was getting myself into, but it was actually really interesting. The project is an extension of the last homework in that it still deals with the stock market. Instead of posting prices to a stock exchange, the stocks put their prices into a tuplespace server. The server holds on to these lists of data and hands them out to whoever requests them. The idea is that an arbitrary number of things can all operate in different processes using the data and not get in anyone's way. The really fun part about this is that the project is a sort of competition for which pair can make the most money once the project is due. It's going to be interesting to see all the different strategies.

Monday, January 28, 2013

Oh, GUIs

I managed to add in a menu system to my Tic-Tac-Toe program on Friday. It was rudimentary. There was a prompt for each player and the user could select Human, Dumb Ai, or Smart AI. Simple, but it got the job done.

This morning, I turned my io class into a wrapper for something that will actually do the input/output. This allows me to pass in an object like StringIO for a test when I want output to essentially go nowhere and Kernel when I want it to go to the command line.

My hope was that this would allow me to easily pass in some sort of gui object and I'd be off and running. That would imply that I easily selected a gui library. I didn't. There seemed to be roadblock after roadblock. This one was poorly maintained or that one wasn't documented or another didn't work on macs right now. Maybe tomorrow I'll have better luck.

Thursday, January 24, 2013

Refactoring

I spent a lot of today refactoring my Tic Tac Toe program. There's something very satisfying about optimization. Most of what I did was to make it easier to implement the controls that will select what kinds of players are added to the game. The player and ai are now the same class. The difference is in what strategy they use to make their moves. A human will use an input strategy. An ai player uses a dumb strategy or negamax. There could be other strategies in the future. Things were going smoothly until I got to adding the new code. Then I stalled. I know what I need to do, but I'm having trouble taking the first steps. With everything that I've learned so far, this means that I'm trying to take too big of a step. Hopefully I can work this out tomorrow.

Wednesday, January 23, 2013

Now Do This

So, this phase of my Tic-Tac-Toe project is complete. I can't say how long I'm going to have to continue with this game but it's going to be long time. The image I got was that I will never want to play this game again by the end. Oh well, at least I'm learning.

I was given my next two assignments. Add support for choosing players and easy/hard ai and add a gui while still supporting the command line. I started on the first part by doing some necessary refactoring. My program is improving, but until I work out some issues it isn't working as expected yet. Hopefully the first assignment doesn't take me too long. In the meantime, I need to investigate some graphical frameworks.

Tuesday, January 22, 2013

Relative Depth

There isn't much to say about today. I fixed a few problems with my code. One of them was to prioritize winning moves that take fewer steps over ones that take more. This required a surprisingly trivial modification to my negamax algorithm. That's great when you don't make any typos. It cost me at least half an hour of frantic searching this evening to figure out how I could have improperly done negamax. In the end, it was because of an equals sign in a function call.

I also completed a test to run all possible player moves and make sure my ai is unbeatable. I'm pretty confident that it works. It worries me that it only executes about 1400 moves. I guess that's right though because the ai should never lose and that cuts out a ton of possible outcomes. As I said, I'm confident but not too confident.

Monday, January 21, 2013

A New Day

Today was mostly spent refining. I made a few modifications to my ai's get_move function to cut down on the time spent computing moves. For an empty board it could take ten to fifteen seconds to calculate a move. After adding a few shortcuts, it doesn't take more than two or three seconds to get any single move. I also added some much needed gui messages. Now it prints whose turn it is and a winner at the end. Before the game was a little confusing to play if you weren't used to it. One thing I want to work on next is seeing if I can't get the AI to play for a larger board. I tried running negamax for a 4x4 board but after twenty minutes it hadn't returned any results. This isn't a requirement, just something I'm curious about.

There was also a new apprentice event today. We met for a talk and afterwards were given a small pair homework assignment. The topic today was the observer pattern. The homework is to implement a stock that is held by a stock exchange and is reported on by a stock ticker. Whenever the stock updates its price, it sends a message to anything watching it and then goes about its business. The idea is that what is watching never has to ask for an update. These events seem like they'll be fun and a good way to work on stuff with the other apprentices.

Sunday, January 20, 2013

Catching Up

So far I haven't been good about daily updates. This is my attempt to catch up on the last week-ish of progress. The timeline for events might be a little off because I'm doing this late. I guess it's more incentive to keep on top of this.

Tuesday - I'd been having trouble figuring out how to implement my main game loop "run". I couldn't think of how to test it. I thought about it for a while but rather than end up wasting too much time I asked Brian. He explained that I shouldn't be testing the implementation of the code. Instead I should be testing the behavior. With that in mind, I wrote tests for and implemented a game_over? function. My test for the main game loop then became "is game_over? true when run is finished?".

Wednesday - At this point I could check that the game was over but not who won. To fix this, I extracted the winner checking code and put in a function called winner. This simplified things a little. My next task was to implement a simple AI player. This required changing my Player class to implement a method called get_move. This allowed me to have the game ask the current player for their move regardless of whether it is a human or the computer.

Thursday - I finished the AI player and was told to make it smarter. There was a specific way I was supposed to make it smarter. I needed to implement the Minimax algorithm. To do that, I first needed to understand it. This required most of my time on Thursday. Looking back, I honestly didn't get it. I couldn't understand how to test it and still hadn't figured out how it worked on a low level by the end of the day. Now it seems so simple. Essentially it checks every possible move combination on the current board and scores it. The goal is to find the move or moves that give the AI the best move that is the worst for the opponent. In Tic-Tac-Toe this translates into if two AI players use this and play against each other then they will always draw.

Friday - I was still having trouble with the Minimax. My mentor recommended looking at the Negamax implementation of Minimax because it is simpler and only involves one function call. I asked a few other apprentices how they had tested it and didn't really make any real progress. This was frustrating because Wikipedia outlines the algorithm in easy to implement pseudo-code but has not advice for implementing it with TDD.

Weekend - I finally started to make some progress. I wrote some sample boards and checked the score that came back from Negamax. It took a while to get this right because I was still having some trouble with understanding how to implement it. I'd given up trying to test it and implement it piece by piece though. Without help, I just couldn't do it. After some web searching though, I came across the vital clue to what I was doing wrong. I needed to take the negative of the result I got out of Negamax. After that, I could no longer beat the AI on my command line interface. This was good, but I still needed tests. In the end, I tested that the function returned the correct move/moves in a number of specific situations. Hopefully that's what I was supposed to do and that I won't get in trouble for doing my TDD a bit backwards this time.

Anyway, two things to take away from this post for me.

  1. Write these on time so that I don't have so much work to do.
  2. I keep trying to enter Vim shortcuts into this web interface, so they must be sinking in.

Monday, January 14, 2013

Being Professional

Friday I received my first reading assignment. It was The Clean Coder. It wasn't a very long book, but I feel like it had a lot to say. Honestly, it was intimidating. The requirements laid out in the book for being a professional are very strict. Things like always taking responsibility for mistakes and time management don't seem too bad at first. When you add in how to say yes or no, how to estimate a project's time, and communicating clearly with other people it was all pretty heavy. I found myself agreeing with most of the requirements but I don't know how I could live up to all of them right now. I think that the book is best taken as a goal that you will never achieve. At least there's something to work towards.

On the Tic-Tac-Toe front, I've still been trying to get the game into a playable state. This means handling input, drawing the board, handling win/draw conditions, and then tying them all together. I've gotten the first two working and have already figured out how to check for a win/draw. I need to write the tests and then the code. I was a little stuck today because I was focusing on how to test the main game loop. The problem was that what terminates the game loop is a game over condition and I didn't have anything that would generate that. So after some trial and error, I changed course and began checking win/draw. I am happy because I figured out a way to check all the necessary combinations for a win with a formula. That way it works if I want to play on a 4x4 board. No such luck in 3d, but that's ok. I'd be worried if it somehow worked.

Thursday, January 10, 2013

Slow Progress

Today marked day two of my apprenticeship. My goal was the same, continue working on my Tic-Tac-Toe program. I had made some progress the previous day but moving forward felt sluggish. Trying to write code using TDD feels like a barrier has been erected between my brain and the computer. It's probably bad practice, but my normal approach to coding has been to put down some code, play with it, tweak it, and ultimately keep it or reject it. The necessity of writing a test first causes me to try to think of a test for code that hasn't been conceived yet. This leads to blockage.

During my morning meeting with my mentor, I explained some of this and he reminded me that I can still design the software first. I had somehow forgotten about this in my focus on writing a test first. Tests are important but they have to come from somewhere. A design is a logical origin. It's funny though, as much as I enjoy using computers for tasks, it's so much more enjoyable to draw a design on paper.

Perhaps another reason work felt slow was because I am still getting comfortable working in vim. Most of my previous programming work has been in GUI-based text editors and IDEs. I've used vim before but mostly for editing a Linux config file or two. Right now it's taking some getting used to. I keep hitting the wrong keys or have to think for a moment about what I want to do. Today was easier than yesterday, so here's hoping that feeling continues. I still don't have a strong opinion on the benefits of vim, but after seeing how many people in the office use a console editor, I feel it might make working with them easier.

As for progress on my program, the game creates a board and two players. The players can make moves on the board, but only the first player. I haven't added rotating turns yet or win/lose conditions or a whole bunch of things. I'm not sure I like where I've put getting the input. Right now console input is read in the Player class. Thinking about it though, the game doesn't care which player is typing the input or where the input is coming from. It just wants input. I should probably write a more generic get_input function for the game class that takes a prompt and returns the input. Still have to deal with invalid selections and quitting the game, but I'm not going to worry about that at this hour. At least I have an idea of where to start tomorrow.

Wednesday, January 9, 2013

Day 1

My first day at 8th Light was pleasant. After some initial setup, I was given my first task. Write a Tic-Tac-Toe game from scratch using TDD. Not earth-shattering, but still challenging. Thinking in terms of TDD doesn't come naturally right now. Thus progress was slow. I started by building the board and working from the bottom up. After some trouble, my mentor advised me that it might be easier to start from the top and work on making a move. Perhaps a different perspective on the problem will help.

The day ended the same as it began, with a handshake. I learned that everyone is expected to shake hands when they arrive in the morning and leave in the evening. I wasn't sure what to think of this. It seems like a small gesture. Thinking about it now, it marked a distinct beginning and end to the day and set a friendly tone in the office. It will also force me to learn everyone's name, something I should be better at.