Friday, May 27, 2011

Writing a Java HTTP Server from scratch

During my second week at 8th Light I was asked to create an HTTP Server to serve TTT games to remote players. That being said, it really had nothing to do with playing TTT, which is a good thing, since the code was architecturally sound enough to place the game logic in a Package named TTTGame and create an independent package named TTTServer. The two packages only cross paths on one occasion, in an abstract class to integrate game logic and web requests.

About five minutes into development I stumbled upon the holy grail, the Sun class com.sun.httpserver. I could bind paths and verbs in different combinations to different handler classes (similar to Rails). Of course, my joy was killed and I was told not to use this class. I had to go forward and build the server from the bottom up.

I started with the essentials (this is Agile after all, I need to build iteratively out from the core). I had experience with Socket programming, although it was a little hazy. So I setup a Server class to wrap around a Server Socket and dish out new Client Sockets as they come in. This was easy enough. From here, I started to run into problems. My experience with Socket programming was to leave a connection open, send data, and close the Socket. Well, this doesn't work for HTTP. I had some learning to do. Namely, I need to learn about HTTP packets and a little refresher on rendering HTML.

The majority of this week was then spent building a Packet class and a Packet Parser class. Initially, I was attempting to build the Packet Parser in a laborious line-by-line fashion. This had to go, it was too painful to write and too ugly to use. Paul put me on the right path, at this point, by implementing the parser recursively. Not only did the LOC drop dramatically, but the class experienced a speed up (which is important with the potential for huge amounts of HTTP packets flying to and from in short amounts of time). I created a utility program to chart the two styles of parsing side by side.


I then wrote my Packet class to nicely integrate with the Parser and voila (as the French say) I had the groundwork of an HTTP Server. Now, I need to add routes based on path (throwing 404 errors when a path isn't valid), and integrating the game logic so a remote user can play.

Finally, the last item on my list of things to do is generate a Session Key for each user on my end and have the user then pass the key in to play their unique game (since we can not keep the Socket connection open throughout the entirety of the game).

Hopefully, I will have a hand made HTTP Java Server up and running in the near future.

Friday, May 20, 2011

Week one at 8th Light

When I first wrote my Tic-Tac-Toe application I tried to create working code and that was all. I didn't make any piece reusable, I didn't make my code flexible, I didn't write unit tests, and I didn't separate concerns. My computer player algorithm was brute force and worked only after too much prayer and cursing. If someone else were asked to work on the code without me being there they would probably first rip out their hair and then rewrite it. When I started, on my first day, my first task was to work with the code I had already written and I became nervous. I had to write unit tests for my working Tic-Tac-Toe. I wrote the JUnit tests in Eclipse and when Eclipse complained too much I switched to Intellij and found my new favorite Java IDE. After my tests passed it was time to re-factor.

This is when I did myself a favor and started over from scratch. I went through and implemented all the components of a Tic-Tac-Toe game (board, game rules, game logic, etc). I made a mistake in extending Board in Game for code reuse. Paul advised me to change this to a has-a relationship and went into SOL of the SOLID principles. Everything was going well and looked much cleaner.

This time around I also did strict TDD, which I had never done before. In school I typically write my code and then write tests to pass after the fact. This, I have learned, makes some people cringe. The reason my code was so clean was in part due to TDD and in part due to thinking about architecture more in depth before beginning. Regardless, clean and well written tests during TDD are invaluable to catching little bugs that blow up as the project grows.

Then it came time to make Tic-Tac-Toe players. I was told to write the Players in a way that I could drop in Players to square off, Human vs. AI, Human vs. Human, and AI vs. AI. Since I was coding this project in Java I just made a Player Interface to hold player number and return the x, y coordinates of their move when given the board state. I wrote an adapter for my brute force algorithm and a human player. I was able to drop them both in and have them play out Tic-Tac-Toe games. Then came the toughest part of the project, writing an AI player who picks their move based of a minimax implementation. This was a recursive mess when I first dove in. I developed my own TreeNode data structure (since Java Collections doesn't have trees) and tried to store each possible board state as a TreeNode. After getting essentially no where when doing this I decided to try again. Thankfully, Eric Meyer delivered a minimax lesson for all of the apprentices. Finally, I had a working AI player which used minimax.

During the second half of the week Doug introduced myself and two other apprentices to Fitnesse accepting testing framework. We're currently working through Java Fitnesse tutorials using Slim with the final goal being an Objective-C implementation. That's where I'm at now, at the end of the first week.