Week 3, Friday

April 13, 2009 at 6:31 pm (Java, Week 3) (, , )

This post has been in the works for days, because I took a big trip down to Georgia to play an Easter gig and pick up my car (my wife and I drove her car up here together last month). I was only at work for half a day on Friday, and I spent most of the time brainstorming and working on ways to make the 3-D game fast enough to be playable. Right now, it just hammers the CPU until I’m afraid for my machine’s life. So Micah’s made 3 suggestions:

  1. have ONE reusable board (rather than creating Board objects for each possible position)
  2. make the Board smarter (so that it knows its state – that is, it has fields for the winner and game end)
  3. caching known board positions and results (based on score from the minimax algorithm call)

I’ve started implementing these, but haven’t done enough to see any large improvements yet. I’m anticipating the biggest improvement in the last step, because of the huge number of boards that need to be scored and the relatively small number of unique boards.


Permalink 4 Comments

Week 3, Thursday

April 9, 2009 at 9:04 pm (Java, Week 3) (, , , , , , , )

Micah led me to a particularly big realization today about how subclassing and field overriding / hiding work in Java. I was in the process of changing my newly-created Board interface into an abstract class, since I realized that the implementations could be used, with very few changes, in both the 2-D and 3-D board implementation classes. The differences would be in the fields: an int[] squares and int[][] winSets. I was having a problem where I couldn’t get the abstract class’s methods to use the subclasses’ fields, and it turned out that the reason was that I’d declared the fields AGAIN in the subclasses. I wasn’t overriding the fields, as I thought I was; I was literally creating new fields with the same names and types, which were accessible only to the subclass.

And what I should have done (what Micah showed me to do) was to declare the fields only once, in the abstract class (as protected so the subclasses get access), and set the values in the subclasses’ constructors. This change worked fine and made me feel kind of dumb for not realizing it. But feeling dumb for something I didn’t already know isn’t such a bad thing: if I didn’t feel that way, I wouldn’t know that information now. I got better! If I feel like code I wrote weeks ago is bad, that means I learned something in the meantime. It doesn’t mean I should try to write bad code to make myself feel good later, but I think it’s a good metric of improvement to look at months-old code and see how bad you think it is. I’m sure once you get to a certain level it gets more difficult, but if it’s anything like trumpet playing, the real masters will see problems that less skilled artists don’t.

I got 3-D Tic-Tac-Toe working for two human players, which was not as big of a challenge as I assumed it would be. However, the AI for the computer player is slow enough as to be basically useless, for the time being. I spent several hours (with tips from Micah) trying to track down bottlenecks in my recursive algorithm, but the more time I spend on it, the more convinced I am that the algorithm itself is going to have to change, to check fewer nodes of the game tree. I was looking into alpha-beta pruning, in particular, as it’s one of the speed strategies I see consistently mentioned for the minimax algorithm. Micah, on the other hand, is convinced that I’ve got at least one method call that’s bottlenecking in the recursion, so I think I’ll benefit from stepping away from the problem tonight and getting fresh eyes on it in the morning.

Permalink Leave a Comment

Week 3, Wednesday

April 8, 2009 at 7:36 pm (Java, Ruby, Week 3) (, , , , )

My apologies for missing yesterday to anyone reading on a daily basis, but I ended up staying home from work and sleeping most of the day on Tuesday. I did get some reading done, but my programming work yesterday was negligible.

Today, however, my illness seems to be receding, and there’s quite a bit to write about. I spent a couple of hours on Java and Tic-Tac-Toe this morning, mostly re-organizing my packages in a way that (I think) better satisfies the package principles in Uncle Bob’s Agile Software Development, Principles, Patterns, and Practices. It took me longer than it should have to get an Ant task back to running the main program – ever since I created the initial packages, that task had been broken (failing with a NoClassDefFound error). I probably spent close to an hour trying to get the classpath where I thought I needed it, but eventually was able to make it work by scoping my “main” class (TicTacToe) down as my package structure was laid out: trptcolin.main.TicTacToe. Now, something tells me this is a hacky way to do it and that I should be able to just specify the classpath and the class name, so I’d be happy to hear any confirmation or denial of that sentiment!

Originally, I had the interfaces and abstract classes for my players, views, and controllers in the same packages as their implementations and subclasses, but then I started to think that because the implementations are likely to change, I wouldn’t want to require each package containing an implementation to ALSO contain a duplicate of the interface. It seems better to have the interfaces pulled up with the main application code, at least at the moment. So I did that, and along the way did some work to ensure that Git saved the file history, which is starting to feel more unnecessary the more time I spend doing it. I think I may start letting IntelliJ do this kind of file-moving work (from package to package), and let Git go ahead and believe that the files have been deleted and created again.

I made my first (small) steps toward a 3-D Tic-Tac-Toe game: I pulled public methods from my Board class into an interface, which I can now implement in a BoardIn3D class the way I already have in my (newly named) BoardIn2D class. Luckily, I don’t have to render the board in 3-D; the display will just be 3 vertical slices of the board in console mode. I love the IDEA of rendering 3-D, but I’d have been scared to try it, especially since I can’t imagine a good user interface that would allow someone to get at the center cube. And speaking of cubes, I have some methods and variables I’m definitely going to need to rename now that 3-D is a possibility (“squares” isn’t going to work anymore).

Eric and I got some more stories done on our Rails project, and I’m enjoying the constant testing we’re doing. It’s a really disciplined approach, and I know the end result is going to be a great product (that’s pretty easy to maintain). He also got a ton of work cranked out yesterday, and I was able to get the bug fixed from Monday with one of our Apache conf files. Note to Passenger users: Passenger runs as the owner of environment.rb, so the log files (and directory) should be writable by that user. Now, ours were both root-owned, so I’m not sure why that didn’t work, but it led me down a path to change the ownership to the Apache process owner, and that finally got logging to work in a staging environment for our app (and subsequently showed me what was going awry with the Apache conf file).

Permalink 2 Comments

Week 3, Monday

April 6, 2009 at 6:31 pm (Ruby, Week 3) (, , )

Yuck. A cold going around the office finally got to me over the weekend, and I’m still way under full speed in my cognitive capacity. Hopefully I can kick it in the next day or so, because I was pretty useless today.

Eric and I had our second iteration meeting with Micah for our Rails project, and that went pretty well, aside from one bug that got uncovered at the meeting. We made a lot of progress this past week and actually hit our estimates, which we were both happy about. We got a new set of stories estimated and assigned for this iteration, and we wrote a decent amount of code today, finishing one small story and getting most of the way through another.

Mocks and stubs still slow me down when reading code, but I’m getting faster at comprehending them and seeing when they’ll be necessary. My biggest challenge, though, is figuring out what to test next. It’s relatively easy to write tests in Cucumber, because those scenarios basically line up with what the user would do in the browser, but RSpec is so much more granular that I sometimes get overwhelmed and have to really spell out for myself what it is that I’m trying to do.

OK, this’ll have to do for tonight, because I need to get well and be at 100% mentally! The big takeaway for me from today was more experience with RSpec and TDD – the more I see it and do it, the easier it’ll get.

Permalink Leave a Comment