Search

Tuesday, August 28, 2012

Day 20: Logger



I am having some errors with the change to GTP, so, I need to see what is happening in the program every time this moves. I will need it anyway to study what the program does now, I don't have the console anymore to see results because now I write to the GTP console.

So, I am working on a class to log whatever I want.

Day 20: Problems, problems everywhere...



From the begining I knew this was going to be hard. Now, this is getting harder, I just don't understand what the hell is happening. When I run my program sending manually the command "genmove w" it worked fine, but with gogui, sometimes it sends incorrect data. I am just confused, don't know what is happening, I will try to fix this to continue. I also want to log all what the engine does. I can't use the console for this, I will do it in a file or something...

Monday, August 27, 2012

Day 19: GTP, starting the hard things



The day has come, in the weekend I was reading how GTP works and was thinking how to make it work on my program. I will try to implement a simple command to see if it works...

MAYOR UPDATES MADE IN THE main loop, this is hurting. 

Ok, I downloaded and installed GoGui, to see how it works. As the people of computer-go mailing list told me, GTP uses standard IO so just used inputStreamReader (with the bufferedReader) and System.out.Println().

Right now I implemented:  play, name, version, protocol_version, list_commands, boardsize and clearboard. For now boardsize just returns true, it is hardcoded to 19 so, every game I start will be 19x19 (I can hardcode it to whatever). boardsize calls board initialize.

This is what I get in GoGui:


Well, next have to make it play and then some refactor to make the code more clear.

Friday, August 24, 2012

Day 16: GTP, standard I/O and stuff



So, now it's time to start thinking about GTP, but first, there is the need of understanding standard input & output in java.

So, some tutorials of Java IO:

From Oracle site

Dick Baldwin

GTP:

Site

GnuGO GTP

GTP if you like it un Ruby

Day 16: Ko, part III



Well, something like a ko was implemented in the program, but still couldn't test it.

First I changed tryToKill from void to integer and return number of killed stones:



So now, main loop will take the result when killing stones.

And now I have to pass as parameters the last board, number of killed stones in the last turn and the color to evaluate. So I changed the getPossibleMoves method:



Now I know that the engine should send more parameters to the getPossibleMoves method of the ruleset:


So, last thing to show is the "isKo" method, that returns true if the move is a ko and false if it is not:

Next: I know I should start with suicide rule, but... I want to see it on a better graphic interface so I will work on GTP and loging.

Day 16: Ko, part II



A comment from Steve (see previous post) opened my eyes about alternatives of writing the ko rule in the engine. It is always a good thing to receive comments like this. I don't know if it is that easy to implement his idea in this engine the way it is written. but for now I will take one part of his idea. Maybe in future recodings this will naturally change to his way, but one part interested me now: in a ko the last move before looking at it is a capture of one stone. If there was not a capture of one stone there is no need to search for a ko. Then, for now, I will continue as planed.

First thing then is to change the "tryToKill" method from void to integer, so if the result is 1 try for ko and <>1 don't.

Off topic: It is good to read comments, a lot of new ideas come from this, it is also good to know that you are here, so , when you want, post even a "hello man" in the blog, this gives me strength to continue!

Thanks a lot to all of you!

Thursday, August 23, 2012

Day 15: KO. Part I



This is starting to get hard... And I know that this will be a lot harder...


Definition of KO

The program now can see groups, liberties, kill stones, etc. I think I am able to program the rule of ko. But, what is ko? Let's see...


  According to KGS:
The ko rule says that you can never make a capture that brings the board right back to where it was before

 Here is a little example:


Here, black and white can retake a stone forever, if there is no ko rule. So, if black takes a stone, white should wait a turn to recapture.

Ideas to implement KO

First thing I notice, this is about repetition of positions, so a copy of the board for the last move of every color should be saved. Then if there is a capture of a stone a ko method should be activated to see if there is a move that repeats the saved board.

So, once this method is created it should be something like this:

  1. x plays.
  2. The board for x is saved.
  3. y plays and captures
  4. The board for y is saved.
  5. The program looks at all the possible moves (positions where value==0).
  6. the program verifies that playing a move doesn't repeat the board for x.
  7. If that returns false the move is kept in possible moves, else it is discarded.
  8. 6 and 7 are repeated for all the possible moves.
  9. An array with all the possible moves is returned.
In the next post... CODING!

Day 15: Killing groups, part II



