Sunday, July 29, 2007

MBTI, more on

One problem with the borderline cases is that the difference between two types is bigger than one letter might suggest. For example, just judging by the letters J/P it's easy to conclude that the difference between, say, INTJ and INTP is minor. After all, three letters are equal. However, that's not the case.

To really understand MBTI, one has to go beyond the individual letters and see what they mean in terms of functional analysis. For example, here's a comparison between INTJ and INTP:


Dominant function: Introverted Intuition (Ni)
Auxiliary function : Extraverted Thinking (Te)


Dominant function: Introverted Thinking (Ti)
Auxiliary function : Extraverted iNtuition (Ne)

(There are also a third and a fourth function, but I leave those, except to say that they, like the first two, are different in INTJ and INTP.)

So, being on the fence between J and P in this case means being on the fence between two completely different personalities, and not between two personalities that are 3/4 the same.

Some types are more similar than others. For example, INFJ and INTJ, as I mentioned, share the dominant function Introverted Intuition, so it makes more sense to be on the fence between these two than between INTJ and INTP (there are always exactly two types that share the same dominant function).

Though I might add that I don't think that MBTI is exact enough to really withstand this kind of analysis. It becomes speculation with references to theories rather than correspondence to reality.

Thursday, July 26, 2007


Some ten or so years ago I had some interest in MBTI, a psychological system that divides humans into 16 different personality types.

I think there are some serious problems with this system, but there is some truth to it and it can be fun to play around with.

I first tested out as INTP, but not long thereafter I discovered that I'm probably more of an INTJ. Recently I've become increasingly convinced that INFJ might be the best fit. They are not that different, INTJ and INFJ, as they share the same dominant function (introverted intution), and I find myself somewhere in the middle.

Both are system builders, but INTJ:s tend to be more concerned with technical stuff whereas INFJ:s are more people oriented. (That's not the only difference, and it's not a defining characteristic.)

Anyway, I think of the nerd within me as the INTJ (whose interest are things like programming and chess), and the activist within me as the INFJ. (You don't see much of that latter side in this blog.)


They put a lot of energy into identifying the best system for getting things done, and constantly define and re-define the priorities in their lives.

: )

Wednesday, July 18, 2007

Basic design principles of programming

I'm going to try to compile a list of the most fundamental design principles of programming. The current list will most likely not be the last one, but I have to start somewhere. I want perhaps 4-5 principles (although it's not entirely up to me to decide -- it depends on the nature of the subject).

The criteria of a fundamental principles, which probably will become updated in time, is something like:

1. The principle should be broad, cover a lot of ground. So a design pattern doesn't count, it's too narrow. On the other hand, the principles these patterns are based on (using interfaces, loose coupling, etc) are candidates.

2. Not be trivial. The principle could (and maybe should) be easy to understand definition-wise, but not be easy to apply fully. (A counterpart in chess would be a positional principle like piece activity. Takes 15 seconds to understand the meaning of, but a lifetime to apply fully. Both a beginner and a grandmaster can study aspects thereof.)

3. I should have experience with it directly. There are some design principles that sounds great and useful that I've read about, but that I haven't thought in terms of and haven't seen in action directly. They may be great, I just don't know yet.

Also, it should, of course, really be a design principle, and not a design goal. You can't say for example "my design principle is to write efficient and correct code. Yihaa!", because that's a goal. It doesn't really guide or tell how to achieve that, just what to achieve. And I don't know what "yihaa" was supposed to contribute. Be serious, and cut that silly stuff out, okay? Okay.

What I've come up with, so far: (There are no revolutions here; these are well established principles, but they are usually not compiled into a list like this, or they may be mentioned together with less fundamental principles etc. The subject is somewhat chaotic, perhaps like the pre-modern area in chess was. So I'm basically extracting and compiling my personal collection, but I don't originate anything really new. Maybe someday I'll become an evil nerd-genius, but until then I'm just a lost farm boy.)

  1. Avoiding duplicity. This applies on many levels, anything from using a loop and a table instead of 30 assignments in a row, to merging two big units of some sort. Usually what is merged isn't literally duplicates, but it's similar enough so that you can extract one aspect of it and put it separately. Or something like that.

  2. High Cohesion. I think of this as 'classification'. It's basically putting related instructions (and data) in the same place, neither having non-related info in the same place nor having highly related info spread out. So it's clearly related to avoiding duplicity (but not the same), and this also applies on all levels: functions, classes, units, libraries, whatever. I once read an interview with one the programmers behind Age of Empires, and when asked for some programming advice, the only one he gave,as I recall, was having a well defined task (no more and no less) for each function. Well, the principle of high cohesion covers that, and more.

  3. Loose coupling. Often mentioned together with high cohesion. It means not having unnecessary connections between different parts of the program. A simple example: Three parts, A, B and C. A calls both B and C, and B calls C upon receiving a call from A. Now, instead of B calling C it's, or could be, possible to make B return whatever value it sends to C, to A and then let A send it to C. That would eliminated the (direct) connection between B and C, with A as an operator. Assuming that's a reasonable task for A (which it probably is since it already has contact with both anyway.)

  4. Encapsulation. As in information hiding. Maybe this is too object oriented to be included. But I feel three principles are too few, so I'll include it for now, and maybe remove it when I have 1-2 new principles. Or maybe I keep it, because OO is growing stronger by each day, and is, in my opinion, the best paradigm. (Let the flame war begin...)

  5. Modularization. Another principle with close ties to the other principles, yet different. It's breaking up the code into different units, each as independent of the others as possible. Loose coupling, mentioned above, is an important principle in achieving this.

