June 1, 2009 at 9:50 pm (Scala, Week 11) (, , , )

After Caleb and I finished setting up a Slicehost account for a site we’d worked on, Micah met with me to talk about my apprenticeship challenges. I have three major projects to complete by the end of next week: a presentation at this coming Friday’s Lunch & Learn, an article on something I’d learned recently as part of my apprenticeship (more formal and expert-level than posts on this blog), and another version of Tic-Tac-Toe, this time in a language I’d never used before. After a bit of waffling on my part among Clojure, C++, Objective-C, and Scala, I finally settled on Scala.

I’d attended Dean Wampler’s excellent talk at this past weekend’s Chicago Code Camp, so I had some basic syntax knowledge coming in, and there are a lot of similarities to Java. But I thought I should spend some time getting a decent handle on the basics of the language before diving into Tic-Tac-Toe. I discovered what looks like the best test framework for Scala: ScalaTest. It’s pretty nifty, allowing several styles of testing, including one that looks suspiciously like RSpec. There’s also an IntelliJ plugin for Scala, which works well. Since I’m still getting the hang of all of IntelliJ’s features and options, it did take me awhile to get the IDE set up to run tests and write code, but by the end of the afternoon, I had my first failing test.

Things were pretty slow going since I was having to look up basic syntax at first, but I’m already seeing some really cool things in Scala. For one thing, I can mix functional and object-oriented ideas in the same program. It’s hard for me to think about things like a Board outside of an object-oriented space, which makes Scheme difficult for me (so far), but Scala deals with classes and objects without problems. My first implementation code (on the board class) looked basically like Java with a weird syntax and a fancy & functional map method:

def full: Boolean = { =>
     if(position == null)
       return false
   return true

And I thought this was pretty concise, so I was fairly proud. But I did some reading later this evening, and now I’m really psyched about the refactoring Scala allowed me to do:

def full: Boolean = {
  !positions.exists(_ == null)

This seems more like Ruby, but with a really beefed-up version of the Symbol#to_proc syntax that we get with Rails (1.1+) or Ruby 1.9. Nice, right?

Permalink 2 Comments

The big dummy moment and first remote pairing

May 19, 2009 at 8:47 pm (Java, Javascript, Ruby, Week 9) (, , , , , , , , )

This morning I finished up most of a task from our biggest story, with some pointers from Micah. The big dummy moment came at the end of the morning, when I spent about an hour debugging why Javascript wasn’t working properly in our customized Webkit browser, and after going through everything I could think of, I realized that the browser had cached the Javascript file! Ack. So, my choices were to figure out where the cache was and clear it, or to do what Rails has always done for me behind the scenes to prevent caching: append a question mark and a big number to the filename. We’re using Sinatra, so I wrote a simple helper that does the latter:

def no_cache

Pretty simple, but I’m not sure I like the way it looks tacked onto the end of the filename in the Erb templates; that may need to change to take a parameter…

I spent a little time in the afternoon working on a JRuby bug that the JRuby team posted on their Twitter feed. The problem was with Array#pack, which I’d never used before (and quite honestly, still don’t entirely understand). It takes a formatting string and packs an array into a string. There was a problem when the asterisk (*) was used in a format string like “A4N*” – it’s supposed to take all the rest of the parameters from the string, but it was taking too few. I tracked it down to a change in value of a local variable (listSize). It was hard to spot, because I wouldn’t have expected the list size to change, so I wasn’t looking for that. Lots of System.out.println’s and compiling ensued. It really gave me an appreciation for Ruby’s interpreted nature. I’m sure there’s a way I could’ve streamlined things, but it was taking me 30 seconds to build the project each time, which is an eternity when you’re just debugging and adding print statements (and especially if you’re not too sure of what you’re looking for).

Micah and I did some remote pairing in the late afternoon, which I’d never done. We used iChat, which was really pretty awesome. We had some problems with audio volume and crashy programs, but all in all, I think it was pretty successful. Micah came up with a new data structure to eliminate some network traffic in our application, and we implemented it, simplifying code and adding a feature along the way. This was code I hadn’t seen before, but it felt a bit easier to get around – partly because it’s just simpler, and (hopefully) partly because I’m getting better.

Permalink Leave a Comment

More fun with JRuby (but for real this time)

May 14, 2009 at 10:19 pm (Java, Ruby, Week 8) (, , , , , )

Well, I knew I would see some benefits from my seemingly unproductive work yesterday, but I didn’t imagine that I’d be able to have a patch together today. It turned out that with the knowledge I gained yesterday, along with some smarter strategies, I was able to fix the issue with spaces in directories housing jarred gems that was haunting me. It wasn’t easy, but I tracked my way through the JRuby source and submitted a tested patch to the JRuby issue tracker. We’ll see; maybe it’ll get accepted, or maybe there’s something I haven’t thought of that’ll hold it back. Either way, I gained a lot of confidence, and I’m excited about taking up Charles Nutter’s call to fix RubySpecs in JRuby. Very timely!

I was also in on some meetings with the rest of the development team Micah and Doug are working with. They’re based remotely (Doug just flew back into town after working onsite with them), so we did some teleconferencing using Skype for video chat and Adobe Connect for screen sharing. It’s pretty amazing technology, and while I can’t discount the great value you see from working side-by-side all the time, I’m impressed that it’s so easy.

Micah and I did some CSS and Javascript (JQuery) work towards the end of the day. He’s not a fan of the CSS float attribute, so I had to convince him that it was worthwhile for the layout we were working with. Of course, there are generally multiple options, this case included, but I think we ended up with a good starting point for a screen we were laying out. JQuery’s AJAX capability is pretty awesome. We used JQuery.getScript(), which fetches a script from a URL and then loads and executes it (with an optional extra function parameter to run afterwards). It basically does the work that we would’ve had RJS do in a Rails application, but it seems much cleaner to me. We still have some thinking to do about how the performance is going to be in our particular case (1 web request per second will almost certainly be too heavyweight), but it’s a great start. The other big question mark for our current task is to what extent we’ll be able to test it. Luckily, resident TDD Javascript expert Jim Suchy is going to help us out with that. Thanks Jim 😉

Permalink Leave a Comment

Crazy Java/Windows problem and some Scheming

May 12, 2009 at 8:34 pm (Java, Limelight, Ruby, Scheme, Week 8) (, , , , , )

As soon as I came in this morning, Micah asked for my help with a bug he’d been working on tracking down in some Java JNA code in the Limelight source. The gist of the code is that it was calling some native code in Windows DLLs, and about half the time, one of the API hooks didn’t get properly installed. We looked and looked, eventually doing some print statements looking for threading issues and other possibilities. Take a look at the code and see if you can spot the problem:

new Thread()
  public void run()
    W32API.HINSTANCE appInstance = Kernel32.INSTANCE.GetModuleHandle(null);
    final User32.HHOOK keystrokeHook = User32.INSTANCE.SetWindowsHookEx(User32.WH_KEYBOARD_LL, new KeyboardHandler(), appInstance, 0);
    hookThreadId = Kernel32.INSTANCE.GetCurrentThreadId();

Well, if you knew right away that the new KeyboardHandler() might sometimes get garbage collected before the Windows code gets around to calling it, then you’re lying. Just kidding! I am very impressed if so. Once we looked back on the problem, we could see how the problem might have happened, but it was really bizarre. The idea is that because we don’t hold onto a reference to the new KeyboardHandler() that we create, the garbage collector could think we’re all done with it, even though the Windows code really needs to hold onto it. We didn’t look in depth into how JNA translates the Java code into native Windows code, but Micah understands it, and I think he said it passes a function pointer to the Windows code in this case, so when Windows tries to callback to our Java code residing in that pointer, that code is no longer there. Wacky.

We also made an installer using install4j, which seemed really easy. I’m not sure how much setup Micah had already done, but we were able to drop in some custom icons and a splash screen really easily for our application, and it looks good on both Mac and Windows. I did my first work in Photoshop CS 3, and it was weird not so have the Save Optimized As.. option that I’m used to from Photoshop/ImageReady CS.

I spent some time this afternoon practicing recursion by writing methods to identify palindromes. I did it in Scheme, Ruby, and Java (in that order), all TDD, all in different editors. Of course, Ruby was the easiest and clearest by the end (negative array indexing helped out!), but Scheme wasn’t as hard as I’d expected. Things may be getting easier!

By the way, if anyone else is going through SICP and feeling like you need some more interesting assignments than reading the online book and watching the lectures, check out the sample programming assignments on the website. Even the first one (Exercise 11) might blow your mind if you’re like me and not so used to functional programming.

Here’s a taste:

(define foo6
  (lambda (x)
    (x (lambda (y) (y y))))

Give a Curried application of foo6 that evaluates to 3. Keep in mind this means that at some point you have to evaluate an expression which is a function applied to itself! Yikes. I’ll post my solution later, if anybody’s interested, but I don’t want to give it away too easily. I probably spent a good hour thinking this last one over, and learned to think in a different way in the process.

I need to find a new way of embedding code in this blog. Since it’s hosted on WordPress, I can’t include Javascript embeds of a Gist or Pastie, and I also don’t really have control over the styling. Any suggestions?

Permalink 1 Comment

Some Limelight refactoring and Java learning

May 10, 2009 at 10:33 pm (Java, Limelight, Week 7) (, , , , )

Micah and I paired most of the day on Friday on adding a kiosk mode to Limelight. Since the codebase is a mix of Java and Ruby, we were moving back and forth between the two languages (and JUnit/RSpec), but our changes were mostly in Java. There weren’t really too many big surprises along the way, and we worked incrementally enough that, in most cases, I was able to figure out what kind of tests to write. Of course, I did get stumped a few times, but rather than just write the tests himself (which I know he could’ve done in a few seconds), Micah helped me to see the bigger picture of what exactly we were trying to test, and the tests themselves came soon enough after that.

Our Friday Lunch & Learn went in a very different direction than usual – we took a little field trip out to the movie theater and caught the new Star Trek movie. Good stuff; I recommend it!

This weekend, I’ve been finishing up reading the book I’m reviewing, and I’m really enjoying that. It’ll be a good read when it’s done, and it’s already really interesting and helpful (it’s on agile coaching). The other book I’m working on is Thinking in Java by Bruce Eckel. I’ve been pecking at Java since I arrived in March, but I feel like I’d be much better off armed with a more solid understanding of the language, like I have with Ruby. This book is great. I have it checked out from the library right now, but I may actually still end up buying it just because it clarifies so many things. One particular thing I loved when reading this morning Eckel’s coverage of polymorphism, edge cases where you might expect late binding but don’t get it, and the fact that you shouldn’t encounter these edge cases often because there are better ways to design your code. I’m reading in this book a lot of the same OO design principles I read and hear about everywhere else, but with different words, which kind of hammers it home even more.

I watched Uncle Bob’s RailsConf keynote and enjoyed it. I know that a few have pooh-poohed the talk (though many more loved it), and I do agree that the tongue-in-cheek testosterone / estrogen metaphor is outdated, but who can disagree with the crux of his argument? We should drive development with tests, have some humility, and take on tough problems like legacy codebases. Being a professional means different things to different people (one of Uncle Bob’s descriptions), but to most it means you’re good at what you do and that you’re serious about being good (but not necessarily serious about yourself and wearing a 3-piece suit all the time; that’s an entirely different meaning).

Well-tested code means you don’t have to be afraid of change. I worked on a larger project on my last job that took forever to change, because there were virtually no tests. Any change I made to the code (and on any big project, there are plenty of changes) meant I risked breakage. Luckily, the code wasn’t hammered by users or mission-critical, but it is so embarrassing to have bugs in your code, especially when they’re discovered by the client. If I had the skills at the time to get more of that project under test (and I have a good idea of what to do thanks to my apprenticeship experience so far, along with Michael Feathers’ book), things would have gone differently. Changes might not have been that much easier just because of the tests (there are also OO design issues to consider), but they would have been verifiable. I would have known when I had it right.

Permalink Leave a Comment

Prime factors and the first client project

May 6, 2009 at 6:34 pm (Flex, Java, Limelight, Ruby, Scheme, Week 7) (, , , , , , )

I worked with Doug almost the whole day today, which was great. This morning when I came in, I happened to mention that last night, I’d done the prime factors kata, inspired by tweets from Doug and Caleb, but I used Scheme: the results are in a Gist. It was pretty frustrating trying to do this in a functional style, purposefully avoiding defining anything other than functions, but I sure learned how poorly I understood Scheme’s list-building constructs (cons, cdr, and car). I have a feeling there are clearer ways to do this, and I’ll definitely try again at some point to make it more fluid (I was completely stumped several times).

So, we spent some time in the morning working through the kata in C++, which was awesome. I hadn’t written any C++ since my only CS course in college, around 10 years ago, and what I wrote then was of course very simple. We used CPPUTest as our unit testing framework, but luckily, Doug already had the tests constructed, so we uncommented one at a time and concentrated on the implementation. I’d like to look into testing C++ a bit more at some point, but it may be awhile, considering all the other things I’m learning. We found several variations on the process of solving this problem, and the process of solving it became clearer, slowly but surely, as we worked through it several times. Then Doug said I should “perform” the kata for Caleb, which I did in Java (and in the process learned how much I rely on my IntelliJ Live Templates when I’m writing JUnit test code!) At some point I may try my hand at screencasting and record myself performing it, but I think I need a little more practice first!

Later on, after I struggled through setting up FlexUnit for the small AIR/Flex I’m building, Doug helped me get my bearings in the client project I’m working on now. We were writing Ruby, HTML, and JavaScript code most of the day, though Objective-C is also part of the project, and Flex/ActionScript may be eventually. It was awesome to be working on a bigger project and finding myself able to figure our what’s going on relatively quickly. My Limelight experience with Tic-Tac-Toe definitely paid off – if I hadn’t spent some time with that, there’s no way I would’ve known what was going on today. Of course, the technology itself wasn’t the sole aim of the Limelight Tic-Tac-Toe project – visual design was a big part of that, too.

At any rate, I’ll obviously have to be a bit more vague about project details now, but I’m excited to be getting into some client work, and I know I’m going to learn a lot from seeing Doug and Micah code on a regular basis.

Permalink 2 Comments

Back and ready for action: reading and writing

May 4, 2009 at 9:40 pm (Limelight, Reading, Week 7) (, , , , , , , )

Well, I’ve played my last trumpet gig on the books for the time being. Took a trip down to South Carolina over the weekend to play a wedding ceremony and visit my mom. It was a good trip, and I actually got a decent amount of work done, believe it or not. The Limelight GUI that talks to my Java Tic-Tac-Toe code is finally in a completed state! I showed it to Micah this morning, and he didn’t have much to say at first besides that it worked pretty smoothly (he also noticed that I’d put in artificial sleeps to make the Computer vs. Computer game look more interesting). We spent a bit of time looking at some problems I was having with a refactoring in a Props file, but didn’t make much headway.

Most of the other work I did over the long weekend was reading – I’m really enjoying Michael Feathers’ Working Effectively with Legacy Code. I’ve noticed that most TDD resources I’ve read so far have dealt with simple, granular situations, where the design is perfect. But when I go to write tests for my code, I find that things are much more complicated. This tells me that at least one of two things are happening:

  1. Most textbook examples are simpler than real life situations
  2. My design isn’t clean enough

My estimation is that both are the case, but at any rate, I’m getting more and more motivated to write tests, even when it seems like it might be difficult. Particularly, the ideas of “sensing” and “separating” are helping me to crystallize what exactly I’m trying to accomplish when I write tests. The idea is that if I have an implementation method that needs to set a variable, I need to write a test that somehow senses the change in that variable based on the use of that method. It’s a simple idea, but there are a lot of ways that legacy code can make this difficult.

My next assignment was to pretend I was a writer (gasp!) and write a review of Limelight, as though it was for a magazine or something. I found myself drifting into tutorial mode for a paragraph or two, but eventually made my way toward an opinion on the framework. Basically, I think it’s great. There are a few strange behaviors here and there, and some features I’d like to see added, but it’s pretty cool to have a desktop application framework where you only need to write Ruby. Now, I must be completely forthcoming and admit that I’ve never tried any other Ruby GUI frameworks like Shoes, RubyCocoa, or wxRuby. In taking a cursory glance at Shoes (by everyone’s favorite Ruby mad scientist, _why), it looks interesting and feature-packed, but I’d like to see bigger examples, with the same separation of concerns that Limelight boasts. I’d also be surprised if interfacing with Java code was easy, or even possible, since Shoes doesn’t use the JVM.

Whew, I think I’ve written about all the prose I can write in a day; think I’ll spend the rest of the evening working some more SICP exercises. I watched another lecture over the weekend and finally started to look at the book and its exercises. It’s definitely forcing me to think in a very different way than I’m used to – I think this is exactly what Dave Thomas and Andy Hunt had in mind in The Pragmatic Programmer with their suggestion to learn a new language every year. At this point, I’m trying to learn several this half of the year, but since I’d at least written some cursory Java and Javascript code, I think I’m OK for now. I do worry sometimes about stretching myself too thin and becoming a jack of all trades, master of none, but as long as I can keep improving on all the fronts I’m aware of, I think I’m in good shape.

Permalink 1 Comment

Exploring Limelight

April 28, 2009 at 9:44 pm (Limelight, Ruby, Week 6) (, , , , , )

I spent the day continuing and accelerating my learning in the Limelight GUI framework. I’m sure I’ve mentioned before, but everything you write is Ruby code (there’s Java behind the scenes, so you run your applications with the JRuby interpreter and gems. Limelight is still very young (pre-1.0), and as with any framework, it takes time and advice to learn how the framework wants you to code. I ran across a couple of things that I felt would be more intuitive with a slightly different API (mostly styling-related), and Micah agreed and had me report them on the project’s Lighthouse page. There’s not a ton of tutorial documentation on Limelight so far, but here are the most important ones I know about already:

  • Installing Limelight
  • Calculator in 10 Minutes Screencast – Micah walks you through building a lightweight calculator application
  • Tutorial #1 – there’s a slight tweak you need to do to get it working this way, at least on the latest Limelight version
  • A Cook’s Tour of Limelight – great deeper-level overview of the parts of Limelight (Production, Props, Scenes, Players, Stages)
  • Style Attributes – similar to CSS style attributes, but with some awesome additions like built-in gradients and rounded corners (there are plans for drop shadows as well)

I’m sure as time goes by, there will be a lot more available, especially as JRuby gains in popularity. Keep your ears open!

I got the Tic-Tac-Toe game working with human players, which was a big step. There are still some kinks to be worked out with the “Play Again” process (I think my Java code is left waiting for input), but I’m excited to have it working, and to have spent the day getting better and more confident with BDD. Once I’ve patched those up, the real work will start on this assignment: styling it up, adding some effects, and in general just making it really presentable, with relation to the UI and design. I know my designer pals would be scared to hear about me designing anything, but I’d like to add some more design skill to the old bag of tricks, so I may be hitting them up for links to design blogs and other learning resources.

Permalink Leave a Comment

Week 5, Friday

April 25, 2009 at 10:22 am (Java, Limelight, Ruby, Week 5) (, , , , , , )

I took the steps necessary to have no parameters in the constructor for my Tic-Tac-Toe view class, so that we could implement the interface in JRuby during our Randori session over lunch. I’d spent a little time thinking about what it would take, so it wasn’t too bad. I had three parameters initially: a Controller, a PlayerFactory, and a Board.

Well, the PlayerFactory was only really being used in one method, and all we really needed there was an array of Strings that showed the types of games that were available, like “Computer (X) vs. Human (O)”. So I changed that method to take an array of strings, and changed uses of that method to pass in information from the PlayerFactory (they were all in the Controller, so no new package dependencies resulted).

Also, since the Controller already had a reference to the same Board object as the View, I just added a getter called getBoard() on the Controller, and used that to set the Board on the View rather than the constructor.

The last thing was taking the controller out of the constructor. The View needs the Controller, for sure, so I added a setter on the View, which any class that instantiates a View would need to call right after creating it. I don’t much like this, since I had to change all my test class setups, and it’s more work for anyone wanting to implement a View, but I think it’s necessary to make the connection to Ruby code.

I also started with the Limelight props and styles being built already, so for the Randori, we focused on implementing the View interface in Ruby. We worked in IntelliJ, and there were a few tongue-in-cheek complaints about that (from Textmate fans). I definitely don’t know IntelliJ as well as I know Textmate or even Vim, but the big plus it has for me is the ease of refactoring, and the color-codification of things that are not going to compile or run properly. At any rate, we got a lot done. After a bit over an hour, with rotation of pairs every 5 minutes, we almost had a running Limelight application that used two computer players. I just had to change a couple lines right afterwards to get it to work as expected.

I have to say, I was initially skeptical when Micah told me we could use my Ruby version OR Java version of Tic-Tac-Toe to implement it in Limelight. I knew my Ruby version worked, but looking back, I knew its OO design was weak; I don’t think there was any kind of display class at all, so I’d have had to change a lot – I may still do that. But to use Java classes in Ruby code? That sounds crazy, but honestly, it wasn’t too bad. But I guess the person showing us how to do this has written a framework using Java and Ruby, so you’ll have to decide for yourself:

require '/Users/colin/IdeaProjects/TicTacToe/tttt.jar'
module Board
def scene_opened(e)
@view = new View(self)

class View
include Java::trptcolin.baseGame.View
# implement methods

Now, it may only be this easy because we’re doing it through Limelight, but either way, I think it’s pretty nifty.

I felt a lot less embarrassed about my abilities during this Randori than at the last one, where I was basically useless. This time I had a lot of domain knowledge to offer (since I wrote the Java code and the Limelight props), but more importantly, I had a better idea of what to test when I was at the keyboard. I still felt slower than everybody else, but at least this time I felt like we were more or less on the same page.

Permalink Leave a Comment

Week 5, Wednesday

April 22, 2009 at 10:37 pm (Java, Week 5) (, , , , , , )

From yesterday morning to this afternoon I improved my understanding of the Hashtable a lot. Micah found a flaw in my hashing yesterday, but when I started to blog about it last night, I found I didn’t really understand my problem, so I held off until tonight.

I was doing this sort of thing:

private Board board;
private static Hashtable boardScores = new Hashtable();
// ... (calculating the score for a particular board position)
boardScores.put(board, calculatedBoardScore);

I had hashCode() and equals() defined on my Board class according to the squares filled on the board, but I wasn’t REALLY following the way that hashing works in Java (actually, in any language). My big flaw was in not realizing that while a given board position would always resolve to a given hashCode(), there’s no guarantee that it will be distinct from the hashCodes for other positions! So “XOX XOO X” (for a 3×3 board) might go in the same “bucket” as “OOXX OO X”, for all I know. Well, that’s not necessarily a problem when I store the positions in the Hashtable; the problem is getting them back out.

From Hashtable’s get() method:

if ((e.hash == hash) && e.key.equals(key)) {
return e.value;

And the key WAS a Board, which has equals() defined as having every square equal. So a hash lookup with Boards as keys really should work? No, actually! (This is where I got lost trying to work things out in my head last night) It’s true that the board is the key and 2 boards with different square configurations will not compare as true with equals(), but the keys are not really different boards. In fact, they were all references to the same board, which means that when if I get a hashCode() collision (which will most likely happen with the millions of boards that I’m hashing), there will be confusion, because the second part of the conditional in the Hashtable code above will always be true.

So anyway, Micah helped me to refactor to use new String objects as the Hashtable keys instead, which fixed the logic flaw, but took up even more memory and crashed the program at a lower depth search (running out of room in the heap). This all took place yesterday. Today I came in with the idea that I’d refactor things, write some more tests, and clean up some dependencies. I think I accomplished those goals, starting with a lot of refactoring (using IntelliJ’s built-in refactoring tools). I tried out a new-to-me tool called JDepend to check out problems with my packages, and I tracked down a few dependency cycles (that’s a BAD Java programmer. No dependency cycles. Nnnoo!). JDepend is an open source project by Mike Clark of Advanced Rails Recipes fame. It was pretty easy to use, and while class-level detail could’ve been nice, it was easy enough to do a “Find in Path” to track down the naughty dependencies. Here’s how it went:

  1. downloaded from Github (
  2. ran ant task to build it
  3. $ java jdepend.swingui.JDepend ~/IdeaProjects/TicTacToe/ (there’s also a textui and xmlui version)
  4. too many packages shown for me to process well, so I added in home directory to ignore junit, hamcrest, java
  5. ran again, started doing searches for dependencies in my packages and breaking them where necessary to avoid the cycles

Now my package dependencies were as follows:

  • main => depends on baseGame, boards, players, and ui
  • ui => depends on baseGame, boards, and players
  • players => depends on baseGame and boards
  • boards => depends on baseGame
  • baseGame => no other project dependencies

Before my refactorings, every single one had a dependency cycle (icky).

And then we came to the afternoon, when I finally got fed up enough with the memory constraints of the Hashtable to open a JDBC connection and write the millions of positions and scores to a database. This was new to me, but the MySQL website was helpful enough that it wasn’t a big deal to do. One false start (only 8 levels deep), ~10 million database records, 16 levels deep, and ~6 hours of writes and indexing later, my computer player can play a 4×4 board more quickly, but in exactly the same way as he did at 6 levels deep with the (corrected) Hashtable. Which was not that badly, except at the opening. He makes smart moves to avoid a loss (on both sides) at the end, but at the beginning he thinks all the positions are equivalent. My impression in thinking as deeply as I can about this for a week or so is that on a 4×4 board, it is extremely easy to force a tie. So easy that a player would need to make at least two bad moves in order to lose. There’s no forcing a win after one misstep like on a 3×3 board. I think in order to get the computer to play like a human, I’d have to use an evaluation function that added value for 2-in-a-rows and 3-in-a-rows, which I’d have to do anyway in a more complicated game like chess, since there are so many more possibilities to consider there.

At any rate, Micah decreed that today was my last day on Java Tic-Tac-Toe, and so I’m moving on to Limelight tomorrow. Micah’s actually the author of Limelight; it’s a framework based on Java and JRuby that allows you to write rich GUI applications in Ruby. Pretty cool stuff; I’ve looked at some here and there since arriving in Illinois, and Eric and I looked at some this afternoon. I don’t know yet whether I’ll be doing some more Tic-Tac-Toe or something else, but I’m looking forward to digging into the new technology.

Whew, how’s that for an epic send-off for Java Tic-Tac-Toe? Apparently that’s what happens when you write 10 millions records to a database!

Permalink Leave a Comment

Next page »