Something was missing in the last post. I should add the dead stones to a "dead stones counter", so I created 2 new private variables in board.




Everytime a group is killed, I have to add all those stones to one of the counters. Now the killing method of the board will be something like this:



I just have to create a method to return how many dead stones have a player, that's easy, something like "getDeadStones(int color)" and show it on the screen using the console class.

Next: 2 rules to add: ko and suicide.

Day 15: Killing groups


Now that the engine can see groups and count liberties (and see where are the liberties), the obvious step is to see if a group is killed. Basically when someone plays the board will look using the ruleset if any group have 0 liberties. If it is the case, all those positions becomes empty (value of the position = 0), and the number of dead stones should increase to a "dead stones" variable for the outsider or the engine.

This is the "search for liberties" method (I didn't publish it yesterday, you have it now):



I need a new method in the ruleset that analizes a group and if it have 0 liberties will return true. Else will return false.




And, the board should be the responsible of killing the stones. So, in the board class, I create a method that given a color It should see if there is any group without liberties:



And the last step: in the main board, when someone plays something (that is not "pass" or "resign") it should first see if there is something dead for the opposite color that is played and kill it.

Wednesday, August 22, 2012

Day 14: Videos explaining go and computer go



From time to time I will make this kind of  "off topic". It is not really an off topic because it is about computer go, but not about my engine. So, for me time to relax a little, drink a coffe and watch a nice video about go and programming.

 

Day 14: Liberties.


Now that I have the group, I can count liberties of the group. It is basically the same of finding groups. This time I will replace the while with the boolean variable with a for that covers the group array and if something surrounding the stone is a 0, then add it (if it was not added before).

Thing I noticed: There is a BIG bug I found. I don't know how I didn't see this before... Coordinate to position method is not working with numbers with more than 1 digit :(

Added a method to write the liberties number and coordinates.

Update: Solved the bug, just changed: 

row= Integer.parseInt(String.valueOf(coordinate.charAt(1)));
With:

row=Integer.parseInt(coordinate.substring(1,coordinate.length())); 

Next post will be about killing stones.

Tuesday, August 21, 2012

Day 13: Groups



It's time for the engine to recognize groups!

A little thing I saw as I was coding this: The size of the board and the moves it have should be part of the board class. So, I am changing all the "size" coming from the main loop, and the methods that received the whole board array.
First thing I made is an arraylist that have all the positions of the group. Then I followed this logic:


  1. Create a pointer variable with value 0, this variable is simply an integer that have the value of the last visited element of the arraylist.
  2. Start a while loop, all what happens now will be done until I reach the end of the array.
  3. Search the position to the left in the board, if it have the same value as the first element it adds the position to the arraylist (if it is not in the arraylist yet).
  4. Search the position to the right in the board, if it have the same value as the first element it adds the position to the arraylist (if it is not in the arraylist yet).
  5. Search the position up in the board, if it have the same value as the first element it adds the position to the arraylist (if it is not in the arraylist yet).
  6. Search the position down in the board, if it have the same value as the first element it adds the position to the arraylist (if it is not in the arraylist yet).
  7. If the pointer is = to the arraylist size of the arraylist, then all the group was found, so it should exit from the loop.
  8. If the pointer < to the arraylist size, then increase the pointer by one.
  9. When exits the loop return the arraylist.
After a lot of problems implementing this, I have some code:



I also made a method in Console to show the groups and a method in the engine that gets the groups.

Next step: Liberties.

Monday, August 20, 2012

Day 12: Recording moves


I didn't have time this weekend to code, I just started with the game recorder. The class GameWriter takes the integer in the method puthMove and returns a method with getMove. There is also a method with the length of the class.

The main loop class creates a new GameWriter and in every move takes the move. The console writer takes it and writes it translated to coordinates.

Friday, August 17, 2012

Day 9: Refactoring



As I said this midnight, one of the things I have to change is the possibleMoves method. Why? Because the responsability of knowing what moves are legal is not of the engine. The ruleset actor is the one that should know what moves are legal.

So, I moved the method to Ruleset, deleted the Actors class. So, Engine and Human don't inherit from nobody now.

Engine now creates a Ruleset object and gets the legal moves from him.

Day 9: Midnight reflection.


Midnight, I can't sleep, my go sucks, barely won my third game, and because my opponent mada a big mistake (bigger than all the mistakes I made). Well, a list of things for the future days:


  1. Send the possibleMoves method to the rules (and then delete Actors class).
  2. Start saving all the moves done in the game and show them in the console class. Right now some println are in the main loop.
  3. Start searching for groups.
  4. When I can find groups, I need to count liberties.
  5. If liberties=0 then kill.
  6. KO.
  7. Eyes (?)
  8. GTP.
  9. Seki
  10. Montecarlo.
  11. Conquer the world.
A video about computer go:


Thursday, August 16, 2012

Day 8: Main loop



Until now, the engine played, the "outside" played and that's all. Now, I want some "flow". For now I will make a loop so the game will go until I type "Pass" or "Resign". I think that adding some things to the translator it will work better. I will put some conditions to coordinateToPosition method. If from the outside there is a pass it will return a -1 and if it receives a Resign it will return a -2.
Then if the number is a -2 for now it will end the program, -1 only will change the turn.

At first I thought this would be a really easy task for a day where I didn't want to code a lot. But... this project is evil...

I just had to change code everywhere!!!!!!! From Human class to translator. But, well, it is working now.

I will publish code on future posts, when I change more things (just lazy to put code for every change).


Wednesday, August 15, 2012

Day 7: Coding the "human"



As I promised, there is a first approach to "Human" interface that works like this:


  1. The player puts a coordinate.
  2. The translator converts it to a position.
  3. If there is a 0 in that position it returns the position.
  4. If not, the player shpuld write another position.

 

 This should work, and only have to add a human object in the main loop and get the move and put it on the board.

 

Next post will be about making the main loop  a real loop XD.

Day 7: A week!

The project is in his first week, and his state is a lot better than I expected because I don't have the time I want for this, so, let's continue with this.

Right now the "class design" is like this:



Today I want to do something simple. First, I want an input to the program, the first input will be manual input, I will "play white" and put manually a stone by writing a coordinate. The translator should convert it to a position and the stone should be played.

When I first thought about this project I was only thinking about the engine playing against humans. Now I see that it will be playing humans and engines, so "Human" class name is "anything that comes from the outher space to the engine, no matter if it is human, machine, a dog or an alien".

But for now a manual entry is ok.

I need a method: public int externalMove(Board board,int size) This covers all the external interaction (for now a manual input).

Now I am coding it, next post, the code!

Day 7: Coding the translator



I updated the class design with this information:


  1. I need a class Translator. For now, it will be a new actor, so in the package Actors there is a new class. It have some methods.
  2. This class have two methods: coordinateToPosition, that translates a coordinate to a position in the array. It takes 2 arguments: the coordinate and the size of the board. The other method is positionToCoordinate that translates from a position in the board array to a coordinate.
  3. There is also a private variable, coord, that have all the coordinates first part. It is needed to change it to a number. For example A=0 (0 is the position and will be the value), B=1, etc.
The code:


This should work looking at the last post. Now, let's see if this works. For now, I will add a println in the main loop so when the engine sends a position it will write the coordinate.



And...



A 22x22 board:


That's it, next time I think I will start with some loop and then I think I will try to group.


Tuesday, August 14, 2012

Day 6: Converting coordinates.

As I said yesterday, a "translator" is needed, this is the first model that I think I will implement:


  1. The engine sends the integer value to the board. This is actually working.
  2. The engine should show to the outside a coordinate, so it sends the numerical value to the Translator, it converts it to a coordinate and sends it to the outside.
  3. A coordinate comes from the outside, it is sent to the translator that convert it to an integer with the position. Then it is sent to the board.


The maths

First I need to convert from a coordinate to a number. If we look at a 6x6 board with coordinates we see this:

            A    B   C    D    E   F
   00 01 02 03 04 05 06
1 07 08 09 10 11 12 13
2 14 15 16 17 18 19 20
3 21 22 23 24 25 26 27
4 28 29 30 31 32 33 34
5 35 36 37 38 39 40 41
6 42 43 44 45 46 47 48
  49 50 51 52 53 54 55 56

Now, let's think that letters have a numerical value A=0, B=1, C=2, D=3, E=4...

Using as reference: Row=r, Column=c, n=number of rows or columns

I can use:  c + n + 2 + (r-1)*(n+1) 

(I guess it is easy for people with good knowledge of mathematics, but for me, to get here was like hell).

For example: 

  • D4 = 3 + 6 + 2 + 3*7 = 11 + 21 = 32
  • A6 = 0 + 6 + 2 + 5*7 = 8 + 35 = 43
Have to try it in 9x9:


         A  B  C  D  E   F  G  H  J
   00 01 02 03 04 05 06 07 08 09
1 10 11 12 13 14 15 16 17 18 19
2 20 21 22 23 24 25 26 27 28 29
3 30 31 32 33 34 35 36 37 38 39
4 40 41 42 43 44 45 46 47 48 49
5 50 51 52 53 54 55 56 57 58 59
6 60 61 62 63 64 65 66 67 68 69
7 70 71 72 73 74 75 76 77 78 79
8 80 81 82 83 84 85 86 87 88 89
9 90 91 92 93 94 95 96 97 98 99
  00 01 02 03 04 05 06 07 08 09 10

And now, let's try the magic:

  • H3 = 7 + 9 + 2 + 2*10 = 18 + 20 = 38
  • B8 = 1 + 9 + 2 + 7*10 = 12 + 70 = 82
I can think now that this works.

And now... I have to convert from the postions to the equivalent coordinate:

The fastest approach to this (not in therms of algorithms but in therms of the first solution I thought) is to try all combinations against the formula. In other words, I have to try from c=1 to number of columns and from r
to number of rows.

This is why I really love to work with paper and pencil:


Monday, August 13, 2012

Day 5: Translating



In the last post, the machine selected a position where the number was 0 (empty spot). I need to translate this to a valid go coordinate. Let's graphic this:


For example in a 6x6 board we had:

01 02 03 04 05 06 07
08 09 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31 32 33 34 35
36 37 38 39 40 41 42
43 44 45 46 47 48 49
50 51 52 53 54 55 56 57

The program just puts a stone on position 25, but a human, for example don't know what is 25. I have to add coordinates.

         A  B   C  D  E  F
   01 02 03 04 05 06 07
1 08 09 10 11 12 13 14
2 15 16 17 18 19 20 21
3 22 23 24 25 26 27 28
4 29 30 31 32 33 34 35
5 36 37 38 39 40 41 42
6 43 44 45 46 47 48 49
  50 51 52 53 54 55 56 57.

Now, we have that 25 is C3, easier to understand right? 

Also GTP (I will start writing about this in the really near future), uses coordinates, so let´s use GTP standard.

What I need now is a translator between array positions and coordinates. I will create a new class with two methods to translate from coordinate to array position and from array position to coordinate.

Day 5: Starting the engine.



Well, this post will be like thinking loud.


  • First I will need a method play for the engine. It will need a board as a parameter. This method will return an integer that will have the position where it should play.
  • Then it should see what possible moves are (all where the state is 0). For this I will create a method getPossibleMoves, and will have the board as the only parameter.
  • Finally the engine will select one position randomly and play it. So I will create another method makeMove with the array of possible moves.
  • the mainloop of the game should receive the move and send it to the board that should have a setMove method with the integer of the position and the "color" integer.
First, the creation of the play method. It should receive the board.


Let's start with the method getPossibleMoves, this method will return an array of integers. Those integers should be the different positions. This method will be in the Actors class, because it will be taken both from the engine and from the human player.

 

Well, now I have all the possible moves and the machine have to pick one and return the number. For now it will be a random number.

 

 Now in the board a setMove method is needed. It will take an integer with the position and the color and put the stone in the board



And now, the mainLoop's method startGame:




And here we are:

9x9:

19x19:





Saturday, August 11, 2012

Day 3: Changes in board...


While I was thinking how to start with the engine I saw that some changes were needed. For example, I need a Board object for the engine, but at start I don't know the size of the board, so I created an empty constructor and then I assign the board that the game flow uses. A good idea (maybe, I am not sure yet, but let's believe in intuition), was to quit the board initializacion from the parametrized constructor, so I created a method boardInitialization(int). It is now like this:
Another thing that I changes was the main class. The game loop should not be in the main class, the main class only calls a "game loop" class, so now I have gameLoop class. And main now is this:

Day 3: Some changes to the class design

Looking at the last two posts, is obvious that some changes were made to my class design paper. Here is the new picture:


I deleted the "Stone" class, for now I think that an integer should be enough.
Added some methods and variables to board and console to create the board ad to show it on the console.

Next post will be about engine random movements.

Day 3: Board Representation -Coding-


Well, time to code!

Important note: I just changed: "Stone" is not needed as a class right now, if I need it in the future I will change it, for now, there will be an integer in every position: 0-No stone 1-Black Stone 2-White Stone, 3-Unplayable place

Some things about how I will program this:


  • Even if inside an IF there is only one line, I will still use the "{"
  • Lot's of comments on code.
  • Obvious comments mode=on.
First way I thought about creating the board:


This goes with the math of the last post. Puts the correct "component" in every space of the array.

So, now, just to show it on the console, in the "Console" class:


And in the "Principal" class (main), just start the program creating the board (hardcoded to 9x9 but can be changed to whatever). In the near future I will quit this from main and create a class for the game loop.
So, that's it for now, runnig this I had:

In 9x9:



In 19x19:



Thursday, August 9, 2012

Day 1: Board Representation II



Well, let's put in practise the theory I learnt in the previous post. The board will be an array (I will use the class Vector) and in theory the size should be (n+2)*(n+1)-1. So, I will write some examples of this just to understand:

6x6 board = 8*7+1=57


01 02 03 04 05 06 07
08 09 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31 32 33 34 35
36 37 38 39 40 41 42
43 44 45 46 47 48 49
50 51 52 53 54 55 56 57

Borders will be at 1,2,3,4,5,6,7,8,15,22,29,36,43,50,51,52,53,54,55,56,57

9x9 board = 11*10+1=111

01 02 03 04 05 06 07 08 09 10
11 12 13 14 15 16 17 18 19 20
21 22 23 24 25 26 27 28 29 30
31 32 33 34 35 36 37 38 39 40
41 42 43 44 45 46 47 48 49 50
51 52 53 54 55 56 57 58 59 60
61 62 63 64 65 66 67 68 69 70
71 72 73 74 75 76 77 78 79 80
81 82 83 84 85 86 87 88 89 90
91 92 93 94 95 96 97 98 99 00
01 02 03 04 05 06 07 08 09 10 11

Borders will be at 1,2,3,4,5,6,7,8,9,10,11,21,31,41,51,61,71,81,91,101,111

So, lets say that borders will be in

  • 1 to n+1 
  • (n+1)*x+1 (x is a for from 1 to n)
  • (n+1)*(n+1) to (n+2)*(n+1)+1
Well, this is theory, let's see if it works. In the next entry I will put it in code and see if this really works like this.

Day 1: Board representation.



First of all, I have to thank a lot to the Computer Go mailing list, so if you are interested in computer go, suscribe to it here. I asked them for some papers and information for beginners information and they answered me with very interesting information.

The first document that I am reading is the one about board representation on Senseis. It is very interesting, so I will divide the text and comment my impressions and conclutions. If the owners of the wiki don't want this text copied please tell me and I will quit it.


Board representation
The most basic of all basics. In order to have a program that can play Go, we need a representation of a Go board in computer terms. Although Go is payed on a variety of board sizes, the most popular by far is 19x19. For teaching purposes or for entertainment it also is occasionally played on 13x13 or 9x9. As far as I know, smaller sizes than that are only occasionally used as testing grounds for computer programs. Also boards larger than 19x19 are so rare that I choose to ignore them completely.
So, I think I will try to implement a dynamic array limited by a number  of rows and cols (in theory both are equal, but it should be possible to change it).
Since the board is always square (with an uneven number of lines), common sense would point to using a two-dimensional array to represent the board. Unfortunately computers take much longer to access a two-dimensional array than a one-dimensional array. For this reason most serious Go playing programs will use a one-dimensional array to represent the board. The one-dimensional position z of a board-point x,y is then arrived at by the following conversion: z = x + y *19 (for a 19x19 board represented by a one-dimensional array of size 361). From now on I'll use xy instead of z as the one-dimensional equivalent of the two-dimensional coordinate x,y. Since the program will internally only use one-dimensional arrays, it will in practice not have to do such conversion often. A computer doesn't care whether the coordinate is represented in a one dimension or two.

  • So, the board will be a square (rows=cols), that's good.
  • One dimension array? Ok, this will be more difficult, but... 


There's a practical difficulty with representing the board in a one dimensional array however. How can the program distinguish between the borders of the board? This is still possible by looking at the coordinate. When xy%19 equals 1 or 19, or when xy/19 equals 1 or 19 we have a point on the 1st line.
 Now, there is a good explanation. I will need to create a method to convert from a 2 coordinates position to a 1 coordinate position.
Next to that is the edge of the board. This is a rather cumbersome way however, and such calculation will cancel out any performance gained by using a one-dimensional representation. The common way to solve this is by usig a bigger array and use border-points around the board to indicate the board boundaries. At first you may think this would lead to a 21x21 representation, and indeed in a two-dimensional board representation this would be the case. When this gets mapped to a one-dimensional array and you'd print out the information stored, you may notice something interesting however. Whenever a border-point is reached to mark the edge of the board, you see two consecutive border-points next to each other. For this reason, the one-dimensional representation can be a little smaller. Instead of 21x21=441 points, we can make do with 20x21+1=421 points. This has one more advantage: to convert a one-dimensional coordinate to two dimensions, the division is by 20 instead of 19 or 21, which is a lot easier for humans. As said before, computers don't care about such things, but it's a lot easier when seeing one-dimensional coordinates in your debugger this way. Trust me, it's a lot easier! After this you should understand the reason behind the constant values defined at the top of the class tesuji.games.go.util.GoArray.
So, let's see if I understand, when I reach the border in one side the next one will be a border to, so I don't need to tell there is a border. For example something like this (let's say a 9x9 board):

##########
#*********   <---The next one will be a border.
#*********
#*********
#*********
#*********
#*********
#*********
#*********
#*********
##########
OK, this is initially about the Go board. The Go board has all the information there is, still it's rather limited for a computer program to do anything useful. A Go board has points that can only be in one of three states: empty, a black stone or a white stone. So that's all that the array will contain. 
Well I can go with an integer, for example 1=black, 2=white, 3=not playable

This will be hard... very hard

Day 1: First ideas

Well, the time I was thinking about this go engine I displayed in my mind what classes would I need, what objects have the go game and this is the first approach (I know this will change a lot in the future, while I discover how things work):


Let's describe some of the packages and classes here:

Package: Material (will have all the "hardware" of the go game).

Class: Stone. 

Class: Board.

Package: Actors (will have the players)

Class: Actor. This is an abstract class with the methods that human players and the engine will need.

Class: Human. For human players. Inherits from Actor.

Class: Engine. For the go engine. Inherits from Actor.

Class: Ruleset. Well, I still don't know if put this class on this package or put it in another. this class will have the rules of the game and will determine if a move is valid or not. I thought of this as an actor because in some way it is kind of "judge".

Package: Showing (all the ays to show information of the game goes here)


Class: Console. To show the game on the console.

Package: Start (just to have the main class).


Class: Principal. Main class.


I know this will change a lot and this is just a first sketch of the program, so I accept all kind of comments and suggestions to make this better. 

Here it is, in NetBeans:


Day 1:Things I know about the go project



Well, let's start with the project, so here are some facts:


  • Name of the project: Evil Tesuji
  • Programming language: Java
  • Designing material: Paper, pen and a rubber (I will put all in paper before start to program, and I don't like to much tools like Visio, I think I can do it faster manually).
  • Other tools: My old notebook, NetBeans (maybe Eclipse in the future, let's see).
The way I will implement this project is first, write what I need to solve in kind of "requirement". If I need to do it in paper first, I will upload a picture of it, and then code. 
I understand this will be a good hobby, sometimes frustrating but in the way I know that I will learn a lot of things (about go, programming, english, etc.).

Well, let's start!!!!!!!!!!!!!!!!!!!!!!

Hello World


Thanks for coming to read my blog. My name is Pablo, and I am a go fan. In this blog I will try to document and keep a diary of a go engine that I will start to write. Also, some things about go, go world, computer go world and thing related to all this stuff will appear in this site.

 You can find me some times in KGS under the nickname "Draculinio", so if you see me don't hesitate to say hello to me or challenge me in the goban. If some day you visit Argentina, please come to play me and my friends at Club de Go Buenos Ayres, we will be really glad to play with you.

My other hobbies are running (in two months I will run my first marathon), playing RPG games (right now I am playing Mana Khemia, a really good game for PS2) and programming.

If you came here without knowing what is go, please look at the article in wikipedia, trust me, if you start with this, your way to live will change.

I have another blog where I post things about nerd stuff, programming, life, and whatever, it is in spanish. BTW, sorry for my horrible english, I am from Argentina and my knowledge of the language is not very good, I will try my bet but please be patient.

Well, welcome again to this blog, I hope you enjoy it.