That's it for now.

Thursday, July 12, 2007

TV shows, top ten list updated

This is an update from the list I published 5:th of May.

It's almost the same list, but with some extra fluff like links and pictures. And it's a top ten now, from being a top eight, since I've finally found two more shows worthy of inclusion (Babylon 5 and 24). I'm probably the latest kid on the block to discover 24, but I'm usually years behind in that sort of thing.

As before some shows share the same spot, but it's otherwise in order:

  1. Buffy the Vampire Slayer
  2. Angel and Babylon 5
  3. House M.D, Firefly
  4. 24
  5. Veronica Mars
  6. Battlestar Galactica
  7. Star Trek: the Next Generation, Lost

Monday, July 09, 2007

Babylon Vs Fritz, SEE now implemented, threefold repetition, more on q search

Some results: Babylon easily beats Fritz set to a rating of 1350 (lowest possible). It became a threefold repetition at rating 1500 (with big advantage for Babylon), and another threefold repetition when Fritz was set to 1596 (with equal position, endgame). I claimed some time ago that one goal was to beat Fritz set to 1350, so that is now achieved. Of course, I don't know what this rating means in relation to other scales (other than that it's much inflated compared to elo), but it ranges from 1350 to 2150. (It's btw an old free version of Fritz, and the personality used was Reckless.)

I will soon have to something about those threefold repetitions. It's a well known problem with chess computers and something all engines need to deal with one way or the other. Most implement hash tables (to remember positions) sooner or later. I probably will too, but not anytime soon. Instead I will do the following: Always save the two best moves (instead of one), and never play the same move that was played two moves ago (assuming the position is good enough, and that the second best move is good enough). That will not stop all threefold repetitions, but at least the most common one, like 14.Rba1 Rab8 15. Rab1 Rba8 16. ... it will break the potentially repetitions pattern here by not playing Rba1). Also, by saving two moves I will be able to create some randomness, by giving it a certain chance of playing the second best move (if it's good enough). However, for testing purposes it is better having it playing deterministically, that way I can more easily spot errors (by detecting deviation from previous play when it should play the same).

I've discovered that having a quiescence search not only helps in the middle of tactical sequences, but also plays an important role in making the engine play positional. The reason is that without it, the computer will always think that it can take a piece at the end of the search (or that the opponent can do so, depending on whether it's an even or odd search depth), near the horizon beyond which it cannot see. And it will adapt its move choice to that and play more non-positional, even in a completely quiet position with no immediate captures possible. Well, I just find that interesting, but not so relevant now that I have a fully functional quiescence search.

And I've also implemented SEE to improve the move order (and therefore search speed) for the q search. The result is impressive: one position that earlier took over 600 seconds to analyze now takes only 21s. Usually the difference isn't that dramatic, but it's always faster. However, I still can't go deeper than 3 (complete) plies within reasonable time, so I haven't gained anything strength-wise by using SEE, but it's faster with three plies and also pretty close to being playable at 4 plies. I consider anything lesser than 10 seconds per move in average to be "within reasonable time" (then it can play 2 12:s, with some margin). (Btw, 3 and 4 plies may not sound like much, but with q search it can still play pretty decent chess. The q search often makes it go deeper than 20 plies into the position when analyzing captures.)

Next stop is iterative deepening (again, but this time I'll make it right and not give up easily.) That'll speed up things a lot I think, maybe even get me 5 plies deep.

Friday, July 06, 2007

Found opponent. Two new games. And who's Babylon?

I've found a chess engine under current development that is of similar strength as mine (two games, both draw, will follow below), and that has been developed during the same period. That's pretty cool, as I need competitors of similar strength. And maybe they will progress together.

Meet Vicki. There is also a related blog, but it is not updated frequently.

Vicki has some fancy stuff not yet implemented in my program, like SEE (a function to improve the move order of captures, which prunes the search tree, which improves search speed) and principal variation with iterative deepening (also a way to prune the tree, but not just for captures). I did try to implement this last thing, but it went wrong and I moved on to something else. But I'll be back on that. But first I'm going to implement my own SEE-function, since it is of great help to the quiescence function (which is a real bottleneck right now).

I downloaded Arena yesterday to be able to play with chess engines. But since my program isn't connectible to it yet, I have to be the "operator" (moving the pieces manually using two boards) when competing with my program, so I can't test the relative strengths with many games (becomes too boring). But I did play through two games (and more will come, especially after new stuff has been implemented in either engine), and both became draw. The first game I decided to stop, since nothing was happening. Vicki was pawn up, but never did anything. Both just made meaningless moves, so at move 100 I decided upon draw, but Vicki had for the most part the better position. In game #2 there was a real draw by three-fold repetition.

Vicki is probably slightly better, but they are pretty equal.

Oh and btw, I've decided to call my chess program Babylon, influenced by my recent and valuable discovery of Babylon 5.

And now (drum roll), the games. (For the record, the time format was 3 6, but both used much less time that that.)

Round 1:

(There is some deep stuff going on in the game above. First, at move 36, Vicki sacrifices the exchange, and then just a couple of moves later Babylon also sacrifices the exchange. Both sacs seem unforced, but I may be wrong on that.)

Round 2:

Tuesday, July 03, 2007

Clash of the dilettantes -- game and quiescence search

Later in this post: a new game by my chess computer, against another chess computer. But first some boring techno-talk.

I've finally implemented what is called a quiescence search. It's a basic search algorithm that improves any chess computer greatly. I tried to implement it weeks ago, but there was a bug I couldn't find and I gave up knowing I would return to the task. Now I did, with success this time.

So, what's a quiescence search? A chess computer suffers from the horizon effect. It doesn't see beyond the assigned number of plies. So if it stops searching in the middle of a tactical sequence the evaluation of the position becomes very wrong. For example, white may just have taken a knight with its queen. Great, a knight up! Easy win! But, what the search algorithm didn't see is that black the next move can take the queen with a pawn. The computer didn't search deep enough to notice. But, that's with the ordinary search algorithm. Quiescence search to the rescue! Q-search is basically a search algorithm that searches only captures, so at the end of the ordinary search the q-search takes over and searches all the captures (as deep as needed), and evaluates the position as soon as no captures are left (technically it actually evaluates the position during the search too, for reasons I won't go into). No more searches that run out of depth in the middle of a tactical sequence.

Having a q-search makes the chess computer much more difficult to out-tactic (and it makes it more likely to out-tactic you!). And it is noticeable. My program was finally able to draw (with the better position) against its old nemesis The Thinking Machine. The Thinking Machine is basically a dilettante chess computer, but my chess computer isn't ready to take on Rybka just yet so I have go for easier competition for now.

The Game:

My chess computer (got to give it a name soon) is only thinking 3 ordinary plies deep (the q-search can be really time consuming) and was analyzing 34090 positions/s in average, and was thinking 3.11s per move average. It does play some funny moves, but not as funny or frequent as in earlier games. (It actually plays better now, with q-search, going only 1 ordinary ply deep, than it did before going 5 ordinary plies deep).

(And BTW, I was wrong in my post on null move pruning. It was wrongly implemented, and the branching factor and plies didn't get that boost. I'm not sure whether it improved anything at all, but it will when I get it right... but it's not a priority right now.)

Monday, July 02, 2007

TV watching

In the post on my favorite TV shows I halfly expected some critical comments for writing the following: "for years I foolishly lived without a TV". More exactly, for using the word "foolishly". That's because most people don't hold TV watching in high regard; it's a low status activity and many would consider it some sort of strength to live without a TV (even if they themselves don't).

I find this strange, because it so obviously equates "TV watching" in general with a certain kind of TV watching (although a common one). That's like saying that reading poetry or meditating is bad because it's possible to do it too much, or in a wrong way, or whatever. Anything can be done destructively.

There is also a light version of TV bashing, and that's when someone would say something like "sure TV watching has its uses -- it's great for entertainment or relaxation" with the obvious implication that while not being bad, TV watching still can't be, say, a deeply meaningful or spiritual activity, like I'm sure they would (if they're typical) say that reading books can be.

I'm suspicious of people whose value hierarchy happens to mirror the cultural norms exactly. It doesn't prove anything, but it indicates that they instead of independently having reached conclusions simply have adopted intellectual cliches, like "TV bad, books good". The indication becomes stronger when you get to know that they do watch TV but never read any books... (I might also add that my criticism is directed at TV bashing, not TV avoiding. It is a perfectly valid choice to not watch any TV. The reason it was foolish in my case is that it was the wrong choice for me. Or maybe it was the right choice at the time since I hadn't found the good TV stuff yet.)

But it's also worth saying that TV is a challenging medium to use correctly. It's easy to get too much of it (even watching boring stuff), and it's difficult to find the really good stuff (though somewhat easy to find *rather* good stuff, but that may not be good enough to spend time on.) I was serious when I said that it wasn't until I found Buffy the Vampire Slayer that I really understood the value of TV shows.

Anyway, having now seen four complete seasons of Babylon 5, I can easily add that show to the list of "deeply meaningful" TV shows. Really great show. Stay tuned for an update of my favorite TV shows list to see how I rate it in relation to my other favorites.
Locations of visitors to this page